Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    r0442f93f r46da46b  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun  7 14:32:28 2023
    13 // Update Count     : 6341
     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 ) {
     
    108104        assert( declList );
    109105        // printf( "distAttr1 typeSpec %p\n", typeSpec ); typeSpec->print( std::cout );
    110         DeclarationNode * cl = (new DeclarationNode)->addType( typeSpec );
     106        DeclarationNode * cur = declList, * cl = (new DeclarationNode)->addType( typeSpec );
    111107        // printf( "distAttr2 cl %p\n", cl ); cl->type->print( std::cout );
    112108        // cl->type->aggregate.name = cl->type->aggInst.aggregate->aggregate.name;
    113109
    114         for ( DeclarationNode * cur = dynamic_cast<DeclarationNode *>( declList->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) {
     110        for ( cur = dynamic_cast<DeclarationNode *>( cur->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) {
    115111                cl->cloneBaseType( cur );
    116112        } // for
     
    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)
    208 #define MISSING_ANON_FIELD "syntax error, missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
    209 #define MISSING_LOW "syntax error, missing low value for up-to range so index is uninitialized."
    210 #define MISSING_HIGH "syntax error, missing high value for down-to range so index is uninitialized."
    211 
    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 ) {
     204#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     205#define MISSING_LOW "Missing low value for up-to range so index is uninitialized."
     206#define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
     207
     208ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    233209        if ( index->initializer ) {
    234                 SemanticError( yylloc, "syntax error, direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     210                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
    235211        } // if
    236212        if ( index->next ) {
    237                 SemanticError( yylloc, "syntax error, multiple loop indexes disallowed in for-loop declaration." );
     213                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 {
    262                         SemanticError( yylloc, "syntax error, loop-index name missing. Expression disallowed." ); return nullptr;
     243                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
    263244                } // if
    264245        } else {
    265                 SemanticError( yylloc, "syntax error, loop-index name missing. Expression disallowed. ." ); return nullptr;
     246                SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
    266247        } // if
    267248} // forCtrl
    268249
    269250static void IdentifierBeforeIdentifier( string & identifier1, string & identifier2, const char * kind ) {
    270         SemanticError( yylloc, ::toString( "syntax error, adjacent identifiers \"", identifier1, "\" and \"", identifier2, "\" are not meaningful in a", kind, ".\n"
     251        SemanticError( yylloc, ::toString( "Adjacent identifiers \"", identifier1, "\" and \"", identifier2, "\" are not meaningful in a", kind, ".\n"
    271252                                   "Possible cause is misspelled type name or missing generic parameter." ) );
    272253} // IdentifierBeforeIdentifier
    273254
    274255static void IdentifierBeforeType( string & identifier, const char * kind ) {
    275         SemanticError( yylloc, ::toString( "syntax error, identifier \"", identifier, "\" cannot appear before a ", kind, ".\n"
     256        SemanticError( yylloc, ::toString( "Identifier \"", identifier, "\" cannot appear before a ", kind, ".\n"
    276257                                   "Possible cause is misspelled storage/CV qualifier, misspelled typename, or missing generic parameter." ) );
    277258} // IdentifierBeforeType
     
    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;
    309     ast::WaitUntilStmt::ClauseNode * wucn;
     286        AggregateDecl::Aggregate aggKey;
     287        TypeDecl::Kind tclass;
     288        StatementNode * sn;
     289        WaitForStmt * wfs;
     290        Expression * constant;
    310291        CondCtl * ifctl;
    311         ForCtrl * forctl;
    312         LabelNode * labels;
    313         InitializerNode * init;
    314         OperKinds oper;
     292        ForCtrl * fctl;
     293        OperKinds compop;
     294        LabelNode * label;
     295        InitializerNode * in;
     296        OperKinds op;
    315297        std::string * str;
    316         bool is_volatile;
    317         EnumHiding enum_hiding;
    318         ast::ExceptionKind except_kind;
    319         ast::GenericExpr * genexpr;
     298        bool flag;
     299        EnumHiding hide;
     300        CatchStmt::Kind catch_kind;
     301        GenericExpr * genexpr;
    320302}
    321303
    322 // ************************ TERMINAL TOKENS ********************************
     304//************************* TERMINAL TOKENS ********************************
    323305
    324306// keywords
     
    349331%token ATTRIBUTE EXTENSION                                                              // GCC
    350332%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
    351 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL // CFA
     333%token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR    // CFA
    352334%token DISABLE ENABLE TRY THROW THROWRESUME AT                  // CFA
    353335%token ASM                                                                                              // C99, extension ISO/IEC 9899:1999 Section J.5.10(1)
     
    355337
    356338// names and constants: lexer differentiates between identifier and typedef names
    357 %token<tok> IDENTIFIER          TYPEDIMname             TYPEDEFname             TYPEGENname
    358 %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
    359341%token<tok> INTEGERconstant     CHARACTERconstant       STRINGliteral
    360342%token<tok> DIRECTIVE
     
    382364%type<tok> identifier                                   identifier_at                           identifier_or_type_name         attr_name
    383365%type<tok> quasi_keyword
    384 %type<expr> string_literal
     366%type<constant> string_literal
    385367%type<str> string_literal_list
    386368
    387 %type<enum_hiding> hide_opt                                     visible_hide_opt
     369%type<hide> hide_opt                                    visible_hide_opt
    388370
    389371// expressions
    390 %type<expr> constant
    391 %type<expr> tuple                                                       tuple_expression_list
    392 %type<oper> ptrref_operator                             unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
    393 %type<expr> primary_expression                  postfix_expression                      unary_expression
    394 %type<expr> cast_expression_list                        cast_expression                         exponential_expression          multiplicative_expression       additive_expression
    395 %type<expr> shift_expression                            relational_expression           equality_expression
    396 %type<expr> AND_expression                              exclusive_OR_expression         inclusive_OR_expression
    397 %type<expr> logical_AND_expression              logical_OR_expression
    398 %type<expr> conditional_expression              constant_expression                     assignment_expression           assignment_expression_opt
    399 %type<expr> comma_expression                            comma_expression_opt
    400 %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
    401383%type<ifctl> conditional_declaration
    402 %type<forctl> for_control_expression            for_control_expression_list
    403 %type<oper> upupeq updown updowneq downupdowneq
    404 %type<expr> subrange
     384%type<fctl> for_control_expression              for_control_expression_list
     385%type<compop> upupeq updown updowneq downupdowneq
     386%type<en> subrange
    405387%type<decl> asm_name_opt
    406 %type<expr> asm_operands_opt                            asm_operands_list                       asm_operand
    407 %type<labels> label_list
    408 %type<expr> asm_clobbers_list_opt
    409 %type<is_volatile> asm_volatile_opt
    410 %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
    411393%type<genexpr> generic_association              generic_assoc_list
    412394
    413395// statements
    414 %type<stmt> statement                                           labeled_statement                       compound_statement
    415 %type<stmt> statement_decl                              statement_decl_list                     statement_list_nodecl
    416 %type<stmt> selection_statement                 if_statement
    417 %type<clause> switch_clause_list_opt            switch_clause_list
    418 %type<expr> case_value
    419 %type<clause> case_clause                               case_value_list                         case_label                                      case_label_list
    420 %type<stmt> iteration_statement                 jump_statement
    421 %type<stmt> expression_statement                        asm_statement
    422 %type<stmt> with_statement
    423 %type<expr> with_clause_opt
    424 %type<stmt> exception_statement
    425 %type<clause> handler_clause                    finally_clause
    426 %type<except_kind> handler_key
    427 %type<stmt> mutex_statement
    428 %type<expr> when_clause                                 when_clause_opt                         waitfor         waituntil               timeout
    429 %type<stmt> waitfor_statement                           waituntil_statement
    430 %type<wfs> wor_waitfor_clause
    431 %type<wucn> 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
    432412
    433413// declarations
     
    441421%type<decl> assertion assertion_list assertion_list_opt
    442422
    443 %type<expr> bit_subrange_size_opt bit_subrange_size
     423%type<en> bit_subrange_size_opt bit_subrange_size
    444424
    445425%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     
    454434
    455435%type<decl> enumerator_list enum_type enum_type_nobody
    456 %type<init> enumerator_value_opt
     436%type<in> enumerator_value_opt
    457437
    458438%type<decl> external_definition external_definition_list external_definition_list_opt
     
    461441
    462442%type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract
    463 %type<expr> field field_name_list field_name fraction_constants_opt
     443%type<en> field field_name_list field_name fraction_constants_opt
    464444
    465445%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    502482%type<decl> typedef_name typedef_declaration typedef_expression
    503483
    504 %type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function
    505 %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
    506485
    507486%type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function
     
    510489%type<decl> type_parameter type_parameter_list type_initializer_opt
    511490
    512 %type<expr> type_parameters_opt type_list array_type_list
     491%type<en> type_parameters_opt type_list array_type_list
    513492
    514493%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    521500
    522501// initializers
    523 %type<init>  initializer initializer_list_opt initializer_opt
     502%type<in>  initializer initializer_list_opt initializer_opt
    524503
    525504// designators
    526 %type<expr>  designator designator_list designation
     505%type<en>  designator designator_list designation
    527506
    528507
     
    533512// Similar issues exit with the waitfor statement.
    534513
    535 // Order of these lines matters (low-to-high precedence). THEN is left associative over WAND/WOR/TIMEOUT/ELSE, WAND/WOR
    536 // 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.
    537516%precedence THEN                // rule precedence for IF/WAITFOR statement
    538 %precedence ANDAND              // token precedence for start of WAND in WAITFOR statement
    539 %precedence WAND                // token precedence for start of WAND in WAITFOR statement
    540 %precedence OROR                // token precedence for start of WOR in WAITFOR statement
    541517%precedence WOR                 // token precedence for start of WOR in WAITFOR statement
    542518%precedence TIMEOUT             // token precedence for start of TIMEOUT in WAITFOR statement
     
    616592constant:
    617593                // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
    618         INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( yylloc, *$1 ) ); }
    619         | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
    620         | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
    621         | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
    622         | 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 ) ); }
    623599        ;
    624600
    625601quasi_keyword:                                                                                  // CFA
    626602        TIMEOUT
    627         | WAND
    628603        | WOR
    629604        | CATCH
     
    646621
    647622string_literal:
    648         string_literal_list                                                     { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 ) ); }
     623        string_literal_list                                                     { $$ = build_constantStr( *$1 ); }
    649624        ;
    650625
     
    663638primary_expression:
    664639        IDENTIFIER                                                                                      // typedef name cannot be used as a variable name
    665                 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
     640                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    666641        | quasi_keyword
    667                 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
     642                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    668643        | TYPEDIMname                                                                           // CFA, generic length argument
    669644                // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); }
    670645                // { $$ = new ExpressionNode( build_varref( $1 ) ); }
    671                 { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); }
     646                { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }
    672647        | tuple
    673648        | '(' comma_expression ')'
    674649                { $$ = $2; }
    675650        | '(' compound_statement ')'                                            // GCC, lambda expression
    676                 { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); }
     651                { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }
    677652        | type_name '.' identifier                                                      // CFA, nested type
    678                 { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
     653                { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
    679654        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    680655                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    682657                {
    683658                        // add the missing control expression to the GenericExpr and return it
    684                         $5->control = maybeMoveBuild( $3 );
     659                        $5->control = maybeMoveBuild<Expression>( $3 );
    685660                        $$ = new ExpressionNode( $5 );
    686661                }
     
    689664        // | RESUME '(' comma_expression ')' compound_statement
    690665        //      { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; }
    691         | IDENTIFIER IDENTIFIER                                                         // invalid syntax rules
     666        | IDENTIFIER IDENTIFIER                                                         // syntax error
    692667                { IdentifierBeforeIdentifier( *$1.str, *$2.str, "n expression" ); $$ = nullptr; }
    693         | IDENTIFIER type_qualifier                                                     // invalid syntax rules
     668        | IDENTIFIER type_qualifier                                                     // syntax error
    694669                { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; }
    695         | IDENTIFIER storage_class                                                      // invalid syntax rules
     670        | IDENTIFIER storage_class                                                      // syntax error
    696671                { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; }
    697         | IDENTIFIER basic_type_name                                            // invalid syntax rules
     672        | IDENTIFIER basic_type_name                                            // syntax error
    698673                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    699         | IDENTIFIER TYPEDEFname                                                        // invalid syntax rules
     674        | IDENTIFIER TYPEDEFname                                                        // syntax error
    700675                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    701         | IDENTIFIER TYPEGENname                                                        // invalid syntax rules
     676        | IDENTIFIER TYPEGENname                                                        // syntax error
    702677                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    703678        ;
     
    708683                {
    709684                        // steal the association node from the singleton and delete the wrapper
    710                         assert( 1 == $3->associations.size() );
    711                         $1->associations.push_back( $3->associations.front() );
     685                        $1->associations.splice($1->associations.end(), $3->associations);
    712686                        delete $3;
    713687                        $$ = $1;
     
    719693                {
    720694                        // create a GenericExpr wrapper with one association pair
    721                         $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );
     695                        $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } );
    722696                }
    723697        | DEFAULT ':' assignment_expression
    724                 { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }
     698                { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); }
    725699        ;
    726700
     
    731705                // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
    732706                // Current: Commas in subscripts make tuples.
    733                 { $$ = 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 ) ) )) ) ); }
    734708        | postfix_expression '[' assignment_expression ']'
    735709                // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
     
    737711                // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
    738712                // equivalent to the old x[i,j].
    739                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
     713                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
    740714        | constant '[' assignment_expression ']'                        // 3[a], 'a'[a], 3.5[a]
    741                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
     715                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
    742716        | string_literal '[' assignment_expression ']'          // "abc"[3], 3["abc"]
    743                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
     717                { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
    744718        | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call
    745719                {
    746720                        Token fn;
    747721                        fn.str = new std::string( "?{}" );                      // location undefined - use location of '{'?
    748                         $$ = 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 ) ) ) );
    749723                }
    750724        | postfix_expression '(' argument_expression_list_opt ')'
    751                 { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); }
     725                { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
    752726        | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')'
    753727                // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; }
    754                 { $$ = 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") ) ),
    755729                                                                                           (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); }
    756730        | postfix_expression '`' identifier                                     // CFA, postfix call
    757                 { $$ = 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 ) ); }
    758732        | constant '`' identifier                                                       // CFA, postfix call
    759                 { $$ = 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 ) ); }
    760734        | string_literal '`' identifier                                         // CFA, postfix call
    761                 { $$ = 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 ) ) ); }
    762736        | postfix_expression '.' identifier
    763                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
     737                { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
    764738        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
    765                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
     739                { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); }
    766740        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    767                 { $$ = 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 ) ) ); }
    768742        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    769                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
     743                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    770744        | postfix_expression '.' aggregate_control
    771                 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); }
     745                { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
    772746        | postfix_expression ARROW identifier
    773                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
     747                { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
    774748        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    775                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
     749                { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
    776750        | postfix_expression ARROW '[' field_name_list ']'      // CFA, tuple field selector
    777                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
     751                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
    778752        | postfix_expression ICR
    779                 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); }
     753                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
    780754        | postfix_expression DECR
    781                 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); }
     755                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); }
    782756        | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
    783                 { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); }
     757                { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
    784758        | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
    785                 { $$ = 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 ) ) ); }
    786760        | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call
    787761                {
    788762                        Token fn;
    789763                        fn.str = new string( "^?{}" );                          // location undefined
    790                         $$ = 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 ) ) );
    791765                }
    792766        ;
     
    807781        '@'                                                                                                     // CFA, default parameter
    808782                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
    809                 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
     783                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
    810784        | assignment_expression
    811785        ;
     
    819793        field_name
    820794        | FLOATING_DECIMALconstant field
    821                 { $$ = 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 ) ) ); }
    822796        | FLOATING_DECIMALconstant '[' field_name_list ']'
    823                 { $$ = 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 ) ) ); }
    824798        | field_name '.' field
    825                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
     799                { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    826800        | field_name '.' '[' field_name_list ']'
    827                 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
     801                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    828802        | field_name ARROW field
    829                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
     803                { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    830804        | field_name ARROW '[' field_name_list ']'
    831                 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
     805                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
    832806        ;
    833807
    834808field_name:
    835809        INTEGERconstant fraction_constants_opt
    836                 { $$ = 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 ) ); }
    837811        | FLOATINGconstant fraction_constants_opt
    838                 { $$ = 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 ) ); }
    839813        | identifier_at fraction_constants_opt                          // CFA, allow anonymous fields
    840814                {
    841                         $$ = 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 ) );
    842816                }
    843817        ;
     
    848822        | fraction_constants_opt FLOATING_FRACTIONconstant
    849823                {
    850                         ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 );
    851                         $$ = $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 );
    852826                }
    853827        ;
     
    859833        | constant
    860834        | string_literal
    861                 { $$ = $1; }
     835                { $$ = new ExpressionNode( $1 ); }
    862836        | EXTENSION cast_expression                                                     // GCC
    863837                { $$ = $2->set_extension( true ); }
     
    868842                {
    869843                        switch ( $1 ) {
    870                         case OperKinds::AddressOf:
    871                                 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );
     844                          case OperKinds::AddressOf:
     845                                $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) );
    872846                                break;
    873                         case OperKinds::PointTo:
    874                                 $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) );
     847                          case OperKinds::PointTo:
     848                                $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
    875849                                break;
    876                         case OperKinds::And:
    877                                 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );
     850                          case OperKinds::And:
     851                                $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) );
    878852                                break;
    879                         default:
     853                          default:
    880854                                assert( false );
    881855                        }
    882856                }
    883857        | unary_operator cast_expression
    884                 { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); }
     858                { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }
    885859        | ICR unary_expression
    886                 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); }
     860                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Incr, $2 ) ); }
    887861        | DECR unary_expression
    888                 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); }
     862                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Decr, $2 ) ); }
    889863        | SIZEOF unary_expression
    890                 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
     864                { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
    891865        | SIZEOF '(' type_no_function ')'
    892                 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
     866                { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); }
    893867        | ALIGNOF unary_expression                                                      // GCC, variable alignment
    894                 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
     868                { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
    895869        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    896                 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
     870                { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
    897871        | OFFSETOF '(' type_no_function ',' identifier ')'
    898                 { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); }
     872                { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
    899873        | TYPEID '(' type_no_function ')'
    900874                {
     
    921895        unary_expression
    922896        | '(' type_no_function ')' cast_expression
    923                 { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
     897                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    924898        | '(' aggregate_control '&' ')' cast_expression         // CFA
    925                 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
     899                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    926900        | '(' aggregate_control '*' ')' cast_expression         // CFA
    927                 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
     901                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    928902        | '(' VIRTUAL ')' cast_expression                                       // CFA
    929                 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     903                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    930904        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    931                 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
     905                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); }
    932906        | '(' RETURN type_no_function ')' cast_expression       // CFA
    933                 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
     907                { $$ = new ExpressionNode( build_cast( $3, $5, CastExpr::Return ) ); }
    934908        | '(' COERCE type_no_function ')' cast_expression       // CFA
    935909                { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
     
    937911                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    938912//      | '(' type_no_function ')' tuple
    939 //              { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
     913//              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    940914        ;
    941915
     
    955929        cast_expression
    956930        | exponential_expression '\\' cast_expression
    957                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); }
     931                { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }
    958932        ;
    959933
     
    961935        exponential_expression
    962936        | multiplicative_expression '*' exponential_expression
    963                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); }
     937                { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }
    964938        | multiplicative_expression '/' exponential_expression
    965                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); }
     939                { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }
    966940        | multiplicative_expression '%' exponential_expression
    967                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); }
     941                { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }
    968942        ;
    969943
     
    971945        multiplicative_expression
    972946        | additive_expression '+' multiplicative_expression
    973                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); }
     947                { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }
    974948        | additive_expression '-' multiplicative_expression
    975                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); }
     949                { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }
    976950        ;
    977951
     
    979953        additive_expression
    980954        | shift_expression LS additive_expression
    981                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); }
     955                { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }
    982956        | shift_expression RS additive_expression
    983                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); }
     957                { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }
    984958        ;
    985959
     
    987961        shift_expression
    988962        | relational_expression '<' shift_expression
    989                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); }
     963                { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }
    990964        | relational_expression '>' shift_expression
    991                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); }
     965                { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }
    992966        | relational_expression LE shift_expression
    993                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); }
     967                { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }
    994968        | relational_expression GE shift_expression
    995                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); }
     969                { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }
    996970        ;
    997971
     
    999973        relational_expression
    1000974        | equality_expression EQ relational_expression
    1001                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); }
     975                { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }
    1002976        | equality_expression NE relational_expression
    1003                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); }
     977                { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }
    1004978        ;
    1005979
     
    1007981        equality_expression
    1008982        | AND_expression '&' equality_expression
    1009                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); }
     983                { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }
    1010984        ;
    1011985
     
    1013987        AND_expression
    1014988        | exclusive_OR_expression '^' AND_expression
    1015                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); }
     989                { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }
    1016990        ;
    1017991
     
    1019993        exclusive_OR_expression
    1020994        | inclusive_OR_expression '|' exclusive_OR_expression
    1021                 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); }
     995                { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }
    1022996        ;
    1023997
     
    1025999        inclusive_OR_expression
    10261000        | logical_AND_expression ANDAND inclusive_OR_expression
    1027                 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); }
     1001                { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); }
    10281002        ;
    10291003
     
    10311005        logical_AND_expression
    10321006        | logical_OR_expression OROR logical_AND_expression
    1033                 { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); }
     1007                { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); }
    10341008        ;
    10351009
     
    10371011        logical_OR_expression
    10381012        | logical_OR_expression '?' comma_expression ':' conditional_expression
    1039                 { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); }
     1013                { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
    10401014                // FIX ME: computes $1 twice
    10411015        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    1042                 { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); }
     1016                { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
    10431017        ;
    10441018
     
    10551029//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    10561030//                      } else {
    1057                                 $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) );
     1031                                $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
    10581032//                      } // if
    10591033                }
     
    11001074//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    11011075        '[' ',' tuple_expression_list ']'
    1102                 { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     1076                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    11031077        | '[' push assignment_expression pop ',' tuple_expression_list ']'
    1104                 { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); }
     1078                { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }
    11051079        ;
    11061080
     
    11181092        assignment_expression
    11191093        | comma_expression ',' assignment_expression
    1120                 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1094                { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
    11211095        ;
    11221096
     
    11391113        | mutex_statement
    11401114        | waitfor_statement
    1141         | waituntil_statement
    11421115        | exception_statement
    11431116        | enable_disable_statement
     
    11451118        | asm_statement
    11461119        | DIRECTIVE
    1147                 { $$ = new StatementNode( build_directive( yylloc, $1 ) ); }
     1120                { $$ = new StatementNode( build_directive( $1 ) ); }
    11481121        ;
    11491122
     
    11511124                // labels cannot be identifiers 0 or 1
    11521125        identifier_or_type_name ':' attribute_list_opt statement
    1153                 { $$ = $4->add_label( yylloc, $1, $3 ); }
    1154         | identifier_or_type_name ':' attribute_list_opt error // invalid syntax rule
    1155                 {
    1156                         SemanticError( yylloc, ::toString( "syntx error, label \"", *$1.str, "\" must be associated with a statement, "
     1126                { $$ = $4->add_label( $1, $3 ); }
     1127        | identifier_or_type_name ':' attribute_list_opt error // syntax error
     1128                {
     1129                        SemanticError( yylloc, ::toString( "Label \"", *$1.str, "\" must be associated with a statement, "
    11571130                                                                                           "where a declaration, case, or default is not a statement. "
    11581131                                                                                           "Move the label or terminate with a semi-colon." ) );
     
    11631136compound_statement:
    11641137        '{' '}'
    1165                 { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); }
     1138                { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
    11661139        | '{' push
    11671140          local_label_declaration_opt                                           // GCC, local labels appear at start of block
    11681141          statement_decl_list                                                           // C99, intermix declarations and statements
    11691142          pop '}'
    1170                 { $$ = new StatementNode( build_compound( yylloc, $4 ) ); }
     1143                { $$ = new StatementNode( build_compound( $4 ) ); }
    11711144        ;
    11721145
     
    11931166        | statement_list_nodecl statement
    11941167                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
    1195         | statement_list_nodecl error                                           // invalid syntax rule
    1196                 { SemanticError( yylloc, "syntax error, declarations only allowed at the start of the switch body, i.e., after the '{'." ); $$ = nullptr; }
     1168        | statement_list_nodecl error                                           // syntax error
     1169                { SemanticError( yylloc, "Declarations only allowed at the start of the switch body, i.e., after the '{'." ); $$ = nullptr; }
    11971170        ;
    11981171
    11991172expression_statement:
    12001173        comma_expression_opt ';'
    1201                 { $$ = 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 ) ) ) ); }
    12021177        ;
    12031178
     
    12081183                { $$ = $2; }
    12091184        | SWITCH '(' comma_expression ')' case_clause
    1210                 { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); }
     1185                { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
    12111186        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12121187                {
    1213                         StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) );
     1188                        StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
    12141189                        // The semantics of the declaration list is changed to include associated initialization, which is performed
    12151190                        // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
     
    12171192                        // therefore, are removed from the grammar even though C allows it. The change also applies to choose
    12181193                        // statement.
    1219                         $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    1220                 }
    1221         | SWITCH '(' comma_expression ')' '{' error '}'         // CFA, invalid syntax rule error
    1222                 { SemanticError( yylloc, "synatx error, declarations can only appear before the list of case clauses." ); $$ = nullptr; }
     1194                        $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1195                }
     1196        | SWITCH '(' comma_expression ')' '{' error '}'         // CFA, syntax error
     1197                { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    12231198        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    1224                 { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); }
     1199                { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
    12251200        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12261201                {
    1227                         StatementNode *sw = new StatementNode( build_switch( yylloc, false, $3, $8 ) );
    1228                         $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    1229                 }
    1230         | CHOOSE '(' comma_expression ')' '{' error '}'         // CFA, invalid syntax rule
    1231                 { SemanticError( yylloc, "syntax error, declarations can only appear before the list of case clauses." ); $$ = nullptr; }
     1202                        StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );
     1203                        $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1204                }
     1205        | CHOOSE '(' comma_expression ')' '{' error '}'         // CFA, syntax error
     1206                { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    12321207        ;
    12331208
     
    12351210        IF '(' conditional_declaration ')' statement            %prec THEN
    12361211                // explicitly deal with the shift/reduce conflict on if/else
    1237                 { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); }
     1212                { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
    12381213        | IF '(' conditional_declaration ')' statement ELSE statement
    1239                 { $$ = 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 ) ) ); }
    12401215        ;
    12411216
     
    12491224        | declaration comma_expression                                          // semi-colon separated
    12501225                { $$ = new CondCtl( $1, $2 ); }
    1251         ;
     1226        ;
    12521227
    12531228// CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case
     
    12571232        constant_expression                                                     { $$ = $1; }
    12581233        | constant_expression ELLIPSIS constant_expression      // GCC, subrange
    1259                 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1234                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
    12601235        | subrange                                                                                      // CFA, subrange
    12611236        ;
    12621237
    12631238case_value_list:                                                                                // CFA
    1264         case_value                                                                      { $$ = new ClauseNode( build_case( yylloc, $1 ) ); }
     1239        case_value                                                                      { $$ = new StatementNode( build_case( $1 ) ); }
    12651240                // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5"
    1266         | 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 ) ) ) ); }
    12671242        ;
    12681243
    12691244case_label:                                                                                             // CFA
    1270         CASE error                                                                                      // invalid syntax rule
    1271                 { SemanticError( yylloc, "syntax error, case list missing after case." ); $$ = nullptr; }
     1245        CASE error                                                                                      // syntax error
     1246                { SemanticError( yylloc, "Missing case list after case." ); $$ = nullptr; }
    12721247        | CASE case_value_list ':'                                      { $$ = $2; }
    1273         | CASE case_value_list error                                            // invalid syntax rule
    1274                 { SemanticError( yylloc, "syntax error, colon missing after case list." ); $$ = nullptr; }
    1275         | DEFAULT ':'                                                           { $$ = new ClauseNode( build_default( yylloc ) ); }
     1248        | CASE case_value_list error                                            // syntax error
     1249                { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
     1250        | DEFAULT ':'                                                           { $$ = new StatementNode( build_default() ); }
    12761251                // A semantic check is required to ensure only one default clause per switch/choose statement.
    1277         | DEFAULT error                                                                         //  invalid syntax rules
    1278                 { SemanticError( yylloc, "syntax error, colon missing after default." ); $$ = nullptr; }
     1252        | DEFAULT error                                                                         //  syntax error
     1253                { SemanticError( yylloc, "Missing colon after default." ); $$ = nullptr; }
    12791254        ;
    12801255
    12811256case_label_list:                                                                                // CFA
    12821257        case_label
    1283         | case_label_list case_label                            { $$ = $1->set_last( $2 ); }
     1258        | case_label_list case_label                            { $$ = (StatementNode *)( $1->set_last( $2 )); }
    12841259        ;
    12851260
    12861261case_clause:                                                                                    // CFA
    1287         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 ) ); }
    12881263        ;
    12891264
     
    12961271switch_clause_list:                                                                             // CFA
    12971272        case_label_list statement_list_nodecl
    1298                 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); }
     1273                { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
    12991274        | switch_clause_list case_label_list statement_list_nodecl
    1300                 { $$ = $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 ) ) ) ) ); }
    13011276        ;
    13021277
    13031278iteration_statement:
    13041279        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1305                 { $$ = 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 ) ) ); }
    13061281        | WHILE '(' ')' statement ELSE statement                        // CFA
    13071282                {
    1308                         $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) );
    1309                         SemanticWarning( yylloc, Warning::SuperfluousElse );
     1283                        $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
     1284                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    13101285                }
    13111286        | WHILE '(' conditional_declaration ')' statement       %prec THEN
    1312                 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
     1287                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
    13131288        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
    1314                 { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
     1289                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
    13151290        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1316                 { $$ = 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 ) ) ); }
    13171292        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    13181293                {
    1319                         $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) );
    1320                         SemanticWarning( yylloc, Warning::SuperfluousElse );
     1294                        $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
     1295                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    13211296                }
    13221297        | DO statement WHILE '(' comma_expression ')' ';'
    1323                 { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); }
     1298                { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
    13241299        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
    1325                 { $$ = 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 ) ); }
    13261301        | FOR '(' ')' statement                                                         %prec THEN // CFA => for ( ;; )
    1327                 { $$ = 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 ) ) ); }
    13281303        | FOR '(' ')' statement ELSE statement                          // CFA
    13291304                {
    1330                         $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) );
    1331                         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, "" );
    13321307                }
    13331308        | FOR '(' for_control_expression_list ')' statement     %prec THEN
    1334                 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
     1309                { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
    13351310        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
    1336                 { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
     1311                { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
    13371312        ;
    13381313
     
    13481323                        if ( $1->condition ) {
    13491324                                if ( $3->condition ) {
    1350                                         $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 ) );
    13511326                                } // if
    13521327                        } else $1->condition = $3->condition;
    13531328                        if ( $1->change ) {
    13541329                                if ( $3->change ) {
    1355                                         $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() ) );
    13561331                                } // if
    13571332                        } else $1->change = $3->change;
     
    13621337for_control_expression:
    13631338        ';' comma_expression_opt ';' comma_expression_opt
    1364                 { $$ = new ForCtrl( nullptr, $2, $4 ); }
     1339                { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
    13651340        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    1366                 {
    1367                         StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr;
    1368                         $$ = new ForCtrl( init, $3, $5 );
    1369                 }
     1341                { $$ = new ForCtrl( $1, $3, $5 ); }
    13701342        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    1371                 { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); }
     1343                { $$ = new ForCtrl( $1, $2, $4 ); }
    13721344
    13731345        | '@' ';' comma_expression                                                      // CFA, empty loop-index
    1374                 { $$ = new ForCtrl( nullptr, $3, nullptr ); }
     1346                { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }
    13751347        | '@' ';' comma_expression ';' comma_expression         // CFA, empty loop-index
    1376                 { $$ = new ForCtrl( nullptr, $3, $5 ); }
     1348                { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }
    13771349
    13781350        | comma_expression                                                                      // CFA, anonymous loop-index
    1379                 { $$ = 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 ); }
    13801352        | downupdowneq comma_expression                                         // CFA, anonymous loop-index
    1381                 { $$ = 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 ); }
    13821354
    13831355        | comma_expression updowneq comma_expression            // CFA, anonymous loop-index
    1384                 { $$ = 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 ); }
    13851357        | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
    13861358                {
    13871359                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1388                         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 );
    13891361                }
    13901362        | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
     
    13941366                }
    13951367        | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    1396                 { $$ = 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 ); }
    13971369        | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    13981370                {
    13991371                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1400                         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 );
    14011373                }
    14021374        | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
     
    14051377                        else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14061378                }
    1407         | comma_expression updowneq comma_expression '~' '@' // CFA, invalid syntax rules
     1379        | comma_expression updowneq comma_expression '~' '@' // CFA, error
    14081380                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1409         | '@' updowneq '@'                                                                      // CFA, invalid syntax rules
     1381        | '@' updowneq '@'                                                                      // CFA, error
    14101382                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1411         | '@' updowneq comma_expression '~' '@'                         // CFA, invalid syntax rules
     1383        | '@' updowneq comma_expression '~' '@'                         // CFA, error
    14121384                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1413         | comma_expression updowneq '@' '~' '@'                         // CFA, invalid syntax rules
     1385        | comma_expression updowneq '@' '~' '@'                         // CFA, error
    14141386                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1415         | '@' updowneq '@' '~' '@'                                                      // CFA, invalid syntax rules
     1387        | '@' updowneq '@' '~' '@'                                                      // CFA, error
    14161388                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    14171389
    14181390        | comma_expression ';' comma_expression                         // CFA
    1419                 { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1391                { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    14201392        | comma_expression ';' downupdowneq comma_expression // CFA
    1421                 { $$ = 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 ); }
    14221394
    14231395        | comma_expression ';' comma_expression updowneq comma_expression // CFA
    1424                 { $$ = 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 ); }
    14251397        | comma_expression ';' '@' updowneq comma_expression // CFA
    14261398                {
    14271399                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1428                         else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1400                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    14291401                }
    14301402        | comma_expression ';' comma_expression updowneq '@' // CFA
    14311403                {
    14321404                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1433                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1434                         else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    1435                 }
    1436         | comma_expression ';' '@' updowneq '@'                         // CFA, invalid syntax rules
    1437                 { SemanticError( yylloc, "syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1405                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1406                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
     1407                }
     1408        | comma_expression ';' '@' updowneq '@'                         // CFA, error
     1409                { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    14381410
    14391411        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    1440                 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    1441         | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, invalid syntax rules
     1412                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
     1413        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
    14421414                {
    14431415                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1444                         else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 );
     1416                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
    14451417                }
    14461418        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
    14471419                {
    14481420                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1449                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1450                         else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, $7 );
     1421                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1422                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
    14511423                }
    14521424        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    1453                 { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    1454         | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, invalid syntax rules
     1425                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
     1426        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
    14551427                {
    14561428                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1457                         else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr );
     1429                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
    14581430                }
    14591431        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
    14601432                {
    14611433                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1462                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1463                         else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, nullptr );
     1434                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1435                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
    14641436                }
    14651437        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
    1466                 { SemanticError( yylloc, "syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1438                { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    14671439
    14681440        | declaration comma_expression                                          // CFA
    1469                 { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1441                { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    14701442        | declaration downupdowneq comma_expression                     // CFA
    1471                 { $$ = 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 ); }
    14721444
    14731445        | declaration comma_expression updowneq comma_expression // CFA
    1474                 { $$ = 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 ); }
    14751447        | declaration '@' updowneq comma_expression                     // CFA
    14761448                {
    14771449                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1478                         else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE );
     1450                        else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
    14791451                }
    14801452        | declaration comma_expression updowneq '@'                     // CFA
    14811453                {
    14821454                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1483                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1484                         else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, NEW_ONE );
     1455                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1456                        else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
    14851457                }
    14861458
    14871459        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1488                 { $$ = 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 ); }
    14891461        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    14901462                {
    14911463                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1492                         else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 );
     1464                        else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
    14931465                }
    14941466        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
    14951467                {
    14961468                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1497                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1498                         else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, $6 );
     1469                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1470                        else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
    14991471                }
    15001472        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1501                 { $$ = 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 ); }
    15021474        | declaration '@' updowneq comma_expression '~' '@' // CFA
    15031475                {
    15041476                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1505                         else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr );
     1477                        else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
    15061478                }
    15071479        | declaration comma_expression updowneq '@' '~' '@'     // CFA
    15081480                {
    15091481                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1510                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "syntax error, equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1511                         else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr );
    1512                 }
    1513         | declaration '@' updowneq '@' '~' '@'                          // CFA, invalid syntax rules
    1514                 { SemanticError( yylloc, "syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1482                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1483                        else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
     1484                }
     1485        | declaration '@' updowneq '@' '~' '@'                          // CFA, error
     1486                { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    15151487
    15161488        | comma_expression ';' TYPEDEFname                                      // CFA, array type
     
    15211493        | comma_expression ';' downupdowneq TYPEDEFname         // CFA, array type
    15221494                {
    1523                         if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) {
    1524                                 SemanticError( yylloc, "syntax error, all enumeration ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr;
    1525                         }
     1495                        if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; }
    15261496                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    15271497                }
    1528         ;
     1498        ;
    15291499
    15301500downupdowneq:
     
    15351505        | ErangeDownEq
    15361506                { $$ = OperKinds::GEThan; }
    1537         ;
     1507        ;
    15381508
    15391509updown:
     
    15421512        | ErangeDown
    15431513                { $$ = OperKinds::GThan; }
    1544         ;
     1514        ;
    15451515
    15461516updowneq:
     
    15501520        | ErangeDownEq
    15511521                { $$ = OperKinds::GEThan; }
    1552         ;
     1522        ;
    15531523
    15541524jump_statement:
    15551525        GOTO identifier_or_type_name ';'
    1556                 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }
     1526                { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); }
    15571527        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    15581528                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    15611531                // A semantic check is required to ensure fallthru appears only in the body of a choose statement.
    15621532        | fall_through_name ';'                                                         // CFA
    1563                 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }
     1533                { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }
    15641534        | fall_through_name identifier_or_type_name ';'         // CFA
    1565                 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }
     1535                { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); }
    15661536        | fall_through_name DEFAULT ';'                                         // CFA
    1567                 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }
     1537                { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }
    15681538        | CONTINUE ';'
    15691539                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1570                 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }
     1540                { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); }
    15711541        | CONTINUE identifier_or_type_name ';'                          // CFA, multi-level continue
    15721542                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15731543                // the target of the transfer appears only at the start of an iteration statement.
    1574                 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }
     1544                { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); }
    15751545        | BREAK ';'
    15761546                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1577                 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }
     1547                { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); }
    15781548        | BREAK identifier_or_type_name ';'                                     // CFA, multi-level exit
    15791549                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15801550                // the target of the transfer appears only at the start of an iteration statement.
    1581                 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }
     1551                { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); }
    15821552        | RETURN comma_expression_opt ';'
    1583                 { $$ = new StatementNode( build_return( yylloc, $2 ) ); }
     1553                { $$ = new StatementNode( build_return( $2 ) ); }
    15841554        | RETURN '{' initializer_list_opt comma_opt '}' ';'
    15851555                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    15861556        | SUSPEND ';'
    1587                 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); }
     1557                { $$ = new StatementNode( build_suspend( nullptr ) ); }
    15881558        | SUSPEND compound_statement
    1589                 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); }
     1559                { $$ = new StatementNode( build_suspend( $2 ) ); }
    15901560        | SUSPEND COROUTINE ';'
    1591                 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }
     1561                { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); }
    15921562        | SUSPEND COROUTINE compound_statement
    1593                 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }
     1563                { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); }
    15941564        | SUSPEND GENERATOR ';'
    1595                 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }
     1565                { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); }
    15961566        | SUSPEND GENERATOR compound_statement
    1597                 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }
     1567                { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); }
    15981568        | THROW assignment_expression_opt ';'                           // handles rethrow
    1599                 { $$ = new StatementNode( build_throw( yylloc, $2 ) ); }
     1569                { $$ = new StatementNode( build_throw( $2 ) ); }
    16001570        | THROWRESUME assignment_expression_opt ';'                     // handles reresume
    1601                 { $$ = new StatementNode( build_resume( yylloc, $2 ) ); }
     1571                { $$ = new StatementNode( build_resume( $2 ) ); }
    16021572        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    16031573                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
     
    16111581with_statement:
    16121582        WITH '(' tuple_expression_list ')' statement
    1613                 { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); }
    1614         ;
    1615 
    1616 // 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".
    16171587mutex_statement:
    1618         MUTEX '(' argument_expression_list_opt ')' statement
    1619                 {
    1620                         if ( ! $3 ) { SemanticError( yylloc, "syntax error, mutex argument list cannot be empty." ); $$ = nullptr; }
    1621                         $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) );
    1622                 }
     1588        MUTEX '(' argument_expression_list ')' statement
     1589                { $$ = new StatementNode( build_mutex( $3, $5 ) ); }
    16231590        ;
    16241591
     
    16311598                { $$ = nullptr; }
    16321599        | 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 )); }
    16331609        ;
    16341610
     
    16411617
    16421618timeout:
    1643         TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
    1644         ;
    1645 
    1646 wor:
    1647         OROR
    1648         | WOR
    1649 
    1650 waitfor:
    1651         WAITFOR '(' cast_expression ')'
    1652                 { $$ = $3; }
    1653         | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')'
    1654                 { $$ = (ExpressionNode *)($3->set_last( $5 )); }
    1655         ;
    1656 
    1657 wor_waitfor_clause:
     1619        TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
     1620        ;
     1621
     1622waitfor_clause:
    16581623        when_clause_opt waitfor statement                                       %prec THEN
    1659                 // Called first: create header for WaitForStmt.
    1660                 { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); }
    1661         | wor_waitfor_clause wor when_clause_opt waitfor statement
    1662                 { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    1663         | wor_waitfor_clause wor when_clause_opt ELSE statement
    1664                 { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); }
    1665         | wor_waitfor_clause wor when_clause_opt timeout statement      %prec THEN
    1666                 { $$ = 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 ); }
    16671631        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    1668         | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // invalid syntax rules
    1669                 { SemanticError( yylloc, "syntax error, else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    1670         | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1671                 { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); }
     1632        | when_clause_opt timeout statement WOR ELSE statement // syntax error
     1633                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
     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 ); }
    16721636        ;
    16731637
    16741638waitfor_statement:
    1675         wor_waitfor_clause                                                                      %prec THEN
    1676                 { $$ = new StatementNode( $1 ); }
    1677         ;
    1678 
    1679 wand:
    1680         ANDAND
    1681         | WAND
    1682         ;
    1683 
    1684 waituntil:
    1685         WAITUNTIL '(' comma_expression ')'
    1686                 { $$ = $3; }
    1687         ;
    1688 
    1689 waituntil_clause:
    1690         when_clause_opt waituntil statement
    1691                 { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); }
    1692         | '(' wor_waituntil_clause ')'
    1693                 { $$ = $2; }
    1694         ;
    1695 
    1696 wand_waituntil_clause:
    1697         waituntil_clause                                                                        %prec THEN
    1698                 { $$ = $1; }
    1699         | waituntil_clause wand wand_waituntil_clause
    1700                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); }
    1701         ;
    1702 
    1703 wor_waituntil_clause:
    1704         wand_waituntil_clause
    1705                 { $$ = $1; }
    1706         | wor_waituntil_clause wor wand_waituntil_clause
    1707                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); }
    1708         | wor_waituntil_clause wor when_clause_opt ELSE statement
    1709                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    1710         | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
    1711                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); }
    1712         // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    1713         | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // invalid syntax rules
    1714                 { SemanticError( yylloc, "syntax error, else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    1715         | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1716                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1,
    1717                 new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR,
    1718                     build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ),
    1719                     build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); }
    1720         ;
    1721 
    1722 waituntil_statement:
    1723         wor_waituntil_clause                                                            %prec THEN
    1724                 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
    1725                 {
    1726             $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) );
    1727             // $$ = new StatementNode( build_compound( yylloc, nullptr ) );
    1728         }
     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 ) ); }
    17291643        ;
    17301644
    17311645exception_statement:
    1732         TRY compound_statement handler_clause                                   %prec THEN
    1733                 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
     1646        TRY compound_statement handler_clause                                   %prec THEN
     1647                { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
    17341648        | TRY compound_statement finally_clause
    1735                 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
     1649                { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }
    17361650        | TRY compound_statement handler_clause finally_clause
    1737                 { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
     1651                { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
    17381652        ;
    17391653
    17401654handler_clause:
    17411655        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1742                 { $$ = new ClauseNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
     1656                { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
    17431657        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1744                 { $$ = $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 ) ) ); }
    17451659        ;
    17461660
     
    17521666
    17531667handler_key:
    1754         CATCH                                                                           { $$ = ast::Terminate; }
    1755         | RECOVER                                                                       { $$ = ast::Terminate; }
    1756         | CATCHRESUME                                                           { $$ = ast::Resume; }
    1757         | FIXUP                                                                         { $$ = ast::Resume; }
     1668        CATCH                                                                           { $$ = CatchStmt::Terminate; }
     1669        | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
     1670        | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
     1671        | FIXUP                                                                         { $$ = CatchStmt::Resume; }
    17581672        ;
    17591673
    17601674finally_clause:
    1761         FINALLY compound_statement                                      { $$ = new ClauseNode( build_finally( yylloc, $2 ) ); }
     1675        FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
    17621676        ;
    17631677
     
    17851699asm_statement:
    17861700        ASM asm_volatile_opt '(' string_literal ')' ';'
    1787                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
     1701                { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); }
    17881702        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1789                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
     1703                { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
    17901704        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1791                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
     1705                { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
    17921706        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';'
    1793                 { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
     1707                { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); }
    17941708        | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';'
    1795                 { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
     1709                { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); }
    17961710        ;
    17971711
     
    18171731asm_operand:                                                                                    // GCC
    18181732        string_literal '(' constant_expression ')'
    1819                 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1733                { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    18201734        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1821                 {
    1822                         $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) );
    1823                         delete $2.str;
    1824                 }
     1735                { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); }
    18251736        ;
    18261737
     
    18291740                { $$ = nullptr; }                                                               // use default argument
    18301741        | string_literal
    1831                 { $$ = $1; }
     1742                { $$ = new ExpressionNode( $1 ); }
    18321743        | asm_clobbers_list_opt ',' string_literal
    1833                 { $$ = (ExpressionNode *)( $1->set_last( $3 ) ); }
     1744                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); }
    18341745        ;
    18351746
     
    18371748        identifier
    18381749                {
    1839                         $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
     1750                        $$ = new LabelNode(); $$->labels.push_back( *$1 );
    18401751                        delete $1;                                                                      // allocated by lexer
    18411752                }
    18421753        | label_list ',' identifier
    18431754                {
    1844                         $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
     1755                        $$ = $1; $1->labels.push_back( *$3 );
    18451756                        delete $3;                                                                      // allocated by lexer
    18461757                }
     
    18931804                {
    18941805                        // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" );
    1895                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     1806                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    18961807                        //   printf( "\tattr %s\n", attr->name.c_str() );
    18971808                        // } // for
     
    19031814static_assert:
    19041815        STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
    1905                 { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 ) ); }
     1816                { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
    19061817        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1907                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
     1818                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
    19081819
    19091820// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    19691880//      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
    19701881//              {
    1971 //                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );
     1882//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
    19721883//              }
    19731884//      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
    19741885//              {
    19751886//                      typedefTable.setNextIdentifier( *$5 );
    1976 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
     1887//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    19771888//              }
    19781889//      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
    19791890//              {
    19801891//                      typedefTable.setNextIdentifier( *$5 );
    1981 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
     1892//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
    19821893//              }
    19831894//      | '[' ']' typegen_name
     
    19911902        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    19921903                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    1993                 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
     1904                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
    19941905        | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    1995                 { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
     1906                { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
    19961907        ;
    19971908
     
    20291940                {
    20301941                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
    2031                         if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) {
    2032                                 SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr;
    2033                         } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
     1942                        $$ = $3->addType( $2 )->addTypedef();
    20341943                }
    20351944        | typedef_declaration pop ',' push declarator
     
    20391948                }
    20401949        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
    2041                 { 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                }
    20421954        | type_specifier TYPEDEF declarator
    2043                 { 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                }
    20441959        | type_specifier TYPEDEF type_qualifier_list declarator
    2045                 { 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                }
    20461964        ;
    20471965
     
    20501968        TYPEDEF identifier '=' assignment_expression
    20511969                {
    2052                         SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     1970                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    20531971                }
    20541972        | typedef_expression pop ',' push identifier '=' assignment_expression
    20551973                {
    2056                         SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     1974                        SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    20571975                }
    20581976        ;
     
    20641982        | typedef_expression                                                            // deprecated GCC, naming expression type
    20651983        | sue_declaration_specifier
    2066                 {
    2067                         assert( $1->type );
    2068                         if ( $1->type->qualifiers.any() ) {                     // CV qualifiers ?
    2069                                 SemanticError( yylloc, "syntax error, useless type qualifier(s) in empty declaration." ); $$ = nullptr;
    2070                         }
    2071                         // enums are never empty declarations because there must have at least one enumeration.
    2072                         if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?
    2073                                 SemanticError( yylloc, "syntax error, useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;
    2074                         }
    2075                 }
    20761984        ;
    20771985
     
    20791987                // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    20801988                // storage-class
    2081         variable_declarator asm_name_opt initializer_opt
     1989        declarator asm_name_opt initializer_opt
    20821990                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
    2083         | variable_type_redeclarator asm_name_opt initializer_opt
    2084                 { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
    2085 
    2086         | general_function_declarator asm_name_opt
    2087                 { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }
    2088         | general_function_declarator asm_name_opt '=' VOID
    2089                 { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }
    2090 
    20911991        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    20921992                { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
    20931993        ;
    20941994
    2095 general_function_declarator:
    2096         function_type_redeclarator
    2097         | function_declarator
    2098         ;
    2099 
    21001995declaration_specifier:                                                                  // type specifier + storage class
    21011996        basic_declaration_specifier
     1997        | sue_declaration_specifier
    21021998        | type_declaration_specifier
    2103         | sue_declaration_specifier
    2104         | sue_declaration_specifier invalid_types                       // invalid syntax rule
    2105                 {
    2106                         SemanticError( yylloc, ::toString( "syntax error, expecting ';' at end of ",
    2107                                 $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),
    2108                                 " declaration." ) );
    2109                         $$ = nullptr;
    2110                 }
    2111         ;
    2112 
    2113 invalid_types:
    2114         aggregate_key
    2115         | basic_type_name
    2116         | indirect_type
    21171999        ;
    21182000
     
    21312013        basic_type_specifier
    21322014        | 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                }
    21332021        | type_type_specifier
    21342022        ;
     
    21772065                { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); }
    21782066        | forall
    2179                 { $$ = DeclarationNode::newForall( $1 ); }
    21802067        ;
    21812068
    21822069forall:
    21832070        FORALL '(' type_parameter_list ')'                                      // CFA
    2184                 { $$ = $3; }
     2071                { $$ = DeclarationNode::newForall( $3 ); }
    21852072        ;
    21862073
     
    23392226                { $$ = DeclarationNode::newTypeof( $3 ); }
    23402227        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2341                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
     2228                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
    23422229        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    23432230                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    23522239                {
    23532240                        // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2354                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2241                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23552242                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23562243                        // } // for
     
    23682255                {
    23692256                        // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2370                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2257                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23712258                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23722259                        // } // for
     
    24462333                {
    24472334                        // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2448                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2335                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    24492336                        //   printf( "\tattr %s\n", attr->name.c_str() );
    24502337                        // } // for
     
    24702357          '{' field_declaration_list_opt '}' type_parameters_opt
    24712358                {
     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
    24722364                        $$ = 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
    24732369                }
    24742370        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     
    24792375          '{' field_declaration_list_opt '}' type_parameters_opt
    24802376                {
     2377                        // printf( "AGG3\n" );
    24812378                        DeclarationNode::newFromTypedef( $3 );
    24822379                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    24892386          '{' field_declaration_list_opt '}' type_parameters_opt
    24902387                {
     2388                        // printf( "AGG4\n" );
    24912389                        DeclarationNode::newFromTypeGen( $3, nullptr );
    24922390                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    25152413                        // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
    25162414                        // delete newFromTypeGen.
    2517                         if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) {
    2518                                 $$ = $3->addQualifiers( $2 );
    2519                         } else {
    2520                                 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
    2521                                 $3->type->symbolic.name = nullptr;                      // copied to $$
    2522                                 $3->type->symbolic.actuals = nullptr;
    2523                                 delete $3;
    2524                         }
     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;
    25252419                }
    25262420        ;
     
    25332427aggregate_data:
    25342428        STRUCT vtable_opt
    2535                 { $$ = ast::AggregateDecl::Struct; }
     2429                { $$ = AggregateDecl::Struct; }
    25362430        | UNION
    2537                 { $$ = ast::AggregateDecl::Union; }
     2431                { $$ = AggregateDecl::Union; }
    25382432        | EXCEPTION                                                                                     // CFA
    2539                 { $$ = ast::AggregateDecl::Exception; }
    2540           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
     2433                { $$ = AggregateDecl::Exception; }
     2434          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25412435        ;
    25422436
    25432437aggregate_control:                                                                              // CFA
    25442438        MONITOR
    2545                 { $$ = ast::AggregateDecl::Monitor; }
     2439                { $$ = AggregateDecl::Monitor; }
    25462440        | MUTEX STRUCT
    2547                 { $$ = ast::AggregateDecl::Monitor; }
     2441                { $$ = AggregateDecl::Monitor; }
    25482442        | GENERATOR
    2549                 { $$ = ast::AggregateDecl::Generator; }
     2443                { $$ = AggregateDecl::Generator; }
    25502444        | MUTEX GENERATOR
    2551                 {
    2552                         SemanticError( yylloc, "monitor generator is currently unimplemented." );
    2553                         $$ = ast::AggregateDecl::NoAggregate;
    2554                 }
     2445                { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25552446        | COROUTINE
    2556                 { $$ = ast::AggregateDecl::Coroutine; }
     2447                { $$ = AggregateDecl::Coroutine; }
    25572448        | MUTEX COROUTINE
    2558                 {
    2559                         SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
    2560                         $$ = ast::AggregateDecl::NoAggregate;
    2561                 }
     2449                { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25622450        | THREAD
    2563                 { $$ = ast::AggregateDecl::Thread; }
     2451                { $$ = AggregateDecl::Thread; }
    25642452        | MUTEX THREAD
    2565                 {
    2566                         SemanticError( yylloc, "monitor thread is currently unimplemented." );
    2567                         $$ = ast::AggregateDecl::NoAggregate;
    2568                 }
     2453                { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    25692454        ;
    25702455
     
    25822467                        $$ = fieldDecl( $1, $2 );
    25832468                        // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2584                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2469                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    25852470                        //   printf( "\tattr %s\n", attr->name.c_str() );
    25862471                        // } // for
    25872472                }
    2588         | type_specifier field_declaring_list_opt '}'           // invalid syntax rule
    2589                 {
    2590                         SemanticError( yylloc, ::toString( "syntax error, expecting ';' at end of previous declaration." ) );
    2591                         $$ = nullptr;
    2592                 }
    25932473        | EXTENSION type_specifier field_declaring_list_opt ';' // GCC
    25942474                { $$ = fieldDecl( $2, $3 ); distExt( $$ ); }
    2595         | STATIC type_specifier field_declaring_list_opt ';' // CFA
    2596                 { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }
    25972475        | INLINE type_specifier field_abstract_list_opt ';'     // CFA
    25982476                {
     
    26052483                }
    26062484        | INLINE aggregate_control ';'                                          // CFA
    2607                 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
     2485                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    26082486        | typedef_declaration ';'                                                       // CFA
    26092487        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
     
    26312509                { $$ = $1->addBitfield( $2 ); }
    26322510        | variable_type_redeclarator bit_subrange_size_opt
    2633                 // A semantic check is required to ensure bit_subrange only appears on integral types.
    2634                 { $$ = $1->addBitfield( $2 ); }
    2635         | function_type_redeclarator bit_subrange_size_opt
    26362511                // A semantic check is required to ensure bit_subrange only appears on integral types.
    26372512                { $$ = $1->addBitfield( $2 ); }
     
    26882563                { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
    26892564        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2690                 {
    2691                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.any() ) {
    2692                                 SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." );
    2693                         }
     2565                {
     2566                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 )
     2567                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
     2568
    26942569                        $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 );
    26952570                }
     
    27002575        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    27012576                {
    2702                         if ( $3->storageClasses.any() || $3->type->qualifiers.val != 0 ) {
    2703                                 SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." );
    2704                         }
     2577                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    27052578                        typedefTable.makeTypedef( *$6 );
    27062579                }
     
    27362609enum_type_nobody:                                                                               // enum - {...}
    27372610        ENUM attribute_list_opt identifier
    2738                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }
     2611                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
    27392612        | ENUM attribute_list_opt type_name
    2740                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }
     2613                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
    27412614        ;
    27422615
     
    28782751type_no_function:                                                                               // sizeof, alignof, cast (constructor)
    28792752        cfa_abstract_declarator_tuple                                           // CFA
    2880         | type_specifier                                                                        // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
     2753        | type_specifier
    28812754        | type_specifier abstract_declarator
    28822755                { $$ = $2->addType( $1 ); }
     
    29232796        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    29242797        | identifier_at ':'                                                                     // GCC, field name
    2925                 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
     2798                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    29262799        ;
    29272800
     
    29352808designator:
    29362809        '.' identifier_at                                                                       // C99, field name
    2937                 { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
     2810                { $$ = new ExpressionNode( build_varref( $2 ) ); }
    29382811        | '[' push assignment_expression pop ']'                        // C99, single array element
    29392812                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    29422815                { $$ = $3; }
    29432816        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2944                 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
     2817                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); }
    29452818        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    29462819                { $$ = $4; }
     
    29822855                {
    29832856                        typedefTable.addToScope( *$2, TYPEDEFname, "9" );
    2984                         if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
    2985                         if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
    2986                         if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
     2857                        if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
     2858                        if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     2859                        if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
    29872860                }
    29882861          type_initializer_opt assertion_list_opt
     
    29952868                {
    29962869                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2997                         $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
     2870                        $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
    29982871                }
    29992872        // | type_specifier identifier_parameter_declarator
    30002873        | assertion_list
    3001                 { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2874                { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    30022875        ;
    30032876
    30042877new_type_class:                                                                                 // CFA
    30052878        // empty
    3006                 { $$ = ast::TypeDecl::Otype; }
     2879                { $$ = TypeDecl::Otype; }
    30072880        | '&'
    3008                 { $$ = ast::TypeDecl::Dtype; }
     2881                { $$ = TypeDecl::Dtype; }
    30092882        | '*'
    3010                 { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
     2883                { $$ = TypeDecl::DStype; }                                              // dtype + sized
    30112884        // | '(' '*' ')'
    3012         //      { $$ = ast::TypeDecl::Ftype; }
     2885        //      { $$ = TypeDecl::Ftype; }
    30132886        | ELLIPSIS
    3014                 { $$ = ast::TypeDecl::Ttype; }
     2887                { $$ = TypeDecl::Ttype; }
    30152888        ;
    30162889
    30172890type_class:                                                                                             // CFA
    30182891        OTYPE
    3019                 { $$ = ast::TypeDecl::Otype; }
     2892                { $$ = TypeDecl::Otype; }
    30202893        | DTYPE
    3021                 { $$ = ast::TypeDecl::Dtype; }
     2894                { $$ = TypeDecl::Dtype; }
    30222895        | FTYPE
    3023                 { $$ = ast::TypeDecl::Ftype; }
     2896                { $$ = TypeDecl::Ftype; }
    30242897        | TTYPE
    3025                 { $$ = ast::TypeDecl::Ttype; }
     2898                { $$ = TypeDecl::Ttype; }
    30262899        ;
    30272900
     
    30492922type_list:                                                                                              // CFA
    30502923        type
    3051                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     2924                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    30522925        | assignment_expression
    30532926        | type_list ',' type
    3054                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     2927                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    30552928        | type_list ',' assignment_expression
    30562929                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    30772950                {
    30782951                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    3079                         $$ = DeclarationNode::newTypeDecl( $1, nullptr );
     2952                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
    30802953                }
    30812954        | identifier_or_type_name '(' type_parameter_list ')'
     
    30882961trait_specifier:                                                                                // CFA
    30892962        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    3090                 {
    3091                         SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
    3092                         $$ = DeclarationNode::newTrait( $2, $4, nullptr );
    3093                 }
    3094         | forall TRAIT identifier_or_type_name '{' '}'          // alternate
    3095                 { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); }
     2963                { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
    30962964        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    3097                 {
    3098                         SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
    3099                         $$ = DeclarationNode::newTrait( $2, $4, $8 );
    3100                 }
    3101         | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate
    3102                 { $$ = DeclarationNode::newTrait( $3, $1, $6 ); }
     2965                { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
    31032966        ;
    31042967
     
    31593022external_definition:
    31603023        DIRECTIVE
    3161                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
     3024                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
    31623025        | declaration
    3163                 {
    3164                         // Variable declarations of anonymous types requires creating a unique type-name across multiple translation
    3165                         // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is
    3166                         // disallowed at the moment.
    3167                         if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
    3168                                 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
    3169                                         SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
    3170                                 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union
    3171                                         SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;
    3172                                 }
    3173                         }
    3174                 }
    31753026        | IDENTIFIER IDENTIFIER
    31763027                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
    3177         | IDENTIFIER type_qualifier                                                     // invalid syntax rules
     3028        | IDENTIFIER type_qualifier                                                     // syntax error
    31783029                { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; }
    3179         | IDENTIFIER storage_class                                                      // invalid syntax rules
     3030        | IDENTIFIER storage_class                                                      // syntax error
    31803031                { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; }
    3181         | IDENTIFIER basic_type_name                                            // invalid syntax rules
     3032        | IDENTIFIER basic_type_name                                            // syntax error
    31823033                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    3183         | IDENTIFIER TYPEDEFname                                                        // invalid syntax rules
     3034        | IDENTIFIER TYPEDEFname                                                        // syntax error
    31843035                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    3185         | IDENTIFIER TYPEGENname                                                        // invalid syntax rules
     3036        | IDENTIFIER TYPEGENname                                                        // syntax error
    31863037                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    31873038        | external_function_definition
     
    31923043                }
    31933044        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3194                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
     3045                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
    31953046        | EXTERN STRINGliteral
    31963047                {
    31973048                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3198                         linkage = ast::Linkage::update( yylloc, linkage, $2 );
     3049                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
    31993050                }
    32003051          up external_definition down
     
    32073058                {
    32083059                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3209                         linkage = ast::Linkage::update( yylloc, linkage, $2 );
     3060                        linkage = LinkageSpec::update( yylloc, linkage, $2 );
    32103061                }
    32113062          '{' up external_definition_list_opt down '}'
     
    32183069        | type_qualifier_list
    32193070                {
    3220                         if ( $1->type->qualifiers.any() ) {
    3221                                 SemanticError( yylloc, "syntax error, CV qualifiers cannot be distributed; only storage-class and forall qualifiers." );
    3222                         }
     3071                        if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    32233072                        if ( $1->type->forall ) forall = true;          // remember generic type
    32243073                }
     
    32263075                {
    32273076                        distQual( $5, $1 );
    3228                         forall = false;
     3077                        forall = false;
    32293078                        $$ = $5;
    32303079                }
    32313080        | declaration_qualifier_list
    32323081                {
    3233                         if ( $1->type && $1->type->qualifiers.any() ) {
    3234                                 SemanticError( yylloc, "syntax error, CV qualifiers cannot be distributed; only storage-class and forall qualifiers." );
    3235                         }
     3082                        if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    32363083                        if ( $1->type && $1->type->forall ) forall = true; // remember generic type
    32373084                }
     
    32393086                {
    32403087                        distQual( $5, $1 );
    3241                         forall = false;
     3088                        forall = false;
    32423089                        $$ = $5;
    32433090                }
    32443091        | declaration_qualifier_list type_qualifier_list
    32453092                {
    3246                         if ( ($1->type && $1->type->qualifiers.any()) || ($2->type && $2->type->qualifiers.any()) ) {
    3247                                 SemanticError( yylloc, "syntax error, CV qualifiers cannot be distributed; only storage-class and forall qualifiers." );
    3248                         }
     3093                        if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    32493094                        if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type
    32503095                }
     
    32523097                {
    32533098                        distQual( $6, $1->addQualifiers( $2 ) );
    3254                         forall = false;
     3099                        forall = false;
    32553100                        $$ = $6;
    32563101                }
     
    32773122                        $$ = $3; forall = false;
    32783123                        if ( $5 ) {
    3279                                 SemanticError( yylloc, "syntax error, attributes cannot be associated with function body. Move attribute(s) before \"with\" clause." );
     3124                                SemanticError( yylloc, "Attributes cannot be associated with function body. Move attribute(s) before \"with\" clause." );
    32803125                                $$ = nullptr;
    32813126                        } // if
     
    32963141                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    32973142                }
    3298         | declaration_specifier function_type_redeclarator with_clause_opt compound_statement
     3143        | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
    32993144                {
    33003145                        rebindForall( $1, $2 );
     
    33323177        | variable_type_redeclarator
    33333178        | function_declarator
    3334         | function_type_redeclarator
    33353179        ;
    33363180
    33373181subrange:
    33383182        constant_expression '~' constant_expression                     // CFA, integer subrange
    3339                 { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     3183                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
    33403184        ;
    33413185
     
    33463190                {
    33473191                        DeclarationNode * name = new DeclarationNode();
    3348                         name->asmName = maybeMoveBuild( $3 );
     3192                        name->asmName = $3;
    33493193                        $$ = name->addQualifiers( $5 );
    33503194                }
     
    34433287variable_ptr:
    34443288        ptrref_operator variable_declarator
    3445                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3289                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    34463290        | ptrref_operator type_qualifier_list variable_declarator
    34473291                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34593303        | '(' attribute_list variable_ptr ')' array_dimension
    34603304                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3461         | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     3305        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
    34623306                { $$ = $2->addArray( $4 ); }
    34633307        | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis
     
    35073351function_ptr:
    35083352        ptrref_operator function_declarator
    3509                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3353                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    35103354        | ptrref_operator type_qualifier_list function_declarator
    35113355                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35593403KR_function_ptr:
    35603404        ptrref_operator KR_function_declarator
    3561                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3405                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    35623406        | ptrref_operator type_qualifier_list KR_function_declarator
    35633407                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35833427        ;
    35843428
    3585 // This pattern parses a declaration for a variable that redefines a type name, e.g.:
     3429// This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.:
    35863430//
    35873431//              typedef int foo;
     
    35893433//                 int foo; // redefine typedef name in new scope
    35903434//              }
     3435//
     3436// The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
     3437// and functions versus pointers to arrays and functions.
    35913438
    35923439paren_type:
     
    36033450        paren_type attribute_list_opt
    36043451                { $$ = $1->addQualifiers( $2 ); }
    3605         | variable_type_ptr
    3606         | variable_type_array attribute_list_opt
     3452        | type_ptr
     3453        | type_array attribute_list_opt
    36073454                { $$ = $1->addQualifiers( $2 ); }
    3608         | variable_type_function attribute_list_opt
     3455        | type_function attribute_list_opt
    36093456                { $$ = $1->addQualifiers( $2 ); }
    36103457        ;
    36113458
    3612 variable_type_ptr:
     3459type_ptr:
    36133460        ptrref_operator variable_type_redeclarator
    3614                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3461                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    36153462        | ptrref_operator type_qualifier_list variable_type_redeclarator
    36163463                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3617         | '(' variable_type_ptr ')' attribute_list_opt          // redundant parenthesis
     3464        | '(' type_ptr ')' attribute_list_opt                           // redundant parenthesis
    36183465                { $$ = $2->addQualifiers( $4 ); }
    3619         | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis
     3466        | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis
    36203467                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    36213468        ;
    36223469
    3623 variable_type_array:
     3470type_array:
    36243471        paren_type array_dimension
    36253472                { $$ = $1->addArray( $2 ); }
    3626         | '(' variable_type_ptr ')' array_dimension
     3473        | '(' type_ptr ')' array_dimension
    36273474                { $$ = $2->addArray( $4 ); }
    3628         | '(' attribute_list variable_type_ptr ')' array_dimension
     3475        | '(' attribute_list type_ptr ')' array_dimension
    36293476                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3630         | '(' variable_type_array ')' multi_array_dimension     // redundant parenthesis
     3477        | '(' type_array ')' multi_array_dimension                      // redundant parenthesis
    36313478                { $$ = $2->addArray( $4 ); }
    3632         | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis
     3479        | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis
    36333480                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3634         | '(' variable_type_array ')'                                           // redundant parenthesis
     3481        | '(' type_array ')'                                                            // redundant parenthesis
    36353482                { $$ = $2; }
    3636         | '(' attribute_list variable_type_array ')'            // redundant parenthesis
     3483        | '(' attribute_list type_array ')'                                     // redundant parenthesis
    36373484                { $$ = $3->addQualifiers( $2 ); }
    36383485        ;
    36393486
    3640 variable_type_function:
    3641         '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3642                 { $$ = $2->addParamList( $6 ); }
    3643         | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3644                 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3645         | '(' variable_type_function ')'                                        // redundant parenthesis
    3646                 { $$ = $2; }
    3647         | '(' attribute_list variable_type_function ')'         // redundant parenthesis
    3648                 { $$ = $3->addQualifiers( $2 ); }
    3649         ;
    3650 
    3651 // This pattern parses a declaration for a function prototype that redefines a type name.  It precludes declaring an
    3652 // array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to
    3653 // arrays and functions.
    3654 
    3655 function_type_redeclarator:
    3656         function_type_no_ptr attribute_list_opt
    3657                 { $$ = $1->addQualifiers( $2 ); }
    3658         | function_type_ptr
    3659         | function_type_array attribute_list_opt
    3660                 { $$ = $1->addQualifiers( $2 ); }
    3661         ;
    3662 
    3663 function_type_no_ptr:
     3487type_function:
    36643488        paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36653489                { $$ = $1->addParamList( $4 ); }
    3666         | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
     3490        | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36673491                { $$ = $2->addParamList( $6 ); }
    3668         | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
     3492        | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    36693493                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3670         | '(' function_type_no_ptr ')'                                          // redundant parenthesis
     3494        | '(' type_function ')'                                                         // redundant parenthesis
    36713495                { $$ = $2; }
    3672         | '(' attribute_list function_type_no_ptr ')'           // redundant parenthesis
    3673                 { $$ = $3->addQualifiers( $2 ); }
    3674         ;
    3675 
    3676 function_type_ptr:
    3677         ptrref_operator function_type_redeclarator
    3678                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    3679         | ptrref_operator type_qualifier_list function_type_redeclarator
    3680                 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3681         | '(' function_type_ptr ')' attribute_list_opt
    3682                 { $$ = $2->addQualifiers( $4 ); }
    3683         | '(' attribute_list function_type_ptr ')' attribute_list_opt
    3684                 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    3685         ;
    3686 
    3687 function_type_array:
    3688         '(' function_type_ptr ')' array_dimension
    3689                 { $$ = $2->addArray( $4 ); }
    3690         | '(' attribute_list function_type_ptr ')' array_dimension
    3691                 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3692         | '(' function_type_array ')' multi_array_dimension     // redundant parenthesis
    3693                 { $$ = $2->addArray( $4 ); }
    3694         | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis
    3695                 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3696         | '(' function_type_array ')'                                           // redundant parenthesis
    3697                 { $$ = $2; }
    3698         | '(' attribute_list function_type_array ')'            // redundant parenthesis
     3496        | '(' attribute_list type_function ')'                          // redundant parenthesis
    36993497                { $$ = $3->addQualifiers( $2 ); }
    37003498        ;
     
    37193517identifier_parameter_ptr:
    37203518        ptrref_operator identifier_parameter_declarator
    3721                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3519                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    37223520        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    37233521                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    37763574type_parameter_ptr:
    37773575        ptrref_operator type_parameter_redeclarator
    3778                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3576                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    37793577        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    37803578                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38193617abstract_ptr:
    38203618        ptrref_operator
    3821                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     3619                { $$ = DeclarationNode::newPointer( 0, $1 ); }
    38223620        | ptrref_operator type_qualifier_list
    38233621                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    38243622        | ptrref_operator abstract_declarator
    3825                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3623                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    38263624        | ptrref_operator type_qualifier_list abstract_declarator
    38273625                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38523650                // Only the first dimension can be empty.
    38533651        '[' ']'
    3854                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
     3652                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    38553653        | '[' ']' multi_array_dimension
    3856                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }
     3654                { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); }
    38573655                // Cannot use constant_expression because of tuples => semantic check
    38583656        | '[' push assignment_expression pop ',' comma_expression ']' // CFA
    3859                 { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }
     3657                { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }
    38603658                // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; }
    38613659        | '[' push array_type_list pop ']'                                      // CFA
     
    38663664array_type_list:
    38673665        basic_type_name
    3868                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     3666                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    38693667        | type_name
    3870                 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
     3668                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    38713669        | assignment_expression upupeq assignment_expression
    38723670        | array_type_list ',' basic_type_name
    3873                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    3874         | array_type_list ',' type_name
    3875                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     3671                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3672        | array_type_list ',' type_name 
     3673                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    38763674        | array_type_list ',' assignment_expression upupeq assignment_expression
    38773675        ;
     
    38823680        | ErangeUpEq
    38833681                { $$ = OperKinds::LEThan; }
    3884         ;
     3682        ;
    38853683
    38863684multi_array_dimension:
    38873685        '[' push assignment_expression pop ']'
    3888                 { $$ = DeclarationNode::newArray( $3, nullptr, false ); }
     3686                { $$ = DeclarationNode::newArray( $3, 0, false ); }
    38893687        | '[' push '*' pop ']'                                                          // C99
    38903688                { $$ = DeclarationNode::newVarArray( 0 ); }
    38913689        | multi_array_dimension '[' push assignment_expression pop ']'
    3892                 { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }
     3690                { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
    38933691        | multi_array_dimension '[' push '*' pop ']'            // C99
    38943692                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
     
    39873785array_parameter_1st_dimension:
    39883786        '[' ']'
    3989                 { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
     3787                { $$ = DeclarationNode::newArray( 0, 0, false ); }
    39903788                // multi_array_dimension handles the '[' '*' ']' case
    39913789        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    39923790                { $$ = DeclarationNode::newVarArray( $3 ); }
    39933791        | '[' push type_qualifier_list pop ']'
    3994                 { $$ = DeclarationNode::newArray( nullptr, $3, false ); }
     3792                { $$ = DeclarationNode::newArray( 0, $3, false ); }
    39953793                // multi_array_dimension handles the '[' assignment_expression ']' case
    39963794        | '[' push type_qualifier_list assignment_expression pop ']'
     
    40213819variable_abstract_ptr:
    40223820        ptrref_operator
    4023                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     3821                { $$ = DeclarationNode::newPointer( 0, $1 ); }
    40243822        | ptrref_operator type_qualifier_list
    40253823                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    40263824        | ptrref_operator variable_abstract_declarator
    4027                 { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3825                { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40283826        | ptrref_operator type_qualifier_list variable_abstract_declarator
    40293827                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    40673865                // No SUE declaration in parameter list.
    40683866        ptrref_operator type_specifier_nobody
    4069                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3867                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40703868        | type_qualifier_list ptrref_operator type_specifier_nobody
    40713869                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    40723870        | ptrref_operator cfa_abstract_function
    4073                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3871                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40743872        | type_qualifier_list ptrref_operator cfa_abstract_function
    40753873                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    40763874        | ptrref_operator cfa_identifier_parameter_declarator_tuple
    4077                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3875                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    40783876        | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple
    40793877                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
     
    40843882                // shift/reduce conflict with new-style empty (void) function return type.
    40853883        '[' ']' type_specifier_nobody
    4086                 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3884                { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40873885        | cfa_array_parameter_1st_dimension type_specifier_nobody
    40883886                { $$ = $2->addNewArray( $1 ); }
    40893887        | '[' ']' multi_array_dimension type_specifier_nobody
    4090                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3888                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40913889        | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody
    40923890                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    40953893
    40963894        | '[' ']' cfa_identifier_parameter_ptr
    4097                 { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3895                { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    40983896        | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr
    40993897                { $$ = $2->addNewArray( $1 ); }
    41003898        | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr
    4101                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
     3899                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
    41023900        | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr
    41033901                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    41553953cfa_abstract_ptr:                                                                               // CFA
    41563954        ptrref_operator type_specifier
    4157                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3955                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41583956        | type_qualifier_list ptrref_operator type_specifier
    41593957                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    41603958        | ptrref_operator cfa_abstract_function
    4161                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3959                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41623960        | type_qualifier_list ptrref_operator cfa_abstract_function
    41633961                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    41643962        | ptrref_operator cfa_abstract_declarator_tuple
    4165                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3963                { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
    41663964        | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple
    41673965                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note: See TracChangeset for help on using the changeset viewer.