Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    r46da46b r0442f93f  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Nov 21 22:34:30 2022
    13 // Update Count     : 5848
     12// Last Modified On : Wed Jun  7 14:32:28 2023
     13// Update Count     : 6341
    1414//
    1515
     
    4444
    4545#include <cstdio>
     46#include <sstream>
    4647#include <stack>
    4748using namespace std;
    4849
    49 #include "SynTree/Declaration.h"
    50 #include "ParseNode.h"
     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_...
    5156#include "TypedefTable.h"
    5257#include "TypeData.h"
    53 #include "SynTree/LinkageSpec.h"
    5458#include "Common/SemanticError.h"                                               // error_str
    5559#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
    5660
    57 #include "SynTree/Attribute.h"     // for Attribute
     61#include "SynTree/Attribute.h"                                                  // for Attribute
    5862
    5963// lex uses __null in a boolean context, it's fine.
     
    6367
    6468extern DeclarationNode * parseTree;
    65 extern LinkageSpec::Spec linkage;
     69extern ast::Linkage::Spec linkage;
    6670extern TypedefTable typedefTable;
    6771
    68 stack<LinkageSpec::Spec> linkageStack;
     72stack<ast::Linkage::Spec> linkageStack;
    6973
    7074bool appendStr( string & to, string & from ) {
     
    104108        assert( declList );
    105109        // printf( "distAttr1 typeSpec %p\n", typeSpec ); typeSpec->print( std::cout );
    106         DeclarationNode * cur = declList, * cl = (new DeclarationNode)->addType( typeSpec );
     110        DeclarationNode * cl = (new DeclarationNode)->addType( typeSpec );
    107111        // printf( "distAttr2 cl %p\n", cl ); cl->type->print( std::cout );
    108112        // cl->type->aggregate.name = cl->type->aggInst.aggregate->aggregate.name;
    109113
    110         for ( cur = dynamic_cast<DeclarationNode *>( cur->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) {
     114        for ( DeclarationNode * cur = dynamic_cast<DeclarationNode *>( declList->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) {
    111115                cl->cloneBaseType( cur );
    112116        } // for
     
    199203} // fieldDecl
    200204
    201 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
    202 #define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
     205#define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) )
     206#define NEW_ONE  new ExpressionNode( build_constantInteger( yylloc, *new string( "1" ) ) )
    203207#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    204 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
    205 #define MISSING_LOW "Missing low value for up-to range so index is uninitialized."
    206 #define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
    207 
    208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     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
     212static 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
     232ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    209233        if ( index->initializer ) {
    210                 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     234                SemanticError( yylloc, "syntax error, direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
    211235        } // if
    212236        if ( index->next ) {
    213                 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
     237                SemanticError( yylloc, "syntax error, multiple loop indexes disallowed in for-loop declaration." );
    214238        } // if
    215         return new ForCtrl( index->addInitializer( new InitializerNode( start ) ),
    216                 // NULL comp/inc => leave blank
    217                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr,
    218                 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    219                                                         OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr );
     239        DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) );
     240        return makeForCtrl( location, initDecl, compop, comp, inc );
    220241} // forCtrl
    221242
    222 ForCtrl * 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 ) ) );
     243ForCtrl * 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 ) ) );
    226247        } // if
    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 );
     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 );
    234253} // forCtrl
    235254
    236 ForCtrl * 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 );
     255ForCtrl * 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 );
    242261                } else {
    243                         SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     262                        SemanticError( yylloc, "syntax error, loop-index name missing. Expression disallowed." ); return nullptr;
    244263                } // if
    245264        } else {
    246                 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     265                SemanticError( yylloc, "syntax error, loop-index name missing. Expression disallowed. ." ); return nullptr;
    247266        } // if
    248267} // forCtrl
    249268
    250269static void IdentifierBeforeIdentifier( string & identifier1, string & identifier2, const char * kind ) {
    251         SemanticError( yylloc, ::toString( "Adjacent identifiers \"", identifier1, "\" and \"", identifier2, "\" are not meaningful in a", kind, ".\n"
     270        SemanticError( yylloc, ::toString( "syntax error, adjacent identifiers \"", identifier1, "\" and \"", identifier2, "\" are not meaningful in a", kind, ".\n"
    252271                                   "Possible cause is misspelled type name or missing generic parameter." ) );
    253272} // IdentifierBeforeIdentifier
    254273
    255274static void IdentifierBeforeType( string & identifier, const char * kind ) {
    256         SemanticError( yylloc, ::toString( "Identifier \"", identifier, "\" cannot appear before a ", kind, ".\n"
     275        SemanticError( yylloc, ::toString( "syntax error, identifier \"", identifier, "\" cannot appear before a ", kind, ".\n"
    257276                                   "Possible cause is misspelled storage/CV qualifier, misspelled typename, or missing generic parameter." ) );
    258277} // IdentifierBeforeType
     
    281300%union {
    282301        Token tok;
    283         ParseNode * pn;
    284         ExpressionNode * en;
     302        ExpressionNode * expr;
    285303        DeclarationNode * decl;
    286         AggregateDecl::Aggregate aggKey;
    287         TypeDecl::Kind tclass;
    288         StatementNode * sn;
    289         WaitForStmt * wfs;
    290         Expression * constant;
     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;
    291310        CondCtl * ifctl;
    292         ForCtrl * fctl;
    293         OperKinds compop;
    294         LabelNode * label;
    295         InitializerNode * in;
    296         OperKinds op;
     311        ForCtrl * forctl;
     312        LabelNode * labels;
     313        InitializerNode * init;
     314        OperKinds oper;
    297315        std::string * str;
    298         bool flag;
    299         EnumHiding hide;
    300         CatchStmt::Kind catch_kind;
    301         GenericExpr * genexpr;
     316        bool is_volatile;
     317        EnumHiding enum_hiding;
     318        ast::ExceptionKind except_kind;
     319        ast::GenericExpr * genexpr;
    302320}
    303321
    304 //************************* TERMINAL TOKENS ********************************
     322// ************************ TERMINAL TOKENS ********************************
    305323
    306324// keywords
     
    331349%token ATTRIBUTE EXTENSION                                                              // GCC
    332350%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
    333 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR    // CFA
     351%token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL // CFA
    334352%token DISABLE ENABLE TRY THROW THROWRESUME AT                  // CFA
    335353%token ASM                                                                                              // C99, extension ISO/IEC 9899:1999 Section J.5.10(1)
     
    337355
    338356// names and constants: lexer differentiates between identifier and typedef names
    339 %token<tok> IDENTIFIER          QUOTED_IDENTIFIER       TYPEDIMname             TYPEDEFname             TYPEGENname
    340 %token<tok> TIMEOUT                     WOR                                     CATCH                   RECOVER                 CATCHRESUME             FIXUP           FINALLY         // CFA
     357%token<tok> IDENTIFIER          TYPEDIMname             TYPEDEFname             TYPEGENname
     358%token<tok> TIMEOUT                     WAND    WOR                     CATCH                   RECOVER                 CATCHRESUME             FIXUP           FINALLY         // CFA
    341359%token<tok> INTEGERconstant     CHARACTERconstant       STRINGliteral
    342360%token<tok> DIRECTIVE
     
    364382%type<tok> identifier                                   identifier_at                           identifier_or_type_name         attr_name
    365383%type<tok> quasi_keyword
    366 %type<constant> string_literal
     384%type<expr> string_literal
    367385%type<str> string_literal_list
    368386
    369 %type<hide> hide_opt                                    visible_hide_opt
     387%type<enum_hiding> hide_opt                                     visible_hide_opt
    370388
    371389// expressions
    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
     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
    383401%type<ifctl> conditional_declaration
    384 %type<fctl> for_control_expression              for_control_expression_list
    385 %type<compop> upupeq updown updowneq downupdowneq
    386 %type<en> subrange
     402%type<forctl> for_control_expression            for_control_expression_list
     403%type<oper> upupeq updown updowneq downupdowneq
     404%type<expr> subrange
    387405%type<decl> asm_name_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
     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
    393411%type<genexpr> generic_association              generic_assoc_list
    394412
    395413// statements
    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
     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
    412432
    413433// declarations
     
    421441%type<decl> assertion assertion_list assertion_list_opt
    422442
    423 %type<en> bit_subrange_size_opt bit_subrange_size
     443%type<expr> bit_subrange_size_opt bit_subrange_size
    424444
    425445%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     
    434454
    435455%type<decl> enumerator_list enum_type enum_type_nobody
    436 %type<in> enumerator_value_opt
     456%type<init> enumerator_value_opt
    437457
    438458%type<decl> external_definition external_definition_list external_definition_list_opt
     
    441461
    442462%type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract
    443 %type<en> field field_name_list field_name fraction_constants_opt
     463%type<expr> field field_name_list field_name fraction_constants_opt
    444464
    445465%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    482502%type<decl> typedef_name typedef_declaration typedef_expression
    483503
    484 %type<decl> variable_type_redeclarator type_ptr type_array type_function
     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
    485506
    486507%type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function
     
    489510%type<decl> type_parameter type_parameter_list type_initializer_opt
    490511
    491 %type<en> type_parameters_opt type_list array_type_list
     512%type<expr> type_parameters_opt type_list array_type_list
    492513
    493514%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    500521
    501522// initializers
    502 %type<in>  initializer initializer_list_opt initializer_opt
     523%type<init>  initializer initializer_list_opt initializer_opt
    503524
    504525// designators
    505 %type<en>  designator designator_list designation
     526%type<expr>  designator designator_list designation
    506527
    507528
     
    512533// Similar issues exit with the waitfor statement.
    513534
    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.
     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.
    516537%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
    517541%precedence WOR                 // token precedence for start of WOR in WAITFOR statement
    518542%precedence TIMEOUT             // token precedence for start of TIMEOUT in WAITFOR statement
     
    592616constant:
    593617                // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
    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 ) ); }
     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 ) ); }
    599623        ;
    600624
    601625quasi_keyword:                                                                                  // CFA
    602626        TIMEOUT
     627        | WAND
    603628        | WOR
    604629        | CATCH
     
    621646
    622647string_literal:
    623         string_literal_list                                                     { $$ = build_constantStr( *$1 ); }
     648        string_literal_list                                                     { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 ) ); }
    624649        ;
    625650
     
    638663primary_expression:
    639664        IDENTIFIER                                                                                      // typedef name cannot be used as a variable name
    640                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     665                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    641666        | quasi_keyword
    642                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     667                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    643668        | TYPEDIMname                                                                           // CFA, generic length argument
    644669                // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); }
    645670                // { $$ = new ExpressionNode( build_varref( $1 ) ); }
    646                 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }
     671                { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); }
    647672        | tuple
    648673        | '(' comma_expression ')'
    649674                { $$ = $2; }
    650675        | '(' compound_statement ')'                                            // GCC, lambda expression
    651                 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }
     676                { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); }
    652677        | type_name '.' identifier                                                      // CFA, nested type
    653                 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
     678                { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    654679        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    655680                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    657682                {
    658683                        // add the missing control expression to the GenericExpr and return it
    659                         $5->control = maybeMoveBuild<Expression>( $3 );
     684                        $5->control = maybeMoveBuild( $3 );
    660685                        $$ = new ExpressionNode( $5 );
    661686                }
     
    664689        // | RESUME '(' comma_expression ')' compound_statement
    665690        //      { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; }
    666         | IDENTIFIER IDENTIFIER                                                         // syntax error
     691        | IDENTIFIER IDENTIFIER                                                         // invalid syntax rules
    667692                { IdentifierBeforeIdentifier( *$1.str, *$2.str, "n expression" ); $$ = nullptr; }
    668         | IDENTIFIER type_qualifier                                                     // syntax error
     693        | IDENTIFIER type_qualifier                                                     // invalid syntax rules
    669694                { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; }
    670         | IDENTIFIER storage_class                                                      // syntax error
     695        | IDENTIFIER storage_class                                                      // invalid syntax rules
    671696                { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; }
    672         | IDENTIFIER basic_type_name                                            // syntax error
     697        | IDENTIFIER basic_type_name                                            // invalid syntax rules
    673698                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    674         | IDENTIFIER TYPEDEFname                                                        // syntax error
     699        | IDENTIFIER TYPEDEFname                                                        // invalid syntax rules
    675700                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    676         | IDENTIFIER TYPEGENname                                                        // syntax error
     701        | IDENTIFIER TYPEGENname                                                        // invalid syntax rules
    677702                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    678703        ;
     
    683708                {
    684709                        // steal the association node from the singleton and delete the wrapper
    685                         $1->associations.splice($1->associations.end(), $3->associations);
     710                        assert( 1 == $3->associations.size() );
     711                        $1->associations.push_back( $3->associations.front() );
    686712                        delete $3;
    687713                        $$ = $1;
     
    693719                {
    694720                        // create a GenericExpr wrapper with one association pair
    695                         $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } );
     721                        $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );
    696722                }
    697723        | DEFAULT ':' assignment_expression
    698                 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); }
     724                { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }
    699725        ;
    700726
     
    705731                // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
    706732                // Current: Commas in subscripts make tuples.
    707                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
     733                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
    708734        | postfix_expression '[' assignment_expression ']'
    709735                // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
     
    711737                // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
    712738                // equivalent to the old x[i,j].
    713                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     739                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    714740        | constant '[' assignment_expression ']'                        // 3[a], 'a'[a], 3.5[a]
    715                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     741                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    716742        | string_literal '[' assignment_expression ']'          // "abc"[3], 3["abc"]
    717                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
     743                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    718744        | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call
    719745                {
    720746                        Token fn;
    721747                        fn.str = new std::string( "?{}" );                      // location undefined - use location of '{'?
    722                         $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
     748                        $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
    723749                }
    724750        | postfix_expression '(' argument_expression_list_opt ')'
    725                 { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
     751                { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); }
    726752        | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')'
    727753                // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; }
    728                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ),
     754                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, new string( "__builtin_va_arg") ) ),
    729755                                                                                           (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); }
    730756        | postfix_expression '`' identifier                                     // CFA, postfix call
    731                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     757                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    732758        | constant '`' identifier                                                       // CFA, postfix call
    733                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     759                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    734760        | string_literal '`' identifier                                         // CFA, postfix call
    735                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
     761                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    736762        | postfix_expression '.' identifier
    737                 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
     763                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    738764        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
    739                 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); }
     765                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    740766        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    741                 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
     767                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ) ) ); }
    742768        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    743                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     769                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    744770        | postfix_expression '.' aggregate_control
    745                 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
     771                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); }
    746772        | postfix_expression ARROW identifier
    747                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
     773                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    748774        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    749                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
     775                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    750776        | postfix_expression ARROW '[' field_name_list ']'      // CFA, tuple field selector
    751                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     777                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    752778        | postfix_expression ICR
    753                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
     779                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); }
    754780        | postfix_expression DECR
    755                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); }
     781                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); }
    756782        | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
    757                 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
     783                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); }
    758784        | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
    759                 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
     785                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
    760786        | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call
    761787                {
    762788                        Token fn;
    763789                        fn.str = new string( "^?{}" );                          // location undefined
    764                         $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
     790                        $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
    765791                }
    766792        ;
     
    781807        '@'                                                                                                     // CFA, default parameter
    782808                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
    783                 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
     809                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
    784810        | assignment_expression
    785811        ;
     
    793819        field_name
    794820        | FLOATING_DECIMALconstant field
    795                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
     821                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); }
    796822        | FLOATING_DECIMALconstant '[' field_name_list ']'
    797                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
     823                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc, $3 ) ) ); }
    798824        | field_name '.' field
    799                 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     825                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    800826        | field_name '.' '[' field_name_list ']'
    801                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     827                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    802828        | field_name ARROW field
    803                 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     829                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    804830        | field_name ARROW '[' field_name_list ']'
    805                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     831                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    806832        ;
    807833
    808834field_name:
    809835        INTEGERconstant fraction_constants_opt
    810                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }
     836                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc, *$1 ), $2 ) ); }
    811837        | FLOATINGconstant fraction_constants_opt
    812                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
     838                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc, *$1 ), $2 ) ); }
    813839        | identifier_at fraction_constants_opt                          // CFA, allow anonymous fields
    814840                {
    815                         $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
     841                        $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc, $1 ), $2 ) );
    816842                }
    817843        ;
     
    822848        | fraction_constants_opt FLOATING_FRACTIONconstant
    823849                {
    824                         Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
    825                         $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant );
     850                        ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 );
     851                        $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1, constant ) ) : new ExpressionNode( constant );
    826852                }
    827853        ;
     
    833859        | constant
    834860        | string_literal
    835                 { $$ = new ExpressionNode( $1 ); }
     861                { $$ = $1; }
    836862        | EXTENSION cast_expression                                                     // GCC
    837863                { $$ = $2->set_extension( true ); }
     
    842868                {
    843869                        switch ( $1 ) {
    844                           case OperKinds::AddressOf:
    845                                 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) );
     870                        case OperKinds::AddressOf:
     871                                $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );
    846872                                break;
    847                           case OperKinds::PointTo:
    848                                 $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
     873                        case OperKinds::PointTo:
     874                                $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) );
    849875                                break;
    850                           case OperKinds::And:
    851                                 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) );
     876                        case OperKinds::And:
     877                                $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );
    852878                                break;
    853                           default:
     879                        default:
    854880                                assert( false );
    855881                        }
    856882                }
    857883        | unary_operator cast_expression
    858                 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }
     884                { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); }
    859885        | ICR unary_expression
    860                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Incr, $2 ) ); }
     886                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); }
    861887        | DECR unary_expression
    862                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Decr, $2 ) ); }
     888                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); }
    863889        | SIZEOF unary_expression
    864                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
     890                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    865891        | SIZEOF '(' type_no_function ')'
    866                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); }
     892                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    867893        | ALIGNOF unary_expression                                                      // GCC, variable alignment
    868                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
     894                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    869895        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    870                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
     896                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    871897        | OFFSETOF '(' type_no_function ',' identifier ')'
    872                 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
     898                { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); }
    873899        | TYPEID '(' type_no_function ')'
    874900                {
     
    895921        unary_expression
    896922        | '(' type_no_function ')' cast_expression
    897                 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     923                { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    898924        | '(' aggregate_control '&' ')' cast_expression         // CFA
    899                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     925                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    900926        | '(' aggregate_control '*' ')' cast_expression         // CFA
    901                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     927                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    902928        | '(' VIRTUAL ')' cast_expression                                       // CFA
    903                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     929                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    904930        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    905                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); }
     931                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
    906932        | '(' RETURN type_no_function ')' cast_expression       // CFA
    907                 { $$ = new ExpressionNode( build_cast( $3, $5, CastExpr::Return ) ); }
     933                { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
    908934        | '(' COERCE type_no_function ')' cast_expression       // CFA
    909935                { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
     
    911937                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    912938//      | '(' type_no_function ')' tuple
    913 //              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     939//              { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    914940        ;
    915941
     
    929955        cast_expression
    930956        | exponential_expression '\\' cast_expression
    931                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }
     957                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); }
    932958        ;
    933959
     
    935961        exponential_expression
    936962        | multiplicative_expression '*' exponential_expression
    937                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }
     963                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); }
    938964        | multiplicative_expression '/' exponential_expression
    939                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }
     965                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); }
    940966        | multiplicative_expression '%' exponential_expression
    941                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }
     967                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); }
    942968        ;
    943969
     
    945971        multiplicative_expression
    946972        | additive_expression '+' multiplicative_expression
    947                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }
     973                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); }
    948974        | additive_expression '-' multiplicative_expression
    949                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }
     975                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); }
    950976        ;
    951977
     
    953979        additive_expression
    954980        | shift_expression LS additive_expression
    955                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }
     981                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); }
    956982        | shift_expression RS additive_expression
    957                 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }
     983                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); }
    958984        ;
    959985
     
    961987        shift_expression
    962988        | relational_expression '<' shift_expression
    963                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }
     989                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); }
    964990        | relational_expression '>' shift_expression
    965                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }
     991                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); }
    966992        | relational_expression LE shift_expression
    967                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }
     993                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); }
    968994        | relational_expression GE shift_expression
    969                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }
     995                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); }
    970996        ;
    971997
     
    973999        relational_expression
    9741000        | equality_expression EQ relational_expression
    975                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }
     1001                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); }
    9761002        | equality_expression NE relational_expression
    977                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }
     1003                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); }
    9781004        ;
    9791005
     
    9811007        equality_expression
    9821008        | AND_expression '&' equality_expression
    983                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }
     1009                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); }
    9841010        ;
    9851011
     
    9871013        AND_expression
    9881014        | exclusive_OR_expression '^' AND_expression
    989                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }
     1015                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); }
    9901016        ;
    9911017
     
    9931019        exclusive_OR_expression
    9941020        | inclusive_OR_expression '|' exclusive_OR_expression
    995                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }
     1021                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); }
    9961022        ;
    9971023
     
    9991025        inclusive_OR_expression
    10001026        | logical_AND_expression ANDAND inclusive_OR_expression
    1001                 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); }
     1027                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); }
    10021028        ;
    10031029
     
    10051031        logical_AND_expression
    10061032        | logical_OR_expression OROR logical_AND_expression
    1007                 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); }
     1033                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); }
    10081034        ;
    10091035
     
    10111037        logical_OR_expression
    10121038        | logical_OR_expression '?' comma_expression ':' conditional_expression
    1013                 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
     1039                { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); }
    10141040                // FIX ME: computes $1 twice
    10151041        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    1016                 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
     1042                { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); }
    10171043        ;
    10181044
     
    10291055//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    10301056//                      } else {
    1031                                 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
     1057                                $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) );
    10321058//                      } // if
    10331059                }
     
    10741100//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    10751101        '[' ',' tuple_expression_list ']'
    1076                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     1102                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    10771103        | '[' push assignment_expression pop ',' tuple_expression_list ']'
    1078                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }
     1104                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); }
    10791105        ;
    10801106
     
    10921118        assignment_expression
    10931119        | comma_expression ',' assignment_expression
    1094                 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     1120                { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    10951121        ;
    10961122
     
    11131139        | mutex_statement
    11141140        | waitfor_statement
     1141        | waituntil_statement
    11151142        | exception_statement
    11161143        | enable_disable_statement
     
    11181145        | asm_statement
    11191146        | DIRECTIVE
    1120                 { $$ = new StatementNode( build_directive( $1 ) ); }
     1147                { $$ = new StatementNode( build_directive( yylloc, $1 ) ); }
    11211148        ;
    11221149
     
    11241151                // labels cannot be identifiers 0 or 1
    11251152        identifier_or_type_name ':' attribute_list_opt 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, "
     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, "
    11301157                                                                                           "where a declaration, case, or default is not a statement. "
    11311158                                                                                           "Move the label or terminate with a semi-colon." ) );
     
    11361163compound_statement:
    11371164        '{' '}'
    1138                 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     1165                { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); }
    11391166        | '{' push
    11401167          local_label_declaration_opt                                           // GCC, local labels appear at start of block
    11411168          statement_decl_list                                                           // C99, intermix declarations and statements
    11421169          pop '}'
    1143                 { $$ = new StatementNode( build_compound( $4 ) ); }
     1170                { $$ = new StatementNode( build_compound( yylloc, $4 ) ); }
    11441171        ;
    11451172
     
    11661193        | statement_list_nodecl statement
    11671194                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
    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; }
     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; }
    11701197        ;
    11711198
    11721199expression_statement:
    11731200        comma_expression_opt ';'
    1174                 { $$ = new StatementNode( build_expr( $1 ) ); }
    1175         | MUTEX '(' ')' comma_expression ';'
    1176                 { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); }
     1201                { $$ = new StatementNode( build_expr( yylloc, $1 ) ); }
    11771202        ;
    11781203
     
    11831208                { $$ = $2; }
    11841209        | SWITCH '(' comma_expression ')' case_clause
    1185                 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
     1210                { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); }
    11861211        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    11871212                {
    1188                         StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
     1213                        StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) );
    11891214                        // The semantics of the declaration list is changed to include associated initialization, which is performed
    11901215                        // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
     
    11921217                        // therefore, are removed from the grammar even though C allows it. The change also applies to choose
    11931218                        // statement.
    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; }
     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; }
    11981223        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    1199                 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
     1224                { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); }
    12001225        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12011226                {
    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; }
     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; }
    12071232        ;
    12081233
     
    12101235        IF '(' conditional_declaration ')' statement            %prec THEN
    12111236                // explicitly deal with the shift/reduce conflict on if/else
    1212                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
     1237                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); }
    12131238        | IF '(' conditional_declaration ')' statement ELSE statement
    1214                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); }
     1239                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); }
    12151240        ;
    12161241
     
    12241249        | declaration comma_expression                                          // semi-colon separated
    12251250                { $$ = new CondCtl( $1, $2 ); }
    1226         ;
     1251        ;
    12271252
    12281253// CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case
     
    12321257        constant_expression                                                     { $$ = $1; }
    12331258        | constant_expression ELLIPSIS constant_expression      // GCC, subrange
    1234                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     1259                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    12351260        | subrange                                                                                      // CFA, subrange
    12361261        ;
    12371262
    12381263case_value_list:                                                                                // CFA
    1239         case_value                                                                      { $$ = new StatementNode( build_case( $1 ) ); }
     1264        case_value                                                                      { $$ = new ClauseNode( build_case( yylloc, $1 ) ); }
    12401265                // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5"
    1241         | case_value_list ',' case_value                        { $$ = (StatementNode *)($1->set_last( new StatementNode( build_case( $3 ) ) ) ); }
     1266        | case_value_list ',' case_value                        { $$ = $1->set_last( new ClauseNode( build_case( yylloc, $3 ) ) ); }
    12421267        ;
    12431268
    12441269case_label:                                                                                             // CFA
    1245         CASE error                                                                                      // syntax error
    1246                 { SemanticError( yylloc, "Missing case list after case." ); $$ = nullptr; }
     1270        CASE error                                                                                      // invalid syntax rule
     1271                { SemanticError( yylloc, "syntax error, case list missing after case." ); $$ = nullptr; }
    12471272        | CASE case_value_list ':'                                      { $$ = $2; }
    1248         | CASE case_value_list error                                            // syntax error
    1249                 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
    1250         | DEFAULT ':'                                                           { $$ = new StatementNode( build_default() ); }
     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 ) ); }
    12511276                // A semantic check is required to ensure only one default clause per switch/choose statement.
    1252         | DEFAULT error                                                                         //  syntax error
    1253                 { SemanticError( yylloc, "Missing colon after default." ); $$ = nullptr; }
     1277        | DEFAULT error                                                                         //  invalid syntax rules
     1278                { SemanticError( yylloc, "syntax error, colon missing after default." ); $$ = nullptr; }
    12541279        ;
    12551280
    12561281case_label_list:                                                                                // CFA
    12571282        case_label
    1258         | case_label_list case_label                            { $$ = (StatementNode *)( $1->set_last( $2 )); }
     1283        | case_label_list case_label                            { $$ = $1->set_last( $2 ); }
    12591284        ;
    12601285
    12611286case_clause:                                                                                    // CFA
    1262         case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }
     1287        case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( yylloc, $2 ) ); }
    12631288        ;
    12641289
     
    12711296switch_clause_list:                                                                             // CFA
    12721297        case_label_list statement_list_nodecl
    1273                 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
     1298                { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); }
    12741299        | switch_clause_list case_label_list statement_list_nodecl
    1275                 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
     1300                { $$ = $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ); }
    12761301        ;
    12771302
    12781303iteration_statement:
    12791304        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1280                 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
     1305                { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); }
    12811306        | WHILE '(' ')' statement ELSE statement                        // CFA
    12821307                {
    1283                         $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
    1284                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1308                        $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) );
     1309                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    12851310                }
    12861311        | WHILE '(' conditional_declaration ')' statement       %prec THEN
    1287                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
     1312                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    12881313        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
    1289                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
     1314                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    12901315        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1291                 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
     1316                { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); }
    12921317        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    12931318                {
    1294                         $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
    1295                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1319                        $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) );
     1320                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    12961321                }
    12971322        | DO statement WHILE '(' comma_expression ')' ';'
    1298                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
     1323                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); }
    12991324        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
    1300                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
     1325                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ), $8 ) ); }
    13011326        | FOR '(' ')' statement                                                         %prec THEN // CFA => for ( ;; )
    1302                 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); }
     1327                { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); }
    13031328        | FOR '(' ')' statement ELSE statement                          // CFA
    13041329                {
    1305                         $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) );
    1306                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1330                        $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) );
     1331                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13071332                }
    13081333        | FOR '(' for_control_expression_list ')' statement     %prec THEN
    1309                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
     1334                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    13101335        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
    1311                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
     1336                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    13121337        ;
    13131338
     
    13231348                        if ( $1->condition ) {
    13241349                                if ( $3->condition ) {
    1325                                         $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
     1350                                        $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr ) );
    13261351                                } // if
    13271352                        } else $1->condition = $3->condition;
    13281353                        if ( $1->change ) {
    13291354                                if ( $3->change ) {
    1330                                         $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
     1355                                        $1->change->expr.reset( new ast::CommaExpr( yylloc, $1->change->expr.release(), $3->change->expr.release() ) );
    13311356                                } // if
    13321357                        } else $1->change = $3->change;
     
    13371362for_control_expression:
    13381363        ';' comma_expression_opt ';' comma_expression_opt
    1339                 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
     1364                { $$ = new ForCtrl( nullptr, $2, $4 ); }
    13401365        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    1341                 { $$ = new ForCtrl( $1, $3, $5 ); }
     1366                {
     1367                        StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr;
     1368                        $$ = new ForCtrl( init, $3, $5 );
     1369                }
    13421370        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    1343                 { $$ = new ForCtrl( $1, $2, $4 ); }
     1371                { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); }
    13441372
    13451373        | '@' ';' comma_expression                                                      // CFA, empty loop-index
    1346                 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }
     1374                { $$ = new ForCtrl( nullptr, $3, nullptr ); }
    13471375        | '@' ';' comma_expression ';' comma_expression         // CFA, empty loop-index
    1348                 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }
     1376                { $$ = new ForCtrl( nullptr, $3, $5 ); }
    13491377
    13501378        | comma_expression                                                                      // CFA, anonymous loop-index
    1351                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
     1379                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
    13521380        | downupdowneq comma_expression                                         // CFA, anonymous loop-index
    1353                 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
     1381                { $$ = forCtrl( yylloc, $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
    13541382
    13551383        | comma_expression updowneq comma_expression            // CFA, anonymous loop-index
    1356                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
     1384                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
    13571385        | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
    13581386                {
    13591387                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1360                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
     1388                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
    13611389                }
    13621390        | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
     
    13661394                }
    13671395        | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    1368                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
     1396                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
    13691397        | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    13701398                {
    13711399                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1372                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
     1400                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
    13731401                }
    13741402        | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
     
    13771405                        else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    13781406                }
    1379         | comma_expression updowneq comma_expression '~' '@' // CFA, error
     1407        | comma_expression updowneq comma_expression '~' '@' // CFA, invalid syntax rules
    13801408                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1381         | '@' updowneq '@'                                                                      // CFA, error
     1409        | '@' updowneq '@'                                                                      // CFA, invalid syntax rules
    13821410                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1383         | '@' updowneq comma_expression '~' '@'                         // CFA, error
     1411        | '@' updowneq comma_expression '~' '@'                         // CFA, invalid syntax rules
    13841412                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1385         | comma_expression updowneq '@' '~' '@'                         // CFA, error
     1413        | comma_expression updowneq '@' '~' '@'                         // CFA, invalid syntax rules
    13861414                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1387         | '@' updowneq '@' '~' '@'                                                      // CFA, error
     1415        | '@' updowneq '@' '~' '@'                                                      // CFA, invalid syntax rules
    13881416                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    13891417
    13901418        | comma_expression ';' comma_expression                         // CFA
    1391                 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1419                { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    13921420        | comma_expression ';' downupdowneq comma_expression // CFA
    1393                 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
     1421                { $$ = forCtrl( yylloc, $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
    13941422
    13951423        | comma_expression ';' comma_expression updowneq comma_expression // CFA
    1396                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
     1424                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
    13971425        | comma_expression ';' '@' updowneq comma_expression // CFA
    13981426                {
    13991427                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1400                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1428                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    14011429                }
    14021430        | comma_expression ';' comma_expression updowneq '@' // CFA
    14031431                {
    14041432                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    1405                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1406                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, 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; }
     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; }
    14101438
    14111439        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    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
     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
    14141442                {
    14151443                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1416                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
     1444                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 );
    14171445                }
    14181446        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
    14191447                {
    14201448                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    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 );
     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 );
    14231451                }
    14241452        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    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
     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
    14271455                {
    14281456                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1429                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
     1457                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr );
    14301458                }
    14311459        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
    14321460                {
    14331461                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = 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 );
     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 );
    14361464                }
    14371465        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
    1438                 { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1466                { SemanticError( yylloc, "syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    14391467
    14401468        | declaration comma_expression                                          // CFA
    1441                 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1469                { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    14421470        | declaration downupdowneq comma_expression                     // CFA
    1443                 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
     1471                { $$ = forCtrl( yylloc, $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
    14441472
    14451473        | declaration comma_expression updowneq comma_expression // CFA
    1446                 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
     1474                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
    14471475        | declaration '@' updowneq comma_expression                     // CFA
    14481476                {
    14491477                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1450                         else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
     1478                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE );
    14511479                }
    14521480        | declaration comma_expression updowneq '@'                     // CFA
    14531481                {
    14541482                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    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 );
     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 );
    14571485                }
    14581486
    14591487        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1460                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
     1488                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
    14611489        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    14621490                {
    14631491                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1464                         else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
     1492                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 );
    14651493                }
    14661494        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
    14671495                {
    14681496                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    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 );
     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 );
    14711499                }
    14721500        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1473                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
     1501                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
    14741502        | declaration '@' updowneq comma_expression '~' '@' // CFA
    14751503                {
    14761504                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1477                         else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
     1505                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr );
    14781506                }
    14791507        | declaration comma_expression updowneq '@' '~' '@'     // CFA
    14801508                {
    14811509                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = 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; }
     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; }
    14871515
    14881516        | comma_expression ';' TYPEDEFname                                      // CFA, array type
     
    14931521        | comma_expression ';' downupdowneq TYPEDEFname         // CFA, array type
    14941522                {
    1495                         if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; }
     1523                        if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) {
     1524                                SemanticError( yylloc, "syntax error, all enumeration ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr;
     1525                        }
    14961526                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    14971527                }
    1498         ;
     1528        ;
    14991529
    15001530downupdowneq:
     
    15051535        | ErangeDownEq
    15061536                { $$ = OperKinds::GEThan; }
    1507         ;
     1537        ;
    15081538
    15091539updown:
     
    15121542        | ErangeDown
    15131543                { $$ = OperKinds::GThan; }
    1514         ;
     1544        ;
    15151545
    15161546updowneq:
     
    15201550        | ErangeDownEq
    15211551                { $$ = OperKinds::GEThan; }
    1522         ;
     1552        ;
    15231553
    15241554jump_statement:
    15251555        GOTO identifier_or_type_name ';'
    1526                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); }
     1556                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }
    15271557        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    15281558                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    15311561                // A semantic check is required to ensure fallthru appears only in the body of a choose statement.
    15321562        | fall_through_name ';'                                                         // CFA
    1533                 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }
     1563                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }
    15341564        | fall_through_name identifier_or_type_name ';'         // CFA
    1535                 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); }
     1565                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }
    15361566        | fall_through_name DEFAULT ';'                                         // CFA
    1537                 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }
     1567                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }
    15381568        | CONTINUE ';'
    15391569                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1540                 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); }
     1570                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }
    15411571        | CONTINUE identifier_or_type_name ';'                          // CFA, multi-level continue
    15421572                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15431573                // the target of the transfer appears only at the start of an iteration statement.
    1544                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); }
     1574                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }
    15451575        | BREAK ';'
    15461576                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1547                 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); }
     1577                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }
    15481578        | BREAK identifier_or_type_name ';'                                     // CFA, multi-level exit
    15491579                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15501580                // the target of the transfer appears only at the start of an iteration statement.
    1551                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); }
     1581                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }
    15521582        | RETURN comma_expression_opt ';'
    1553                 { $$ = new StatementNode( build_return( $2 ) ); }
     1583                { $$ = new StatementNode( build_return( yylloc, $2 ) ); }
    15541584        | RETURN '{' initializer_list_opt comma_opt '}' ';'
    15551585                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    15561586        | SUSPEND ';'
    1557                 { $$ = new StatementNode( build_suspend( nullptr ) ); }
     1587                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); }
    15581588        | SUSPEND compound_statement
    1559                 { $$ = new StatementNode( build_suspend( $2 ) ); }
     1589                { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); }
    15601590        | SUSPEND COROUTINE ';'
    1561                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); }
     1591                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }
    15621592        | SUSPEND COROUTINE compound_statement
    1563                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); }
     1593                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }
    15641594        | SUSPEND GENERATOR ';'
    1565                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); }
     1595                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }
    15661596        | SUSPEND GENERATOR compound_statement
    1567                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); }
     1597                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }
    15681598        | THROW assignment_expression_opt ';'                           // handles rethrow
    1569                 { $$ = new StatementNode( build_throw( $2 ) ); }
     1599                { $$ = new StatementNode( build_throw( yylloc, $2 ) ); }
    15701600        | THROWRESUME assignment_expression_opt ';'                     // handles reresume
    1571                 { $$ = new StatementNode( build_resume( $2 ) ); }
     1601                { $$ = new StatementNode( build_resume( yylloc, $2 ) ); }
    15721602        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    15731603                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
     
    15811611with_statement:
    15821612        WITH '(' tuple_expression_list ')' statement
    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".
     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".
    15871617mutex_statement:
    1588         MUTEX '(' argument_expression_list ')' statement
    1589                 { $$ = new StatementNode( build_mutex( $3, $5 ) ); }
     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                }
    15901623        ;
    15911624
     
    15981631                { $$ = nullptr; }
    15991632        | when_clause
    1600         ;
    1601 
    1602 waitfor:
    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 )); }
    16091633        ;
    16101634
     
    16171641
    16181642timeout:
    1619         TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
    1620         ;
    1621 
    1622 waitfor_clause:
     1643        TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
     1644        ;
     1645
     1646wor:
     1647        OROR
     1648        | WOR
     1649
     1650waitfor:
     1651        WAITFOR '(' cast_expression ')'
     1652                { $$ = $3; }
     1653        | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')'
     1654                { $$ = (ExpressionNode *)($3->set_last( $5 )); }
     1655        ;
     1656
     1657wor_waitfor_clause:
    16231658        when_clause_opt waitfor statement                                       %prec THEN
    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 ); }
     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 ) ); }
    16311667        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    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 ); }
     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 ) ); }
    16361672        ;
    16371673
    16381674waitfor_statement:
    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 ) ); }
     1675        wor_waitfor_clause                                                                      %prec THEN
     1676                { $$ = new StatementNode( $1 ); }
     1677        ;
     1678
     1679wand:
     1680        ANDAND
     1681        | WAND
     1682        ;
     1683
     1684waituntil:
     1685        WAITUNTIL '(' comma_expression ')'
     1686                { $$ = $3; }
     1687        ;
     1688
     1689waituntil_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
     1696wand_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
     1703wor_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
     1722waituntil_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        }
    16431729        ;
    16441730
    16451731exception_statement:
    1646         TRY compound_statement handler_clause                                   %prec THEN
    1647                 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
     1732        TRY compound_statement handler_clause                                   %prec THEN
     1733                { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
    16481734        | TRY compound_statement finally_clause
    1649                 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }
     1735                { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
    16501736        | TRY compound_statement handler_clause finally_clause
    1651                 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
     1737                { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
    16521738        ;
    16531739
    16541740handler_clause:
    16551741        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1656                 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
     1742                { $$ = new ClauseNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
    16571743        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1658                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }
     1744                { $$ = $1->set_last( new ClauseNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
    16591745        ;
    16601746
     
    16661752
    16671753handler_key:
    1668         CATCH                                                                           { $$ = CatchStmt::Terminate; }
    1669         | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
    1670         | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
    1671         | FIXUP                                                                         { $$ = CatchStmt::Resume; }
     1754        CATCH                                                                           { $$ = ast::Terminate; }
     1755        | RECOVER                                                                       { $$ = ast::Terminate; }
     1756        | CATCHRESUME                                                           { $$ = ast::Resume; }
     1757        | FIXUP                                                                         { $$ = ast::Resume; }
    16721758        ;
    16731759
    16741760finally_clause:
    1675         FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
     1761        FINALLY compound_statement                                      { $$ = new ClauseNode( build_finally( yylloc, $2 ) ); }
    16761762        ;
    16771763
     
    16991785asm_statement:
    17001786        ASM asm_volatile_opt '(' string_literal ')' ';'
    1701                 { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); }
     1787                { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
    17021788        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1703                 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
     1789                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
    17041790        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1705                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
     1791                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
    17061792        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';'
    1707                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); }
     1793                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
    17081794        | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';'
    1709                 { $$ = new StatementNode( build_asm( $2, $5, 0, $8, $10, $12 ) ); }
     1795                { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
    17101796        ;
    17111797
     
    17311817asm_operand:                                                                                    // GCC
    17321818        string_literal '(' constant_expression ')'
    1733                 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     1819                { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    17341820        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1735                 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); }
     1821                {
     1822                        $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) );
     1823                        delete $2.str;
     1824                }
    17361825        ;
    17371826
     
    17401829                { $$ = nullptr; }                                                               // use default argument
    17411830        | string_literal
    1742                 { $$ = new ExpressionNode( $1 ); }
     1831                { $$ = $1; }
    17431832        | asm_clobbers_list_opt ',' string_literal
    1744                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); }
     1833                { $$ = (ExpressionNode *)( $1->set_last( $3 ) ); }
    17451834        ;
    17461835
     
    17481837        identifier
    17491838                {
    1750                         $$ = new LabelNode(); $$->labels.push_back( *$1 );
     1839                        $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
    17511840                        delete $1;                                                                      // allocated by lexer
    17521841                }
    17531842        | label_list ',' identifier
    17541843                {
    1755                         $$ = $1; $1->labels.push_back( *$3 );
     1844                        $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
    17561845                        delete $3;                                                                      // allocated by lexer
    17571846                }
     
    18041893                {
    18051894                        // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" );
    1806                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     1895                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    18071896                        //   printf( "\tattr %s\n", attr->name.c_str() );
    18081897                        // } // for
     
    18141903static_assert:
    18151904        STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
    1816                 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
     1905                { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 ) ); }
    18171906        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1818                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
     1907                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
    18191908
    18201909// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    18801969//      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
    18811970//              {
    1882 //                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
     1971//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );
    18831972//              }
    18841973//      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
    18851974//              {
    18861975//                      typedefTable.setNextIdentifier( *$5 );
    1887 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1976//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
    18881977//              }
    18891978//      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
    18901979//              {
    18911980//                      typedefTable.setNextIdentifier( *$5 );
    1892 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1981//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
    18931982//              }
    18941983//      | '[' ']' typegen_name
     
    19021991        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    19031992                // To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
    1904                 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
     1993                { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
    19051994        | cfa_function_return identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    1906                 { $$ = DeclarationNode::newFunction( $2, $1, $5, 0 )->addQualifiers( $8 ); }
     1995                { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
    19071996        ;
    19081997
     
    19402029                {
    19412030                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
    1942                         $$ = $3->addType( $2 )->addTypedef();
     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
    19432034                }
    19442035        | typedef_declaration pop ',' push declarator
     
    19482039                }
    19492040        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
    1950                 {
    1951                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "6" );
    1952                         $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef();
    1953                 }
     2041                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19542042        | type_specifier TYPEDEF declarator
    1955                 {
    1956                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" );
    1957                         $$ = $3->addType( $1 )->addTypedef();
    1958                 }
     2043                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19592044        | type_specifier TYPEDEF type_qualifier_list declarator
    1960                 {
    1961                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" );
    1962                         $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
    1963                 }
     2045                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19642046        ;
    19652047
     
    19682050        TYPEDEF identifier '=' assignment_expression
    19692051                {
    1970                         SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     2052                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    19712053                }
    19722054        | typedef_expression pop ',' push identifier '=' assignment_expression
    19732055                {
    1974                         SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     2056                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    19752057                }
    19762058        ;
     
    19822064        | typedef_expression                                                            // deprecated GCC, naming expression type
    19832065        | 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                }
    19842076        ;
    19852077
     
    19872079                // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    19882080                // storage-class
    1989         declarator asm_name_opt initializer_opt
     2081        variable_declarator asm_name_opt initializer_opt
    19902082                { $$ = $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
    19912091        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    19922092                { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
    19932093        ;
    19942094
     2095general_function_declarator:
     2096        function_type_redeclarator
     2097        | function_declarator
     2098        ;
     2099
    19952100declaration_specifier:                                                                  // type specifier + storage class
    19962101        basic_declaration_specifier
     2102        | type_declaration_specifier
    19972103        | sue_declaration_specifier
    1998         | type_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
     2113invalid_types:
     2114        aggregate_key
     2115        | basic_type_name
     2116        | indirect_type
    19992117        ;
    20002118
     
    20132131        basic_type_specifier
    20142132        | 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                 }
    20212133        | type_type_specifier
    20222134        ;
     
    20652177                { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); }
    20662178        | forall
     2179                { $$ = DeclarationNode::newForall( $1 ); }
    20672180        ;
    20682181
    20692182forall:
    20702183        FORALL '(' type_parameter_list ')'                                      // CFA
    2071                 { $$ = DeclarationNode::newForall( $3 ); }
     2184                { $$ = $3; }
    20722185        ;
    20732186
     
    22262339                { $$ = DeclarationNode::newTypeof( $3 ); }
    22272340        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2228                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
     2341                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
    22292342        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    22302343                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    22392352                {
    22402353                        // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2241                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2354                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    22422355                        //   printf( "\tattr %s\n", attr->name.c_str() );
    22432356                        // } // for
     
    22552368                {
    22562369                        // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2257                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2370                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    22582371                        //   printf( "\tattr %s\n", attr->name.c_str() );
    22592372                        // } // for
     
    23332446                {
    23342447                        // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2335                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2448                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23362449                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23372450                        // } // for
     
    23572470          '{' field_declaration_list_opt '}' type_parameters_opt
    23582471                {
    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
    23642472                        $$ = 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
    23692473                }
    23702474        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     
    23752479          '{' field_declaration_list_opt '}' type_parameters_opt
    23762480                {
    2377                         // printf( "AGG3\n" );
    23782481                        DeclarationNode::newFromTypedef( $3 );
    23792482                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    23862489          '{' field_declaration_list_opt '}' type_parameters_opt
    23872490                {
    2388                         // printf( "AGG4\n" );
    23892491                        DeclarationNode::newFromTypeGen( $3, nullptr );
    23902492                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    24132515                        // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
    24142516                        // delete newFromTypeGen.
    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;
     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                        }
    24192525                }
    24202526        ;
     
    24272533aggregate_data:
    24282534        STRUCT vtable_opt
    2429                 { $$ = AggregateDecl::Struct; }
     2535                { $$ = ast::AggregateDecl::Struct; }
    24302536        | UNION
    2431                 { $$ = AggregateDecl::Union; }
     2537                { $$ = ast::AggregateDecl::Union; }
    24322538        | EXCEPTION                                                                                     // CFA
    2433                 { $$ = AggregateDecl::Exception; }
    2434           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2539                { $$ = ast::AggregateDecl::Exception; }
     2540          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
    24352541        ;
    24362542
    24372543aggregate_control:                                                                              // CFA
    24382544        MONITOR
    2439                 { $$ = AggregateDecl::Monitor; }
     2545                { $$ = ast::AggregateDecl::Monitor; }
    24402546        | MUTEX STRUCT
    2441                 { $$ = AggregateDecl::Monitor; }
     2547                { $$ = ast::AggregateDecl::Monitor; }
    24422548        | GENERATOR
    2443                 { $$ = AggregateDecl::Generator; }
     2549                { $$ = ast::AggregateDecl::Generator; }
    24442550        | MUTEX GENERATOR
    2445                 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2551                {
     2552                        SemanticError( yylloc, "monitor generator is currently unimplemented." );
     2553                        $$ = ast::AggregateDecl::NoAggregate;
     2554                }
    24462555        | COROUTINE
    2447                 { $$ = AggregateDecl::Coroutine; }
     2556                { $$ = ast::AggregateDecl::Coroutine; }
    24482557        | MUTEX COROUTINE
    2449                 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2558                {
     2559                        SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
     2560                        $$ = ast::AggregateDecl::NoAggregate;
     2561                }
    24502562        | THREAD
    2451                 { $$ = AggregateDecl::Thread; }
     2563                { $$ = ast::AggregateDecl::Thread; }
    24522564        | MUTEX THREAD
    2453                 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2565                {
     2566                        SemanticError( yylloc, "monitor thread is currently unimplemented." );
     2567                        $$ = ast::AggregateDecl::NoAggregate;
     2568                }
    24542569        ;
    24552570
     
    24672582                        $$ = fieldDecl( $1, $2 );
    24682583                        // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2469                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2584                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    24702585                        //   printf( "\tattr %s\n", attr->name.c_str() );
    24712586                        // } // for
    24722587                }
     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                }
    24732593        | EXTENSION type_specifier field_declaring_list_opt ';' // GCC
    24742594                { $$ = fieldDecl( $2, $3 ); distExt( $$ ); }
     2595        | STATIC type_specifier field_declaring_list_opt ';' // CFA
     2596                { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }
    24752597        | INLINE type_specifier field_abstract_list_opt ';'     // CFA
    24762598                {
     
    24832605                }
    24842606        | INLINE aggregate_control ';'                                          // CFA
    2485                 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
     2607                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    24862608        | typedef_declaration ';'                                                       // CFA
    24872609        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
     
    25092631                { $$ = $1->addBitfield( $2 ); }
    25102632        | 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
    25112636                // A semantic check is required to ensure bit_subrange only appears on integral types.
    25122637                { $$ = $1->addBitfield( $2 ); }
     
    25632688                { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
    25642689        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    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 
     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                        }
    25692694                        $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 );
    25702695                }
     
    25752700        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    25762701                {
    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." ); }
     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                        }
    25782705                        typedefTable.makeTypedef( *$6 );
    25792706                }
     
    26092736enum_type_nobody:                                                                               // enum - {...}
    26102737        ENUM attribute_list_opt identifier
    2611                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
     2738                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }
    26122739        | ENUM attribute_list_opt type_name
    2613                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
     2740                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }
    26142741        ;
    26152742
     
    27512878type_no_function:                                                                               // sizeof, alignof, cast (constructor)
    27522879        cfa_abstract_declarator_tuple                                           // CFA
    2753         | type_specifier
     2880        | type_specifier                                                                        // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
    27542881        | type_specifier abstract_declarator
    27552882                { $$ = $2->addType( $1 ); }
     
    27962923        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    27972924        | identifier_at ':'                                                                     // GCC, field name
    2798                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     2925                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    27992926        ;
    28002927
     
    28082935designator:
    28092936        '.' identifier_at                                                                       // C99, field name
    2810                 { $$ = new ExpressionNode( build_varref( $2 ) ); }
     2937                { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
    28112938        | '[' push assignment_expression pop ']'                        // C99, single array element
    28122939                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    28152942                { $$ = $3; }
    28162943        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2817                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); }
     2944                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
    28182945        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    28192946                { $$ = $4; }
     
    28552982                {
    28562983                        typedefTable.addToScope( *$2, TYPEDEFname, "9" );
    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 ..." ); }
     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 ..." ); }
    28602987                }
    28612988          type_initializer_opt assertion_list_opt
     
    28682995                {
    28692996                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2870                         $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
     2997                        $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
    28712998                }
    28722999        // | type_specifier identifier_parameter_declarator
    28733000        | assertion_list
    2874                 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     3001                { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    28753002        ;
    28763003
    28773004new_type_class:                                                                                 // CFA
    28783005        // empty
    2879                 { $$ = TypeDecl::Otype; }
     3006                { $$ = ast::TypeDecl::Otype; }
    28803007        | '&'
    2881                 { $$ = TypeDecl::Dtype; }
     3008                { $$ = ast::TypeDecl::Dtype; }
    28823009        | '*'
    2883                 { $$ = TypeDecl::DStype; }                                              // dtype + sized
     3010                { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
    28843011        // | '(' '*' ')'
    2885         //      { $$ = TypeDecl::Ftype; }
     3012        //      { $$ = ast::TypeDecl::Ftype; }
    28863013        | ELLIPSIS
    2887                 { $$ = TypeDecl::Ttype; }
     3014                { $$ = ast::TypeDecl::Ttype; }
    28883015        ;
    28893016
    28903017type_class:                                                                                             // CFA
    28913018        OTYPE
    2892                 { $$ = TypeDecl::Otype; }
     3019                { $$ = ast::TypeDecl::Otype; }
    28933020        | DTYPE
    2894                 { $$ = TypeDecl::Dtype; }
     3021                { $$ = ast::TypeDecl::Dtype; }
    28953022        | FTYPE
    2896                 { $$ = TypeDecl::Ftype; }
     3023                { $$ = ast::TypeDecl::Ftype; }
    28973024        | TTYPE
    2898                 { $$ = TypeDecl::Ttype; }
     3025                { $$ = ast::TypeDecl::Ttype; }
    28993026        ;
    29003027
     
    29223049type_list:                                                                                              // CFA
    29233050        type
    2924                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3051                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    29253052        | assignment_expression
    29263053        | type_list ',' type
    2927                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3054                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    29283055        | type_list ',' assignment_expression
    29293056                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    29503077                {
    29513078                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    2952                         $$ = DeclarationNode::newTypeDecl( $1, 0 );
     3079                        $$ = DeclarationNode::newTypeDecl( $1, nullptr );
    29533080                }
    29543081        | identifier_or_type_name '(' type_parameter_list ')'
     
    29613088trait_specifier:                                                                                // CFA
    29623089        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    2963                 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
     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 ); }
    29643096        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    2965                 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
     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 ); }
    29663103        ;
    29673104
     
    30223159external_definition:
    30233160        DIRECTIVE
    3024                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
     3161                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
    30253162        | 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                }
    30263175        | IDENTIFIER IDENTIFIER
    30273176                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
    3028         | IDENTIFIER type_qualifier                                                     // syntax error
     3177        | IDENTIFIER type_qualifier                                                     // invalid syntax rules
    30293178                { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; }
    3030         | IDENTIFIER storage_class                                                      // syntax error
     3179        | IDENTIFIER storage_class                                                      // invalid syntax rules
    30313180                { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; }
    3032         | IDENTIFIER basic_type_name                                            // syntax error
     3181        | IDENTIFIER basic_type_name                                            // invalid syntax rules
    30333182                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    3034         | IDENTIFIER TYPEDEFname                                                        // syntax error
     3183        | IDENTIFIER TYPEDEFname                                                        // invalid syntax rules
    30353184                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    3036         | IDENTIFIER TYPEGENname                                                        // syntax error
     3185        | IDENTIFIER TYPEGENname                                                        // invalid syntax rules
    30373186                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    30383187        | external_function_definition
     
    30433192                }
    30443193        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3045                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
     3194                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
    30463195        | EXTERN STRINGliteral
    30473196                {
    30483197                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3049                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3198                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    30503199                }
    30513200          up external_definition down
     
    30583207                {
    30593208                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3060                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3209                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    30613210                }
    30623211          '{' up external_definition_list_opt down '}'
     
    30693218        | type_qualifier_list
    30703219                {
    3071                         if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3220                        if ( $1->type->qualifiers.any() ) {
     3221                                SemanticError( yylloc, "syntax error, CV qualifiers cannot be distributed; only storage-class and forall qualifiers." );
     3222                        }
    30723223                        if ( $1->type->forall ) forall = true;          // remember generic type
    30733224                }
     
    30753226                {
    30763227                        distQual( $5, $1 );
    3077                         forall = false;
     3228                        forall = false;
    30783229                        $$ = $5;
    30793230                }
    30803231        | declaration_qualifier_list
    30813232                {
    3082                         if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     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                        }
    30833236                        if ( $1->type && $1->type->forall ) forall = true; // remember generic type
    30843237                }
     
    30863239                {
    30873240                        distQual( $5, $1 );
    3088                         forall = false;
     3241                        forall = false;
    30893242                        $$ = $5;
    30903243                }
    30913244        | declaration_qualifier_list type_qualifier_list
    30923245                {
    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." ); }
     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                        }
    30943249                        if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type
    30953250                }
     
    30973252                {
    30983253                        distQual( $6, $1->addQualifiers( $2 ) );
    3099                         forall = false;
     3254                        forall = false;
    31003255                        $$ = $6;
    31013256                }
     
    31223277                        $$ = $3; forall = false;
    31233278                        if ( $5 ) {
    3124                                 SemanticError( yylloc, "Attributes cannot be associated with function body. Move attribute(s) before \"with\" clause." );
     3279                                SemanticError( yylloc, "syntax error, attributes cannot be associated with function body. Move attribute(s) before \"with\" clause." );
    31253280                                $$ = nullptr;
    31263281                        } // if
     
    31413296                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    31423297                }
    3143         | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
     3298        | declaration_specifier function_type_redeclarator with_clause_opt compound_statement
    31443299                {
    31453300                        rebindForall( $1, $2 );
     
    31773332        | variable_type_redeclarator
    31783333        | function_declarator
     3334        | function_type_redeclarator
    31793335        ;
    31803336
    31813337subrange:
    31823338        constant_expression '~' constant_expression                     // CFA, integer subrange
    3183                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     3339                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    31843340        ;
    31853341
     
    31903346                {
    31913347                        DeclarationNode * name = new DeclarationNode();
    3192                         name->asmName = $3;
     3348                        name->asmName = maybeMoveBuild( $3 );
    31933349                        $$ = name->addQualifiers( $5 );
    31943350                }
     
    32873443variable_ptr:
    32883444        ptrref_operator variable_declarator
    3289                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3445                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    32903446        | ptrref_operator type_qualifier_list variable_declarator
    32913447                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    33033459        | '(' attribute_list variable_ptr ')' array_dimension
    33043460                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3305         | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     3461        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
    33063462                { $$ = $2->addArray( $4 ); }
    33073463        | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis
     
    33513507function_ptr:
    33523508        ptrref_operator function_declarator
    3353                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3509                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    33543510        | ptrref_operator type_qualifier_list function_declarator
    33553511                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34033559KR_function_ptr:
    34043560        ptrref_operator KR_function_declarator
    3405                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3561                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    34063562        | ptrref_operator type_qualifier_list KR_function_declarator
    34073563                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34273583        ;
    34283584
    3429 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.:
     3585// This pattern parses a declaration for a variable that redefines a type name, e.g.:
    34303586//
    34313587//              typedef int foo;
     
    34333589//                 int foo; // redefine typedef name in new scope
    34343590//              }
    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.
    34383591
    34393592paren_type:
     
    34503603        paren_type attribute_list_opt
    34513604                { $$ = $1->addQualifiers( $2 ); }
    3452         | type_ptr
    3453         | type_array attribute_list_opt
     3605        | variable_type_ptr
     3606        | variable_type_array attribute_list_opt
    34543607                { $$ = $1->addQualifiers( $2 ); }
    3455         | type_function attribute_list_opt
     3608        | variable_type_function attribute_list_opt
    34563609                { $$ = $1->addQualifiers( $2 ); }
    34573610        ;
    34583611
    3459 type_ptr:
     3612variable_type_ptr:
    34603613        ptrref_operator variable_type_redeclarator
    3461                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3614                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    34623615        | ptrref_operator type_qualifier_list variable_type_redeclarator
    34633616                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3464         | '(' type_ptr ')' attribute_list_opt                           // redundant parenthesis
     3617        | '(' variable_type_ptr ')' attribute_list_opt          // redundant parenthesis
    34653618                { $$ = $2->addQualifiers( $4 ); }
    3466         | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis
     3619        | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis
    34673620                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    34683621        ;
    34693622
    3470 type_array:
     3623variable_type_array:
    34713624        paren_type array_dimension
    34723625                { $$ = $1->addArray( $2 ); }
    3473         | '(' type_ptr ')' array_dimension
     3626        | '(' variable_type_ptr ')' array_dimension
    34743627                { $$ = $2->addArray( $4 ); }
    3475         | '(' attribute_list type_ptr ')' array_dimension
     3628        | '(' attribute_list variable_type_ptr ')' array_dimension
    34763629                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3477         | '(' type_array ')' multi_array_dimension                      // redundant parenthesis
     3630        | '(' variable_type_array ')' multi_array_dimension     // redundant parenthesis
    34783631                { $$ = $2->addArray( $4 ); }
    3479         | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis
     3632        | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis
    34803633                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3481         | '(' type_array ')'                                                            // redundant parenthesis
     3634        | '(' variable_type_array ')'                                           // redundant parenthesis
    34823635                { $$ = $2; }
    3483         | '(' attribute_list type_array ')'                                     // redundant parenthesis
     3636        | '(' attribute_list variable_type_array ')'            // redundant parenthesis
    34843637                { $$ = $3->addQualifiers( $2 ); }
    34853638        ;
    34863639
    3487 type_function:
     3640variable_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
     3655function_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
     3663function_type_no_ptr:
    34883664        paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    34893665                { $$ = $1->addParamList( $4 ); }
    3490         | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3666        | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    34913667                { $$ = $2->addParamList( $6 ); }
    3492         | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3668        | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    34933669                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3494         | '(' type_function ')'                                                         // redundant parenthesis
     3670        | '(' function_type_no_ptr ')'                                          // redundant parenthesis
    34953671                { $$ = $2; }
    3496         | '(' attribute_list type_function ')'                          // redundant parenthesis
     3672        | '(' attribute_list function_type_no_ptr ')'           // redundant parenthesis
     3673                { $$ = $3->addQualifiers( $2 ); }
     3674        ;
     3675
     3676function_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
     3687function_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
    34973699                { $$ = $3->addQualifiers( $2 ); }
    34983700        ;
     
    35173719identifier_parameter_ptr:
    35183720        ptrref_operator identifier_parameter_declarator
    3519                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3721                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    35203722        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    35213723                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35743776type_parameter_ptr:
    35753777        ptrref_operator type_parameter_redeclarator
    3576                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3778                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    35773779        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    35783780                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36173819abstract_ptr:
    36183820        ptrref_operator
    3619                 { $$ = DeclarationNode::newPointer( 0, $1 ); }
     3821                { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
    36203822        | ptrref_operator type_qualifier_list
    36213823                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    36223824        | ptrref_operator abstract_declarator
    3623                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3825                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    36243826        | ptrref_operator type_qualifier_list abstract_declarator
    36253827                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36503852                // Only the first dimension can be empty.
    36513853        '[' ']'
    3652                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
     3854                { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
    36533855        | '[' ']' multi_array_dimension
    3654                 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); }
     3856                { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }
    36553857                // Cannot use constant_expression because of tuples => semantic check
    36563858        | '[' push assignment_expression pop ',' comma_expression ']' // CFA
    3657                 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }
     3859                { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }
    36583860                // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; }
    36593861        | '[' push array_type_list pop ']'                                      // CFA
     
    36643866array_type_list:
    36653867        basic_type_name
    3666                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3868                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    36673869        | type_name
    3668                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3870                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    36693871        | assignment_expression upupeq assignment_expression
    36703872        | array_type_list ',' basic_type_name
    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 ) ) ) )); }
     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 ) ) ) )); }
    36743876        | array_type_list ',' assignment_expression upupeq assignment_expression
    36753877        ;
     
    36803882        | ErangeUpEq
    36813883                { $$ = OperKinds::LEThan; }
    3682         ;
     3884        ;
    36833885
    36843886multi_array_dimension:
    36853887        '[' push assignment_expression pop ']'
    3686                 { $$ = DeclarationNode::newArray( $3, 0, false ); }
     3888                { $$ = DeclarationNode::newArray( $3, nullptr, false ); }
    36873889        | '[' push '*' pop ']'                                                          // C99
    36883890                { $$ = DeclarationNode::newVarArray( 0 ); }
    36893891        | multi_array_dimension '[' push assignment_expression pop ']'
    3690                 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
     3892                { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }
    36913893        | multi_array_dimension '[' push '*' pop ']'            // C99
    36923894                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
     
    37853987array_parameter_1st_dimension:
    37863988        '[' ']'
    3787                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
     3989                { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
    37883990                // multi_array_dimension handles the '[' '*' ']' case
    37893991        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    37903992                { $$ = DeclarationNode::newVarArray( $3 ); }
    37913993        | '[' push type_qualifier_list pop ']'
    3792                 { $$ = DeclarationNode::newArray( 0, $3, false ); }
     3994                { $$ = DeclarationNode::newArray( nullptr, $3, false ); }
    37933995                // multi_array_dimension handles the '[' assignment_expression ']' case
    37943996        | '[' push type_qualifier_list assignment_expression pop ']'
     
    38194021variable_abstract_ptr:
    38204022        ptrref_operator
    3821                 { $$ = DeclarationNode::newPointer( 0, $1 ); }
     4023                { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
    38224024        | ptrref_operator type_qualifier_list
    38234025                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    38244026        | ptrref_operator variable_abstract_declarator
    3825                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4027                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38264028        | ptrref_operator type_qualifier_list variable_abstract_declarator
    38274029                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38654067                // No SUE declaration in parameter list.
    38664068        ptrref_operator type_specifier_nobody
    3867                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4069                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38684070        | type_qualifier_list ptrref_operator type_specifier_nobody
    38694071                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    38704072        | ptrref_operator cfa_abstract_function
    3871                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4073                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38724074        | type_qualifier_list ptrref_operator cfa_abstract_function
    38734075                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    38744076        | ptrref_operator cfa_identifier_parameter_declarator_tuple
    3875                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4077                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38764078        | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple
    38774079                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
     
    38824084                // shift/reduce conflict with new-style empty (void) function return type.
    38834085        '[' ']' type_specifier_nobody
    3884                 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4086                { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38854087        | cfa_array_parameter_1st_dimension type_specifier_nobody
    38864088                { $$ = $2->addNewArray( $1 ); }
    38874089        | '[' ']' multi_array_dimension type_specifier_nobody
    3888                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4090                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38894091        | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody
    38904092                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    38934095
    38944096        | '[' ']' cfa_identifier_parameter_ptr
    3895                 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4097                { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38964098        | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr
    38974099                { $$ = $2->addNewArray( $1 ); }
    38984100        | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr
    3899                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4101                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    39004102        | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr
    39014103                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    39534155cfa_abstract_ptr:                                                                               // CFA
    39544156        ptrref_operator type_specifier
    3955                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4157                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39564158        | type_qualifier_list ptrref_operator type_specifier
    39574159                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    39584160        | ptrref_operator cfa_abstract_function
    3959                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4161                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39604162        | type_qualifier_list ptrref_operator cfa_abstract_function
    39614163                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    39624164        | ptrref_operator cfa_abstract_declarator_tuple
    3963                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4165                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39644166        | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple
    39654167                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note: See TracChangeset for help on using the changeset viewer.