Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    rc86b08d r46da46b  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Apr  4 14:02:00 2023
    13 // Update Count     : 6329
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Nov 21 22:34:30 2022
     13// Update Count     : 5848
    1414//
    1515
     
    4444
    4545#include <cstdio>
    46 #include <sstream>
    4746#include <stack>
    4847using namespace std;
     
    5655#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
    5756
    58 #include "SynTree/Attribute.h"                                                  // for Attribute
     57#include "SynTree/Attribute.h"     // for Attribute
    5958
    6059// lex uses __null in a boolean context, it's fine.
     
    6463
    6564extern DeclarationNode * parseTree;
    66 extern ast::Linkage::Spec linkage;
     65extern LinkageSpec::Spec linkage;
    6766extern TypedefTable typedefTable;
    6867
    69 stack<ast::Linkage::Spec> linkageStack;
     68stack<LinkageSpec::Spec> linkageStack;
    7069
    7170bool appendStr( string & to, string & from ) {
     
    200199} // fieldDecl
    201200
    202 #define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) )
    203 #define NEW_ONE  new ExpressionNode( build_constantInteger( yylloc, *new string( "1" ) ) )
     201#define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
     202#define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
    204203#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    205204#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     
    207206#define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
    208207
    209 static ForCtrl * makeForCtrl(
    210                 const CodeLocation & location,
    211                 DeclarationNode * init,
    212                 enum OperKinds compop,
    213                 ExpressionNode * comp,
    214                 ExpressionNode * inc ) {
    215         // Wrap both comp/inc if they are non-null.
    216         if ( comp ) comp = new ExpressionNode( build_binary_val( location,
    217                 compop,
    218                 new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
    219                 comp ) );
    220         if ( inc ) inc = new ExpressionNode( build_binary_val( location,
    221                 // choose += or -= for upto/downto
    222                 compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn,
    223                 new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
    224                 inc ) );
    225         // The StatementNode call frees init->name, it must happen later.
    226         return new ForCtrl( new StatementNode( init ), comp, inc );
    227 }
    228 
    229 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     208ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    230209        if ( index->initializer ) {
    231210                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    234213                SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
    235214        } // if
    236         DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) );
    237         return makeForCtrl( location, initDecl, compop, comp, inc );
     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 );
    238220} // forCtrl
    239221
    240 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    241         ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());
    242         if ( constant && (constant->rep == "0" || constant->rep == "1") ) {
    243                 type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) );
     222ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     223        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
     224        if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
     225                type = new ExpressionNode( new CastExpr( maybeMoveBuild<Expression>(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
    244226        } // if
    245         DeclarationNode * initDecl = distAttr(
    246                 DeclarationNode::newTypeof( type, true ),
    247                 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) )
    248         );
    249         return makeForCtrl( location, initDecl, compop, comp, inc );
     227//      type = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__for_control_index_constraints__" ) ) ), type ) );
     228        return new ForCtrl(
     229                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
     230                // NULL comp/inc => leave blank
     231                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr,
     232                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 );
    250234} // forCtrl
    251235
    252 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    253         if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {
    254                 return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
    255         } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {
    256                 if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
    257                         return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
     236ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     237        if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {
     238                return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     239        } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {
     240                if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) {
     241                        return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
    258242                } else {
    259243                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     
    300284        ExpressionNode * en;
    301285        DeclarationNode * decl;
    302         ast::AggregateDecl::Aggregate aggKey;
    303         ast::TypeDecl::Kind tclass;
     286        AggregateDecl::Aggregate aggKey;
     287        TypeDecl::Kind tclass;
    304288        StatementNode * sn;
    305         ast::WaitForStmt * wfs;
    306     ast::WaitUntilStmt::ClauseNode * wuscn;
    307         ast::Expr * constant;
     289        WaitForStmt * wfs;
     290        Expression * constant;
    308291        CondCtl * ifctl;
    309292        ForCtrl * fctl;
     
    315298        bool flag;
    316299        EnumHiding hide;
    317         ast::ExceptionKind catch_kind;
    318         ast::GenericExpr * genexpr;
     300        CatchStmt::Kind catch_kind;
     301        GenericExpr * genexpr;
    319302}
    320303
    321 // ************************ TERMINAL TOKENS ********************************
     304//************************* TERMINAL TOKENS ********************************
    322305
    323306// keywords
     
    348331%token ATTRIBUTE EXTENSION                                                              // GCC
    349332%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
    350 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL // CFA
     333%token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR    // CFA
    351334%token DISABLE ENABLE TRY THROW THROWRESUME AT                  // CFA
    352335%token ASM                                                                                              // C99, extension ISO/IEC 9899:1999 Section J.5.10(1)
     
    354337
    355338// names and constants: lexer differentiates between identifier and typedef names
    356 %token<tok> IDENTIFIER          TYPEDIMname             TYPEDEFname             TYPEGENname
    357 %token<tok> TIMEOUT                     WAND    WOR                     CATCH                   RECOVER                 CATCHRESUME             FIXUP           FINALLY         // CFA
     339%token<tok> IDENTIFIER          QUOTED_IDENTIFIER       TYPEDIMname             TYPEDEFname             TYPEGENname
     340%token<tok> TIMEOUT                     WOR                                     CATCH                   RECOVER                 CATCHRESUME             FIXUP           FINALLY         // CFA
    358341%token<tok> INTEGERconstant     CHARACTERconstant       STRINGliteral
    359342%token<tok> DIRECTIVE
     
    424407%type<catch_kind> handler_key
    425408%type<sn> mutex_statement
    426 %type<en> when_clause                                   when_clause_opt                         waitfor         waituntil               timeout
    427 %type<sn> waitfor_statement                             waituntil_statement
    428 %type<wfs> wor_waitfor_clause
    429 %type<wuscn> waituntil_clause                   wand_waituntil_clause       wor_waituntil_clause
     409%type<en> when_clause                                   when_clause_opt                         waitfor                                         timeout
     410%type<sn> waitfor_statement
     411%type<wfs> waitfor_clause
    430412
    431413// declarations
     
    500482%type<decl> typedef_name typedef_declaration typedef_expression
    501483
    502 %type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function
    503 %type<decl> general_function_declarator function_type_redeclarator function_type_array function_type_no_ptr function_type_ptr
     484%type<decl> variable_type_redeclarator type_ptr type_array type_function
    504485
    505486%type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function
     
    531512// Similar issues exit with the waitfor statement.
    532513
    533 // Order of these lines matters (low-to-high precedence). THEN is left associative over WAND/WOR/TIMEOUT/ELSE, WAND/WOR
    534 // is left associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.
     514// Order of these lines matters (low-to-high precedence). THEN is left associative over WOR/TIMEOUT/ELSE, WOR is left
     515// associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.
    535516%precedence THEN                // rule precedence for IF/WAITFOR statement
    536 %precedence ANDAND              // token precedence for start of WAND in WAITFOR statement
    537 %precedence WAND                // token precedence for start of WAND in WAITFOR statement
    538 %precedence OROR                // token precedence for start of WOR in WAITFOR statement
    539517%precedence WOR                 // token precedence for start of WOR in WAITFOR statement
    540518%precedence TIMEOUT             // token precedence for start of TIMEOUT in WAITFOR statement
     
    614592constant:
    615593                // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
    616         INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( yylloc, *$1 ) ); }
    617         | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
    618         | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
    619         | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
    620         | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( yylloc, *$1 ) ); }
     594        INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }
     595        | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
     596        | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
     597        | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
     598        | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( *$1 ) ); }
    621599        ;
    622600
    623601quasi_keyword:                                                                                  // CFA
    624602        TIMEOUT
    625         | WAND
    626603        | WOR
    627604        | CATCH
     
    644621
    645622string_literal:
    646         string_literal_list                                                     { $$ = build_constantStr( yylloc, *$1 ); }
     623        string_literal_list                                                     { $$ = build_constantStr( *$1 ); }
    647624        ;
    648625
     
    661638primary_expression:
    662639        IDENTIFIER                                                                                      // typedef name cannot be used as a variable name
    663                 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
     640                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    664641        | quasi_keyword
    665                 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
     642                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    666643        | TYPEDIMname                                                                           // CFA, generic length argument
    667644                // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); }
    668645                // { $$ = new ExpressionNode( build_varref( $1 ) ); }
    669                 { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); }
     646                { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }
    670647        | tuple
    671648        | '(' comma_expression ')'
    672649                { $$ = $2; }
    673650        | '(' compound_statement ')'                                            // GCC, lambda expression
    674                 { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); }
     651                { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }
    675652        | type_name '.' identifier                                                      // CFA, nested type
    676                 { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
     653                { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
    677654        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    678655                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    680657                {
    681658                        // add the missing control expression to the GenericExpr and return it
    682                         $5->control = maybeMoveBuild( $3 );
     659                        $5->control = maybeMoveBuild<Expression>( $3 );
    683660                        $$ = new ExpressionNode( $5 );
    684661                }
     
    706683                {
    707684                        // steal the association node from the singleton and delete the wrapper
    708                         assert( 1 == $3->associations.size() );
    709                         $1->associations.push_back( $3->associations.front() );
     685                        $1->associations.splice($1->associations.end(), $3->associations);
    710686                        delete $3;
    711687                        $$ = $1;
     
    717693                {
    718694                        // create a GenericExpr wrapper with one association pair
    719                         $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );
     695                        $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } );
    720696                }
    721697        | DEFAULT ':' assignment_expression
    722                 { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }
     698                { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); }
    723699        ;
    724700
     
    729705                // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
    730706                // Current: Commas in subscripts make tuples.
    731                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
     707                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
    732708        | postfix_expression '[' assignment_expression ']'
    733709                // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
     
    735711                // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
    736712                // equivalent to the old x[i,j].
    737                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
     713                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
    738714        | constant '[' assignment_expression ']'                        // 3[a], 'a'[a], 3.5[a]
    739                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
     715                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
    740716        | string_literal '[' assignment_expression ']'          // "abc"[3], 3["abc"]
    741                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
     717                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
    742718        | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call
    743719                {
    744720                        Token fn;
    745721                        fn.str = new std::string( "?{}" );                      // location undefined - use location of '{'?
    746                         $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
     722                        $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
    747723                }
    748724        | postfix_expression '(' argument_expression_list_opt ')'
    749                 { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); }
     725                { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
    750726        | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')'
    751727                // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; }
    752                 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, new string( "__builtin_va_arg") ) ),
     728                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ),
    753729                                                                                           (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); }
    754730        | postfix_expression '`' identifier                                     // CFA, postfix call
    755                 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
     731                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
    756732        | constant '`' identifier                                                       // CFA, postfix call
    757                 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
     733                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
    758734        | string_literal '`' identifier                                         // CFA, postfix call
    759                 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
     735                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
    760736        | postfix_expression '.' identifier
    761                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
     737                { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
    762738        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
    763                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
     739                { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); }
    764740        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    765                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ) ) ); }
     741                { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
    766742        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    767                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
     743                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    768744        | postfix_expression '.' aggregate_control
    769                 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); }
     745                { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
    770746        | postfix_expression ARROW identifier
    771                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
     747                { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
    772748        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    773                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
     749                { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
    774750        | postfix_expression ARROW '[' field_name_list ']'      // CFA, tuple field selector
    775                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
     751                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
    776752        | postfix_expression ICR
    777                 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); }
     753                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
    778754        | postfix_expression DECR
    779                 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); }
     755                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); }
    780756        | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
    781                 { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); }
     757                { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
    782758        | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
    783                 { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
     759                { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
    784760        | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call
    785761                {
    786762                        Token fn;
    787763                        fn.str = new string( "^?{}" );                          // location undefined
    788                         $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
     764                        $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
    789765                }
    790766        ;
     
    805781        '@'                                                                                                     // CFA, default parameter
    806782                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
    807                 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
     783                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
    808784        | assignment_expression
    809785        ;
     
    817793        field_name
    818794        | FLOATING_DECIMALconstant field
    819                 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); }
     795                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
    820796        | FLOATING_DECIMALconstant '[' field_name_list ']'
    821                 { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc, $3 ) ) ); }
     797                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
    822798        | field_name '.' field
    823                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
     799                { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    824800        | field_name '.' '[' field_name_list ']'
    825                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
     801                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    826802        | field_name ARROW field
    827                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
     803                { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    828804        | field_name ARROW '[' field_name_list ']'
    829                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
     805                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
    830806        ;
    831807
    832808field_name:
    833809        INTEGERconstant fraction_constants_opt
    834                 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc, *$1 ), $2 ) ); }
     810                { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }
    835811        | FLOATINGconstant fraction_constants_opt
    836                 { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc, *$1 ), $2 ) ); }
     812                { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
    837813        | identifier_at fraction_constants_opt                          // CFA, allow anonymous fields
    838814                {
    839                         $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc, $1 ), $2 ) );
     815                        $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
    840816                }
    841817        ;
     
    846822        | fraction_constants_opt FLOATING_FRACTIONconstant
    847823                {
    848                         ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 );
    849                         $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1, constant ) ) : new ExpressionNode( constant );
     824                        Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
     825                        $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant );
    850826                }
    851827        ;
     
    866842                {
    867843                        switch ( $1 ) {
    868                         case OperKinds::AddressOf:
    869                                 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );
     844                          case OperKinds::AddressOf:
     845                                $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) );
    870846                                break;
    871                         case OperKinds::PointTo:
    872                                 $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) );
     847                          case OperKinds::PointTo:
     848                                $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
    873849                                break;
    874                         case OperKinds::And:
    875                                 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );
     850                          case OperKinds::And:
     851                                $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) );
    876852                                break;
    877                         default:
     853                          default:
    878854                                assert( false );
    879855                        }
    880856                }
    881857        | unary_operator cast_expression
    882                 { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); }
     858                { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }
    883859        | ICR unary_expression
    884                 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); }
     860                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Incr, $2 ) ); }
    885861        | DECR unary_expression
    886                 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); }
     862                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Decr, $2 ) ); }
    887863        | SIZEOF unary_expression
    888                 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
     864                { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
    889865        | SIZEOF '(' type_no_function ')'
    890                 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
     866                { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); }
    891867        | ALIGNOF unary_expression                                                      // GCC, variable alignment
    892                 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
     868                { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
    893869        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    894                 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
     870                { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
    895871        | OFFSETOF '(' type_no_function ',' identifier ')'
    896                 { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); }
     872                { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
    897873        | TYPEID '(' type_no_function ')'
    898874                {
     
    919895        unary_expression
    920896        | '(' type_no_function ')' cast_expression
    921                 { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
     897                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    922898        | '(' aggregate_control '&' ')' cast_expression         // CFA
    923                 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
     899                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    924900        | '(' aggregate_control '*' ')' cast_expression         // CFA
    925                 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
     901                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    926902        | '(' VIRTUAL ')' cast_expression                                       // CFA
    927                 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     903                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    928904        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    929                 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
     905                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); }
    930906        | '(' RETURN type_no_function ')' cast_expression       // CFA
    931                 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
     907                { $$ = new ExpressionNode( build_cast( $3, $5, CastExpr::Return ) ); }
    932908        | '(' COERCE type_no_function ')' cast_expression       // CFA
    933909                { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
     
    935911                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    936912//      | '(' type_no_function ')' tuple
    937 //              { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
     913//              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    938914        ;
    939915
     
    953929        cast_expression
    954930        | exponential_expression '\\' cast_expression
    955                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); }
     931                { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }
    956932        ;
    957933
     
    959935        exponential_expression
    960936        | multiplicative_expression '*' exponential_expression
    961                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); }
     937                { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }
    962938        | multiplicative_expression '/' exponential_expression
    963                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); }
     939                { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }
    964940        | multiplicative_expression '%' exponential_expression
    965                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); }
     941                { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }
    966942        ;
    967943
     
    969945        multiplicative_expression
    970946        | additive_expression '+' multiplicative_expression
    971                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); }
     947                { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }
    972948        | additive_expression '-' multiplicative_expression
    973                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); }
     949                { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }
    974950        ;
    975951
     
    977953        additive_expression
    978954        | shift_expression LS additive_expression
    979                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); }
     955                { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }
    980956        | shift_expression RS additive_expression
    981                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); }
     957                { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }
    982958        ;
    983959
     
    985961        shift_expression
    986962        | relational_expression '<' shift_expression
    987                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); }
     963                { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }
    988964        | relational_expression '>' shift_expression
    989                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); }
     965                { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }
    990966        | relational_expression LE shift_expression
    991                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); }
     967                { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }
    992968        | relational_expression GE shift_expression
    993                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); }
     969                { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }
    994970        ;
    995971
     
    997973        relational_expression
    998974        | equality_expression EQ relational_expression
    999                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); }
     975                { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }
    1000976        | equality_expression NE relational_expression
    1001                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); }
     977                { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }
    1002978        ;
    1003979
     
    1005981        equality_expression
    1006982        | AND_expression '&' equality_expression
    1007                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); }
     983                { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }
    1008984        ;
    1009985
     
    1011987        AND_expression
    1012988        | exclusive_OR_expression '^' AND_expression
    1013                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); }
     989                { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }
    1014990        ;
    1015991
     
    1017993        exclusive_OR_expression
    1018994        | inclusive_OR_expression '|' exclusive_OR_expression
    1019                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); }
     995                { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }
    1020996        ;
    1021997
     
    1023999        inclusive_OR_expression
    10241000        | logical_AND_expression ANDAND inclusive_OR_expression
    1025                 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); }
     1001                { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); }
    10261002        ;
    10271003
     
    10291005        logical_AND_expression
    10301006        | logical_OR_expression OROR logical_AND_expression
    1031                 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); }
     1007                { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); }
    10321008        ;
    10331009
     
    10351011        logical_OR_expression
    10361012        | logical_OR_expression '?' comma_expression ':' conditional_expression
    1037                 { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); }
     1013                { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
    10381014                // FIX ME: computes $1 twice
    10391015        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    1040                 { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); }
     1016                { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
    10411017        ;
    10421018
     
    10531029//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    10541030//                      } else {
    1055                                 $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) );
     1031                                $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
    10561032//                      } // if
    10571033                }
     
    10981074//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    10991075        '[' ',' tuple_expression_list ']'
    1100                 { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     1076                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    11011077        | '[' push assignment_expression pop ',' tuple_expression_list ']'
    1102                 { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); }
     1078                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }
    11031079        ;
    11041080
     
    11161092        assignment_expression
    11171093        | comma_expression ',' assignment_expression
    1118                 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1094                { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
    11191095        ;
    11201096
     
    11371113        | mutex_statement
    11381114        | waitfor_statement
    1139         | waituntil_statement
    11401115        | exception_statement
    11411116        | enable_disable_statement
     
    11431118        | asm_statement
    11441119        | DIRECTIVE
    1145                 { $$ = new StatementNode( build_directive( yylloc, $1 ) ); }
     1120                { $$ = new StatementNode( build_directive( $1 ) ); }
    11461121        ;
    11471122
     
    11491124                // labels cannot be identifiers 0 or 1
    11501125        identifier_or_type_name ':' attribute_list_opt statement
    1151                 { $$ = $4->add_label( yylloc, $1, $3 ); }
     1126                { $$ = $4->add_label( $1, $3 ); }
    11521127        | identifier_or_type_name ':' attribute_list_opt error // syntax error
    11531128                {
     
    11611136compound_statement:
    11621137        '{' '}'
    1163                 { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); }
     1138                { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
    11641139        | '{' push
    11651140          local_label_declaration_opt                                           // GCC, local labels appear at start of block
    11661141          statement_decl_list                                                           // C99, intermix declarations and statements
    11671142          pop '}'
    1168                 { $$ = new StatementNode( build_compound( yylloc, $4 ) ); }
     1143                { $$ = new StatementNode( build_compound( $4 ) ); }
    11691144        ;
    11701145
     
    11971172expression_statement:
    11981173        comma_expression_opt ';'
    1199                 { $$ = new StatementNode( build_expr( yylloc, $1 ) ); }
     1174                { $$ = new StatementNode( build_expr( $1 ) ); }
     1175        | MUTEX '(' ')' comma_expression ';'
     1176                { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); }
    12001177        ;
    12011178
     
    12061183                { $$ = $2; }
    12071184        | SWITCH '(' comma_expression ')' case_clause
    1208                 { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); }
     1185                { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
    12091186        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12101187                {
    1211                         StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) );
     1188                        StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
    12121189                        // The semantics of the declaration list is changed to include associated initialization, which is performed
    12131190                        // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
     
    12151192                        // therefore, are removed from the grammar even though C allows it. The change also applies to choose
    12161193                        // statement.
    1217                         $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1194                        $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    12181195                }
    12191196        | SWITCH '(' comma_expression ')' '{' error '}'         // CFA, syntax error
    12201197                { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    12211198        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    1222                 { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); }
     1199                { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
    12231200        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12241201                {
    1225                         StatementNode *sw = new StatementNode( build_switch( yylloc, false, $3, $8 ) );
    1226                         $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1202                        StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );
     1203                        $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    12271204                }
    12281205        | CHOOSE '(' comma_expression ')' '{' error '}'         // CFA, syntax error
     
    12331210        IF '(' conditional_declaration ')' statement            %prec THEN
    12341211                // explicitly deal with the shift/reduce conflict on if/else
    1235                 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); }
     1212                { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
    12361213        | IF '(' conditional_declaration ')' statement ELSE statement
    1237                 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); }
     1214                { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); }
    12381215        ;
    12391216
     
    12471224        | declaration comma_expression                                          // semi-colon separated
    12481225                { $$ = new CondCtl( $1, $2 ); }
    1249         ;
     1226        ;
    12501227
    12511228// CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case
     
    12551232        constant_expression                                                     { $$ = $1; }
    12561233        | constant_expression ELLIPSIS constant_expression      // GCC, subrange
    1257                 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1234                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
    12581235        | subrange                                                                                      // CFA, subrange
    12591236        ;
     
    12711248        | CASE case_value_list error                                            // syntax error
    12721249                { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
    1273         | DEFAULT ':'                                                           { $$ = new StatementNode( build_default( yylloc ) ); }
     1250        | DEFAULT ':'                                                           { $$ = new StatementNode( build_default() ); }
    12741251                // A semantic check is required to ensure only one default clause per switch/choose statement.
    12751252        | DEFAULT error                                                                         //  syntax error
     
    12831260
    12841261case_clause:                                                                                    // CFA
    1285         case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( yylloc, $2 ) ); }
     1262        case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }
    12861263        ;
    12871264
     
    12941271switch_clause_list:                                                                             // CFA
    12951272        case_label_list statement_list_nodecl
    1296                 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); }
     1273                { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
    12971274        | switch_clause_list case_label_list statement_list_nodecl
    1298                 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ) ); }
     1275                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
    12991276        ;
    13001277
    13011278iteration_statement:
    13021279        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1303                 { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); }
     1280                { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
    13041281        | WHILE '(' ')' statement ELSE statement                        // CFA
    13051282                {
    1306                         $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) );
    1307                         SemanticWarning( yylloc, Warning::SuperfluousElse );
     1283                        $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
     1284                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    13081285                }
    13091286        | WHILE '(' conditional_declaration ')' statement       %prec THEN
    1310                 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
     1287                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
    13111288        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
    1312                 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
     1289                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
    13131290        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1314                 { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); }
     1291                { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
    13151292        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    13161293                {
    1317                         $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) );
    1318                         SemanticWarning( yylloc, Warning::SuperfluousElse );
     1294                        $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
     1295                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    13191296                }
    13201297        | DO statement WHILE '(' comma_expression ')' ';'
    1321                 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); }
     1298                { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
    13221299        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
    1323                 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ), $8 ) ); }
     1300                { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
    13241301        | FOR '(' ')' statement                                                         %prec THEN // CFA => for ( ;; )
    1325                 { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); }
     1302                { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); }
    13261303        | FOR '(' ')' statement ELSE statement                          // CFA
    13271304                {
    1328                         $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) );
    1329                         SemanticWarning( yylloc, Warning::SuperfluousElse );
     1305                        $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) );
     1306                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    13301307                }
    13311308        | FOR '(' for_control_expression_list ')' statement     %prec THEN
    1332                 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
     1309                { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
    13331310        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
    1334                 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
     1311                { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
    13351312        ;
    13361313
     
    13461323                        if ( $1->condition ) {
    13471324                                if ( $3->condition ) {
    1348                                         $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr ) );
     1325                                        $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
    13491326                                } // if
    13501327                        } else $1->condition = $3->condition;
    13511328                        if ( $1->change ) {
    13521329                                if ( $3->change ) {
    1353                                         $1->change->expr.reset( new ast::CommaExpr( yylloc, $1->change->expr.release(), $3->change->expr.release() ) );
     1330                                        $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
    13541331                                } // if
    13551332                        } else $1->change = $3->change;
     
    13601337for_control_expression:
    13611338        ';' comma_expression_opt ';' comma_expression_opt
    1362                 { $$ = new ForCtrl( nullptr, $2, $4 ); }
     1339                { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
    13631340        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    1364                 {
    1365                         StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr;
    1366                         $$ = new ForCtrl( init, $3, $5 );
    1367                 }
     1341                { $$ = new ForCtrl( $1, $3, $5 ); }
    13681342        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    1369                 { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); }
     1343                { $$ = new ForCtrl( $1, $2, $4 ); }
    13701344
    13711345        | '@' ';' comma_expression                                                      // CFA, empty loop-index
    1372                 { $$ = new ForCtrl( nullptr, $3, nullptr ); }
     1346                { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }
    13731347        | '@' ';' comma_expression ';' comma_expression         // CFA, empty loop-index
    1374                 { $$ = new ForCtrl( nullptr, $3, $5 ); }
     1348                { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }
    13751349
    13761350        | comma_expression                                                                      // CFA, anonymous loop-index
    1377                 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
     1351                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
    13781352        | downupdowneq comma_expression                                         // CFA, anonymous loop-index
    1379                 { $$ = forCtrl( yylloc, $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
     1353                { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
    13801354
    13811355        | comma_expression updowneq comma_expression            // CFA, anonymous loop-index
    1382                 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
     1356                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
    13831357        | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
    13841358                {
    13851359                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1386                         else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
     1360                        else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
    13871361                }
    13881362        | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
     
    13921366                }
    13931367        | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    1394                 { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
     1368                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
    13951369        | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    13961370                {
    13971371                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1398                         else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
     1372                        else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
    13991373                }
    14001374        | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
     
    14151389
    14161390        | comma_expression ';' comma_expression                         // CFA
    1417                 { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1391                { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    14181392        | comma_expression ';' downupdowneq comma_expression // CFA
    1419                 { $$ = forCtrl( yylloc, $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
     1393                { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
    14201394
    14211395        | comma_expression ';' comma_expression updowneq comma_expression // CFA
    1422                 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
     1396                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
    14231397        | comma_expression ';' '@' updowneq comma_expression // CFA
    14241398                {
    14251399                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1426                         else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1400                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    14271401                }
    14281402        | comma_expression ';' comma_expression updowneq '@' // CFA
     
    14301404                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14311405                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1432                         else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
     1406                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    14331407                }
    14341408        | comma_expression ';' '@' updowneq '@'                         // CFA, error
     
    14361410
    14371411        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    1438                 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
     1412                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    14391413        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
    14401414                {
    14411415                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1442                         else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 );
     1416                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
    14431417                }
    14441418        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
     
    14461420                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14471421                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1448                         else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, $7 );
     1422                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
    14491423                }
    14501424        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    1451                 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
     1425                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    14521426        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
    14531427                {
    14541428                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1455                         else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr );
     1429                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
    14561430                }
    14571431        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
     
    14591433                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14601434                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1461                         else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, nullptr );
     1435                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
    14621436                }
    14631437        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
     
    14651439
    14661440        | declaration comma_expression                                          // CFA
    1467                 { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1441                { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    14681442        | declaration downupdowneq comma_expression                     // CFA
    1469                 { $$ = forCtrl( yylloc, $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
     1443                { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
    14701444
    14711445        | declaration comma_expression updowneq comma_expression // CFA
    1472                 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
     1446                { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
    14731447        | declaration '@' updowneq comma_expression                     // CFA
    14741448                {
    14751449                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1476                         else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE );
     1450                        else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
    14771451                }
    14781452        | declaration comma_expression updowneq '@'                     // CFA
     
    14801454                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14811455                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1482                         else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, NEW_ONE );
     1456                        else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
    14831457                }
    14841458
    14851459        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1486                 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
     1460                { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
    14871461        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    14881462                {
    14891463                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1490                         else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 );
     1464                        else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
    14911465                }
    14921466        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
     
    14941468                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14951469                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1496                         else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, $6 );
     1470                        else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
    14971471                }
    14981472        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1499                 { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
     1473                { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
    15001474        | declaration '@' updowneq comma_expression '~' '@' // CFA
    15011475                {
    15021476                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1503                         else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr );
     1477                        else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
    15041478                }
    15051479        | declaration comma_expression updowneq '@' '~' '@'     // CFA
     
    15071481                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    15081482                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1509                         else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr );
     1483                        else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
    15101484                }
    15111485        | declaration '@' updowneq '@' '~' '@'                          // CFA, error
     
    15221496                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    15231497                }
    1524         ;
     1498        ;
    15251499
    15261500downupdowneq:
     
    15311505        | ErangeDownEq
    15321506                { $$ = OperKinds::GEThan; }
    1533         ;
     1507        ;
    15341508
    15351509updown:
     
    15381512        | ErangeDown
    15391513                { $$ = OperKinds::GThan; }
    1540         ;
     1514        ;
    15411515
    15421516updowneq:
     
    15461520        | ErangeDownEq
    15471521                { $$ = OperKinds::GEThan; }
    1548         ;
     1522        ;
    15491523
    15501524jump_statement:
    15511525        GOTO identifier_or_type_name ';'
    1552                 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }
     1526                { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); }
    15531527        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    15541528                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    15571531                // A semantic check is required to ensure fallthru appears only in the body of a choose statement.
    15581532        | fall_through_name ';'                                                         // CFA
    1559                 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }
     1533                { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }
    15601534        | fall_through_name identifier_or_type_name ';'         // CFA
    1561                 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }
     1535                { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); }
    15621536        | fall_through_name DEFAULT ';'                                         // CFA
    1563                 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }
     1537                { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }
    15641538        | CONTINUE ';'
    15651539                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1566                 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }
     1540                { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); }
    15671541        | CONTINUE identifier_or_type_name ';'                          // CFA, multi-level continue
    15681542                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15691543                // the target of the transfer appears only at the start of an iteration statement.
    1570                 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }
     1544                { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); }
    15711545        | BREAK ';'
    15721546                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1573                 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }
     1547                { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); }
    15741548        | BREAK identifier_or_type_name ';'                                     // CFA, multi-level exit
    15751549                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15761550                // the target of the transfer appears only at the start of an iteration statement.
    1577                 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }
     1551                { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); }
    15781552        | RETURN comma_expression_opt ';'
    1579                 { $$ = new StatementNode( build_return( yylloc, $2 ) ); }
     1553                { $$ = new StatementNode( build_return( $2 ) ); }
    15801554        | RETURN '{' initializer_list_opt comma_opt '}' ';'
    15811555                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    15821556        | SUSPEND ';'
    1583                 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); }
     1557                { $$ = new StatementNode( build_suspend( nullptr ) ); }
    15841558        | SUSPEND compound_statement
    1585                 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); }
     1559                { $$ = new StatementNode( build_suspend( $2 ) ); }
    15861560        | SUSPEND COROUTINE ';'
    1587                 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }
     1561                { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); }
    15881562        | SUSPEND COROUTINE compound_statement
    1589                 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }
     1563                { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); }
    15901564        | SUSPEND GENERATOR ';'
    1591                 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }
     1565                { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); }
    15921566        | SUSPEND GENERATOR compound_statement
    1593                 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }
     1567                { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); }
    15941568        | THROW assignment_expression_opt ';'                           // handles rethrow
    1595                 { $$ = new StatementNode( build_throw( yylloc, $2 ) ); }
     1569                { $$ = new StatementNode( build_throw( $2 ) ); }
    15961570        | THROWRESUME assignment_expression_opt ';'                     // handles reresume
    1597                 { $$ = new StatementNode( build_resume( yylloc, $2 ) ); }
     1571                { $$ = new StatementNode( build_resume( $2 ) ); }
    15981572        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    15991573                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
     
    16071581with_statement:
    16081582        WITH '(' tuple_expression_list ')' statement
    1609                 { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); }
    1610         ;
    1611 
    1612 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so possibly change syntax to "with mutex".
     1583                { $$ = new StatementNode( build_with( $3, $5 ) ); }
     1584        ;
     1585
     1586// If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so change syntax to "with mutex".
    16131587mutex_statement:
    1614         MUTEX '(' argument_expression_list_opt ')' statement
    1615                 {
    1616                         if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; }
    1617                         $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) );
    1618                 }
     1588        MUTEX '(' argument_expression_list ')' statement
     1589                { $$ = new StatementNode( build_mutex( $3, $5 ) ); }
    16191590        ;
    16201591
     
    16271598                { $$ = nullptr; }
    16281599        | when_clause
     1600        ;
     1601
     1602waitfor:
     1603        WAITFOR '(' cast_expression ')'
     1604                { $$ = $3; }
     1605//      | WAITFOR '(' cast_expression ',' argument_expression_list_opt ')'
     1606//              { $$ = (ExpressionNode *)$3->set_last( $5 ); }
     1607        | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')'
     1608                { $$ = (ExpressionNode *)($3->set_last( $5 )); }
    16291609        ;
    16301610
     
    16371617
    16381618timeout:
    1639         TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
    1640         ;
    1641 
    1642 wor:
    1643         OROR
    1644         | WOR
    1645 
    1646 waitfor:
    1647         WAITFOR '(' cast_expression ')'
    1648                 { $$ = $3; }
    1649         | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')'
    1650                 { $$ = (ExpressionNode *)($3->set_last( $5 )); }
    1651         ;
    1652 
    1653 wor_waitfor_clause:
     1619        TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
     1620        ;
     1621
     1622waitfor_clause:
    16541623        when_clause_opt waitfor statement                                       %prec THEN
    1655                 // Called first: create header for WaitForStmt.
    1656                 { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); }
    1657         | wor_waitfor_clause wor when_clause_opt waitfor statement
    1658                 { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    1659         | wor_waitfor_clause wor when_clause_opt ELSE statement
    1660                 { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); }
    1661         | wor_waitfor_clause wor when_clause_opt timeout statement      %prec THEN
    1662                 { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
     1624                { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1 ); }
     1625        | when_clause_opt waitfor statement WOR waitfor_clause
     1626                { $$ = build_waitfor( $2, maybe_build_compound( $3 ), $1, $5 ); }
     1627        | when_clause_opt timeout statement                                     %prec THEN
     1628                { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1 ); }
     1629        | when_clause_opt ELSE statement
     1630                { $$ = build_waitfor_timeout( nullptr, maybe_build_compound( $3 ), $1 ); }
    16631631        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    1664         | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
     1632        | when_clause_opt timeout statement WOR ELSE statement // syntax error
    16651633                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    1666         | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1667                 { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); }
     1634        | when_clause_opt timeout statement WOR when_clause ELSE statement
     1635                { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1, maybe_build_compound( $7 ), $5 ); }
    16681636        ;
    16691637
    16701638waitfor_statement:
    1671         wor_waitfor_clause                                                                      %prec THEN
    1672                 { $$ = new StatementNode( $1 ); }
    1673         ;
    1674 
    1675 wand:
    1676         ANDAND
    1677         | WAND
    1678         ;
    1679 
    1680 waituntil:
    1681         WAITUNTIL '(' cast_expression ')'
    1682                 { $$ = $3; }
    1683         ;
    1684 
    1685 waituntil_clause:
    1686         when_clause_opt waituntil statement
    1687                 { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); }
    1688         | '(' wor_waituntil_clause ')'
    1689                 { $$ = $2; }
    1690         ;
    1691 
    1692 wand_waituntil_clause:
    1693         waituntil_clause                                                                        %prec THEN
    1694                 { $$ = $1; }
    1695         | waituntil_clause wand wand_waituntil_clause
    1696                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); }
    1697         ;
    1698 
    1699 wor_waituntil_clause:
    1700         wand_waituntil_clause
    1701                 { $$ = $1; }
    1702         | wor_waituntil_clause wor wand_waituntil_clause
    1703                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); }
    1704         | wor_waituntil_clause wor when_clause_opt ELSE statement
    1705                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    1706         | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
    1707                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); }
    1708         // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    1709         | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
    1710                 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    1711         | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1712                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1,
    1713                 new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR,
    1714                     build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ),
    1715                     build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); }
    1716         ;
    1717 
    1718 waituntil_statement:
    1719         wor_waituntil_clause                                                            %prec THEN
    1720                 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
    1721                 {
    1722             $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) );
    1723             // $$ = new StatementNode( build_compound( yylloc, nullptr ) );
    1724         }
     1639        when_clause_opt waitfor statement                                       %prec THEN
     1640                { $$ = new StatementNode( build_waitfor( $2, $3, $1 ) ); }
     1641        | when_clause_opt waitfor statement WOR waitfor_clause
     1642                { $$ = new StatementNode( build_waitfor( $2, $3, $1, $5 ) ); }
    17251643        ;
    17261644
    17271645exception_statement:
    1728         TRY compound_statement handler_clause                                   %prec THEN
    1729                 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
     1646        TRY compound_statement handler_clause                                   %prec THEN
     1647                { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
    17301648        | TRY compound_statement finally_clause
    1731                 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
     1649                { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }
    17321650        | TRY compound_statement handler_clause finally_clause
    1733                 { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
     1651                { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
    17341652        ;
    17351653
    17361654handler_clause:
    17371655        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1738                 { $$ = new StatementNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
     1656                { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
    17391657        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1740                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
     1658                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }
    17411659        ;
    17421660
     
    17481666
    17491667handler_key:
    1750         CATCH                                                                           { $$ = ast::Terminate; }
    1751         | RECOVER                                                                       { $$ = ast::Terminate; }
    1752         | CATCHRESUME                                                           { $$ = ast::Resume; }
    1753         | FIXUP                                                                         { $$ = ast::Resume; }
     1668        CATCH                                                                           { $$ = CatchStmt::Terminate; }
     1669        | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
     1670        | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
     1671        | FIXUP                                                                         { $$ = CatchStmt::Resume; }
    17541672        ;
    17551673
    17561674finally_clause:
    1757         FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( yylloc, $2 ) ); }
     1675        FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
    17581676        ;
    17591677
     
    17811699asm_statement:
    17821700        ASM asm_volatile_opt '(' string_literal ')' ';'
    1783                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
     1701                { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); }
    17841702        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1785                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
     1703                { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
    17861704        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1787                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
     1705                { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
    17881706        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';'
    1789                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
     1707                { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); }
    17901708        | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';'
    1791                 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
     1709                { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); }
    17921710        ;
    17931711
     
    18131731asm_operand:                                                                                    // GCC
    18141732        string_literal '(' constant_expression ')'
    1815                 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); }
     1733                { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    18161734        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1817                 {
    1818                         $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, $4, maybeMoveBuild( $6 ) ) );
    1819                         delete $2.str;
    1820                 }
     1735                { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); }
    18211736        ;
    18221737
     
    18331748        identifier
    18341749                {
    1835                         $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
     1750                        $$ = new LabelNode(); $$->labels.push_back( *$1 );
    18361751                        delete $1;                                                                      // allocated by lexer
    18371752                }
    18381753        | label_list ',' identifier
    18391754                {
    1840                         $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
     1755                        $$ = $1; $1->labels.push_back( *$3 );
    18411756                        delete $3;                                                                      // allocated by lexer
    18421757                }
     
    18891804                {
    18901805                        // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" );
    1891                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     1806                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    18921807                        //   printf( "\tattr %s\n", attr->name.c_str() );
    18931808                        // } // for
     
    19011816                { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
    19021817        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1903                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
     1818                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
    19041819
    19051820// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    19651880//      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
    19661881//              {
    1967 //                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );
     1882//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
    19681883//              }
    19691884//      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
    19701885//              {
    19711886//                      typedefTable.setNextIdentifier( *$5 );
    1972 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
     1887//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    19731888//              }
    19741889//      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
    19751890//              {
    19761891//                      typedefTable.setNextIdentifier( *$5 );
    1977 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
     1892//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    19781893//              }
    19791894//      | '[' ']' typegen_name
     
    19871902        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    19881903                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    1989                 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
     1904                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
    19901905        | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    1991                 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
     1906                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
    19921907        ;
    19931908
     
    20251940                {
    20261941                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
    2027                         if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) {
    2028                                 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr;
    2029                         } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
     1942                        $$ = $3->addType( $2 )->addTypedef();
    20301943                }
    20311944        | typedef_declaration pop ',' push declarator
     
    20351948                }
    20361949        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
    2037                 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
     1950                {
     1951                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" );
     1952                        $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
     1953                }
    20381954        | type_specifier TYPEDEF declarator
    2039                 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
     1955                {
     1956                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" );
     1957                        $$ = $3->addType( $1 )->addTypedef();
     1958                }
    20401959        | type_specifier TYPEDEF type_qualifier_list declarator
    2041                 { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
     1960                {
     1961                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" );
     1962                        $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
     1963                }
    20421964        ;
    20431965
     
    20461968        TYPEDEF identifier '=' assignment_expression
    20471969                {
    2048                         SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     1970                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    20491971                }
    20501972        | typedef_expression pop ',' push identifier '=' assignment_expression
    20511973                {
    2052                         SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     1974                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    20531975                }
    20541976        ;
     
    20601982        | typedef_expression                                                            // deprecated GCC, naming expression type
    20611983        | sue_declaration_specifier
    2062                 {
    2063                         assert( $1->type );
    2064                         if ( $1->type->qualifiers.any() ) {                     // CV qualifiers ?
    2065                                 SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr;
    2066                         }
    2067                         // enums are never empty declarations because there must have at least one enumeration.
    2068                         if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?
    2069                                 SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;
    2070                         }
    2071                 }
    20721984        ;
    20731985
     
    20751987                // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    20761988                // storage-class
    2077         variable_declarator asm_name_opt initializer_opt
     1989        declarator asm_name_opt initializer_opt
    20781990                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
    2079         | variable_type_redeclarator asm_name_opt initializer_opt
    2080                 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
    2081 
    2082         | general_function_declarator asm_name_opt
    2083                 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }
    2084         | general_function_declarator asm_name_opt '=' VOID
    2085                 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }
    2086 
    20871991        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    20881992                { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
    20891993        ;
    20901994
    2091 general_function_declarator:
    2092         function_type_redeclarator
    2093         | function_declarator
    2094         ;
    2095 
    20961995declaration_specifier:                                                                  // type specifier + storage class
    20971996        basic_declaration_specifier
     1997        | sue_declaration_specifier
    20981998        | type_declaration_specifier
    2099         | sue_declaration_specifier
    2100         | sue_declaration_specifier invalid_types
    2101                 {
    2102                         SemanticError( yylloc, ::toString( "Missing ';' after end of ",
    2103                                 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),
    2104                                 " declaration" ) );
    2105                         $$ = nullptr;
    2106                 }
    2107         ;
    2108 
    2109 invalid_types:
    2110         aggregate_key
    2111         | basic_type_name
    2112         | indirect_type
    21131999        ;
    21142000
     
    21272013        basic_type_specifier
    21282014        | sue_type_specifier
     2015                {
     2016                        // printf( "sue_type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
     2017                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2018                        //   printf( "\tattr %s\n", attr->name.c_str() );
     2019                        // } // for
     2020                }
    21292021        | type_type_specifier
    21302022        ;
     
    21732065                { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); }
    21742066        | forall
    2175                 { $$ = DeclarationNode::newForall( $1 ); }
    21762067        ;
    21772068
    21782069forall:
    21792070        FORALL '(' type_parameter_list ')'                                      // CFA
    2180                 { $$ = $3; }
     2071                { $$ = DeclarationNode::newForall( $3 ); }
    21812072        ;
    21822073
     
    23352226                { $$ = DeclarationNode::newTypeof( $3 ); }
    23362227        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2337                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
     2228                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
    23382229        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    23392230                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    23482239                {
    23492240                        // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2350                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2241                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23512242                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23522243                        // } // for
     
    23642255                {
    23652256                        // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2366                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2257                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23672258                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23682259                        // } // for
     
    24422333                {
    24432334                        // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2444                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2335                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    24452336                        //   printf( "\tattr %s\n", attr->name.c_str() );
    24462337                        // } // for
     
    24662357          '{' field_declaration_list_opt '}' type_parameters_opt
    24672358                {
     2359                        // printf( "aggregate_type1 %s\n", $3.str->c_str() );
     2360                        // if ( $2 )
     2361                        //      for ( Attribute * attr: reverseIterate( $2->attributes ) ) {
     2362                        //              printf( "copySpecifiers12 %s\n", attr->name.c_str() );
     2363                        //      } // for
    24682364                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     2365                        // printf( "aggregate_type2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
     2366                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2367                        //      printf( "aggregate_type3 %s\n", attr->name.c_str() );
     2368                        // } // for
    24692369                }
    24702370        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     
    24752375          '{' field_declaration_list_opt '}' type_parameters_opt
    24762376                {
     2377                        // printf( "AGG3\n" );
    24772378                        DeclarationNode::newFromTypedef( $3 );
    24782379                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    24852386          '{' field_declaration_list_opt '}' type_parameters_opt
    24862387                {
     2388                        // printf( "AGG4\n" );
    24872389                        DeclarationNode::newFromTypeGen( $3, nullptr );
    24882390                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    25112413                        // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
    25122414                        // delete newFromTypeGen.
    2513                         if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) {
    2514                                 $$ = $3->addQualifiers( $2 );
    2515                         } else {
    2516                                 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
    2517                                 $3->type->symbolic.name = nullptr;                      // copied to $$
    2518                                 $3->type->symbolic.actuals = nullptr;
    2519                                 delete $3;
    2520                         }
     2415                        $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
     2416                        $3->type->symbolic.name = nullptr;
     2417                        $3->type->symbolic.actuals = nullptr;
     2418                        delete $3;
    25212419                }
    25222420        ;
     
    25292427aggregate_data:
    25302428        STRUCT vtable_opt
    2531                 { $$ = ast::AggregateDecl::Struct; }
     2429                { $$ = AggregateDecl::Struct; }
    25322430        | UNION
    2533                 { $$ = ast::AggregateDecl::Union; }
     2431                { $$ = AggregateDecl::Union; }
    25342432        | EXCEPTION                                                                                     // CFA
    2535                 { $$ = ast::AggregateDecl::Exception; }
    2536           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
     2433                { $$ = AggregateDecl::Exception; }
     2434          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25372435        ;
    25382436
    25392437aggregate_control:                                                                              // CFA
    25402438        MONITOR
    2541                 { $$ = ast::AggregateDecl::Monitor; }
     2439                { $$ = AggregateDecl::Monitor; }
    25422440        | MUTEX STRUCT
    2543                 { $$ = ast::AggregateDecl::Monitor; }
     2441                { $$ = AggregateDecl::Monitor; }
    25442442        | GENERATOR
    2545                 { $$ = ast::AggregateDecl::Generator; }
     2443                { $$ = AggregateDecl::Generator; }
    25462444        | MUTEX GENERATOR
    2547                 {
    2548                         SemanticError( yylloc, "monitor generator is currently unimplemented." );
    2549                         $$ = ast::AggregateDecl::NoAggregate;
    2550                 }
     2445                { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25512446        | COROUTINE
    2552                 { $$ = ast::AggregateDecl::Coroutine; }
     2447                { $$ = AggregateDecl::Coroutine; }
    25532448        | MUTEX COROUTINE
    2554                 {
    2555                         SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
    2556                         $$ = ast::AggregateDecl::NoAggregate;
    2557                 }
     2449                { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25582450        | THREAD
    2559                 { $$ = ast::AggregateDecl::Thread; }
     2451                { $$ = AggregateDecl::Thread; }
    25602452        | MUTEX THREAD
    2561                 {
    2562                         SemanticError( yylloc, "monitor thread is currently unimplemented." );
    2563                         $$ = ast::AggregateDecl::NoAggregate;
    2564                 }
     2453                { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25652454        ;
    25662455
     
    25782467                        $$ = fieldDecl( $1, $2 );
    25792468                        // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2580                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2469                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    25812470                        //   printf( "\tattr %s\n", attr->name.c_str() );
    25822471                        // } // for
     
    25842473        | EXTENSION type_specifier field_declaring_list_opt ';' // GCC
    25852474                { $$ = fieldDecl( $2, $3 ); distExt( $$ ); }
    2586         | STATIC type_specifier field_declaring_list_opt ';' // CFA
    2587                 { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }
    25882475        | INLINE type_specifier field_abstract_list_opt ';'     // CFA
    25892476                {
     
    25962483                }
    25972484        | INLINE aggregate_control ';'                                          // CFA
    2598                 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
     2485                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    25992486        | typedef_declaration ';'                                                       // CFA
    26002487        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
     
    26222509                { $$ = $1->addBitfield( $2 ); }
    26232510        | variable_type_redeclarator bit_subrange_size_opt
    2624                 // A semantic check is required to ensure bit_subrange only appears on integral types.
    2625                 { $$ = $1->addBitfield( $2 ); }
    2626         | function_type_redeclarator bit_subrange_size_opt
    26272511                // A semantic check is required to ensure bit_subrange only appears on integral types.
    26282512                { $$ = $1->addBitfield( $2 ); }
     
    26792563                { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
    26802564        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2681                 {
    2682                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.any() )
     2565                {
     2566                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 )
    26832567                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    26842568
     
    26912575        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    26922576                {
    2693                         if ( $3->storageClasses.any() || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
     2577                        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." ); }
    26942578                        typedefTable.makeTypedef( *$6 );
    26952579                }
     
    27252609enum_type_nobody:                                                                               // enum - {...}
    27262610        ENUM attribute_list_opt identifier
    2727                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }
     2611                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
    27282612        | ENUM attribute_list_opt type_name
    2729                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }
     2613                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
    27302614        ;
    27312615
     
    28672751type_no_function:                                                                               // sizeof, alignof, cast (constructor)
    28682752        cfa_abstract_declarator_tuple                                           // CFA
    2869         | type_specifier                                                                        // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
     2753        | type_specifier
    28702754        | type_specifier abstract_declarator
    28712755                { $$ = $2->addType( $1 ); }
     
    29122796        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    29132797        | identifier_at ':'                                                                     // GCC, field name
    2914                 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
     2798                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    29152799        ;
    29162800
     
    29242808designator:
    29252809        '.' identifier_at                                                                       // C99, field name
    2926                 { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
     2810                { $$ = new ExpressionNode( build_varref( $2 ) ); }
    29272811        | '[' push assignment_expression pop ']'                        // C99, single array element
    29282812                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    29312815                { $$ = $3; }
    29322816        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2933                 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
     2817                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); }
    29342818        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    29352819                { $$ = $4; }
     
    29712855                {
    29722856                        typedefTable.addToScope( *$2, TYPEDEFname, "9" );
    2973                         if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
    2974                         if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
    2975                         if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
     2857                        if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
     2858                        if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     2859                        if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
    29762860                }
    29772861          type_initializer_opt assertion_list_opt
     
    29842868                {
    29852869                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2986                         $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
     2870                        $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
    29872871                }
    29882872        // | type_specifier identifier_parameter_declarator
    29892873        | assertion_list
    2990                 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2874                { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    29912875        ;
    29922876
    29932877new_type_class:                                                                                 // CFA
    29942878        // empty
    2995                 { $$ = ast::TypeDecl::Otype; }
     2879                { $$ = TypeDecl::Otype; }
    29962880        | '&'
    2997                 { $$ = ast::TypeDecl::Dtype; }
     2881                { $$ = TypeDecl::Dtype; }
    29982882        | '*'
    2999                 { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
     2883                { $$ = TypeDecl::DStype; }                                              // dtype + sized
    30002884        // | '(' '*' ')'
    3001         //      { $$ = ast::TypeDecl::Ftype; }
     2885        //      { $$ = TypeDecl::Ftype; }
    30022886        | ELLIPSIS
    3003                 { $$ = ast::TypeDecl::Ttype; }
     2887                { $$ = TypeDecl::Ttype; }
    30042888        ;
    30052889
    30062890type_class:                                                                                             // CFA
    30072891        OTYPE
    3008                 { $$ = ast::TypeDecl::Otype; }
     2892                { $$ = TypeDecl::Otype; }
    30092893        | DTYPE
    3010                 { $$ = ast::TypeDecl::Dtype; }
     2894                { $$ = TypeDecl::Dtype; }
    30112895        | FTYPE
    3012                 { $$ = ast::TypeDecl::Ftype; }
     2896                { $$ = TypeDecl::Ftype; }
    30132897        | TTYPE
    3014                 { $$ = ast::TypeDecl::Ttype; }
     2898                { $$ = TypeDecl::Ttype; }
    30152899        ;
    30162900
     
    30382922type_list:                                                                                              // CFA
    30392923        type
    3040                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     2924                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    30412925        | assignment_expression
    30422926        | type_list ',' type
    3043                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     2927                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    30442928        | type_list ',' assignment_expression
    30452929                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    30662950                {
    30672951                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    3068                         $$ = DeclarationNode::newTypeDecl( $1, nullptr );
     2952                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
    30692953                }
    30702954        | identifier_or_type_name '(' type_parameter_list ')'
     
    30772961trait_specifier:                                                                                // CFA
    30782962        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    3079                 {
    3080                         SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
    3081                         $$ = DeclarationNode::newTrait( $2, $4, nullptr );
    3082                 }
    3083         | forall TRAIT identifier_or_type_name '{' '}'          // alternate
    3084                 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); }
     2963                { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
    30852964        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    3086                 {
    3087                         SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
    3088                         $$ = DeclarationNode::newTrait( $2, $4, $8 );
    3089                 }
    3090         | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate
    3091                 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); }
     2965                { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
    30922966        ;
    30932967
     
    31483022external_definition:
    31493023        DIRECTIVE
    3150                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
     3024                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
    31513025        | declaration
    3152                 {
    3153                         // Variable declarations of anonymous types requires creating a unique type-name across multiple translation
    3154                         // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is
    3155                         // disallowed at the moment.
    3156                         if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
    3157                                 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
    3158                                         SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
    3159                                 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union
    3160                                         SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;
    3161                                 }
    3162                         }
    3163                 }
    31643026        | IDENTIFIER IDENTIFIER
    31653027                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
     
    31813043                }
    31823044        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3183                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
     3045                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
    31843046        | EXTERN STRINGliteral
    31853047                {
    31863048                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3187                         linkage = ast::Linkage::update( yylloc, linkage, $2 );
     3049                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
    31883050                }
    31893051          up external_definition down
     
    31963058                {
    31973059                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3198                         linkage = ast::Linkage::update( yylloc, linkage, $2 );
     3060                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
    31993061                }
    32003062          '{' up external_definition_list_opt down '}'
     
    32073069        | type_qualifier_list
    32083070                {
    3209                         if ( $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3071                        if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    32103072                        if ( $1->type->forall ) forall = true;          // remember generic type
    32113073                }
     
    32133075                {
    32143076                        distQual( $5, $1 );
    3215                         forall = false;
     3077                        forall = false;
    32163078                        $$ = $5;
    32173079                }
    32183080        | declaration_qualifier_list
    32193081                {
    3220                         if ( $1->type && $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3082                        if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    32213083                        if ( $1->type && $1->type->forall ) forall = true; // remember generic type
    32223084                }
     
    32243086                {
    32253087                        distQual( $5, $1 );
    3226                         forall = false;
     3088                        forall = false;
    32273089                        $$ = $5;
    32283090                }
    32293091        | declaration_qualifier_list type_qualifier_list
    32303092                {
    3231                         if ( ($1->type && $1->type->qualifiers.any()) || ($2->type && $2->type->qualifiers.any()) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3093                        if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    32323094                        if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type
    32333095                }
     
    32353097                {
    32363098                        distQual( $6, $1->addQualifiers( $2 ) );
    3237                         forall = false;
     3099                        forall = false;
    32383100                        $$ = $6;
    32393101                }
     
    32793141                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    32803142                }
    3281         | declaration_specifier function_type_redeclarator with_clause_opt compound_statement
     3143        | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
    32823144                {
    32833145                        rebindForall( $1, $2 );
     
    33153177        | variable_type_redeclarator
    33163178        | function_declarator
    3317         | function_type_redeclarator
    33183179        ;
    33193180
    33203181subrange:
    33213182        constant_expression '~' constant_expression                     // CFA, integer subrange
    3322                 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     3183                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
    33233184        ;
    33243185
     
    34263287variable_ptr:
    34273288        ptrref_operator variable_declarator
    3428                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3289                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    34293290        | ptrref_operator type_qualifier_list variable_declarator
    34303291                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34423303        | '(' attribute_list variable_ptr ')' array_dimension
    34433304                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3444         | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     3305        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
    34453306                { $$ = $2->addArray( $4 ); }
    34463307        | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis
     
    34903351function_ptr:
    34913352        ptrref_operator function_declarator
    3492                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3353                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    34933354        | ptrref_operator type_qualifier_list function_declarator
    34943355                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35423403KR_function_ptr:
    35433404        ptrref_operator KR_function_declarator
    3544                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3405                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    35453406        | ptrref_operator type_qualifier_list KR_function_declarator
    35463407                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35663427        ;
    35673428
    3568 // This pattern parses a declaration for a variable that redefines a type name, e.g.:
     3429// This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.:
    35693430//
    35703431//              typedef int foo;
     
    35723433//                 int foo; // redefine typedef name in new scope
    35733434//              }
     3435//
     3436// The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
     3437// and functions versus pointers to arrays and functions.
    35743438
    35753439paren_type:
     
    35863450        paren_type attribute_list_opt
    35873451                { $$ = $1->addQualifiers( $2 ); }
    3588         | variable_type_ptr
    3589         | variable_type_array attribute_list_opt
     3452        | type_ptr
     3453        | type_array attribute_list_opt
    35903454                { $$ = $1->addQualifiers( $2 ); }
    3591         | variable_type_function attribute_list_opt
     3455        | type_function attribute_list_opt
    35923456                { $$ = $1->addQualifiers( $2 ); }
    35933457        ;
    35943458
    3595 variable_type_ptr:
     3459type_ptr:
    35963460        ptrref_operator variable_type_redeclarator
    3597                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3461                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    35983462        | ptrref_operator type_qualifier_list variable_type_redeclarator
    35993463                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3600         | '(' variable_type_ptr ')' attribute_list_opt          // redundant parenthesis
     3464        | '(' type_ptr ')' attribute_list_opt                           // redundant parenthesis
    36013465                { $$ = $2->addQualifiers( $4 ); }
    3602         | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis
     3466        | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis
    36033467                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    36043468        ;
    36053469
    3606 variable_type_array:
     3470type_array:
    36073471        paren_type array_dimension
    36083472                { $$ = $1->addArray( $2 ); }
    3609         | '(' variable_type_ptr ')' array_dimension
     3473        | '(' type_ptr ')' array_dimension
    36103474                { $$ = $2->addArray( $4 ); }
    3611         | '(' attribute_list variable_type_ptr ')' array_dimension
     3475        | '(' attribute_list type_ptr ')' array_dimension
    36123476                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3613         | '(' variable_type_array ')' multi_array_dimension     // redundant parenthesis
     3477        | '(' type_array ')' multi_array_dimension                      // redundant parenthesis
    36143478                { $$ = $2->addArray( $4 ); }
    3615         | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis
     3479        | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis
    36163480                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3617         | '(' variable_type_array ')'                                           // redundant parenthesis
     3481        | '(' type_array ')'                                                            // redundant parenthesis
    36183482                { $$ = $2; }
    3619         | '(' attribute_list variable_type_array ')'            // redundant parenthesis
     3483        | '(' attribute_list type_array ')'                                     // redundant parenthesis
    36203484                { $$ = $3->addQualifiers( $2 ); }
    36213485        ;
    36223486
    3623 variable_type_function:
    3624         '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3625                 { $$ = $2->addParamList( $6 ); }
    3626         | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3627                 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3628         | '(' variable_type_function ')'                                        // redundant parenthesis
    3629                 { $$ = $2; }
    3630         | '(' attribute_list variable_type_function ')'         // redundant parenthesis
    3631                 { $$ = $3->addQualifiers( $2 ); }
    3632         ;
    3633 
    3634 // This pattern parses a declaration for a function prototype that redefines a type name.  It precludes declaring an
    3635 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to
    3636 // arrays and functions.
    3637 
    3638 function_type_redeclarator:
    3639         function_type_no_ptr attribute_list_opt
    3640                 { $$ = $1->addQualifiers( $2 ); }
    3641         | function_type_ptr
    3642         | function_type_array attribute_list_opt
    3643                 { $$ = $1->addQualifiers( $2 ); }
    3644         ;
    3645 
    3646 function_type_no_ptr:
     3487type_function:
    36473488        paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36483489                { $$ = $1->addParamList( $4 ); }
    3649         | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
     3490        | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36503491                { $$ = $2->addParamList( $6 ); }
    3651         | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
     3492        | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36523493                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3653         | '(' function_type_no_ptr ')'                                          // redundant parenthesis
     3494        | '(' type_function ')'                                                         // redundant parenthesis
    36543495                { $$ = $2; }
    3655         | '(' attribute_list function_type_no_ptr ')'           // redundant parenthesis
    3656                 { $$ = $3->addQualifiers( $2 ); }
    3657         ;
    3658 
    3659 function_type_ptr:
    3660         ptrref_operator function_type_redeclarator
    3661                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    3662         | ptrref_operator type_qualifier_list function_type_redeclarator
    3663                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3664         | '(' function_type_ptr ')' attribute_list_opt
    3665                 { $$ = $2->addQualifiers( $4 ); }
    3666         | '(' attribute_list function_type_ptr ')' attribute_list_opt
    3667                 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    3668         ;
    3669 
    3670 function_type_array:
    3671         '(' function_type_ptr ')' array_dimension
    3672                 { $$ = $2->addArray( $4 ); }
    3673         | '(' attribute_list function_type_ptr ')' array_dimension
    3674                 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3675         | '(' function_type_array ')' multi_array_dimension     // redundant parenthesis
    3676                 { $$ = $2->addArray( $4 ); }
    3677         | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis
    3678                 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3679         | '(' function_type_array ')'                                           // redundant parenthesis
    3680                 { $$ = $2; }
    3681         | '(' attribute_list function_type_array ')'            // redundant parenthesis
     3496        | '(' attribute_list type_function ')'                          // redundant parenthesis
    36823497                { $$ = $3->addQualifiers( $2 ); }
    36833498        ;
     
    37023517identifier_parameter_ptr:
    37033518        ptrref_operator identifier_parameter_declarator
    3704                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3519                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    37053520        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    37063521                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    37593574type_parameter_ptr:
    37603575        ptrref_operator type_parameter_redeclarator
    3761                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3576                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    37623577        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    37633578                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38023617abstract_ptr:
    38033618        ptrref_operator
    3804                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     3619                { $$ = DeclarationNode::newPointer( 0, $1 ); }
    38053620        | ptrref_operator type_qualifier_list
    38063621                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    38073622        | ptrref_operator abstract_declarator
    3808                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3623                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    38093624        | ptrref_operator type_qualifier_list abstract_declarator
    38103625                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38353650                // Only the first dimension can be empty.
    38363651        '[' ']'
    3837                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
     3652                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    38383653        | '[' ']' multi_array_dimension
    3839                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }
     3654                { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); }
    38403655                // Cannot use constant_expression because of tuples => semantic check
    38413656        | '[' push assignment_expression pop ',' comma_expression ']' // CFA
    3842                 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }
     3657                { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }
    38433658                // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; }
    38443659        | '[' push array_type_list pop ']'                                      // CFA
     
    38493664array_type_list:
    38503665        basic_type_name
    3851                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     3666                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    38523667        | type_name
    3853                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     3668                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    38543669        | assignment_expression upupeq assignment_expression
    38553670        | array_type_list ',' basic_type_name
    3856                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    3857         | array_type_list ',' type_name
    3858                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     3671                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3672        | array_type_list ',' type_name 
     3673                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    38593674        | array_type_list ',' assignment_expression upupeq assignment_expression
    38603675        ;
     
    38653680        | ErangeUpEq
    38663681                { $$ = OperKinds::LEThan; }
    3867         ;
     3682        ;
    38683683
    38693684multi_array_dimension:
    38703685        '[' push assignment_expression pop ']'
    3871                 { $$ = DeclarationNode::newArray( $3, nullptr, false ); }
     3686                { $$ = DeclarationNode::newArray( $3, 0, false ); }
    38723687        | '[' push '*' pop ']'                                                          // C99
    38733688                { $$ = DeclarationNode::newVarArray( 0 ); }
    38743689        | multi_array_dimension '[' push assignment_expression pop ']'
    3875                 { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }
     3690                { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
    38763691        | multi_array_dimension '[' push '*' pop ']'            // C99
    38773692                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
     
    39703785array_parameter_1st_dimension:
    39713786        '[' ']'
    3972                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
     3787                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    39733788                // multi_array_dimension handles the '[' '*' ']' case
    39743789        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    39753790                { $$ = DeclarationNode::newVarArray( $3 ); }
    39763791        | '[' push type_qualifier_list pop ']'
    3977                 { $$ = DeclarationNode::newArray( nullptr, $3, false ); }
     3792                { $$ = DeclarationNode::newArray( 0, $3, false ); }
    39783793                // multi_array_dimension handles the '[' assignment_expression ']' case
    39793794        | '[' push type_qualifier_list assignment_expression pop ']'
     
    40043819variable_abstract_ptr:
    40053820        ptrref_operator
    4006                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     3821                { $$ = DeclarationNode::newPointer( 0, $1 ); }
    40073822        | ptrref_operator type_qualifier_list
    40083823                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    40093824        | ptrref_operator variable_abstract_declarator
    4010                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3825                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40113826        | ptrref_operator type_qualifier_list variable_abstract_declarator
    40123827                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    40503865                // No SUE declaration in parameter list.
    40513866        ptrref_operator type_specifier_nobody
    4052                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3867                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40533868        | type_qualifier_list ptrref_operator type_specifier_nobody
    40543869                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    40553870        | ptrref_operator cfa_abstract_function
    4056                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3871                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40573872        | type_qualifier_list ptrref_operator cfa_abstract_function
    40583873                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    40593874        | ptrref_operator cfa_identifier_parameter_declarator_tuple
    4060                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3875                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40613876        | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple
    40623877                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
     
    40673882                // shift/reduce conflict with new-style empty (void) function return type.
    40683883        '[' ']' type_specifier_nobody
    4069                 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3884                { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40703885        | cfa_array_parameter_1st_dimension type_specifier_nobody
    40713886                { $$ = $2->addNewArray( $1 ); }
    40723887        | '[' ']' multi_array_dimension type_specifier_nobody
    4073                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3888                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40743889        | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody
    40753890                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    40783893
    40793894        | '[' ']' cfa_identifier_parameter_ptr
    4080                 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3895                { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40813896        | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr
    40823897                { $$ = $2->addNewArray( $1 ); }
    40833898        | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr
    4084                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3899                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40853900        | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr
    40863901                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    41383953cfa_abstract_ptr:                                                                               // CFA
    41393954        ptrref_operator type_specifier
    4140                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3955                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41413956        | type_qualifier_list ptrref_operator type_specifier
    41423957                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    41433958        | ptrref_operator cfa_abstract_function
    4144                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3959                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41453960        | type_qualifier_list ptrref_operator cfa_abstract_function
    41463961                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    41473962        | ptrref_operator cfa_abstract_declarator_tuple
    4148                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3963                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41493964        | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple
    41503965                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note: See TracChangeset for help on using the changeset viewer.