Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    r32d6fdc r997185e  
    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;
    4948
    50 #include "SynTree/Type.h"                               // for Type
    51 #include "DeclarationNode.h"                            // for DeclarationNode, ...
    52 #include "ExpressionNode.h"                             // for ExpressionNode, ...
    53 #include "InitializerNode.h"                            // for InitializerNode, ...
    54 #include "ParserTypes.h"
    55 #include "StatementNode.h"                              // for build_...
     49#include "SynTree/Declaration.h"
     50#include "ParseNode.h"
    5651#include "TypedefTable.h"
    5752#include "TypeData.h"
     53#include "SynTree/LinkageSpec.h"
    5854#include "Common/SemanticError.h"                                               // error_str
    5955#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
    6056
    61 #include "SynTree/Attribute.h"                                                  // for Attribute
     57#include "SynTree/Attribute.h"     // for Attribute
    6258
    6359// lex uses __null in a boolean context, it's fine.
     
    6763
    6864extern DeclarationNode * parseTree;
    69 extern ast::Linkage::Spec linkage;
     65extern LinkageSpec::Spec linkage;
    7066extern TypedefTable typedefTable;
    7167
    72 stack<ast::Linkage::Spec> linkageStack;
     68stack<LinkageSpec::Spec> linkageStack;
    7369
    7470bool appendStr( string & to, string & from ) {
     
    203199} // fieldDecl
    204200
    205 #define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) )
    206 #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" ) ) )
    207203#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    208204#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     
    210206#define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
    211207
    212 static ForCtrl * makeForCtrl(
    213                 const CodeLocation & location,
    214                 DeclarationNode * init,
    215                 enum OperKinds compop,
    216                 ExpressionNode * comp,
    217                 ExpressionNode * inc ) {
    218         // Wrap both comp/inc if they are non-null.
    219         if ( comp ) comp = new ExpressionNode( build_binary_val( location,
    220                 compop,
    221                 new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
    222                 comp ) );
    223         if ( inc ) inc = new ExpressionNode( build_binary_val( location,
    224                 // choose += or -= for upto/downto
    225                 compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn,
    226                 new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
    227                 inc ) );
    228         // The StatementNode call frees init->name, it must happen later.
    229         return new ForCtrl( new StatementNode( init ), comp, inc );
    230 }
    231 
    232 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 ) {
    233209        if ( index->initializer ) {
    234210                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    237213                SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
    238214        } // if
    239         DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) );
    240         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 );
    241220} // forCtrl
    242221
    243 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    244         ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());
    245         if ( constant && (constant->rep == "0" || constant->rep == "1") ) {
    246                 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 ) ) );
    247226        } // if
    248         DeclarationNode * initDecl = distAttr(
    249                 DeclarationNode::newTypeof( type, true ),
    250                 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) )
    251         );
    252         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 );
    253234} // forCtrl
    254235
    255 ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    256         if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {
    257                 return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
    258         } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {
    259                 if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
    260                         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 );
    261242                } else {
    262243                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     
    300281%union {
    301282        Token tok;
    302         ExpressionNode * expr;
     283        ParseNode * pn;
     284        ExpressionNode * en;
    303285        DeclarationNode * decl;
    304         ast::AggregateDecl::Aggregate aggKey;
    305         ast::TypeDecl::Kind tclass;
    306         StatementNode * stmt;
    307         ClauseNode * clause;
    308         ast::WaitForStmt * wfs;
     286        AggregateDecl::Aggregate aggKey;
     287        TypeDecl::Kind tclass;
     288        StatementNode * sn;
     289        WaitForStmt * wfs;
     290        Expression * constant;
    309291        CondCtl * ifctl;
    310         ForCtrl * forctl;
    311         LabelNode * labels;
    312         InitializerNode * init;
    313         OperKinds oper;
     292        ForCtrl * fctl;
     293        OperKinds compop;
     294        LabelNode * label;
     295        InitializerNode * in;
     296        OperKinds op;
    314297        std::string * str;
    315         bool is_volatile;
    316         EnumHiding enum_hiding;
    317         ast::ExceptionKind except_kind;
    318         ast::GenericExpr * genexpr;
     298        bool flag;
     299        EnumHiding hide;
     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
     
    381364%type<tok> identifier                                   identifier_at                           identifier_or_type_name         attr_name
    382365%type<tok> quasi_keyword
    383 %type<expr> string_literal
     366%type<constant> string_literal
    384367%type<str> string_literal_list
    385368
    386 %type<enum_hiding> hide_opt                                     visible_hide_opt
     369%type<hide> hide_opt                                    visible_hide_opt
    387370
    388371// expressions
    389 %type<expr> constant
    390 %type<expr> tuple                                                       tuple_expression_list
    391 %type<oper> ptrref_operator                             unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
    392 %type<expr> primary_expression                  postfix_expression                      unary_expression
    393 %type<expr> cast_expression_list                        cast_expression                         exponential_expression          multiplicative_expression       additive_expression
    394 %type<expr> shift_expression                            relational_expression           equality_expression
    395 %type<expr> AND_expression                              exclusive_OR_expression         inclusive_OR_expression
    396 %type<expr> logical_AND_expression              logical_OR_expression
    397 %type<expr> conditional_expression              constant_expression                     assignment_expression           assignment_expression_opt
    398 %type<expr> comma_expression                            comma_expression_opt
    399 %type<expr> argument_expression_list_opt        argument_expression_list        argument_expression                     default_initializer_opt
     372%type<en> constant
     373%type<en> tuple                                                 tuple_expression_list
     374%type<op> ptrref_operator                               unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
     375%type<en> primary_expression                    postfix_expression                      unary_expression
     376%type<en> cast_expression_list                  cast_expression                         exponential_expression          multiplicative_expression       additive_expression
     377%type<en> shift_expression                              relational_expression           equality_expression
     378%type<en> AND_expression                                exclusive_OR_expression         inclusive_OR_expression
     379%type<en> logical_AND_expression                logical_OR_expression
     380%type<en> conditional_expression                constant_expression                     assignment_expression           assignment_expression_opt
     381%type<en> comma_expression                              comma_expression_opt
     382%type<en> argument_expression_list_opt  argument_expression_list        argument_expression                     default_initializer_opt
    400383%type<ifctl> conditional_declaration
    401 %type<forctl> for_control_expression            for_control_expression_list
    402 %type<oper> upupeq updown updowneq downupdowneq
    403 %type<expr> subrange
     384%type<fctl> for_control_expression              for_control_expression_list
     385%type<compop> upupeq updown updowneq downupdowneq
     386%type<en> subrange
    404387%type<decl> asm_name_opt
    405 %type<expr> asm_operands_opt                            asm_operands_list                       asm_operand
    406 %type<labels> label_list
    407 %type<expr> asm_clobbers_list_opt
    408 %type<is_volatile> asm_volatile_opt
    409 %type<expr> handler_predicate_opt
     388%type<en> asm_operands_opt                              asm_operands_list                       asm_operand
     389%type<label> label_list
     390%type<en> asm_clobbers_list_opt
     391%type<flag> asm_volatile_opt
     392%type<en> handler_predicate_opt
    410393%type<genexpr> generic_association              generic_assoc_list
    411394
    412395// statements
    413 %type<stmt> statement                                           labeled_statement                       compound_statement
    414 %type<stmt> statement_decl                              statement_decl_list                     statement_list_nodecl
    415 %type<stmt> selection_statement                 if_statement
    416 %type<clause> switch_clause_list_opt            switch_clause_list
    417 %type<expr> case_value
    418 %type<clause> case_clause                               case_value_list                         case_label                                      case_label_list
    419 %type<stmt> iteration_statement                 jump_statement
    420 %type<stmt> expression_statement                        asm_statement
    421 %type<stmt> with_statement
    422 %type<expr> with_clause_opt
    423 %type<stmt> exception_statement
    424 %type<clause> handler_clause                    finally_clause
    425 %type<except_kind> handler_key
    426 %type<stmt> mutex_statement
    427 %type<expr> when_clause                                 when_clause_opt                         waitfor         waituntil               timeout
    428 %type<stmt> waitfor_statement                           waituntil_statement
    429 %type<wfs> wor_waitfor_clause                   waituntil_clause                        wand_waituntil_clause   wor_waituntil_clause
     396%type<sn> statement                                             labeled_statement                       compound_statement
     397%type<sn> statement_decl                                statement_decl_list                     statement_list_nodecl
     398%type<sn> selection_statement                   if_statement
     399%type<sn> switch_clause_list_opt                switch_clause_list
     400%type<en> case_value
     401%type<sn> case_clause                                   case_value_list                         case_label                                      case_label_list
     402%type<sn> iteration_statement                   jump_statement
     403%type<sn> expression_statement                  asm_statement
     404%type<sn> with_statement
     405%type<en> with_clause_opt
     406%type<sn> exception_statement                   handler_clause                          finally_clause
     407%type<catch_kind> handler_key
     408%type<sn> mutex_statement
     409%type<en> when_clause                                   when_clause_opt                         waitfor                                         timeout
     410%type<sn> waitfor_statement
     411%type<wfs> waitfor_clause
    430412
    431413// declarations
     
    439421%type<decl> assertion assertion_list assertion_list_opt
    440422
    441 %type<expr> bit_subrange_size_opt bit_subrange_size
     423%type<en> bit_subrange_size_opt bit_subrange_size
    442424
    443425%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     
    452434
    453435%type<decl> enumerator_list enum_type enum_type_nobody
    454 %type<init> enumerator_value_opt
     436%type<in> enumerator_value_opt
    455437
    456438%type<decl> external_definition external_definition_list external_definition_list_opt
     
    459441
    460442%type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract
    461 %type<expr> field field_name_list field_name fraction_constants_opt
     443%type<en> field field_name_list field_name fraction_constants_opt
    462444
    463445%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    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
     
    508489%type<decl> type_parameter type_parameter_list type_initializer_opt
    509490
    510 %type<expr> type_parameters_opt type_list array_type_list
     491%type<en> type_parameters_opt type_list array_type_list
    511492
    512493%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    519500
    520501// initializers
    521 %type<init>  initializer initializer_list_opt initializer_opt
     502%type<in>  initializer initializer_list_opt initializer_opt
    522503
    523504// designators
    524 %type<expr>  designator designator_list designation
     505%type<en>  designator designator_list designation
    525506
    526507
     
    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                                                     { $$ = new ExpressionNode( 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, $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 ) ) ), $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        ;
     
    857833        | constant
    858834        | string_literal
    859                 { $$ = $1; }
     835                { $$ = new ExpressionNode( $1 ); }
    860836        | EXTENSION cast_expression                                                     // GCC
    861837                { $$ = $2->set_extension( true ); }
     
    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
    931907                { SemanticError( yylloc, "Return 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        ;
    12601237
    12611238case_value_list:                                                                                // CFA
    1262         case_value                                                                      { $$ = new ClauseNode( build_case( yylloc, $1 ) ); }
     1239        case_value                                                                      { $$ = new StatementNode( build_case( $1 ) ); }
    12631240                // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5"
    1264         | case_value_list ',' case_value                        { $$ = $1->set_last( new ClauseNode( build_case( yylloc, $3 ) ) ); }
     1241        | case_value_list ',' case_value                        { $$ = (StatementNode *)($1->set_last( new StatementNode( build_case( $3 ) ) ) ); }
    12651242        ;
    12661243
     
    12711248        | CASE case_value_list error                                            // syntax error
    12721249                { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
    1273         | DEFAULT ':'                                                           { $$ = new ClauseNode( 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
     
    12791256case_label_list:                                                                                // CFA
    12801257        case_label
    1281         | case_label_list case_label                            { $$ = $1->set_last( $2 ); }
     1258        | case_label_list case_label                            { $$ = (StatementNode *)( $1->set_last( $2 )); }
    12821259        ;
    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                 { $$ = $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                 { printf( "waituntil_clause 1\n" ); $$ = nullptr; }
    1688         | '(' wor_waituntil_clause ')'
    1689                 { printf( "waituntil_clause 2\n" ); $$ = nullptr; }
    1690         ;
    1691 
    1692 wand_waituntil_clause:
    1693         waituntil_clause                                                                        %prec THEN
    1694                 { printf( "wand_waituntil_clause 1\n" ); $$ = nullptr; }
    1695         | waituntil_clause wand wand_waituntil_clause
    1696                 { printf( "wand_waituntil_clause 2\n" ); $$ = nullptr; }
    1697         ;
    1698 
    1699 wor_waituntil_clause:
    1700         wand_waituntil_clause
    1701                 { printf( "wor_waituntil_clause 1\n" ); $$ = nullptr; }
    1702         | wor_waituntil_clause wor wand_waituntil_clause
    1703                 { printf( "wor_waituntil_clause 2\n" ); $$ = nullptr; }
    1704         | wor_waituntil_clause wor when_clause_opt ELSE statement
    1705                 { printf( "wor_waituntil_clause 3\n" ); $$ = nullptr; }
    1706         | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
    1707                 { printf( "wor_waituntil_clause 4\n" ); $$ = nullptr; }
    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                 { printf( "wor_waituntil_clause 6\n" ); $$ = nullptr; }
    1713         ;
    1714 
    1715 waituntil_statement:
    1716         wor_waituntil_clause                                                            %prec THEN
    1717                 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
    1718                 { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); }
     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 ) ); }
    17191643        ;
    17201644
    17211645exception_statement:
    1722         TRY compound_statement handler_clause                                   %prec THEN
    1723                 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
     1646        TRY compound_statement handler_clause                                   %prec THEN
     1647                { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
    17241648        | TRY compound_statement finally_clause
    1725                 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
     1649                { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }
    17261650        | TRY compound_statement handler_clause finally_clause
    1727                 { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
     1651                { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
    17281652        ;
    17291653
    17301654handler_clause:
    17311655        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1732                 { $$ = new ClauseNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
     1656                { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
    17331657        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1734                 { $$ = $1->set_last( new ClauseNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
     1658                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }
    17351659        ;
    17361660
     
    17421666
    17431667handler_key:
    1744         CATCH                                                                           { $$ = ast::Terminate; }
    1745         | RECOVER                                                                       { $$ = ast::Terminate; }
    1746         | CATCHRESUME                                                           { $$ = ast::Resume; }
    1747         | FIXUP                                                                         { $$ = ast::Resume; }
     1668        CATCH                                                                           { $$ = CatchStmt::Terminate; }
     1669        | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
     1670        | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
     1671        | FIXUP                                                                         { $$ = CatchStmt::Resume; }
    17481672        ;
    17491673
    17501674finally_clause:
    1751         FINALLY compound_statement                                      { $$ = new ClauseNode( build_finally( yylloc, $2 ) ); }
     1675        FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
    17521676        ;
    17531677
     
    17751699asm_statement:
    17761700        ASM asm_volatile_opt '(' string_literal ')' ';'
    1777                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
     1701                { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); }
    17781702        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1779                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
     1703                { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
    17801704        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1781                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
     1705                { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
    17821706        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';'
    1783                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
     1707                { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); }
    17841708        | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';'
    1785                 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
     1709                { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); }
    17861710        ;
    17871711
     
    18071731asm_operand:                                                                                    // GCC
    18081732        string_literal '(' constant_expression ')'
    1809                 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1733                { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    18101734        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1811                 {
    1812                         $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) );
    1813                         delete $2.str;
    1814                 }
     1735                { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); }
    18151736        ;
    18161737
     
    18191740                { $$ = nullptr; }                                                               // use default argument
    18201741        | string_literal
    1821                 { $$ = $1; }
     1742                { $$ = new ExpressionNode( $1 ); }
    18221743        | asm_clobbers_list_opt ',' string_literal
    1823                 { $$ = (ExpressionNode *)( $1->set_last( $3 ) ); }
     1744                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); }
    18241745        ;
    18251746
     
    18271748        identifier
    18281749                {
    1829                         $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
     1750                        $$ = new LabelNode(); $$->labels.push_back( *$1 );
    18301751                        delete $1;                                                                      // allocated by lexer
    18311752                }
    18321753        | label_list ',' identifier
    18331754                {
    1834                         $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
     1755                        $$ = $1; $1->labels.push_back( *$3 );
    18351756                        delete $3;                                                                      // allocated by lexer
    18361757                }
     
    18831804                {
    18841805                        // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" );
    1885                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     1806                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    18861807                        //   printf( "\tattr %s\n", attr->name.c_str() );
    18871808                        // } // for
     
    18931814static_assert:
    18941815        STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
    1895                 { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 ) ); }
     1816                { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
    18961817        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1897                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
     1818                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
    18981819
    18991820// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    19591880//      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
    19601881//              {
    1961 //                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );
     1882//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
    19621883//              }
    19631884//      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
    19641885//              {
    19651886//                      typedefTable.setNextIdentifier( *$5 );
    1966 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
     1887//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    19671888//              }
    19681889//      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
    19691890//              {
    19701891//                      typedefTable.setNextIdentifier( *$5 );
    1971 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
     1892//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    19721893//              }
    19731894//      | '[' ']' typegen_name
     
    19811902        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    19821903                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    1983                 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
     1904                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
    19841905        | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    1985                 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
     1906                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
    19861907        ;
    19871908
     
    20191940                {
    20201941                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
    2021                         if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) {
    2022                                 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr;
    2023                         } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
     1942                        $$ = $3->addType( $2 )->addTypedef();
    20241943                }
    20251944        | typedef_declaration pop ',' push declarator
     
    20291948                }
    20301949        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
    2031                 { 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                }
    20321954        | type_specifier TYPEDEF declarator
    2033                 { 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                }
    20341959        | type_specifier TYPEDEF type_qualifier_list declarator
    2035                 { 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                }
    20361964        ;
    20371965
     
    20401968        TYPEDEF identifier '=' assignment_expression
    20411969                {
    2042                         SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     1970                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    20431971                }
    20441972        | typedef_expression pop ',' push identifier '=' assignment_expression
    20451973                {
    2046                         SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     1974                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    20471975                }
    20481976        ;
     
    20541982        | typedef_expression                                                            // deprecated GCC, naming expression type
    20551983        | sue_declaration_specifier
    2056                 {
    2057                         assert( $1->type );
    2058                         if ( $1->type->qualifiers.any() ) {                     // CV qualifiers ?
    2059                                 SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr;
    2060                         }
    2061                         // enums are never empty declarations because there must have at least one enumeration.
    2062                         if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?
    2063                                 SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;
    2064                         }
    2065                 }
    20661984        ;
    20671985
     
    20691987                // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    20701988                // storage-class
    2071         variable_declarator asm_name_opt initializer_opt
     1989        declarator asm_name_opt initializer_opt
    20721990                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
    2073         | variable_type_redeclarator asm_name_opt initializer_opt
    2074                 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
    2075 
    2076         | general_function_declarator asm_name_opt
    2077                 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }
    2078         | general_function_declarator asm_name_opt '=' VOID
    2079                 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }
    2080 
    20811991        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    20821992                { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
    20831993        ;
    20841994
    2085 general_function_declarator:
    2086         function_type_redeclarator
    2087         | function_declarator
    2088         ;
    2089 
    20901995declaration_specifier:                                                                  // type specifier + storage class
    20911996        basic_declaration_specifier
     1997        | sue_declaration_specifier
    20921998        | type_declaration_specifier
    2093         | sue_declaration_specifier
    2094         | sue_declaration_specifier invalid_types
    2095                 {
    2096                         SemanticError( yylloc, ::toString( "Missing ';' after end of ",
    2097                                 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),
    2098                                 " declaration" ) );
    2099                         $$ = nullptr;
    2100                 }
    2101         ;
    2102 
    2103 invalid_types:
    2104         aggregate_key
    2105         | basic_type_name
    2106         | indirect_type
    21071999        ;
    21082000
     
    21212013        basic_type_specifier
    21222014        | 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                }
    21232021        | type_type_specifier
    21242022        ;
     
    21672065                { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); }
    21682066        | forall
    2169                 { $$ = DeclarationNode::newForall( $1 ); }
    21702067        ;
    21712068
    21722069forall:
    21732070        FORALL '(' type_parameter_list ')'                                      // CFA
    2174                 { $$ = $3; }
     2071                { $$ = DeclarationNode::newForall( $3 ); }
    21752072        ;
    21762073
     
    23292226                { $$ = DeclarationNode::newTypeof( $3 ); }
    23302227        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2331                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
     2228                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
    23322229        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    23332230                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    23422239                {
    23432240                        // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2344                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2241                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23452242                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23462243                        // } // for
     
    23582255                {
    23592256                        // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2360                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2257                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23612258                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23622259                        // } // for
     
    24362333                {
    24372334                        // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2438                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2335                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    24392336                        //   printf( "\tattr %s\n", attr->name.c_str() );
    24402337                        // } // for
     
    24602357          '{' field_declaration_list_opt '}' type_parameters_opt
    24612358                {
     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
    24622364                        $$ = 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
    24632369                }
    24642370        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     
    24692375          '{' field_declaration_list_opt '}' type_parameters_opt
    24702376                {
     2377                        // printf( "AGG3\n" );
    24712378                        DeclarationNode::newFromTypedef( $3 );
    24722379                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    24792386          '{' field_declaration_list_opt '}' type_parameters_opt
    24802387                {
     2388                        // printf( "AGG4\n" );
    24812389                        DeclarationNode::newFromTypeGen( $3, nullptr );
    24822390                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    25052413                        // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
    25062414                        // delete newFromTypeGen.
    2507                         if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) {
    2508                                 $$ = $3->addQualifiers( $2 );
    2509                         } else {
    2510                                 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
    2511                                 $3->type->symbolic.name = nullptr;                      // copied to $$
    2512                                 $3->type->symbolic.actuals = nullptr;
    2513                                 delete $3;
    2514                         }
     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;
    25152419                }
    25162420        ;
     
    25232427aggregate_data:
    25242428        STRUCT vtable_opt
    2525                 { $$ = ast::AggregateDecl::Struct; }
     2429                { $$ = AggregateDecl::Struct; }
    25262430        | UNION
    2527                 { $$ = ast::AggregateDecl::Union; }
     2431                { $$ = AggregateDecl::Union; }
    25282432        | EXCEPTION                                                                                     // CFA
    2529                 { $$ = ast::AggregateDecl::Exception; }
    2530           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
     2433                { $$ = AggregateDecl::Exception; }
     2434          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25312435        ;
    25322436
    25332437aggregate_control:                                                                              // CFA
    25342438        MONITOR
    2535                 { $$ = ast::AggregateDecl::Monitor; }
     2439                { $$ = AggregateDecl::Monitor; }
    25362440        | MUTEX STRUCT
    2537                 { $$ = ast::AggregateDecl::Monitor; }
     2441                { $$ = AggregateDecl::Monitor; }
    25382442        | GENERATOR
    2539                 { $$ = ast::AggregateDecl::Generator; }
     2443                { $$ = AggregateDecl::Generator; }
    25402444        | MUTEX GENERATOR
    2541                 {
    2542                         SemanticError( yylloc, "monitor generator is currently unimplemented." );
    2543                         $$ = ast::AggregateDecl::NoAggregate;
    2544                 }
     2445                { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25452446        | COROUTINE
    2546                 { $$ = ast::AggregateDecl::Coroutine; }
     2447                { $$ = AggregateDecl::Coroutine; }
    25472448        | MUTEX COROUTINE
    2548                 {
    2549                         SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
    2550                         $$ = ast::AggregateDecl::NoAggregate;
    2551                 }
     2449                { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25522450        | THREAD
    2553                 { $$ = ast::AggregateDecl::Thread; }
     2451                { $$ = AggregateDecl::Thread; }
    25542452        | MUTEX THREAD
    2555                 {
    2556                         SemanticError( yylloc, "monitor thread is currently unimplemented." );
    2557                         $$ = ast::AggregateDecl::NoAggregate;
    2558                 }
     2453                { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25592454        ;
    25602455
     
    25722467                        $$ = fieldDecl( $1, $2 );
    25732468                        // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2574                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2469                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    25752470                        //   printf( "\tattr %s\n", attr->name.c_str() );
    25762471                        // } // for
     
    25782473        | EXTENSION type_specifier field_declaring_list_opt ';' // GCC
    25792474                { $$ = fieldDecl( $2, $3 ); distExt( $$ ); }
    2580         | STATIC type_specifier field_declaring_list_opt ';' // CFA
    2581                 { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }
    25822475        | INLINE type_specifier field_abstract_list_opt ';'     // CFA
    25832476                {
     
    25902483                }
    25912484        | INLINE aggregate_control ';'                                          // CFA
    2592                 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
     2485                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    25932486        | typedef_declaration ';'                                                       // CFA
    25942487        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
     
    26162509                { $$ = $1->addBitfield( $2 ); }
    26172510        | variable_type_redeclarator bit_subrange_size_opt
    2618                 // A semantic check is required to ensure bit_subrange only appears on integral types.
    2619                 { $$ = $1->addBitfield( $2 ); }
    2620         | function_type_redeclarator bit_subrange_size_opt
    26212511                // A semantic check is required to ensure bit_subrange only appears on integral types.
    26222512                { $$ = $1->addBitfield( $2 ); }
     
    26732563                { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
    26742564        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2675                 {
    2676                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.any() )
     2565                {
     2566                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 )
    26772567                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    26782568
    26792569                        $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 );
    26802570                }
    2681         | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2682                 {
    2683                         $$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 );
    2684                 }
    26852571        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    26862572                {
    2687                         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." ); }
     2573                        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." ); }
    26882574                        typedefTable.makeTypedef( *$6 );
    26892575                }
     
    26912577                {
    26922578                        $$ = DeclarationNode::newEnum( $6, $11, true, true, $3, $9 )->addQualifiers( $5 )->addQualifiers( $7 );
    2693                 }
    2694         | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt
    2695           hide_opt '{' enumerator_list comma_opt '}'
    2696                 {
    2697                         $$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );
    26982579                }
    26992580        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt
     
    27012582                {
    27022583                        $$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3, $8 )->addQualifiers( $5 )->addQualifiers( $7 );
    2703                 }
    2704         | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt
    2705           hide_opt '{' enumerator_list comma_opt '}'
    2706                 {
    2707                         $$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );
    27082584                }
    27092585        | enum_type_nobody
     
    27192595enum_type_nobody:                                                                               // enum - {...}
    27202596        ENUM attribute_list_opt identifier
    2721                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }
     2597                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
    27222598        | ENUM attribute_list_opt type_name
    2723                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }
     2599                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
    27242600        ;
    27252601
     
    28182694
    28192695cfa_abstract_parameter_declaration:                                             // CFA, new & old style parameter declaration
    2820         abstract_parameter_declaration
     2696        // empty
     2697                { $$ = nullptr; }
     2698        | abstract_parameter_declaration
    28212699        | cfa_identifier_parameter_declarator_no_tuple
    28222700        | cfa_abstract_tuple
     
    28612739type_no_function:                                                                               // sizeof, alignof, cast (constructor)
    28622740        cfa_abstract_declarator_tuple                                           // CFA
    2863         | type_specifier                                                                        // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
     2741        | type_specifier
    28642742        | type_specifier abstract_declarator
    28652743                { $$ = $2->addType( $1 ); }
     
    29062784        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    29072785        | identifier_at ':'                                                                     // GCC, field name
    2908                 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
     2786                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    29092787        ;
    29102788
     
    29182796designator:
    29192797        '.' identifier_at                                                                       // C99, field name
    2920                 { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
     2798                { $$ = new ExpressionNode( build_varref( $2 ) ); }
    29212799        | '[' push assignment_expression pop ']'                        // C99, single array element
    29222800                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    29252803                { $$ = $3; }
    29262804        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2927                 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
     2805                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); }
    29282806        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    29292807                { $$ = $4; }
     
    29652843                {
    29662844                        typedefTable.addToScope( *$2, TYPEDEFname, "9" );
    2967                         if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
    2968                         if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
    2969                         if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
     2845                        if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
     2846                        if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     2847                        if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
    29702848                }
    29712849          type_initializer_opt assertion_list_opt
     
    29782856                {
    29792857                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2980                         $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
     2858                        $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
    29812859                }
    29822860        // | type_specifier identifier_parameter_declarator
    29832861        | assertion_list
    2984                 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2862                { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    29852863        ;
    29862864
    29872865new_type_class:                                                                                 // CFA
    29882866        // empty
    2989                 { $$ = ast::TypeDecl::Otype; }
     2867                { $$ = TypeDecl::Otype; }
    29902868        | '&'
    2991                 { $$ = ast::TypeDecl::Dtype; }
     2869                { $$ = TypeDecl::Dtype; }
    29922870        | '*'
    2993                 { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
     2871                { $$ = TypeDecl::DStype; }                                              // dtype + sized
    29942872        // | '(' '*' ')'
    2995         //      { $$ = ast::TypeDecl::Ftype; }
     2873        //      { $$ = TypeDecl::Ftype; }
    29962874        | ELLIPSIS
    2997                 { $$ = ast::TypeDecl::Ttype; }
     2875                { $$ = TypeDecl::Ttype; }
    29982876        ;
    29992877
    30002878type_class:                                                                                             // CFA
    30012879        OTYPE
    3002                 { $$ = ast::TypeDecl::Otype; }
     2880                { $$ = TypeDecl::Otype; }
    30032881        | DTYPE
    3004                 { $$ = ast::TypeDecl::Dtype; }
     2882                { $$ = TypeDecl::Dtype; }
    30052883        | FTYPE
    3006                 { $$ = ast::TypeDecl::Ftype; }
     2884                { $$ = TypeDecl::Ftype; }
    30072885        | TTYPE
    3008                 { $$ = ast::TypeDecl::Ttype; }
     2886                { $$ = TypeDecl::Ttype; }
    30092887        ;
    30102888
     
    30322910type_list:                                                                                              // CFA
    30332911        type
    3034                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     2912                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    30352913        | assignment_expression
    30362914        | type_list ',' type
    3037                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     2915                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    30382916        | type_list ',' assignment_expression
    30392917                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    30602938                {
    30612939                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    3062                         $$ = DeclarationNode::newTypeDecl( $1, nullptr );
     2940                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
    30632941                }
    30642942        | identifier_or_type_name '(' type_parameter_list ')'
     
    30712949trait_specifier:                                                                                // CFA
    30722950        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    3073                 {
    3074                         SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
    3075                         $$ = DeclarationNode::newTrait( $2, $4, nullptr );
    3076                 }
    3077         | forall TRAIT identifier_or_type_name '{' '}'          // alternate
    3078                 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); }
     2951                { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
    30792952        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    3080                 {
    3081                         SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
    3082                         $$ = DeclarationNode::newTrait( $2, $4, $8 );
    3083                 }
    3084         | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate
    3085                 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); }
     2953                { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
    30862954        ;
    30872955
     
    31423010external_definition:
    31433011        DIRECTIVE
    3144                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
     3012                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
    31453013        | declaration
    3146                 {
    3147                         // Variable declarations of anonymous types requires creating a unique type-name across multiple translation
    3148                         // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is
    3149                         // disallowed at the moment.
    3150                         if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
    3151                                 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
    3152                                         SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
    3153                                 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union
    3154                                         SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;
    3155                                 }
    3156                         }
    3157                 }
    31583014        | IDENTIFIER IDENTIFIER
    31593015                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
     
    31753031                }
    31763032        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3177                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
     3033                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
    31783034        | EXTERN STRINGliteral
    31793035                {
    31803036                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3181                         linkage = ast::Linkage::update( yylloc, linkage, $2 );
     3037                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
    31823038                }
    31833039          up external_definition down
     
    31903046                {
    31913047                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3192                         linkage = ast::Linkage::update( yylloc, linkage, $2 );
     3048                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
    31933049                }
    31943050          '{' up external_definition_list_opt down '}'
     
    32013057        | type_qualifier_list
    32023058                {
    3203                         if ( $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3059                        if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    32043060                        if ( $1->type->forall ) forall = true;          // remember generic type
    32053061                }
     
    32073063                {
    32083064                        distQual( $5, $1 );
    3209                         forall = false;
     3065                        forall = false;
    32103066                        $$ = $5;
    32113067                }
    32123068        | declaration_qualifier_list
    32133069                {
    3214                         if ( $1->type && $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3070                        if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    32153071                        if ( $1->type && $1->type->forall ) forall = true; // remember generic type
    32163072                }
     
    32183074                {
    32193075                        distQual( $5, $1 );
    3220                         forall = false;
     3076                        forall = false;
    32213077                        $$ = $5;
    32223078                }
    32233079        | declaration_qualifier_list type_qualifier_list
    32243080                {
    3225                         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." ); }
     3081                        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." ); }
    32263082                        if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type
    32273083                }
     
    32293085                {
    32303086                        distQual( $6, $1->addQualifiers( $2 ) );
    3231                         forall = false;
     3087                        forall = false;
    32323088                        $$ = $6;
    32333089                }
     
    32733129                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    32743130                }
    3275         | declaration_specifier function_type_redeclarator with_clause_opt compound_statement
     3131        | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
    32763132                {
    32773133                        rebindForall( $1, $2 );
     
    33093165        | variable_type_redeclarator
    33103166        | function_declarator
    3311         | function_type_redeclarator
    33123167        ;
    33133168
    33143169subrange:
    33153170        constant_expression '~' constant_expression                     // CFA, integer subrange
    3316                 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     3171                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
    33173172        ;
    33183173
     
    33233178                {
    33243179                        DeclarationNode * name = new DeclarationNode();
    3325                         name->asmName = maybeMoveBuild( $3 );
     3180                        name->asmName = $3;
    33263181                        $$ = name->addQualifiers( $5 );
    33273182                }
     
    34203275variable_ptr:
    34213276        ptrref_operator variable_declarator
    3422                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3277                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    34233278        | ptrref_operator type_qualifier_list variable_declarator
    34243279                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34363291        | '(' attribute_list variable_ptr ')' array_dimension
    34373292                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3438         | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     3293        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
    34393294                { $$ = $2->addArray( $4 ); }
    34403295        | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis
     
    34843339function_ptr:
    34853340        ptrref_operator function_declarator
    3486                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3341                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    34873342        | ptrref_operator type_qualifier_list function_declarator
    34883343                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35363391KR_function_ptr:
    35373392        ptrref_operator KR_function_declarator
    3538                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3393                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    35393394        | ptrref_operator type_qualifier_list KR_function_declarator
    35403395                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35603415        ;
    35613416
    3562 // This pattern parses a declaration for a variable that redefines a type name, e.g.:
     3417// This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.:
    35633418//
    35643419//              typedef int foo;
     
    35663421//                 int foo; // redefine typedef name in new scope
    35673422//              }
     3423//
     3424// The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
     3425// and functions versus pointers to arrays and functions.
    35683426
    35693427paren_type:
     
    35803438        paren_type attribute_list_opt
    35813439                { $$ = $1->addQualifiers( $2 ); }
    3582         | variable_type_ptr
    3583         | variable_type_array attribute_list_opt
     3440        | type_ptr
     3441        | type_array attribute_list_opt
    35843442                { $$ = $1->addQualifiers( $2 ); }
    3585         | variable_type_function attribute_list_opt
     3443        | type_function attribute_list_opt
    35863444                { $$ = $1->addQualifiers( $2 ); }
    35873445        ;
    35883446
    3589 variable_type_ptr:
     3447type_ptr:
    35903448        ptrref_operator variable_type_redeclarator
    3591                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3449                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    35923450        | ptrref_operator type_qualifier_list variable_type_redeclarator
    35933451                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3594         | '(' variable_type_ptr ')' attribute_list_opt          // redundant parenthesis
     3452        | '(' type_ptr ')' attribute_list_opt                           // redundant parenthesis
    35953453                { $$ = $2->addQualifiers( $4 ); }
    3596         | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis
     3454        | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis
    35973455                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    35983456        ;
    35993457
    3600 variable_type_array:
     3458type_array:
    36013459        paren_type array_dimension
    36023460                { $$ = $1->addArray( $2 ); }
    3603         | '(' variable_type_ptr ')' array_dimension
     3461        | '(' type_ptr ')' array_dimension
    36043462                { $$ = $2->addArray( $4 ); }
    3605         | '(' attribute_list variable_type_ptr ')' array_dimension
     3463        | '(' attribute_list type_ptr ')' array_dimension
    36063464                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3607         | '(' variable_type_array ')' multi_array_dimension     // redundant parenthesis
     3465        | '(' type_array ')' multi_array_dimension                      // redundant parenthesis
    36083466                { $$ = $2->addArray( $4 ); }
    3609         | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis
     3467        | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis
    36103468                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3611         | '(' variable_type_array ')'                                           // redundant parenthesis
     3469        | '(' type_array ')'                                                            // redundant parenthesis
    36123470                { $$ = $2; }
    3613         | '(' attribute_list variable_type_array ')'            // redundant parenthesis
     3471        | '(' attribute_list type_array ')'                                     // redundant parenthesis
    36143472                { $$ = $3->addQualifiers( $2 ); }
    36153473        ;
    36163474
    3617 variable_type_function:
    3618         '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3619                 { $$ = $2->addParamList( $6 ); }
    3620         | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3621                 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3622         | '(' variable_type_function ')'                                        // redundant parenthesis
    3623                 { $$ = $2; }
    3624         | '(' attribute_list variable_type_function ')'         // redundant parenthesis
    3625                 { $$ = $3->addQualifiers( $2 ); }
    3626         ;
    3627 
    3628 // This pattern parses a declaration for a function prototype that redefines a type name.  It precludes declaring an
    3629 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to
    3630 // arrays and functions.
    3631 
    3632 function_type_redeclarator:
    3633         function_type_no_ptr attribute_list_opt
    3634                 { $$ = $1->addQualifiers( $2 ); }
    3635         | function_type_ptr
    3636         | function_type_array attribute_list_opt
    3637                 { $$ = $1->addQualifiers( $2 ); }
    3638         ;
    3639 
    3640 function_type_no_ptr:
     3475type_function:
    36413476        paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36423477                { $$ = $1->addParamList( $4 ); }
    3643         | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
     3478        | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36443479                { $$ = $2->addParamList( $6 ); }
    3645         | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
     3480        | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36463481                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3647         | '(' function_type_no_ptr ')'                                          // redundant parenthesis
     3482        | '(' type_function ')'                                                         // redundant parenthesis
    36483483                { $$ = $2; }
    3649         | '(' attribute_list function_type_no_ptr ')'           // redundant parenthesis
    3650                 { $$ = $3->addQualifiers( $2 ); }
    3651         ;
    3652 
    3653 function_type_ptr:
    3654         ptrref_operator function_type_redeclarator
    3655                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    3656         | ptrref_operator type_qualifier_list function_type_redeclarator
    3657                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3658         | '(' function_type_ptr ')' attribute_list_opt
    3659                 { $$ = $2->addQualifiers( $4 ); }
    3660         | '(' attribute_list function_type_ptr ')' attribute_list_opt
    3661                 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    3662         ;
    3663 
    3664 function_type_array:
    3665         '(' function_type_ptr ')' array_dimension
    3666                 { $$ = $2->addArray( $4 ); }
    3667         | '(' attribute_list function_type_ptr ')' array_dimension
    3668                 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3669         | '(' function_type_array ')' multi_array_dimension     // redundant parenthesis
    3670                 { $$ = $2->addArray( $4 ); }
    3671         | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis
    3672                 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3673         | '(' function_type_array ')'                                           // redundant parenthesis
    3674                 { $$ = $2; }
    3675         | '(' attribute_list function_type_array ')'            // redundant parenthesis
     3484        | '(' attribute_list type_function ')'                          // redundant parenthesis
    36763485                { $$ = $3->addQualifiers( $2 ); }
    36773486        ;
     
    36963505identifier_parameter_ptr:
    36973506        ptrref_operator identifier_parameter_declarator
    3698                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3507                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    36993508        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    37003509                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    37533562type_parameter_ptr:
    37543563        ptrref_operator type_parameter_redeclarator
    3755                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3564                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    37563565        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    37573566                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    37963605abstract_ptr:
    37973606        ptrref_operator
    3798                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     3607                { $$ = DeclarationNode::newPointer( 0, $1 ); }
    37993608        | ptrref_operator type_qualifier_list
    38003609                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    38013610        | ptrref_operator abstract_declarator
    3802                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3611                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    38033612        | ptrref_operator type_qualifier_list abstract_declarator
    38043613                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38293638                // Only the first dimension can be empty.
    38303639        '[' ']'
    3831                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
     3640                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    38323641        | '[' ']' multi_array_dimension
    3833                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }
     3642                { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); }
    38343643                // Cannot use constant_expression because of tuples => semantic check
    38353644        | '[' push assignment_expression pop ',' comma_expression ']' // CFA
    3836                 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }
     3645                { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }
    38373646                // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; }
    38383647        | '[' push array_type_list pop ']'                                      // CFA
     
    38433652array_type_list:
    38443653        basic_type_name
    3845                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     3654                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    38463655        | type_name
    3847                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     3656                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    38483657        | assignment_expression upupeq assignment_expression
    38493658        | array_type_list ',' basic_type_name
    3850                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    3851         | array_type_list ',' type_name
    3852                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     3659                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3660        | array_type_list ',' type_name 
     3661                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    38533662        | array_type_list ',' assignment_expression upupeq assignment_expression
    38543663        ;
     
    38593668        | ErangeUpEq
    38603669                { $$ = OperKinds::LEThan; }
    3861         ;
     3670        ;
    38623671
    38633672multi_array_dimension:
    38643673        '[' push assignment_expression pop ']'
    3865                 { $$ = DeclarationNode::newArray( $3, nullptr, false ); }
     3674                { $$ = DeclarationNode::newArray( $3, 0, false ); }
    38663675        | '[' push '*' pop ']'                                                          // C99
    38673676                { $$ = DeclarationNode::newVarArray( 0 ); }
    38683677        | multi_array_dimension '[' push assignment_expression pop ']'
    3869                 { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }
     3678                { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
    38703679        | multi_array_dimension '[' push '*' pop ']'            // C99
    38713680                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
     
    39643773array_parameter_1st_dimension:
    39653774        '[' ']'
    3966                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
     3775                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    39673776                // multi_array_dimension handles the '[' '*' ']' case
    39683777        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    39693778                { $$ = DeclarationNode::newVarArray( $3 ); }
    39703779        | '[' push type_qualifier_list pop ']'
    3971                 { $$ = DeclarationNode::newArray( nullptr, $3, false ); }
     3780                { $$ = DeclarationNode::newArray( 0, $3, false ); }
    39723781                // multi_array_dimension handles the '[' assignment_expression ']' case
    39733782        | '[' push type_qualifier_list assignment_expression pop ']'
     
    39983807variable_abstract_ptr:
    39993808        ptrref_operator
    4000                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     3809                { $$ = DeclarationNode::newPointer( 0, $1 ); }
    40013810        | ptrref_operator type_qualifier_list
    40023811                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    40033812        | ptrref_operator variable_abstract_declarator
    4004                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3813                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40053814        | ptrref_operator type_qualifier_list variable_abstract_declarator
    40063815                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    40443853                // No SUE declaration in parameter list.
    40453854        ptrref_operator type_specifier_nobody
    4046                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3855                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40473856        | type_qualifier_list ptrref_operator type_specifier_nobody
    40483857                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    40493858        | ptrref_operator cfa_abstract_function
    4050                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3859                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40513860        | type_qualifier_list ptrref_operator cfa_abstract_function
    40523861                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    40533862        | ptrref_operator cfa_identifier_parameter_declarator_tuple
    4054                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3863                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40553864        | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple
    40563865                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
     
    40613870                // shift/reduce conflict with new-style empty (void) function return type.
    40623871        '[' ']' type_specifier_nobody
    4063                 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3872                { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40643873        | cfa_array_parameter_1st_dimension type_specifier_nobody
    40653874                { $$ = $2->addNewArray( $1 ); }
    40663875        | '[' ']' multi_array_dimension type_specifier_nobody
    4067                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3876                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40683877        | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody
    40693878                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    40723881
    40733882        | '[' ']' cfa_identifier_parameter_ptr
    4074                 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3883                { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40753884        | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr
    40763885                { $$ = $2->addNewArray( $1 ); }
    40773886        | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr
    4078                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3887                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40793888        | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr
    40803889                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    41323941cfa_abstract_ptr:                                                                               // CFA
    41333942        ptrref_operator type_specifier
    4134                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3943                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41353944        | type_qualifier_list ptrref_operator type_specifier
    41363945                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    41373946        | ptrref_operator cfa_abstract_function
    4138                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3947                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41393948        | type_qualifier_list ptrref_operator cfa_abstract_function
    41403949                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    41413950        | ptrref_operator cfa_abstract_declarator_tuple
    4142                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3951                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41433952        | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple
    41443953                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note: See TracChangeset for help on using the changeset viewer.