Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    r997185e r32d6fdc  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Nov 21 22:34:30 2022
    13 // Update Count     : 5848
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 14:02:00 2023
     13// Update Count     : 6329
    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 ) {
     
    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)
    204208#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     
    206210#define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
    207211
    208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     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 ) {
    210234                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    213237                SemanticError( yylloc, "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 {
    243262                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     
    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;
    291309        CondCtl * ifctl;
    292         ForCtrl * fctl;
    293         OperKinds compop;
    294         LabelNode * label;
    295         InitializerNode * in;
    296         OperKinds op;
     310        ForCtrl * forctl;
     311        LabelNode * labels;
     312        InitializerNode * init;
     313        OperKinds oper;
    297314        std::string * str;
    298         bool flag;
    299         EnumHiding hide;
    300         CatchStmt::Kind catch_kind;
    301         GenericExpr * genexpr;
     315        bool is_volatile;
     316        EnumHiding enum_hiding;
     317        ast::ExceptionKind except_kind;
     318        ast::GenericExpr * genexpr;
    302319}
    303320
    304 //************************* TERMINAL TOKENS ********************************
     321// ************************ TERMINAL TOKENS ********************************
    305322
    306323// keywords
     
    331348%token ATTRIBUTE EXTENSION                                                              // GCC
    332349%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
    333 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR    // CFA
     350%token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL // CFA
    334351%token DISABLE ENABLE TRY THROW THROWRESUME AT                  // CFA
    335352%token ASM                                                                                              // C99, extension ISO/IEC 9899:1999 Section J.5.10(1)
     
    337354
    338355// 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
     356%token<tok> IDENTIFIER          TYPEDIMname             TYPEDEFname             TYPEGENname
     357%token<tok> TIMEOUT                     WAND    WOR                     CATCH                   RECOVER                 CATCHRESUME             FIXUP           FINALLY         // CFA
    341358%token<tok> INTEGERconstant     CHARACTERconstant       STRINGliteral
    342359%token<tok> DIRECTIVE
     
    364381%type<tok> identifier                                   identifier_at                           identifier_or_type_name         attr_name
    365382%type<tok> quasi_keyword
    366 %type<constant> string_literal
     383%type<expr> string_literal
    367384%type<str> string_literal_list
    368385
    369 %type<hide> hide_opt                                    visible_hide_opt
     386%type<enum_hiding> hide_opt                                     visible_hide_opt
    370387
    371388// 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
     389%type<expr> constant
     390%type<expr> tuple                                                       tuple_expression_list
     391%type<oper> ptrref_operator                             unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
     392%type<expr> primary_expression                  postfix_expression                      unary_expression
     393%type<expr> cast_expression_list                        cast_expression                         exponential_expression          multiplicative_expression       additive_expression
     394%type<expr> shift_expression                            relational_expression           equality_expression
     395%type<expr> AND_expression                              exclusive_OR_expression         inclusive_OR_expression
     396%type<expr> logical_AND_expression              logical_OR_expression
     397%type<expr> conditional_expression              constant_expression                     assignment_expression           assignment_expression_opt
     398%type<expr> comma_expression                            comma_expression_opt
     399%type<expr> argument_expression_list_opt        argument_expression_list        argument_expression                     default_initializer_opt
    383400%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
     401%type<forctl> for_control_expression            for_control_expression_list
     402%type<oper> upupeq updown updowneq downupdowneq
     403%type<expr> subrange
    387404%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
     405%type<expr> asm_operands_opt                            asm_operands_list                       asm_operand
     406%type<labels> label_list
     407%type<expr> asm_clobbers_list_opt
     408%type<is_volatile> asm_volatile_opt
     409%type<expr> handler_predicate_opt
    393410%type<genexpr> generic_association              generic_assoc_list
    394411
    395412// 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
     413%type<stmt> statement                                           labeled_statement                       compound_statement
     414%type<stmt> statement_decl                              statement_decl_list                     statement_list_nodecl
     415%type<stmt> selection_statement                 if_statement
     416%type<clause> switch_clause_list_opt            switch_clause_list
     417%type<expr> case_value
     418%type<clause> case_clause                               case_value_list                         case_label                                      case_label_list
     419%type<stmt> iteration_statement                 jump_statement
     420%type<stmt> expression_statement                        asm_statement
     421%type<stmt> with_statement
     422%type<expr> with_clause_opt
     423%type<stmt> exception_statement
     424%type<clause> handler_clause                    finally_clause
     425%type<except_kind> handler_key
     426%type<stmt> mutex_statement
     427%type<expr> when_clause                                 when_clause_opt                         waitfor         waituntil               timeout
     428%type<stmt> waitfor_statement                           waituntil_statement
     429%type<wfs> wor_waitfor_clause                   waituntil_clause                        wand_waituntil_clause   wor_waituntil_clause
    412430
    413431// declarations
     
    421439%type<decl> assertion assertion_list assertion_list_opt
    422440
    423 %type<en> bit_subrange_size_opt bit_subrange_size
     441%type<expr> bit_subrange_size_opt bit_subrange_size
    424442
    425443%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     
    434452
    435453%type<decl> enumerator_list enum_type enum_type_nobody
    436 %type<in> enumerator_value_opt
     454%type<init> enumerator_value_opt
    437455
    438456%type<decl> external_definition external_definition_list external_definition_list_opt
     
    441459
    442460%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
     461%type<expr> field field_name_list field_name fraction_constants_opt
    444462
    445463%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    482500%type<decl> typedef_name typedef_declaration typedef_expression
    483501
    484 %type<decl> variable_type_redeclarator type_ptr type_array type_function
     502%type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function
     503%type<decl> general_function_declarator function_type_redeclarator function_type_array function_type_no_ptr function_type_ptr
    485504
    486505%type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function
     
    489508%type<decl> type_parameter type_parameter_list type_initializer_opt
    490509
    491 %type<en> type_parameters_opt type_list array_type_list
     510%type<expr> type_parameters_opt type_list array_type_list
    492511
    493512%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    500519
    501520// initializers
    502 %type<in>  initializer initializer_list_opt initializer_opt
     521%type<init>  initializer initializer_list_opt initializer_opt
    503522
    504523// designators
    505 %type<en>  designator designator_list designation
     524%type<expr>  designator designator_list designation
    506525
    507526
     
    512531// Similar issues exit with the waitfor statement.
    513532
    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.
     533// Order of these lines matters (low-to-high precedence). THEN is left associative over WAND/WOR/TIMEOUT/ELSE, WAND/WOR
     534// is left associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.
    516535%precedence THEN                // rule precedence for IF/WAITFOR statement
     536%precedence ANDAND              // token precedence for start of WAND in WAITFOR statement
     537%precedence WAND                // token precedence for start of WAND in WAITFOR statement
     538%precedence OROR                // token precedence for start of WOR in WAITFOR statement
    517539%precedence WOR                 // token precedence for start of WOR in WAITFOR statement
    518540%precedence TIMEOUT             // token precedence for start of TIMEOUT in WAITFOR statement
     
    592614constant:
    593615                // 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 ) ); }
     616        INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( yylloc, *$1 ) ); }
     617        | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     618        | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     619        | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     620        | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( yylloc, *$1 ) ); }
    599621        ;
    600622
    601623quasi_keyword:                                                                                  // CFA
    602624        TIMEOUT
     625        | WAND
    603626        | WOR
    604627        | CATCH
     
    621644
    622645string_literal:
    623         string_literal_list                                                     { $$ = build_constantStr( *$1 ); }
     646        string_literal_list                                                     { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 ) ); }
    624647        ;
    625648
     
    638661primary_expression:
    639662        IDENTIFIER                                                                                      // typedef name cannot be used as a variable name
    640                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     663                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    641664        | quasi_keyword
    642                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     665                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    643666        | TYPEDIMname                                                                           // CFA, generic length argument
    644667                // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); }
    645668                // { $$ = new ExpressionNode( build_varref( $1 ) ); }
    646                 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }
     669                { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); }
    647670        | tuple
    648671        | '(' comma_expression ')'
    649672                { $$ = $2; }
    650673        | '(' compound_statement ')'                                            // GCC, lambda expression
    651                 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }
     674                { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); }
    652675        | type_name '.' identifier                                                      // CFA, nested type
    653                 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
     676                { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    654677        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    655678                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    657680                {
    658681                        // add the missing control expression to the GenericExpr and return it
    659                         $5->control = maybeMoveBuild<Expression>( $3 );
     682                        $5->control = maybeMoveBuild( $3 );
    660683                        $$ = new ExpressionNode( $5 );
    661684                }
     
    683706                {
    684707                        // steal the association node from the singleton and delete the wrapper
    685                         $1->associations.splice($1->associations.end(), $3->associations);
     708                        assert( 1 == $3->associations.size() );
     709                        $1->associations.push_back( $3->associations.front() );
    686710                        delete $3;
    687711                        $$ = $1;
     
    693717                {
    694718                        // create a GenericExpr wrapper with one association pair
    695                         $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } );
     719                        $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );
    696720                }
    697721        | DEFAULT ':' assignment_expression
    698                 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); }
     722                { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }
    699723        ;
    700724
     
    705729                // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
    706730                // Current: Commas in subscripts make tuples.
    707                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
     731                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
    708732        | postfix_expression '[' assignment_expression ']'
    709733                // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
     
    711735                // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
    712736                // equivalent to the old x[i,j].
    713                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     737                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    714738        | constant '[' assignment_expression ']'                        // 3[a], 'a'[a], 3.5[a]
    715                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     739                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    716740        | string_literal '[' assignment_expression ']'          // "abc"[3], 3["abc"]
    717                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
     741                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    718742        | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call
    719743                {
    720744                        Token fn;
    721745                        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 ) ) ) );
     746                        $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
    723747                }
    724748        | postfix_expression '(' argument_expression_list_opt ')'
    725                 { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
     749                { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); }
    726750        | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')'
    727751                // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; }
    728                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ),
     752                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, new string( "__builtin_va_arg") ) ),
    729753                                                                                           (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); }
    730754        | postfix_expression '`' identifier                                     // CFA, postfix call
    731                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     755                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    732756        | constant '`' identifier                                                       // CFA, postfix call
    733                 { $$ = 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 ) ); }
    734758        | string_literal '`' identifier                                         // CFA, postfix call
    735                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
     759                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    736760        | postfix_expression '.' identifier
    737                 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
     761                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    738762        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
    739                 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); }
     763                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    740764        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    741                 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
     765                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ) ) ); }
    742766        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    743                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     767                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    744768        | postfix_expression '.' aggregate_control
    745                 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
     769                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); }
    746770        | postfix_expression ARROW identifier
    747                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
     771                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    748772        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    749                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
     773                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    750774        | postfix_expression ARROW '[' field_name_list ']'      // CFA, tuple field selector
    751                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     775                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    752776        | postfix_expression ICR
    753                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
     777                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); }
    754778        | postfix_expression DECR
    755                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); }
     779                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); }
    756780        | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
    757                 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
     781                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); }
    758782        | '(' 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 ) ) ); }
     783                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
    760784        | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call
    761785                {
    762786                        Token fn;
    763787                        fn.str = new string( "^?{}" );                          // location undefined
    764                         $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
     788                        $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
    765789                }
    766790        ;
     
    781805        '@'                                                                                                     // CFA, default parameter
    782806                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
    783                 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
     807                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
    784808        | assignment_expression
    785809        ;
     
    793817        field_name
    794818        | FLOATING_DECIMALconstant field
    795                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
     819                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); }
    796820        | FLOATING_DECIMALconstant '[' field_name_list ']'
    797                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
     821                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc, $3 ) ) ); }
    798822        | field_name '.' field
    799                 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     823                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    800824        | field_name '.' '[' field_name_list ']'
    801                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     825                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    802826        | field_name ARROW field
    803                 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     827                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    804828        | field_name ARROW '[' field_name_list ']'
    805                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     829                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    806830        ;
    807831
    808832field_name:
    809833        INTEGERconstant fraction_constants_opt
    810                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }
     834                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc, *$1 ), $2 ) ); }
    811835        | FLOATINGconstant fraction_constants_opt
    812                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
     836                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc, *$1 ), $2 ) ); }
    813837        | identifier_at fraction_constants_opt                          // CFA, allow anonymous fields
    814838                {
    815                         $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
     839                        $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc, $1 ), $2 ) );
    816840                }
    817841        ;
     
    822846        | fraction_constants_opt FLOATING_FRACTIONconstant
    823847                {
    824                         Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
    825                         $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant );
     848                        ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 );
     849                        $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1, constant ) ) : new ExpressionNode( constant );
    826850                }
    827851        ;
     
    833857        | constant
    834858        | string_literal
    835                 { $$ = new ExpressionNode( $1 ); }
     859                { $$ = $1; }
    836860        | EXTENSION cast_expression                                                     // GCC
    837861                { $$ = $2->set_extension( true ); }
     
    842866                {
    843867                        switch ( $1 ) {
    844                           case OperKinds::AddressOf:
    845                                 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) );
     868                        case OperKinds::AddressOf:
     869                                $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );
    846870                                break;
    847                           case OperKinds::PointTo:
    848                                 $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
     871                        case OperKinds::PointTo:
     872                                $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) );
    849873                                break;
    850                           case OperKinds::And:
    851                                 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) );
     874                        case OperKinds::And:
     875                                $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );
    852876                                break;
    853                           default:
     877                        default:
    854878                                assert( false );
    855879                        }
    856880                }
    857881        | unary_operator cast_expression
    858                 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }
     882                { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); }
    859883        | ICR unary_expression
    860                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Incr, $2 ) ); }
     884                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); }
    861885        | DECR unary_expression
    862                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Decr, $2 ) ); }
     886                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); }
    863887        | SIZEOF unary_expression
    864                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
     888                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    865889        | SIZEOF '(' type_no_function ')'
    866                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); }
     890                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    867891        | ALIGNOF unary_expression                                                      // GCC, variable alignment
    868                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
     892                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    869893        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    870                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
     894                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    871895        | OFFSETOF '(' type_no_function ',' identifier ')'
    872                 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
     896                { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); }
    873897        | TYPEID '(' type_no_function ')'
    874898                {
     
    895919        unary_expression
    896920        | '(' type_no_function ')' cast_expression
    897                 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     921                { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    898922        | '(' aggregate_control '&' ')' cast_expression         // CFA
    899                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     923                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    900924        | '(' aggregate_control '*' ')' cast_expression         // CFA
    901                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     925                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    902926        | '(' VIRTUAL ')' cast_expression                                       // CFA
    903                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     927                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    904928        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    905                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); }
     929                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
    906930        | '(' RETURN type_no_function ')' cast_expression       // CFA
    907931                { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
     
    911935                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    912936//      | '(' type_no_function ')' tuple
    913 //              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     937//              { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    914938        ;
    915939
     
    929953        cast_expression
    930954        | exponential_expression '\\' cast_expression
    931                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }
     955                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); }
    932956        ;
    933957
     
    935959        exponential_expression
    936960        | multiplicative_expression '*' exponential_expression
    937                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }
     961                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); }
    938962        | multiplicative_expression '/' exponential_expression
    939                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }
     963                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); }
    940964        | multiplicative_expression '%' exponential_expression
    941                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }
     965                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); }
    942966        ;
    943967
     
    945969        multiplicative_expression
    946970        | additive_expression '+' multiplicative_expression
    947                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }
     971                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); }
    948972        | additive_expression '-' multiplicative_expression
    949                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }
     973                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); }
    950974        ;
    951975
     
    953977        additive_expression
    954978        | shift_expression LS additive_expression
    955                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }
     979                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); }
    956980        | shift_expression RS additive_expression
    957                 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }
     981                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); }
    958982        ;
    959983
     
    961985        shift_expression
    962986        | relational_expression '<' shift_expression
    963                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }
     987                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); }
    964988        | relational_expression '>' shift_expression
    965                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }
     989                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); }
    966990        | relational_expression LE shift_expression
    967                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }
     991                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); }
    968992        | relational_expression GE shift_expression
    969                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }
     993                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); }
    970994        ;
    971995
     
    973997        relational_expression
    974998        | equality_expression EQ relational_expression
    975                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }
     999                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); }
    9761000        | equality_expression NE relational_expression
    977                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }
     1001                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); }
    9781002        ;
    9791003
     
    9811005        equality_expression
    9821006        | AND_expression '&' equality_expression
    983                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }
     1007                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); }
    9841008        ;
    9851009
     
    9871011        AND_expression
    9881012        | exclusive_OR_expression '^' AND_expression
    989                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }
     1013                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); }
    9901014        ;
    9911015
     
    9931017        exclusive_OR_expression
    9941018        | inclusive_OR_expression '|' exclusive_OR_expression
    995                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }
     1019                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); }
    9961020        ;
    9971021
     
    9991023        inclusive_OR_expression
    10001024        | logical_AND_expression ANDAND inclusive_OR_expression
    1001                 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); }
     1025                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); }
    10021026        ;
    10031027
     
    10051029        logical_AND_expression
    10061030        | logical_OR_expression OROR logical_AND_expression
    1007                 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); }
     1031                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); }
    10081032        ;
    10091033
     
    10111035        logical_OR_expression
    10121036        | logical_OR_expression '?' comma_expression ':' conditional_expression
    1013                 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
     1037                { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); }
    10141038                // FIX ME: computes $1 twice
    10151039        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    1016                 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
     1040                { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); }
    10171041        ;
    10181042
     
    10291053//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    10301054//                      } else {
    1031                                 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
     1055                                $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) );
    10321056//                      } // if
    10331057                }
     
    10741098//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    10751099        '[' ',' tuple_expression_list ']'
    1076                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     1100                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    10771101        | '[' push assignment_expression pop ',' tuple_expression_list ']'
    1078                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }
     1102                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); }
    10791103        ;
    10801104
     
    10921116        assignment_expression
    10931117        | comma_expression ',' assignment_expression
    1094                 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     1118                { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    10951119        ;
    10961120
     
    11131137        | mutex_statement
    11141138        | waitfor_statement
     1139        | waituntil_statement
    11151140        | exception_statement
    11161141        | enable_disable_statement
     
    11181143        | asm_statement
    11191144        | DIRECTIVE
    1120                 { $$ = new StatementNode( build_directive( $1 ) ); }
     1145                { $$ = new StatementNode( build_directive( yylloc, $1 ) ); }
    11211146        ;
    11221147
     
    11241149                // labels cannot be identifiers 0 or 1
    11251150        identifier_or_type_name ':' attribute_list_opt statement
    1126                 { $$ = $4->add_label( $1, $3 ); }
     1151                { $$ = $4->add_label( yylloc, $1, $3 ); }
    11271152        | identifier_or_type_name ':' attribute_list_opt error // syntax error
    11281153                {
     
    11361161compound_statement:
    11371162        '{' '}'
    1138                 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     1163                { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); }
    11391164        | '{' push
    11401165          local_label_declaration_opt                                           // GCC, local labels appear at start of block
    11411166          statement_decl_list                                                           // C99, intermix declarations and statements
    11421167          pop '}'
    1143                 { $$ = new StatementNode( build_compound( $4 ) ); }
     1168                { $$ = new StatementNode( build_compound( yylloc, $4 ) ); }
    11441169        ;
    11451170
     
    11721197expression_statement:
    11731198        comma_expression_opt ';'
    1174                 { $$ = new StatementNode( build_expr( $1 ) ); }
    1175         | MUTEX '(' ')' comma_expression ';'
    1176                 { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); }
     1199                { $$ = new StatementNode( build_expr( yylloc, $1 ) ); }
    11771200        ;
    11781201
     
    11831206                { $$ = $2; }
    11841207        | SWITCH '(' comma_expression ')' case_clause
    1185                 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
     1208                { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); }
    11861209        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    11871210                {
    1188                         StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
     1211                        StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) );
    11891212                        // The semantics of the declaration list is changed to include associated initialization, which is performed
    11901213                        // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
     
    11921215                        // therefore, are removed from the grammar even though C allows it. The change also applies to choose
    11931216                        // statement.
    1194                         $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1217                        $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    11951218                }
    11961219        | SWITCH '(' comma_expression ')' '{' error '}'         // CFA, syntax error
    11971220                { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    11981221        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    1199                 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
     1222                { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); }
    12001223        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12011224                {
    1202                         StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );
    1203                         $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1225                        StatementNode *sw = new StatementNode( build_switch( yylloc, false, $3, $8 ) );
     1226                        $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    12041227                }
    12051228        | CHOOSE '(' comma_expression ')' '{' error '}'         // CFA, syntax error
     
    12101233        IF '(' conditional_declaration ')' statement            %prec THEN
    12111234                // explicitly deal with the shift/reduce conflict on if/else
    1212                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
     1235                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); }
    12131236        | IF '(' conditional_declaration ')' statement ELSE statement
    1214                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); }
     1237                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); }
    12151238        ;
    12161239
     
    12241247        | declaration comma_expression                                          // semi-colon separated
    12251248                { $$ = new CondCtl( $1, $2 ); }
    1226         ;
     1249        ;
    12271250
    12281251// CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case
     
    12321255        constant_expression                                                     { $$ = $1; }
    12331256        | constant_expression ELLIPSIS constant_expression      // GCC, subrange
    1234                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     1257                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    12351258        | subrange                                                                                      // CFA, subrange
    12361259        ;
    12371260
    12381261case_value_list:                                                                                // CFA
    1239         case_value                                                                      { $$ = new StatementNode( build_case( $1 ) ); }
     1262        case_value                                                                      { $$ = new ClauseNode( build_case( yylloc, $1 ) ); }
    12401263                // 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 ) ) ) ); }
     1264        | case_value_list ',' case_value                        { $$ = $1->set_last( new ClauseNode( build_case( yylloc, $3 ) ) ); }
    12421265        ;
    12431266
     
    12481271        | CASE case_value_list error                                            // syntax error
    12491272                { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
    1250         | DEFAULT ':'                                                           { $$ = new StatementNode( build_default() ); }
     1273        | DEFAULT ':'                                                           { $$ = new ClauseNode( build_default( yylloc ) ); }
    12511274                // A semantic check is required to ensure only one default clause per switch/choose statement.
    12521275        | DEFAULT error                                                                         //  syntax error
     
    12561279case_label_list:                                                                                // CFA
    12571280        case_label
    1258         | case_label_list case_label                            { $$ = (StatementNode *)( $1->set_last( $2 )); }
     1281        | case_label_list case_label                            { $$ = $1->set_last( $2 ); }
    12591282        ;
    12601283
    12611284case_clause:                                                                                    // CFA
    1262         case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }
     1285        case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( yylloc, $2 ) ); }
    12631286        ;
    12641287
     
    12711294switch_clause_list:                                                                             // CFA
    12721295        case_label_list statement_list_nodecl
    1273                 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
     1296                { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); }
    12741297        | switch_clause_list case_label_list statement_list_nodecl
    1275                 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
     1298                { $$ = $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ); }
    12761299        ;
    12771300
    12781301iteration_statement:
    12791302        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1280                 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
     1303                { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); }
    12811304        | WHILE '(' ')' statement ELSE statement                        // CFA
    12821305                {
    1283                         $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
    1284                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1306                        $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) );
     1307                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    12851308                }
    12861309        | WHILE '(' conditional_declaration ')' statement       %prec THEN
    1287                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
     1310                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    12881311        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
    1289                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
     1312                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    12901313        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1291                 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
     1314                { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); }
    12921315        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    12931316                {
    1294                         $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
    1295                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1317                        $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) );
     1318                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    12961319                }
    12971320        | DO statement WHILE '(' comma_expression ')' ';'
    1298                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
     1321                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); }
    12991322        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
    1300                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
     1323                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ), $8 ) ); }
    13011324        | FOR '(' ')' statement                                                         %prec THEN // CFA => for ( ;; )
    1302                 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); }
     1325                { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); }
    13031326        | FOR '(' ')' statement ELSE statement                          // CFA
    13041327                {
    1305                         $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) );
    1306                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1328                        $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) );
     1329                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13071330                }
    13081331        | FOR '(' for_control_expression_list ')' statement     %prec THEN
    1309                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
     1332                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    13101333        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
    1311                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
     1334                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    13121335        ;
    13131336
     
    13231346                        if ( $1->condition ) {
    13241347                                if ( $3->condition ) {
    1325                                         $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
     1348                                        $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr ) );
    13261349                                } // if
    13271350                        } else $1->condition = $3->condition;
    13281351                        if ( $1->change ) {
    13291352                                if ( $3->change ) {
    1330                                         $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
     1353                                        $1->change->expr.reset( new ast::CommaExpr( yylloc, $1->change->expr.release(), $3->change->expr.release() ) );
    13311354                                } // if
    13321355                        } else $1->change = $3->change;
     
    13371360for_control_expression:
    13381361        ';' comma_expression_opt ';' comma_expression_opt
    1339                 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
     1362                { $$ = new ForCtrl( nullptr, $2, $4 ); }
    13401363        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    1341                 { $$ = new ForCtrl( $1, $3, $5 ); }
     1364                {
     1365                        StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr;
     1366                        $$ = new ForCtrl( init, $3, $5 );
     1367                }
    13421368        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    1343                 { $$ = new ForCtrl( $1, $2, $4 ); }
     1369                { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); }
    13441370
    13451371        | '@' ';' comma_expression                                                      // CFA, empty loop-index
    1346                 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }
     1372                { $$ = new ForCtrl( nullptr, $3, nullptr ); }
    13471373        | '@' ';' comma_expression ';' comma_expression         // CFA, empty loop-index
    1348                 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }
     1374                { $$ = new ForCtrl( nullptr, $3, $5 ); }
    13491375
    13501376        | comma_expression                                                                      // CFA, anonymous loop-index
    1351                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
     1377                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
    13521378        | 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 ); }
     1379                { $$ = forCtrl( yylloc, $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
    13541380
    13551381        | 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 ); }
     1382                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
    13571383        | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
    13581384                {
    13591385                        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 );
     1386                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
    13611387                }
    13621388        | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
     
    13661392                }
    13671393        | 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 ); }
     1394                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
    13691395        | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    13701396                {
    13711397                        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 );
     1398                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
    13731399                }
    13741400        | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
     
    13891415
    13901416        | comma_expression ';' comma_expression                         // CFA
    1391                 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1417                { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    13921418        | 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 ); }
     1419                { $$ = forCtrl( yylloc, $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
    13941420
    13951421        | 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 ); }
     1422                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
    13971423        | comma_expression ';' '@' updowneq comma_expression // CFA
    13981424                {
    13991425                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1400                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1426                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    14011427                }
    14021428        | comma_expression ';' comma_expression updowneq '@' // CFA
     
    14041430                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14051431                        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 );
     1432                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    14071433                }
    14081434        | comma_expression ';' '@' updowneq '@'                         // CFA, error
     
    14101436
    14111437        | 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 ); }
     1438                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    14131439        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
    14141440                {
    14151441                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1416                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
     1442                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 );
    14171443                }
    14181444        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
     
    14201446                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14211447                        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 );
     1448                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, $7 );
    14231449                }
    14241450        | 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 ); }
     1451                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    14261452        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
    14271453                {
    14281454                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1429                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
     1455                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr );
    14301456                }
    14311457        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
     
    14331459                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14341460                        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 );
     1461                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, nullptr );
    14361462                }
    14371463        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
     
    14391465
    14401466        | declaration comma_expression                                          // CFA
    1441                 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1467                { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    14421468        | declaration downupdowneq comma_expression                     // CFA
    1443                 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
     1469                { $$ = forCtrl( yylloc, $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
    14441470
    14451471        | declaration comma_expression updowneq comma_expression // CFA
    1446                 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
     1472                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
    14471473        | declaration '@' updowneq comma_expression                     // CFA
    14481474                {
    14491475                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1450                         else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
     1476                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE );
    14511477                }
    14521478        | declaration comma_expression updowneq '@'                     // CFA
     
    14541480                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14551481                        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 );
     1482                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, NEW_ONE );
    14571483                }
    14581484
    14591485        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1460                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
     1486                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
    14611487        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    14621488                {
    14631489                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1464                         else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
     1490                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 );
    14651491                }
    14661492        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
     
    14681494                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14691495                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1470                         else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
     1496                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, $6 );
    14711497                }
    14721498        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1473                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
     1499                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
    14741500        | declaration '@' updowneq comma_expression '~' '@' // CFA
    14751501                {
    14761502                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1477                         else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
     1503                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr );
    14781504                }
    14791505        | declaration comma_expression updowneq '@' '~' '@'     // CFA
     
    14811507                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14821508                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1483                         else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
     1509                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr );
    14841510                }
    14851511        | declaration '@' updowneq '@' '~' '@'                          // CFA, error
     
    14961522                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    14971523                }
    1498         ;
     1524        ;
    14991525
    15001526downupdowneq:
     
    15051531        | ErangeDownEq
    15061532                { $$ = OperKinds::GEThan; }
    1507         ;
     1533        ;
    15081534
    15091535updown:
     
    15121538        | ErangeDown
    15131539                { $$ = OperKinds::GThan; }
    1514         ;
     1540        ;
    15151541
    15161542updowneq:
     
    15201546        | ErangeDownEq
    15211547                { $$ = OperKinds::GEThan; }
    1522         ;
     1548        ;
    15231549
    15241550jump_statement:
    15251551        GOTO identifier_or_type_name ';'
    1526                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); }
     1552                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }
    15271553        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    15281554                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    15311557                // A semantic check is required to ensure fallthru appears only in the body of a choose statement.
    15321558        | fall_through_name ';'                                                         // CFA
    1533                 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }
     1559                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }
    15341560        | fall_through_name identifier_or_type_name ';'         // CFA
    1535                 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); }
     1561                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }
    15361562        | fall_through_name DEFAULT ';'                                         // CFA
    1537                 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }
     1563                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }
    15381564        | CONTINUE ';'
    15391565                // 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 ) ); }
     1566                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }
    15411567        | CONTINUE identifier_or_type_name ';'                          // CFA, multi-level continue
    15421568                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15431569                // the target of the transfer appears only at the start of an iteration statement.
    1544                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); }
     1570                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }
    15451571        | BREAK ';'
    15461572                // 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 ) ); }
     1573                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }
    15481574        | BREAK identifier_or_type_name ';'                                     // CFA, multi-level exit
    15491575                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15501576                // the target of the transfer appears only at the start of an iteration statement.
    1551                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); }
     1577                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }
    15521578        | RETURN comma_expression_opt ';'
    1553                 { $$ = new StatementNode( build_return( $2 ) ); }
     1579                { $$ = new StatementNode( build_return( yylloc, $2 ) ); }
    15541580        | RETURN '{' initializer_list_opt comma_opt '}' ';'
    15551581                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    15561582        | SUSPEND ';'
    1557                 { $$ = new StatementNode( build_suspend( nullptr ) ); }
     1583                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); }
    15581584        | SUSPEND compound_statement
    1559                 { $$ = new StatementNode( build_suspend( $2 ) ); }
     1585                { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); }
    15601586        | SUSPEND COROUTINE ';'
    1561                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); }
     1587                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }
    15621588        | SUSPEND COROUTINE compound_statement
    1563                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); }
     1589                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }
    15641590        | SUSPEND GENERATOR ';'
    1565                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); }
     1591                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }
    15661592        | SUSPEND GENERATOR compound_statement
    1567                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); }
     1593                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }
    15681594        | THROW assignment_expression_opt ';'                           // handles rethrow
    1569                 { $$ = new StatementNode( build_throw( $2 ) ); }
     1595                { $$ = new StatementNode( build_throw( yylloc, $2 ) ); }
    15701596        | THROWRESUME assignment_expression_opt ';'                     // handles reresume
    1571                 { $$ = new StatementNode( build_resume( $2 ) ); }
     1597                { $$ = new StatementNode( build_resume( yylloc, $2 ) ); }
    15721598        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    15731599                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
     
    15811607with_statement:
    15821608        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".
     1609                { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); }
     1610        ;
     1611
     1612// If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so possibly change syntax to "with mutex".
    15871613mutex_statement:
    1588         MUTEX '(' argument_expression_list ')' statement
    1589                 { $$ = new StatementNode( build_mutex( $3, $5 ) ); }
     1614        MUTEX '(' argument_expression_list_opt ')' statement
     1615                {
     1616                        if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; }
     1617                        $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) );
     1618                }
    15901619        ;
    15911620
     
    15981627                { $$ = nullptr; }
    15991628        | 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 )); }
    16091629        ;
    16101630
     
    16171637
    16181638timeout:
    1619         TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
    1620         ;
    1621 
    1622 waitfor_clause:
     1639        TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
     1640        ;
     1641
     1642wor:
     1643        OROR
     1644        | WOR
     1645
     1646waitfor:
     1647        WAITFOR '(' cast_expression ')'
     1648                { $$ = $3; }
     1649        | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')'
     1650                { $$ = (ExpressionNode *)($3->set_last( $5 )); }
     1651        ;
     1652
     1653wor_waitfor_clause:
    16231654        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 ); }
     1655                // Called first: create header for WaitForStmt.
     1656                { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); }
     1657        | wor_waitfor_clause wor when_clause_opt waitfor statement
     1658                { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
     1659        | wor_waitfor_clause wor when_clause_opt ELSE statement
     1660                { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); }
     1661        | wor_waitfor_clause wor when_clause_opt timeout statement      %prec THEN
     1662                { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    16311663        // "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
     1664        | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
    16331665                { 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 ); }
     1666        | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
     1667                { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); }
    16361668        ;
    16371669
    16381670waitfor_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 ) ); }
     1671        wor_waitfor_clause                                                                      %prec THEN
     1672                { $$ = new StatementNode( $1 ); }
     1673        ;
     1674
     1675wand:
     1676        ANDAND
     1677        | WAND
     1678        ;
     1679
     1680waituntil:
     1681        WAITUNTIL '(' cast_expression ')'
     1682                { $$ = $3; }
     1683        ;
     1684
     1685waituntil_clause:
     1686        when_clause_opt waituntil statement
     1687                { printf( "waituntil_clause 1\n" ); $$ = nullptr; }
     1688        | '(' wor_waituntil_clause ')'
     1689                { printf( "waituntil_clause 2\n" ); $$ = nullptr; }
     1690        ;
     1691
     1692wand_waituntil_clause:
     1693        waituntil_clause                                                                        %prec THEN
     1694                { printf( "wand_waituntil_clause 1\n" ); $$ = nullptr; }
     1695        | waituntil_clause wand wand_waituntil_clause
     1696                { printf( "wand_waituntil_clause 2\n" ); $$ = nullptr; }
     1697        ;
     1698
     1699wor_waituntil_clause:
     1700        wand_waituntil_clause
     1701                { printf( "wor_waituntil_clause 1\n" ); $$ = nullptr; }
     1702        | wor_waituntil_clause wor wand_waituntil_clause
     1703                { printf( "wor_waituntil_clause 2\n" ); $$ = nullptr; }
     1704        | wor_waituntil_clause wor when_clause_opt ELSE statement
     1705                { printf( "wor_waituntil_clause 3\n" ); $$ = nullptr; }
     1706        | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
     1707                { printf( "wor_waituntil_clause 4\n" ); $$ = nullptr; }
     1708        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
     1709        | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
     1710                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
     1711        | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
     1712                { printf( "wor_waituntil_clause 6\n" ); $$ = nullptr; }
     1713        ;
     1714
     1715waituntil_statement:
     1716        wor_waituntil_clause                                                            %prec THEN
     1717                // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
     1718                { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); }
    16431719        ;
    16441720
    16451721exception_statement:
    1646         TRY compound_statement handler_clause                                   %prec THEN
    1647                 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
     1722        TRY compound_statement handler_clause                                   %prec THEN
     1723                { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
    16481724        | TRY compound_statement finally_clause
    1649                 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }
     1725                { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
    16501726        | TRY compound_statement handler_clause finally_clause
    1651                 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
     1727                { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
    16521728        ;
    16531729
    16541730handler_clause:
    16551731        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1656                 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
     1732                { $$ = new ClauseNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
    16571733        | 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 ) ) ); }
     1734                { $$ = $1->set_last( new ClauseNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
    16591735        ;
    16601736
     
    16661742
    16671743handler_key:
    1668         CATCH                                                                           { $$ = CatchStmt::Terminate; }
    1669         | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
    1670         | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
    1671         | FIXUP                                                                         { $$ = CatchStmt::Resume; }
     1744        CATCH                                                                           { $$ = ast::Terminate; }
     1745        | RECOVER                                                                       { $$ = ast::Terminate; }
     1746        | CATCHRESUME                                                           { $$ = ast::Resume; }
     1747        | FIXUP                                                                         { $$ = ast::Resume; }
    16721748        ;
    16731749
    16741750finally_clause:
    1675         FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
     1751        FINALLY compound_statement                                      { $$ = new ClauseNode( build_finally( yylloc, $2 ) ); }
    16761752        ;
    16771753
     
    16991775asm_statement:
    17001776        ASM asm_volatile_opt '(' string_literal ')' ';'
    1701                 { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); }
     1777                { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
    17021778        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1703                 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
     1779                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
    17041780        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1705                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
     1781                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
    17061782        | 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 ) ); }
     1783                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
    17081784        | 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 ) ); }
     1785                { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
    17101786        ;
    17111787
     
    17311807asm_operand:                                                                                    // GCC
    17321808        string_literal '(' constant_expression ')'
    1733                 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     1809                { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    17341810        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1735                 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); }
     1811                {
     1812                        $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) );
     1813                        delete $2.str;
     1814                }
    17361815        ;
    17371816
     
    17401819                { $$ = nullptr; }                                                               // use default argument
    17411820        | string_literal
    1742                 { $$ = new ExpressionNode( $1 ); }
     1821                { $$ = $1; }
    17431822        | asm_clobbers_list_opt ',' string_literal
    1744                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); }
     1823                { $$ = (ExpressionNode *)( $1->set_last( $3 ) ); }
    17451824        ;
    17461825
     
    17481827        identifier
    17491828                {
    1750                         $$ = new LabelNode(); $$->labels.push_back( *$1 );
     1829                        $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
    17511830                        delete $1;                                                                      // allocated by lexer
    17521831                }
    17531832        | label_list ',' identifier
    17541833                {
    1755                         $$ = $1; $1->labels.push_back( *$3 );
     1834                        $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
    17561835                        delete $3;                                                                      // allocated by lexer
    17571836                }
     
    18041883                {
    18051884                        // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" );
    1806                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     1885                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    18071886                        //   printf( "\tattr %s\n", attr->name.c_str() );
    18081887                        // } // for
     
    18141893static_assert:
    18151894        STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
    1816                 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
     1895                { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 ) ); }
    18171896        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1818                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
     1897                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
    18191898
    18201899// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    18801959//      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
    18811960//              {
    1882 //                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
     1961//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );
    18831962//              }
    18841963//      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
    18851964//              {
    18861965//                      typedefTable.setNextIdentifier( *$5 );
    1887 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1966//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
    18881967//              }
    18891968//      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
    18901969//              {
    18911970//                      typedefTable.setNextIdentifier( *$5 );
    1892 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1971//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
    18931972//              }
    18941973//      | '[' ']' typegen_name
     
    19021981        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    19031982                // 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 ); }
     1983                { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
    19051984        | 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 ); }
     1985                { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
    19071986        ;
    19081987
     
    19402019                {
    19412020                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
    1942                         $$ = $3->addType( $2 )->addTypedef();
     2021                        if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) {
     2022                                SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr;
     2023                        } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
    19432024                }
    19442025        | typedef_declaration pop ',' push declarator
     
    19482029                }
    19492030        | 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                 }
     2031                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19542032        | type_specifier TYPEDEF declarator
    1955                 {
    1956                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" );
    1957                         $$ = $3->addType( $1 )->addTypedef();
    1958                 }
     2033                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19592034        | type_specifier TYPEDEF type_qualifier_list declarator
    1960                 {
    1961                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" );
    1962                         $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
    1963                 }
     2035                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19642036        ;
    19652037
     
    19682040        TYPEDEF identifier '=' assignment_expression
    19692041                {
    1970                         SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     2042                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    19712043                }
    19722044        | typedef_expression pop ',' push identifier '=' assignment_expression
    19732045                {
    1974                         SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     2046                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    19752047                }
    19762048        ;
     
    19822054        | typedef_expression                                                            // deprecated GCC, naming expression type
    19832055        | sue_declaration_specifier
     2056                {
     2057                        assert( $1->type );
     2058                        if ( $1->type->qualifiers.any() ) {                     // CV qualifiers ?
     2059                                SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr;
     2060                        }
     2061                        // enums are never empty declarations because there must have at least one enumeration.
     2062                        if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?
     2063                                SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;
     2064                        }
     2065                }
    19842066        ;
    19852067
     
    19872069                // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    19882070                // storage-class
    1989         declarator asm_name_opt initializer_opt
     2071        variable_declarator asm_name_opt initializer_opt
    19902072                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
     2073        | variable_type_redeclarator asm_name_opt initializer_opt
     2074                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
     2075
     2076        | general_function_declarator asm_name_opt
     2077                { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }
     2078        | general_function_declarator asm_name_opt '=' VOID
     2079                { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }
     2080
    19912081        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    19922082                { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
    19932083        ;
    19942084
     2085general_function_declarator:
     2086        function_type_redeclarator
     2087        | function_declarator
     2088        ;
     2089
    19952090declaration_specifier:                                                                  // type specifier + storage class
    19962091        basic_declaration_specifier
     2092        | type_declaration_specifier
    19972093        | sue_declaration_specifier
    1998         | type_declaration_specifier
     2094        | sue_declaration_specifier invalid_types
     2095                {
     2096                        SemanticError( yylloc, ::toString( "Missing ';' after end of ",
     2097                                $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),
     2098                                " declaration" ) );
     2099                        $$ = nullptr;
     2100                }
     2101        ;
     2102
     2103invalid_types:
     2104        aggregate_key
     2105        | basic_type_name
     2106        | indirect_type
    19992107        ;
    20002108
     
    20132121        basic_type_specifier
    20142122        | 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                 }
    20212123        | type_type_specifier
    20222124        ;
     
    20652167                { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); }
    20662168        | forall
     2169                { $$ = DeclarationNode::newForall( $1 ); }
    20672170        ;
    20682171
    20692172forall:
    20702173        FORALL '(' type_parameter_list ')'                                      // CFA
    2071                 { $$ = DeclarationNode::newForall( $3 ); }
     2174                { $$ = $3; }
    20722175        ;
    20732176
     
    22262329                { $$ = DeclarationNode::newTypeof( $3 ); }
    22272330        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2228                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
     2331                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
    22292332        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    22302333                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    22392342                {
    22402343                        // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2241                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2344                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    22422345                        //   printf( "\tattr %s\n", attr->name.c_str() );
    22432346                        // } // for
     
    22552358                {
    22562359                        // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2257                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2360                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    22582361                        //   printf( "\tattr %s\n", attr->name.c_str() );
    22592362                        // } // for
     
    23332436                {
    23342437                        // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2335                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2438                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23362439                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23372440                        // } // for
     
    23572460          '{' field_declaration_list_opt '}' type_parameters_opt
    23582461                {
    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
    23642462                        $$ = 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
    23692463                }
    23702464        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     
    23752469          '{' field_declaration_list_opt '}' type_parameters_opt
    23762470                {
    2377                         // printf( "AGG3\n" );
    23782471                        DeclarationNode::newFromTypedef( $3 );
    23792472                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    23862479          '{' field_declaration_list_opt '}' type_parameters_opt
    23872480                {
    2388                         // printf( "AGG4\n" );
    23892481                        DeclarationNode::newFromTypeGen( $3, nullptr );
    23902482                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    24132505                        // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
    24142506                        // 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;
     2507                        if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) {
     2508                                $$ = $3->addQualifiers( $2 );
     2509                        } else {
     2510                                $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
     2511                                $3->type->symbolic.name = nullptr;                      // copied to $$
     2512                                $3->type->symbolic.actuals = nullptr;
     2513                                delete $3;
     2514                        }
    24192515                }
    24202516        ;
     
    24272523aggregate_data:
    24282524        STRUCT vtable_opt
    2429                 { $$ = AggregateDecl::Struct; }
     2525                { $$ = ast::AggregateDecl::Struct; }
    24302526        | UNION
    2431                 { $$ = AggregateDecl::Union; }
     2527                { $$ = ast::AggregateDecl::Union; }
    24322528        | EXCEPTION                                                                                     // CFA
    2433                 { $$ = AggregateDecl::Exception; }
    2434           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2529                { $$ = ast::AggregateDecl::Exception; }
     2530          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
    24352531        ;
    24362532
    24372533aggregate_control:                                                                              // CFA
    24382534        MONITOR
    2439                 { $$ = AggregateDecl::Monitor; }
     2535                { $$ = ast::AggregateDecl::Monitor; }
    24402536        | MUTEX STRUCT
    2441                 { $$ = AggregateDecl::Monitor; }
     2537                { $$ = ast::AggregateDecl::Monitor; }
    24422538        | GENERATOR
    2443                 { $$ = AggregateDecl::Generator; }
     2539                { $$ = ast::AggregateDecl::Generator; }
    24442540        | MUTEX GENERATOR
    2445                 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2541                {
     2542                        SemanticError( yylloc, "monitor generator is currently unimplemented." );
     2543                        $$ = ast::AggregateDecl::NoAggregate;
     2544                }
    24462545        | COROUTINE
    2447                 { $$ = AggregateDecl::Coroutine; }
     2546                { $$ = ast::AggregateDecl::Coroutine; }
    24482547        | MUTEX COROUTINE
    2449                 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2548                {
     2549                        SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
     2550                        $$ = ast::AggregateDecl::NoAggregate;
     2551                }
    24502552        | THREAD
    2451                 { $$ = AggregateDecl::Thread; }
     2553                { $$ = ast::AggregateDecl::Thread; }
    24522554        | MUTEX THREAD
    2453                 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2555                {
     2556                        SemanticError( yylloc, "monitor thread is currently unimplemented." );
     2557                        $$ = ast::AggregateDecl::NoAggregate;
     2558                }
    24542559        ;
    24552560
     
    24672572                        $$ = fieldDecl( $1, $2 );
    24682573                        // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2469                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2574                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    24702575                        //   printf( "\tattr %s\n", attr->name.c_str() );
    24712576                        // } // for
     
    24732578        | EXTENSION type_specifier field_declaring_list_opt ';' // GCC
    24742579                { $$ = fieldDecl( $2, $3 ); distExt( $$ ); }
     2580        | STATIC type_specifier field_declaring_list_opt ';' // CFA
     2581                { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }
    24752582        | INLINE type_specifier field_abstract_list_opt ';'     // CFA
    24762583                {
     
    24832590                }
    24842591        | INLINE aggregate_control ';'                                          // CFA
    2485                 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
     2592                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    24862593        | typedef_declaration ';'                                                       // CFA
    24872594        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
     
    25092616                { $$ = $1->addBitfield( $2 ); }
    25102617        | variable_type_redeclarator bit_subrange_size_opt
     2618                // A semantic check is required to ensure bit_subrange only appears on integral types.
     2619                { $$ = $1->addBitfield( $2 ); }
     2620        | function_type_redeclarator bit_subrange_size_opt
    25112621                // A semantic check is required to ensure bit_subrange only appears on integral types.
    25122622                { $$ = $1->addBitfield( $2 ); }
     
    25632673                { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
    25642674        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2565                 {
    2566                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 )
     2675                {
     2676                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.any() )
    25672677                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    25682678
    25692679                        $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 );
    25702680                }
     2681        | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
     2682                {
     2683                        $$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 );
     2684                }
    25712685        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    25722686                {
    2573                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
     2687                        if ( $3->storageClasses.any() || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    25742688                        typedefTable.makeTypedef( *$6 );
    25752689                }
     
    25772691                {
    25782692                        $$ = DeclarationNode::newEnum( $6, $11, true, true, $3, $9 )->addQualifiers( $5 )->addQualifiers( $7 );
     2693                }
     2694        | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt
     2695          hide_opt '{' enumerator_list comma_opt '}'
     2696                {
     2697                        $$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );
    25792698                }
    25802699        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt
     
    25822701                {
    25832702                        $$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3, $8 )->addQualifiers( $5 )->addQualifiers( $7 );
     2703                }
     2704        | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt
     2705          hide_opt '{' enumerator_list comma_opt '}'
     2706                {
     2707                        $$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );
    25842708                }
    25852709        | enum_type_nobody
     
    25952719enum_type_nobody:                                                                               // enum - {...}
    25962720        ENUM attribute_list_opt identifier
    2597                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
     2721                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }
    25982722        | ENUM attribute_list_opt type_name
    2599                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
     2723                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }
    26002724        ;
    26012725
     
    26942818
    26952819cfa_abstract_parameter_declaration:                                             // CFA, new & old style parameter declaration
    2696         // empty
    2697                 { $$ = nullptr; }
    2698         | abstract_parameter_declaration
     2820        abstract_parameter_declaration
    26992821        | cfa_identifier_parameter_declarator_no_tuple
    27002822        | cfa_abstract_tuple
     
    27392861type_no_function:                                                                               // sizeof, alignof, cast (constructor)
    27402862        cfa_abstract_declarator_tuple                                           // CFA
    2741         | type_specifier
     2863        | type_specifier                                                                        // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
    27422864        | type_specifier abstract_declarator
    27432865                { $$ = $2->addType( $1 ); }
     
    27842906        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    27852907        | identifier_at ':'                                                                     // GCC, field name
    2786                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     2908                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    27872909        ;
    27882910
     
    27962918designator:
    27972919        '.' identifier_at                                                                       // C99, field name
    2798                 { $$ = new ExpressionNode( build_varref( $2 ) ); }
     2920                { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
    27992921        | '[' push assignment_expression pop ']'                        // C99, single array element
    28002922                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    28032925                { $$ = $3; }
    28042926        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2805                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); }
     2927                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
    28062928        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    28072929                { $$ = $4; }
     
    28432965                {
    28442966                        typedefTable.addToScope( *$2, TYPEDEFname, "9" );
    2845                         if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
    2846                         if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
    2847                         if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
     2967                        if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
     2968                        if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     2969                        if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
    28482970                }
    28492971          type_initializer_opt assertion_list_opt
     
    28562978                {
    28572979                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2858                         $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
     2980                        $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
    28592981                }
    28602982        // | type_specifier identifier_parameter_declarator
    28612983        | assertion_list
    2862                 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2984                { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    28632985        ;
    28642986
    28652987new_type_class:                                                                                 // CFA
    28662988        // empty
    2867                 { $$ = TypeDecl::Otype; }
     2989                { $$ = ast::TypeDecl::Otype; }
    28682990        | '&'
    2869                 { $$ = TypeDecl::Dtype; }
     2991                { $$ = ast::TypeDecl::Dtype; }
    28702992        | '*'
    2871                 { $$ = TypeDecl::DStype; }                                              // dtype + sized
     2993                { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
    28722994        // | '(' '*' ')'
    2873         //      { $$ = TypeDecl::Ftype; }
     2995        //      { $$ = ast::TypeDecl::Ftype; }
    28742996        | ELLIPSIS
    2875                 { $$ = TypeDecl::Ttype; }
     2997                { $$ = ast::TypeDecl::Ttype; }
    28762998        ;
    28772999
    28783000type_class:                                                                                             // CFA
    28793001        OTYPE
    2880                 { $$ = TypeDecl::Otype; }
     3002                { $$ = ast::TypeDecl::Otype; }
    28813003        | DTYPE
    2882                 { $$ = TypeDecl::Dtype; }
     3004                { $$ = ast::TypeDecl::Dtype; }
    28833005        | FTYPE
    2884                 { $$ = TypeDecl::Ftype; }
     3006                { $$ = ast::TypeDecl::Ftype; }
    28853007        | TTYPE
    2886                 { $$ = TypeDecl::Ttype; }
     3008                { $$ = ast::TypeDecl::Ttype; }
    28873009        ;
    28883010
     
    29103032type_list:                                                                                              // CFA
    29113033        type
    2912                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3034                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    29133035        | assignment_expression
    29143036        | type_list ',' type
    2915                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3037                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    29163038        | type_list ',' assignment_expression
    29173039                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    29383060                {
    29393061                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    2940                         $$ = DeclarationNode::newTypeDecl( $1, 0 );
     3062                        $$ = DeclarationNode::newTypeDecl( $1, nullptr );
    29413063                }
    29423064        | identifier_or_type_name '(' type_parameter_list ')'
     
    29493071trait_specifier:                                                                                // CFA
    29503072        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    2951                 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
     3073                {
     3074                        SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
     3075                        $$ = DeclarationNode::newTrait( $2, $4, nullptr );
     3076                }
     3077        | forall TRAIT identifier_or_type_name '{' '}'          // alternate
     3078                { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); }
    29523079        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    2953                 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
     3080                {
     3081                        SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
     3082                        $$ = DeclarationNode::newTrait( $2, $4, $8 );
     3083                }
     3084        | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate
     3085                { $$ = DeclarationNode::newTrait( $3, $1, $6 ); }
    29543086        ;
    29553087
     
    30103142external_definition:
    30113143        DIRECTIVE
    3012                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
     3144                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
    30133145        | declaration
     3146                {
     3147                        // Variable declarations of anonymous types requires creating a unique type-name across multiple translation
     3148                        // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is
     3149                        // disallowed at the moment.
     3150                        if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
     3151                                if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
     3152                                        SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
     3153                                } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union
     3154                                        SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;
     3155                                }
     3156                        }
     3157                }
    30143158        | IDENTIFIER IDENTIFIER
    30153159                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
     
    30313175                }
    30323176        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3033                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
     3177                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
    30343178        | EXTERN STRINGliteral
    30353179                {
    30363180                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3037                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3181                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    30383182                }
    30393183          up external_definition down
     
    30463190                {
    30473191                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3048                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3192                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    30493193                }
    30503194          '{' up external_definition_list_opt down '}'
     
    30573201        | type_qualifier_list
    30583202                {
    3059                         if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3203                        if ( $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    30603204                        if ( $1->type->forall ) forall = true;          // remember generic type
    30613205                }
     
    30633207                {
    30643208                        distQual( $5, $1 );
    3065                         forall = false;
     3209                        forall = false;
    30663210                        $$ = $5;
    30673211                }
    30683212        | declaration_qualifier_list
    30693213                {
    3070                         if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3214                        if ( $1->type && $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    30713215                        if ( $1->type && $1->type->forall ) forall = true; // remember generic type
    30723216                }
     
    30743218                {
    30753219                        distQual( $5, $1 );
    3076                         forall = false;
     3220                        forall = false;
    30773221                        $$ = $5;
    30783222                }
    30793223        | declaration_qualifier_list type_qualifier_list
    30803224                {
    3081                         if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3225                        if ( ($1->type && $1->type->qualifiers.any()) || ($2->type && $2->type->qualifiers.any()) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    30823226                        if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type
    30833227                }
     
    30853229                {
    30863230                        distQual( $6, $1->addQualifiers( $2 ) );
    3087                         forall = false;
     3231                        forall = false;
    30883232                        $$ = $6;
    30893233                }
     
    31293273                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    31303274                }
    3131         | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
     3275        | declaration_specifier function_type_redeclarator with_clause_opt compound_statement
    31323276                {
    31333277                        rebindForall( $1, $2 );
     
    31653309        | variable_type_redeclarator
    31663310        | function_declarator
     3311        | function_type_redeclarator
    31673312        ;
    31683313
    31693314subrange:
    31703315        constant_expression '~' constant_expression                     // CFA, integer subrange
    3171                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     3316                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    31723317        ;
    31733318
     
    31783323                {
    31793324                        DeclarationNode * name = new DeclarationNode();
    3180                         name->asmName = $3;
     3325                        name->asmName = maybeMoveBuild( $3 );
    31813326                        $$ = name->addQualifiers( $5 );
    31823327                }
     
    32753420variable_ptr:
    32763421        ptrref_operator variable_declarator
    3277                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3422                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    32783423        | ptrref_operator type_qualifier_list variable_declarator
    32793424                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    32913436        | '(' attribute_list variable_ptr ')' array_dimension
    32923437                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3293         | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     3438        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
    32943439                { $$ = $2->addArray( $4 ); }
    32953440        | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis
     
    33393484function_ptr:
    33403485        ptrref_operator function_declarator
    3341                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3486                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    33423487        | ptrref_operator type_qualifier_list function_declarator
    33433488                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    33913536KR_function_ptr:
    33923537        ptrref_operator KR_function_declarator
    3393                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3538                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    33943539        | ptrref_operator type_qualifier_list KR_function_declarator
    33953540                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34153560        ;
    34163561
    3417 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.:
     3562// This pattern parses a declaration for a variable that redefines a type name, e.g.:
    34183563//
    34193564//              typedef int foo;
     
    34213566//                 int foo; // redefine typedef name in new scope
    34223567//              }
    3423 //
    3424 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
    3425 // and functions versus pointers to arrays and functions.
    34263568
    34273569paren_type:
     
    34383580        paren_type attribute_list_opt
    34393581                { $$ = $1->addQualifiers( $2 ); }
    3440         | type_ptr
    3441         | type_array attribute_list_opt
     3582        | variable_type_ptr
     3583        | variable_type_array attribute_list_opt
    34423584                { $$ = $1->addQualifiers( $2 ); }
    3443         | type_function attribute_list_opt
     3585        | variable_type_function attribute_list_opt
    34443586                { $$ = $1->addQualifiers( $2 ); }
    34453587        ;
    34463588
    3447 type_ptr:
     3589variable_type_ptr:
    34483590        ptrref_operator variable_type_redeclarator
    3449                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3591                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    34503592        | ptrref_operator type_qualifier_list variable_type_redeclarator
    34513593                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3452         | '(' type_ptr ')' attribute_list_opt                           // redundant parenthesis
     3594        | '(' variable_type_ptr ')' attribute_list_opt          // redundant parenthesis
    34533595                { $$ = $2->addQualifiers( $4 ); }
    3454         | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis
     3596        | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis
    34553597                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    34563598        ;
    34573599
    3458 type_array:
     3600variable_type_array:
    34593601        paren_type array_dimension
    34603602                { $$ = $1->addArray( $2 ); }
    3461         | '(' type_ptr ')' array_dimension
     3603        | '(' variable_type_ptr ')' array_dimension
    34623604                { $$ = $2->addArray( $4 ); }
    3463         | '(' attribute_list type_ptr ')' array_dimension
     3605        | '(' attribute_list variable_type_ptr ')' array_dimension
    34643606                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3465         | '(' type_array ')' multi_array_dimension                      // redundant parenthesis
     3607        | '(' variable_type_array ')' multi_array_dimension     // redundant parenthesis
    34663608                { $$ = $2->addArray( $4 ); }
    3467         | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis
     3609        | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis
    34683610                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3469         | '(' type_array ')'                                                            // redundant parenthesis
     3611        | '(' variable_type_array ')'                                           // redundant parenthesis
    34703612                { $$ = $2; }
    3471         | '(' attribute_list type_array ')'                                     // redundant parenthesis
     3613        | '(' attribute_list variable_type_array ')'            // redundant parenthesis
    34723614                { $$ = $3->addQualifiers( $2 ); }
    34733615        ;
    34743616
    3475 type_function:
     3617variable_type_function:
     3618        '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3619                { $$ = $2->addParamList( $6 ); }
     3620        | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3621                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
     3622        | '(' variable_type_function ')'                                        // redundant parenthesis
     3623                { $$ = $2; }
     3624        | '(' attribute_list variable_type_function ')'         // redundant parenthesis
     3625                { $$ = $3->addQualifiers( $2 ); }
     3626        ;
     3627
     3628// This pattern parses a declaration for a function prototype that redefines a type name.  It precludes declaring an
     3629// array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to
     3630// arrays and functions.
     3631
     3632function_type_redeclarator:
     3633        function_type_no_ptr attribute_list_opt
     3634                { $$ = $1->addQualifiers( $2 ); }
     3635        | function_type_ptr
     3636        | function_type_array attribute_list_opt
     3637                { $$ = $1->addQualifiers( $2 ); }
     3638        ;
     3639
     3640function_type_no_ptr:
    34763641        paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    34773642                { $$ = $1->addParamList( $4 ); }
    3478         | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3643        | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    34793644                { $$ = $2->addParamList( $6 ); }
    3480         | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3645        | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    34813646                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3482         | '(' type_function ')'                                                         // redundant parenthesis
     3647        | '(' function_type_no_ptr ')'                                          // redundant parenthesis
    34833648                { $$ = $2; }
    3484         | '(' attribute_list type_function ')'                          // redundant parenthesis
     3649        | '(' attribute_list function_type_no_ptr ')'           // redundant parenthesis
     3650                { $$ = $3->addQualifiers( $2 ); }
     3651        ;
     3652
     3653function_type_ptr:
     3654        ptrref_operator function_type_redeclarator
     3655                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3656        | ptrref_operator type_qualifier_list function_type_redeclarator
     3657                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     3658        | '(' function_type_ptr ')' attribute_list_opt
     3659                { $$ = $2->addQualifiers( $4 ); }
     3660        | '(' attribute_list function_type_ptr ')' attribute_list_opt
     3661                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
     3662        ;
     3663
     3664function_type_array:
     3665        '(' function_type_ptr ')' array_dimension
     3666                { $$ = $2->addArray( $4 ); }
     3667        | '(' attribute_list function_type_ptr ')' array_dimension
     3668                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
     3669        | '(' function_type_array ')' multi_array_dimension     // redundant parenthesis
     3670                { $$ = $2->addArray( $4 ); }
     3671        | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis
     3672                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
     3673        | '(' function_type_array ')'                                           // redundant parenthesis
     3674                { $$ = $2; }
     3675        | '(' attribute_list function_type_array ')'            // redundant parenthesis
    34853676                { $$ = $3->addQualifiers( $2 ); }
    34863677        ;
     
    35053696identifier_parameter_ptr:
    35063697        ptrref_operator identifier_parameter_declarator
    3507                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3698                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    35083699        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    35093700                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35623753type_parameter_ptr:
    35633754        ptrref_operator type_parameter_redeclarator
    3564                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3755                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    35653756        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    35663757                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36053796abstract_ptr:
    36063797        ptrref_operator
    3607                 { $$ = DeclarationNode::newPointer( 0, $1 ); }
     3798                { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
    36083799        | ptrref_operator type_qualifier_list
    36093800                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    36103801        | ptrref_operator abstract_declarator
    3611                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3802                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    36123803        | ptrref_operator type_qualifier_list abstract_declarator
    36133804                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36383829                // Only the first dimension can be empty.
    36393830        '[' ']'
    3640                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
     3831                { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
    36413832        | '[' ']' multi_array_dimension
    3642                 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); }
     3833                { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }
    36433834                // Cannot use constant_expression because of tuples => semantic check
    36443835        | '[' push assignment_expression pop ',' comma_expression ']' // CFA
    3645                 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }
     3836                { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }
    36463837                // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; }
    36473838        | '[' push array_type_list pop ']'                                      // CFA
     
    36523843array_type_list:
    36533844        basic_type_name
    3654                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3845                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    36553846        | type_name
    3656                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3847                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    36573848        | assignment_expression upupeq assignment_expression
    36583849        | array_type_list ',' basic_type_name
    3659                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    3660         | array_type_list ',' type_name 
    3661                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3850                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     3851        | array_type_list ',' type_name
     3852                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    36623853        | array_type_list ',' assignment_expression upupeq assignment_expression
    36633854        ;
     
    36683859        | ErangeUpEq
    36693860                { $$ = OperKinds::LEThan; }
    3670         ;
     3861        ;
    36713862
    36723863multi_array_dimension:
    36733864        '[' push assignment_expression pop ']'
    3674                 { $$ = DeclarationNode::newArray( $3, 0, false ); }
     3865                { $$ = DeclarationNode::newArray( $3, nullptr, false ); }
    36753866        | '[' push '*' pop ']'                                                          // C99
    36763867                { $$ = DeclarationNode::newVarArray( 0 ); }
    36773868        | multi_array_dimension '[' push assignment_expression pop ']'
    3678                 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
     3869                { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }
    36793870        | multi_array_dimension '[' push '*' pop ']'            // C99
    36803871                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
     
    37733964array_parameter_1st_dimension:
    37743965        '[' ']'
    3775                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
     3966                { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
    37763967                // multi_array_dimension handles the '[' '*' ']' case
    37773968        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    37783969                { $$ = DeclarationNode::newVarArray( $3 ); }
    37793970        | '[' push type_qualifier_list pop ']'
    3780                 { $$ = DeclarationNode::newArray( 0, $3, false ); }
     3971                { $$ = DeclarationNode::newArray( nullptr, $3, false ); }
    37813972                // multi_array_dimension handles the '[' assignment_expression ']' case
    37823973        | '[' push type_qualifier_list assignment_expression pop ']'
     
    38073998variable_abstract_ptr:
    38083999        ptrref_operator
    3809                 { $$ = DeclarationNode::newPointer( 0, $1 ); }
     4000                { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
    38104001        | ptrref_operator type_qualifier_list
    38114002                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    38124003        | ptrref_operator variable_abstract_declarator
    3813                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4004                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38144005        | ptrref_operator type_qualifier_list variable_abstract_declarator
    38154006                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38534044                // No SUE declaration in parameter list.
    38544045        ptrref_operator type_specifier_nobody
    3855                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4046                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38564047        | type_qualifier_list ptrref_operator type_specifier_nobody
    38574048                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    38584049        | ptrref_operator cfa_abstract_function
    3859                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4050                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38604051        | type_qualifier_list ptrref_operator cfa_abstract_function
    38614052                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    38624053        | ptrref_operator cfa_identifier_parameter_declarator_tuple
    3863                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4054                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38644055        | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple
    38654056                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
     
    38704061                // shift/reduce conflict with new-style empty (void) function return type.
    38714062        '[' ']' type_specifier_nobody
    3872                 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4063                { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38734064        | cfa_array_parameter_1st_dimension type_specifier_nobody
    38744065                { $$ = $2->addNewArray( $1 ); }
    38754066        | '[' ']' multi_array_dimension type_specifier_nobody
    3876                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4067                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38774068        | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody
    38784069                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    38814072
    38824073        | '[' ']' cfa_identifier_parameter_ptr
    3883                 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4074                { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38844075        | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr
    38854076                { $$ = $2->addNewArray( $1 ); }
    38864077        | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr
    3887                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4078                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38884079        | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr
    38894080                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    39414132cfa_abstract_ptr:                                                                               // CFA
    39424133        ptrref_operator type_specifier
    3943                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4134                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39444135        | type_qualifier_list ptrref_operator type_specifier
    39454136                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    39464137        | ptrref_operator cfa_abstract_function
    3947                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4138                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39484139        | type_qualifier_list ptrref_operator cfa_abstract_function
    39494140                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    39504141        | ptrref_operator cfa_abstract_declarator_tuple
    3951                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4142                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39524143        | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple
    39534144                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note: See TracChangeset for help on using the changeset viewer.