Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    r46da46b rc86b08d  
    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;
     
    5556#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
    5657
    57 #include "SynTree/Attribute.h"     // for Attribute
     58#include "SynTree/Attribute.h"                                                  // for Attribute
    5859
    5960// lex uses __null in a boolean context, it's fine.
     
    6364
    6465extern DeclarationNode * parseTree;
    65 extern LinkageSpec::Spec linkage;
     66extern ast::Linkage::Spec linkage;
    6667extern TypedefTable typedefTable;
    6768
    68 stack<LinkageSpec::Spec> linkageStack;
     69stack<ast::Linkage::Spec> linkageStack;
    6970
    7071bool appendStr( string & to, string & from ) {
     
    199200} // fieldDecl
    200201
    201 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
    202 #define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
     202#define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) )
     203#define NEW_ONE  new ExpressionNode( build_constantInteger( yylloc, *new string( "1" ) ) )
    203204#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    204205#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     
    206207#define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
    207208
    208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     209static ForCtrl * makeForCtrl(
     210                const CodeLocation & location,
     211                DeclarationNode * init,
     212                enum OperKinds compop,
     213                ExpressionNode * comp,
     214                ExpressionNode * inc ) {
     215        // Wrap both comp/inc if they are non-null.
     216        if ( comp ) comp = new ExpressionNode( build_binary_val( location,
     217                compop,
     218                new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
     219                comp ) );
     220        if ( inc ) inc = new ExpressionNode( build_binary_val( location,
     221                // choose += or -= for upto/downto
     222                compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn,
     223                new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
     224                inc ) );
     225        // The StatementNode call frees init->name, it must happen later.
     226        return new ForCtrl( new StatementNode( init ), comp, inc );
     227}
     228
     229ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    209230        if ( index->initializer ) {
    210231                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    213234                SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
    214235        } // 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 );
     236        DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) );
     237        return makeForCtrl( location, initDecl, compop, comp, inc );
    220238} // forCtrl
    221239
    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 ) ) );
     240ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     241        ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());
     242        if ( constant && (constant->rep == "0" || constant->rep == "1") ) {
     243                type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) );
    226244        } // 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 );
     245        DeclarationNode * initDecl = distAttr(
     246                DeclarationNode::newTypeof( type, true ),
     247                DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) )
     248        );
     249        return makeForCtrl( location, initDecl, compop, comp, inc );
    234250} // forCtrl
    235251
    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 );
     252ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     253        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {
     254                return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
     255        } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {
     256                if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
     257                        return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
    242258                } else {
    243259                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     
    284300        ExpressionNode * en;
    285301        DeclarationNode * decl;
    286         AggregateDecl::Aggregate aggKey;
    287         TypeDecl::Kind tclass;
     302        ast::AggregateDecl::Aggregate aggKey;
     303        ast::TypeDecl::Kind tclass;
    288304        StatementNode * sn;
    289         WaitForStmt * wfs;
    290         Expression * constant;
     305        ast::WaitForStmt * wfs;
     306    ast::WaitUntilStmt::ClauseNode * wuscn;
     307        ast::Expr * constant;
    291308        CondCtl * ifctl;
    292309        ForCtrl * fctl;
     
    298315        bool flag;
    299316        EnumHiding hide;
    300         CatchStmt::Kind catch_kind;
    301         GenericExpr * genexpr;
     317        ast::ExceptionKind catch_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
     
    407424%type<catch_kind> handler_key
    408425%type<sn> mutex_statement
    409 %type<en> when_clause                                   when_clause_opt                         waitfor                                         timeout
    410 %type<sn> waitfor_statement
    411 %type<wfs> waitfor_clause
     426%type<en> when_clause                                   when_clause_opt                         waitfor         waituntil               timeout
     427%type<sn> waitfor_statement                             waituntil_statement
     428%type<wfs> wor_waitfor_clause
     429%type<wuscn> waituntil_clause                   wand_waituntil_clause       wor_waituntil_clause
    412430
    413431// declarations
     
    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
     
    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                                                     { $$ = 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, new ExpressionNode( $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 ) ) ), new ExpressionNode( $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        ;
     
    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
    907                 { $$ = new ExpressionNode( build_cast( $3, $5, CastExpr::Return ) ); }
     931                { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
    908932        | '(' COERCE type_no_function ')' cast_expression       // CFA
    909933                { SemanticError( yylloc, "Coerce 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        ;
     
    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 StatementNode( build_default( yylloc ) ); }
    12511274                // A semantic check is required to ensure only one default clause per switch/choose statement.
    12521275        | DEFAULT error                                                                         //  syntax error
     
    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                { $$ = (StatementNode *)( $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                { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); }
     1688        | '(' wor_waituntil_clause ')'
     1689                { $$ = $2; }
     1690        ;
     1691
     1692wand_waituntil_clause:
     1693        waituntil_clause                                                                        %prec THEN
     1694                { $$ = $1; }
     1695        | waituntil_clause wand wand_waituntil_clause
     1696                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); }
     1697        ;
     1698
     1699wor_waituntil_clause:
     1700        wand_waituntil_clause
     1701                { $$ = $1; }
     1702        | wor_waituntil_clause wor wand_waituntil_clause
     1703                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); }
     1704        | wor_waituntil_clause wor when_clause_opt ELSE statement
     1705                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
     1706        | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
     1707                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); }
     1708        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
     1709        | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
     1710                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
     1711        | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
     1712                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1,
     1713                new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR,
     1714                    build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ),
     1715                    build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); }
     1716        ;
     1717
     1718waituntil_statement:
     1719        wor_waituntil_clause                                                            %prec THEN
     1720                // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
     1721                {
     1722            $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) );
     1723            // $$ = new StatementNode( build_compound( yylloc, nullptr ) );
     1724        }
    16431725        ;
    16441726
    16451727exception_statement:
    1646         TRY compound_statement handler_clause                                   %prec THEN
    1647                 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
     1728        TRY compound_statement handler_clause                                   %prec THEN
     1729                { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
    16481730        | TRY compound_statement finally_clause
    1649                 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }
     1731                { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
    16501732        | TRY compound_statement handler_clause finally_clause
    1651                 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
     1733                { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
    16521734        ;
    16531735
    16541736handler_clause:
    16551737        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1656                 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
     1738                { $$ = new StatementNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
    16571739        | 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 ) ) ); }
     1740                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
    16591741        ;
    16601742
     
    16661748
    16671749handler_key:
    1668         CATCH                                                                           { $$ = CatchStmt::Terminate; }
    1669         | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
    1670         | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
    1671         | FIXUP                                                                         { $$ = CatchStmt::Resume; }
     1750        CATCH                                                                           { $$ = ast::Terminate; }
     1751        | RECOVER                                                                       { $$ = ast::Terminate; }
     1752        | CATCHRESUME                                                           { $$ = ast::Resume; }
     1753        | FIXUP                                                                         { $$ = ast::Resume; }
    16721754        ;
    16731755
    16741756finally_clause:
    1675         FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
     1757        FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( yylloc, $2 ) ); }
    16761758        ;
    16771759
     
    16991781asm_statement:
    17001782        ASM asm_volatile_opt '(' string_literal ')' ';'
    1701                 { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); }
     1783                { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
    17021784        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1703                 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
     1785                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
    17041786        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1705                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
     1787                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
    17061788        | 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 ) ); }
     1789                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
    17081790        | 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 ) ); }
     1791                { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
    17101792        ;
    17111793
     
    17311813asm_operand:                                                                                    // GCC
    17321814        string_literal '(' constant_expression ')'
    1733                 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     1815                { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); }
    17341816        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1735                 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); }
     1817                {
     1818                        $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, $4, maybeMoveBuild( $6 ) ) );
     1819                        delete $2.str;
     1820                }
    17361821        ;
    17371822
     
    17481833        identifier
    17491834                {
    1750                         $$ = new LabelNode(); $$->labels.push_back( *$1 );
     1835                        $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
    17511836                        delete $1;                                                                      // allocated by lexer
    17521837                }
    17531838        | label_list ',' identifier
    17541839                {
    1755                         $$ = $1; $1->labels.push_back( *$3 );
     1840                        $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
    17561841                        delete $3;                                                                      // allocated by lexer
    17571842                }
     
    18041889                {
    18051890                        // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" );
    1806                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     1891                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    18071892                        //   printf( "\tattr %s\n", attr->name.c_str() );
    18081893                        // } // for
     
    18161901                { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
    18171902        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1818                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
     1903                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
    18191904
    18201905// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    18801965//      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
    18811966//              {
    1882 //                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
     1967//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );
    18831968//              }
    18841969//      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
    18851970//              {
    18861971//                      typedefTable.setNextIdentifier( *$5 );
    1887 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1972//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
    18881973//              }
    18891974//      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
    18901975//              {
    18911976//                      typedefTable.setNextIdentifier( *$5 );
    1892 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1977//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
    18931978//              }
    18941979//      | '[' ']' typegen_name
     
    19021987        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    19031988                // 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 ); }
     1989                { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
    19051990        | 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 ); }
     1991                { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
    19071992        ;
    19081993
     
    19402025                {
    19412026                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
    1942                         $$ = $3->addType( $2 )->addTypedef();
     2027                        if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) {
     2028                                SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr;
     2029                        } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
    19432030                }
    19442031        | typedef_declaration pop ',' push declarator
     
    19482035                }
    19492036        | 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                 }
     2037                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19542038        | type_specifier TYPEDEF declarator
    1955                 {
    1956                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" );
    1957                         $$ = $3->addType( $1 )->addTypedef();
    1958                 }
     2039                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19592040        | type_specifier TYPEDEF type_qualifier_list declarator
    1960                 {
    1961                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" );
    1962                         $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
    1963                 }
     2041                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19642042        ;
    19652043
     
    19682046        TYPEDEF identifier '=' assignment_expression
    19692047                {
    1970                         SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     2048                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    19712049                }
    19722050        | typedef_expression pop ',' push identifier '=' assignment_expression
    19732051                {
    1974                         SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     2052                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    19752053                }
    19762054        ;
     
    19822060        | typedef_expression                                                            // deprecated GCC, naming expression type
    19832061        | sue_declaration_specifier
     2062                {
     2063                        assert( $1->type );
     2064                        if ( $1->type->qualifiers.any() ) {                     // CV qualifiers ?
     2065                                SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr;
     2066                        }
     2067                        // enums are never empty declarations because there must have at least one enumeration.
     2068                        if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?
     2069                                SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;
     2070                        }
     2071                }
    19842072        ;
    19852073
     
    19872075                // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    19882076                // storage-class
    1989         declarator asm_name_opt initializer_opt
     2077        variable_declarator asm_name_opt initializer_opt
    19902078                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
     2079        | variable_type_redeclarator asm_name_opt initializer_opt
     2080                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
     2081
     2082        | general_function_declarator asm_name_opt
     2083                { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }
     2084        | general_function_declarator asm_name_opt '=' VOID
     2085                { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }
     2086
    19912087        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    19922088                { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
    19932089        ;
    19942090
     2091general_function_declarator:
     2092        function_type_redeclarator
     2093        | function_declarator
     2094        ;
     2095
    19952096declaration_specifier:                                                                  // type specifier + storage class
    19962097        basic_declaration_specifier
     2098        | type_declaration_specifier
    19972099        | sue_declaration_specifier
    1998         | type_declaration_specifier
     2100        | sue_declaration_specifier invalid_types
     2101                {
     2102                        SemanticError( yylloc, ::toString( "Missing ';' after end of ",
     2103                                $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),
     2104                                " declaration" ) );
     2105                        $$ = nullptr;
     2106                }
     2107        ;
     2108
     2109invalid_types:
     2110        aggregate_key
     2111        | basic_type_name
     2112        | indirect_type
    19992113        ;
    20002114
     
    20132127        basic_type_specifier
    20142128        | 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                 }
    20212129        | type_type_specifier
    20222130        ;
     
    20652173                { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); }
    20662174        | forall
     2175                { $$ = DeclarationNode::newForall( $1 ); }
    20672176        ;
    20682177
    20692178forall:
    20702179        FORALL '(' type_parameter_list ')'                                      // CFA
    2071                 { $$ = DeclarationNode::newForall( $3 ); }
     2180                { $$ = $3; }
    20722181        ;
    20732182
     
    22262335                { $$ = DeclarationNode::newTypeof( $3 ); }
    22272336        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2228                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
     2337                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
    22292338        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    22302339                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    22392348                {
    22402349                        // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2241                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2350                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    22422351                        //   printf( "\tattr %s\n", attr->name.c_str() );
    22432352                        // } // for
     
    22552364                {
    22562365                        // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2257                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2366                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    22582367                        //   printf( "\tattr %s\n", attr->name.c_str() );
    22592368                        // } // for
     
    23332442                {
    23342443                        // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2335                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2444                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23362445                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23372446                        // } // for
     
    23572466          '{' field_declaration_list_opt '}' type_parameters_opt
    23582467                {
    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
    23642468                        $$ = 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
    23692469                }
    23702470        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     
    23752475          '{' field_declaration_list_opt '}' type_parameters_opt
    23762476                {
    2377                         // printf( "AGG3\n" );
    23782477                        DeclarationNode::newFromTypedef( $3 );
    23792478                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    23862485          '{' field_declaration_list_opt '}' type_parameters_opt
    23872486                {
    2388                         // printf( "AGG4\n" );
    23892487                        DeclarationNode::newFromTypeGen( $3, nullptr );
    23902488                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    24132511                        // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
    24142512                        // 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;
     2513                        if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) {
     2514                                $$ = $3->addQualifiers( $2 );
     2515                        } else {
     2516                                $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
     2517                                $3->type->symbolic.name = nullptr;                      // copied to $$
     2518                                $3->type->symbolic.actuals = nullptr;
     2519                                delete $3;
     2520                        }
    24192521                }
    24202522        ;
     
    24272529aggregate_data:
    24282530        STRUCT vtable_opt
    2429                 { $$ = AggregateDecl::Struct; }
     2531                { $$ = ast::AggregateDecl::Struct; }
    24302532        | UNION
    2431                 { $$ = AggregateDecl::Union; }
     2533                { $$ = ast::AggregateDecl::Union; }
    24322534        | EXCEPTION                                                                                     // CFA
    2433                 { $$ = AggregateDecl::Exception; }
    2434           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2535                { $$ = ast::AggregateDecl::Exception; }
     2536          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
    24352537        ;
    24362538
    24372539aggregate_control:                                                                              // CFA
    24382540        MONITOR
    2439                 { $$ = AggregateDecl::Monitor; }
     2541                { $$ = ast::AggregateDecl::Monitor; }
    24402542        | MUTEX STRUCT
    2441                 { $$ = AggregateDecl::Monitor; }
     2543                { $$ = ast::AggregateDecl::Monitor; }
    24422544        | GENERATOR
    2443                 { $$ = AggregateDecl::Generator; }
     2545                { $$ = ast::AggregateDecl::Generator; }
    24442546        | MUTEX GENERATOR
    2445                 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2547                {
     2548                        SemanticError( yylloc, "monitor generator is currently unimplemented." );
     2549                        $$ = ast::AggregateDecl::NoAggregate;
     2550                }
    24462551        | COROUTINE
    2447                 { $$ = AggregateDecl::Coroutine; }
     2552                { $$ = ast::AggregateDecl::Coroutine; }
    24482553        | MUTEX COROUTINE
    2449                 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2554                {
     2555                        SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
     2556                        $$ = ast::AggregateDecl::NoAggregate;
     2557                }
    24502558        | THREAD
    2451                 { $$ = AggregateDecl::Thread; }
     2559                { $$ = ast::AggregateDecl::Thread; }
    24522560        | MUTEX THREAD
    2453                 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2561                {
     2562                        SemanticError( yylloc, "monitor thread is currently unimplemented." );
     2563                        $$ = ast::AggregateDecl::NoAggregate;
     2564                }
    24542565        ;
    24552566
     
    24672578                        $$ = fieldDecl( $1, $2 );
    24682579                        // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2469                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2580                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    24702581                        //   printf( "\tattr %s\n", attr->name.c_str() );
    24712582                        // } // for
     
    24732584        | EXTENSION type_specifier field_declaring_list_opt ';' // GCC
    24742585                { $$ = fieldDecl( $2, $3 ); distExt( $$ ); }
     2586        | STATIC type_specifier field_declaring_list_opt ';' // CFA
     2587                { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }
    24752588        | INLINE type_specifier field_abstract_list_opt ';'     // CFA
    24762589                {
     
    24832596                }
    24842597        | INLINE aggregate_control ';'                                          // CFA
    2485                 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
     2598                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    24862599        | typedef_declaration ';'                                                       // CFA
    24872600        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
     
    25092622                { $$ = $1->addBitfield( $2 ); }
    25102623        | variable_type_redeclarator bit_subrange_size_opt
     2624                // A semantic check is required to ensure bit_subrange only appears on integral types.
     2625                { $$ = $1->addBitfield( $2 ); }
     2626        | function_type_redeclarator bit_subrange_size_opt
    25112627                // A semantic check is required to ensure bit_subrange only appears on integral types.
    25122628                { $$ = $1->addBitfield( $2 ); }
     
    25632679                { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
    25642680        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2565                 {
    2566                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 )
     2681                {
     2682                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.any() )
    25672683                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    25682684
     
    25752691        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    25762692                {
    2577                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
     2693                        if ( $3->storageClasses.any() || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    25782694                        typedefTable.makeTypedef( *$6 );
    25792695                }
     
    26092725enum_type_nobody:                                                                               // enum - {...}
    26102726        ENUM attribute_list_opt identifier
    2611                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
     2727                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }
    26122728        | ENUM attribute_list_opt type_name
    2613                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
     2729                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }
    26142730        ;
    26152731
     
    27512867type_no_function:                                                                               // sizeof, alignof, cast (constructor)
    27522868        cfa_abstract_declarator_tuple                                           // CFA
    2753         | type_specifier
     2869        | type_specifier                                                                        // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
    27542870        | type_specifier abstract_declarator
    27552871                { $$ = $2->addType( $1 ); }
     
    27962912        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    27972913        | identifier_at ':'                                                                     // GCC, field name
    2798                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     2914                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    27992915        ;
    28002916
     
    28082924designator:
    28092925        '.' identifier_at                                                                       // C99, field name
    2810                 { $$ = new ExpressionNode( build_varref( $2 ) ); }
     2926                { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
    28112927        | '[' push assignment_expression pop ']'                        // C99, single array element
    28122928                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    28152931                { $$ = $3; }
    28162932        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2817                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); }
     2933                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
    28182934        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    28192935                { $$ = $4; }
     
    28552971                {
    28562972                        typedefTable.addToScope( *$2, TYPEDEFname, "9" );
    2857                         if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
    2858                         if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
    2859                         if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
     2973                        if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
     2974                        if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     2975                        if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
    28602976                }
    28612977          type_initializer_opt assertion_list_opt
     
    28682984                {
    28692985                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2870                         $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
     2986                        $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
    28712987                }
    28722988        // | type_specifier identifier_parameter_declarator
    28732989        | assertion_list
    2874                 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2990                { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    28752991        ;
    28762992
    28772993new_type_class:                                                                                 // CFA
    28782994        // empty
    2879                 { $$ = TypeDecl::Otype; }
     2995                { $$ = ast::TypeDecl::Otype; }
    28802996        | '&'
    2881                 { $$ = TypeDecl::Dtype; }
     2997                { $$ = ast::TypeDecl::Dtype; }
    28822998        | '*'
    2883                 { $$ = TypeDecl::DStype; }                                              // dtype + sized
     2999                { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
    28843000        // | '(' '*' ')'
    2885         //      { $$ = TypeDecl::Ftype; }
     3001        //      { $$ = ast::TypeDecl::Ftype; }
    28863002        | ELLIPSIS
    2887                 { $$ = TypeDecl::Ttype; }
     3003                { $$ = ast::TypeDecl::Ttype; }
    28883004        ;
    28893005
    28903006type_class:                                                                                             // CFA
    28913007        OTYPE
    2892                 { $$ = TypeDecl::Otype; }
     3008                { $$ = ast::TypeDecl::Otype; }
    28933009        | DTYPE
    2894                 { $$ = TypeDecl::Dtype; }
     3010                { $$ = ast::TypeDecl::Dtype; }
    28953011        | FTYPE
    2896                 { $$ = TypeDecl::Ftype; }
     3012                { $$ = ast::TypeDecl::Ftype; }
    28973013        | TTYPE
    2898                 { $$ = TypeDecl::Ttype; }
     3014                { $$ = ast::TypeDecl::Ttype; }
    28993015        ;
    29003016
     
    29223038type_list:                                                                                              // CFA
    29233039        type
    2924                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3040                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    29253041        | assignment_expression
    29263042        | type_list ',' type
    2927                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3043                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    29283044        | type_list ',' assignment_expression
    29293045                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    29503066                {
    29513067                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    2952                         $$ = DeclarationNode::newTypeDecl( $1, 0 );
     3068                        $$ = DeclarationNode::newTypeDecl( $1, nullptr );
    29533069                }
    29543070        | identifier_or_type_name '(' type_parameter_list ')'
     
    29613077trait_specifier:                                                                                // CFA
    29623078        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    2963                 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
     3079                {
     3080                        SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
     3081                        $$ = DeclarationNode::newTrait( $2, $4, nullptr );
     3082                }
     3083        | forall TRAIT identifier_or_type_name '{' '}'          // alternate
     3084                { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); }
    29643085        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    2965                 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
     3086                {
     3087                        SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
     3088                        $$ = DeclarationNode::newTrait( $2, $4, $8 );
     3089                }
     3090        | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate
     3091                { $$ = DeclarationNode::newTrait( $3, $1, $6 ); }
    29663092        ;
    29673093
     
    30223148external_definition:
    30233149        DIRECTIVE
    3024                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
     3150                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
    30253151        | declaration
     3152                {
     3153                        // Variable declarations of anonymous types requires creating a unique type-name across multiple translation
     3154                        // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is
     3155                        // disallowed at the moment.
     3156                        if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
     3157                                if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
     3158                                        SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
     3159                                } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union
     3160                                        SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;
     3161                                }
     3162                        }
     3163                }
    30263164        | IDENTIFIER IDENTIFIER
    30273165                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
     
    30433181                }
    30443182        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3045                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
     3183                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
    30463184        | EXTERN STRINGliteral
    30473185                {
    30483186                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3049                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3187                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    30503188                }
    30513189          up external_definition down
     
    30583196                {
    30593197                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3060                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3198                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    30613199                }
    30623200          '{' up external_definition_list_opt down '}'
     
    30693207        | type_qualifier_list
    30703208                {
    3071                         if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3209                        if ( $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    30723210                        if ( $1->type->forall ) forall = true;          // remember generic type
    30733211                }
     
    30753213                {
    30763214                        distQual( $5, $1 );
    3077                         forall = false;
     3215                        forall = false;
    30783216                        $$ = $5;
    30793217                }
    30803218        | declaration_qualifier_list
    30813219                {
    3082                         if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3220                        if ( $1->type && $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    30833221                        if ( $1->type && $1->type->forall ) forall = true; // remember generic type
    30843222                }
     
    30863224                {
    30873225                        distQual( $5, $1 );
    3088                         forall = false;
     3226                        forall = false;
    30893227                        $$ = $5;
    30903228                }
    30913229        | declaration_qualifier_list type_qualifier_list
    30923230                {
    3093                         if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3231                        if ( ($1->type && $1->type->qualifiers.any()) || ($2->type && $2->type->qualifiers.any()) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    30943232                        if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type
    30953233                }
     
    30973235                {
    30983236                        distQual( $6, $1->addQualifiers( $2 ) );
    3099                         forall = false;
     3237                        forall = false;
    31003238                        $$ = $6;
    31013239                }
     
    31413279                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    31423280                }
    3143         | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
     3281        | declaration_specifier function_type_redeclarator with_clause_opt compound_statement
    31443282                {
    31453283                        rebindForall( $1, $2 );
     
    31773315        | variable_type_redeclarator
    31783316        | function_declarator
     3317        | function_type_redeclarator
    31793318        ;
    31803319
    31813320subrange:
    31823321        constant_expression '~' constant_expression                     // CFA, integer subrange
    3183                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     3322                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    31843323        ;
    31853324
     
    32873426variable_ptr:
    32883427        ptrref_operator variable_declarator
    3289                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3428                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    32903429        | ptrref_operator type_qualifier_list variable_declarator
    32913430                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    33033442        | '(' attribute_list variable_ptr ')' array_dimension
    33043443                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3305         | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     3444        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
    33063445                { $$ = $2->addArray( $4 ); }
    33073446        | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis
     
    33513490function_ptr:
    33523491        ptrref_operator function_declarator
    3353                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3492                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    33543493        | ptrref_operator type_qualifier_list function_declarator
    33553494                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34033542KR_function_ptr:
    34043543        ptrref_operator KR_function_declarator
    3405                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3544                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    34063545        | ptrref_operator type_qualifier_list KR_function_declarator
    34073546                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34273566        ;
    34283567
    3429 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.:
     3568// This pattern parses a declaration for a variable that redefines a type name, e.g.:
    34303569//
    34313570//              typedef int foo;
     
    34333572//                 int foo; // redefine typedef name in new scope
    34343573//              }
    3435 //
    3436 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays
    3437 // and functions versus pointers to arrays and functions.
    34383574
    34393575paren_type:
     
    34503586        paren_type attribute_list_opt
    34513587                { $$ = $1->addQualifiers( $2 ); }
    3452         | type_ptr
    3453         | type_array attribute_list_opt
     3588        | variable_type_ptr
     3589        | variable_type_array attribute_list_opt
    34543590                { $$ = $1->addQualifiers( $2 ); }
    3455         | type_function attribute_list_opt
     3591        | variable_type_function attribute_list_opt
    34563592                { $$ = $1->addQualifiers( $2 ); }
    34573593        ;
    34583594
    3459 type_ptr:
     3595variable_type_ptr:
    34603596        ptrref_operator variable_type_redeclarator
    3461                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3597                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    34623598        | ptrref_operator type_qualifier_list variable_type_redeclarator
    34633599                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3464         | '(' type_ptr ')' attribute_list_opt                           // redundant parenthesis
     3600        | '(' variable_type_ptr ')' attribute_list_opt          // redundant parenthesis
    34653601                { $$ = $2->addQualifiers( $4 ); }
    3466         | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis
     3602        | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis
    34673603                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    34683604        ;
    34693605
    3470 type_array:
     3606variable_type_array:
    34713607        paren_type array_dimension
    34723608                { $$ = $1->addArray( $2 ); }
    3473         | '(' type_ptr ')' array_dimension
     3609        | '(' variable_type_ptr ')' array_dimension
    34743610                { $$ = $2->addArray( $4 ); }
    3475         | '(' attribute_list type_ptr ')' array_dimension
     3611        | '(' attribute_list variable_type_ptr ')' array_dimension
    34763612                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3477         | '(' type_array ')' multi_array_dimension                      // redundant parenthesis
     3613        | '(' variable_type_array ')' multi_array_dimension     // redundant parenthesis
    34783614                { $$ = $2->addArray( $4 ); }
    3479         | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis
     3615        | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis
    34803616                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3481         | '(' type_array ')'                                                            // redundant parenthesis
     3617        | '(' variable_type_array ')'                                           // redundant parenthesis
    34823618                { $$ = $2; }
    3483         | '(' attribute_list type_array ')'                                     // redundant parenthesis
     3619        | '(' attribute_list variable_type_array ')'            // redundant parenthesis
    34843620                { $$ = $3->addQualifiers( $2 ); }
    34853621        ;
    34863622
    3487 type_function:
     3623variable_type_function:
     3624        '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3625                { $$ = $2->addParamList( $6 ); }
     3626        | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3627                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
     3628        | '(' variable_type_function ')'                                        // redundant parenthesis
     3629                { $$ = $2; }
     3630        | '(' attribute_list variable_type_function ')'         // redundant parenthesis
     3631                { $$ = $3->addQualifiers( $2 ); }
     3632        ;
     3633
     3634// This pattern parses a declaration for a function prototype that redefines a type name.  It precludes declaring an
     3635// array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to
     3636// arrays and functions.
     3637
     3638function_type_redeclarator:
     3639        function_type_no_ptr attribute_list_opt
     3640                { $$ = $1->addQualifiers( $2 ); }
     3641        | function_type_ptr
     3642        | function_type_array attribute_list_opt
     3643                { $$ = $1->addQualifiers( $2 ); }
     3644        ;
     3645
     3646function_type_no_ptr:
    34883647        paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    34893648                { $$ = $1->addParamList( $4 ); }
    3490         | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3649        | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    34913650                { $$ = $2->addParamList( $6 ); }
    3492         | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3651        | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    34933652                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3494         | '(' type_function ')'                                                         // redundant parenthesis
     3653        | '(' function_type_no_ptr ')'                                          // redundant parenthesis
    34953654                { $$ = $2; }
    3496         | '(' attribute_list type_function ')'                          // redundant parenthesis
     3655        | '(' attribute_list function_type_no_ptr ')'           // redundant parenthesis
     3656                { $$ = $3->addQualifiers( $2 ); }
     3657        ;
     3658
     3659function_type_ptr:
     3660        ptrref_operator function_type_redeclarator
     3661                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3662        | ptrref_operator type_qualifier_list function_type_redeclarator
     3663                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     3664        | '(' function_type_ptr ')' attribute_list_opt
     3665                { $$ = $2->addQualifiers( $4 ); }
     3666        | '(' attribute_list function_type_ptr ')' attribute_list_opt
     3667                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
     3668        ;
     3669
     3670function_type_array:
     3671        '(' function_type_ptr ')' array_dimension
     3672                { $$ = $2->addArray( $4 ); }
     3673        | '(' attribute_list function_type_ptr ')' array_dimension
     3674                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
     3675        | '(' function_type_array ')' multi_array_dimension     // redundant parenthesis
     3676                { $$ = $2->addArray( $4 ); }
     3677        | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis
     3678                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
     3679        | '(' function_type_array ')'                                           // redundant parenthesis
     3680                { $$ = $2; }
     3681        | '(' attribute_list function_type_array ')'            // redundant parenthesis
    34973682                { $$ = $3->addQualifiers( $2 ); }
    34983683        ;
     
    35173702identifier_parameter_ptr:
    35183703        ptrref_operator identifier_parameter_declarator
    3519                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3704                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    35203705        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    35213706                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35743759type_parameter_ptr:
    35753760        ptrref_operator type_parameter_redeclarator
    3576                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3761                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    35773762        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    35783763                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36173802abstract_ptr:
    36183803        ptrref_operator
    3619                 { $$ = DeclarationNode::newPointer( 0, $1 ); }
     3804                { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
    36203805        | ptrref_operator type_qualifier_list
    36213806                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    36223807        | ptrref_operator abstract_declarator
    3623                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3808                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    36243809        | ptrref_operator type_qualifier_list abstract_declarator
    36253810                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36503835                // Only the first dimension can be empty.
    36513836        '[' ']'
    3652                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
     3837                { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
    36533838        | '[' ']' multi_array_dimension
    3654                 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); }
     3839                { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }
    36553840                // Cannot use constant_expression because of tuples => semantic check
    36563841        | '[' push assignment_expression pop ',' comma_expression ']' // CFA
    3657                 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }
     3842                { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }
    36583843                // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; }
    36593844        | '[' push array_type_list pop ']'                                      // CFA
     
    36643849array_type_list:
    36653850        basic_type_name
    3666                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3851                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    36673852        | type_name
    3668                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3853                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    36693854        | assignment_expression upupeq assignment_expression
    36703855        | array_type_list ',' basic_type_name
    3671                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    3672         | array_type_list ',' type_name 
    3673                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3856                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     3857        | array_type_list ',' type_name
     3858                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    36743859        | array_type_list ',' assignment_expression upupeq assignment_expression
    36753860        ;
     
    36803865        | ErangeUpEq
    36813866                { $$ = OperKinds::LEThan; }
    3682         ;
     3867        ;
    36833868
    36843869multi_array_dimension:
    36853870        '[' push assignment_expression pop ']'
    3686                 { $$ = DeclarationNode::newArray( $3, 0, false ); }
     3871                { $$ = DeclarationNode::newArray( $3, nullptr, false ); }
    36873872        | '[' push '*' pop ']'                                                          // C99
    36883873                { $$ = DeclarationNode::newVarArray( 0 ); }
    36893874        | multi_array_dimension '[' push assignment_expression pop ']'
    3690                 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
     3875                { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }
    36913876        | multi_array_dimension '[' push '*' pop ']'            // C99
    36923877                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
     
    37853970array_parameter_1st_dimension:
    37863971        '[' ']'
    3787                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
     3972                { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
    37883973                // multi_array_dimension handles the '[' '*' ']' case
    37893974        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    37903975                { $$ = DeclarationNode::newVarArray( $3 ); }
    37913976        | '[' push type_qualifier_list pop ']'
    3792                 { $$ = DeclarationNode::newArray( 0, $3, false ); }
     3977                { $$ = DeclarationNode::newArray( nullptr, $3, false ); }
    37933978                // multi_array_dimension handles the '[' assignment_expression ']' case
    37943979        | '[' push type_qualifier_list assignment_expression pop ']'
     
    38194004variable_abstract_ptr:
    38204005        ptrref_operator
    3821                 { $$ = DeclarationNode::newPointer( 0, $1 ); }
     4006                { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
    38224007        | ptrref_operator type_qualifier_list
    38234008                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    38244009        | ptrref_operator variable_abstract_declarator
    3825                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4010                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38264011        | ptrref_operator type_qualifier_list variable_abstract_declarator
    38274012                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38654050                // No SUE declaration in parameter list.
    38664051        ptrref_operator type_specifier_nobody
    3867                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4052                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38684053        | type_qualifier_list ptrref_operator type_specifier_nobody
    38694054                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    38704055        | ptrref_operator cfa_abstract_function
    3871                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4056                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38724057        | type_qualifier_list ptrref_operator cfa_abstract_function
    38734058                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    38744059        | ptrref_operator cfa_identifier_parameter_declarator_tuple
    3875                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4060                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38764061        | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple
    38774062                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
     
    38824067                // shift/reduce conflict with new-style empty (void) function return type.
    38834068        '[' ']' type_specifier_nobody
    3884                 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4069                { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38854070        | cfa_array_parameter_1st_dimension type_specifier_nobody
    38864071                { $$ = $2->addNewArray( $1 ); }
    38874072        | '[' ']' multi_array_dimension type_specifier_nobody
    3888                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4073                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38894074        | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody
    38904075                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    38934078
    38944079        | '[' ']' cfa_identifier_parameter_ptr
    3895                 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4080                { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38964081        | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr
    38974082                { $$ = $2->addNewArray( $1 ); }
    38984083        | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr
    3899                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4084                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    39004085        | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr
    39014086                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    39534138cfa_abstract_ptr:                                                                               // CFA
    39544139        ptrref_operator type_specifier
    3955                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4140                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39564141        | type_qualifier_list ptrref_operator type_specifier
    39574142                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    39584143        | ptrref_operator cfa_abstract_function
    3959                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4144                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39604145        | type_qualifier_list ptrref_operator cfa_abstract_function
    39614146                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    39624147        | ptrref_operator cfa_abstract_declarator_tuple
    3963                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4148                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39644149        | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple
    39654150                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note: See TracChangeset for help on using the changeset viewer.