Changeset 24d6572 for src/Parser


Ignore:
Timestamp:
Jun 12, 2023, 2:45:32 PM (2 years ago)
Author:
Fangren Yu <f37yu@…>
Branches:
ast-experimental, master
Children:
62d62db
Parents:
34b4268 (diff), 251ce80 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ast-experimental

Location:
src/Parser
Files:
6 added
15 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r34b4268 r24d6572  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 12:34:05 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug  8 17:07:00 2022
    13 // Update Count     : 1185
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Apr 20 11:46:00 2023
     13// Update Count     : 1393
    1414//
     15
     16#include "DeclarationNode.h"
    1517
    1618#include <cassert>                 // for assert, assertf, strict_dynamic_cast
     
    2123#include <string>                  // for string, operator+, allocator, char...
    2224
     25#include "AST/Attribute.hpp"       // for Attribute
     26#include "AST/Copy.hpp"            // for shallowCopy
     27#include "AST/Decl.hpp"            // for Decl
     28#include "AST/Expr.hpp"            // for Expr
     29#include "AST/Print.hpp"           // for print
     30#include "AST/Stmt.hpp"            // for AsmStmt, DirectiveStmt
     31#include "AST/StorageClasses.hpp"  // for Storage::Class
     32#include "AST/Type.hpp"            // for Type
     33#include "Common/CodeLocation.h"   // for CodeLocation
     34#include "Common/Iterate.hpp"      // for reverseIterate
    2335#include "Common/SemanticError.h"  // for SemanticError
    2436#include "Common/UniqueName.h"     // for UniqueName
    25 #include "Common/utility.h"        // for maybeClone, maybeBuild, CodeLocation
    26 #include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
    27 #include "SynTree/LinkageSpec.h"   // for Spec, linkageName, Cforall
    28 #include "SynTree/Attribute.h"     // for Attribute
    29 #include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration
    30 #include "SynTree/Expression.h"    // for Expression, ConstantExpr
    31 #include "SynTree/Statement.h"     // for AsmStmt
    32 #include "SynTree/Type.h"          // for Type, Type::StorageClasses, Type::...
     37#include "Common/utility.h"        // for maybeClone
     38#include "Parser/ExpressionNode.h" // for ExpressionNode
     39#include "Parser/InitializerNode.h"// for InitializerNode
     40#include "Parser/StatementNode.h"  // for StatementNode
    3341#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
    3442#include "TypedefTable.h"          // for TypedefTable
     
    4149
    4250// These must harmonize with the corresponding DeclarationNode enumerations.
    43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "int128",
    44                                                                                                    "float", "double", "long double", "float80", "float128",
    45                                                                                                    "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" };
    46 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "NoComplexTypeNames", "_Imaginary" }; // Imaginary unsupported => parse, but make invisible and print error message
    47 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
    48 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" };
    49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" };
     51const char * DeclarationNode::basicTypeNames[] = {
     52        "void", "_Bool", "char", "int", "int128",
     53        "float", "double", "long double", "float80", "float128",
     54        "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames"
     55};
     56const char * DeclarationNode::complexTypeNames[] = {
     57        "_Complex", "NoComplexTypeNames", "_Imaginary"
     58}; // Imaginary unsupported => parse, but make invisible and print error message
     59const char * DeclarationNode::signednessNames[] = {
     60        "signed", "unsigned", "NoSignednessNames"
     61};
     62const char * DeclarationNode::lengthNames[] = {
     63        "short", "long", "long long", "NoLengthNames"
     64};
     65const char * DeclarationNode::builtinTypeNames[] = {
     66        "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames"
     67};
    5068
    5169UniqueName DeclarationNode::anonymous( "__anonymous" );
    5270
    53 extern LinkageSpec::Spec linkage;                                               // defined in parser.yy
     71extern ast::Linkage::Spec linkage;                                              // defined in parser.yy
    5472
    5573DeclarationNode::DeclarationNode() :
     
    5775
    5876//      variable.name = nullptr;
    59         variable.tyClass = TypeDecl::NUMBER_OF_KINDS;
     77        variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;
    6078        variable.assertions = nullptr;
    6179        variable.initializer = nullptr;
    6280
    63 //      attr.name = nullptr;
    64         attr.expr = nullptr;
    65         attr.type = nullptr;
    66 
    6781        assert.condition = nullptr;
    6882        assert.message = nullptr;
     
    7084
    7185DeclarationNode::~DeclarationNode() {
    72 //      delete attr.name;
    73         delete attr.expr;
    74         delete attr.type;
    75 
    7686//      delete variable.name;
    7787        delete variable.assertions;
    7888        delete variable.initializer;
    7989
    80 //      delete type;
     90//      delete type;
    8191        delete bitfieldWidth;
    8292
     
    103113        newnode->hasEllipsis = hasEllipsis;
    104114        newnode->linkage = linkage;
    105         newnode->asmName = maybeClone( asmName );
    106         cloneAll( attributes, newnode->attributes );
     115        newnode->asmName = maybeCopy( asmName );
     116        newnode->attributes = attributes;
    107117        newnode->initializer = maybeClone( initializer );
    108118        newnode->extension = extension;
     
    115125        newnode->variable.initializer = maybeClone( variable.initializer );
    116126
    117 //      newnode->attr.name = attr.name ? new string( *attr.name ) : nullptr;
    118         newnode->attr.expr = maybeClone( attr.expr );
    119         newnode->attr.type = maybeClone( attr.type );
    120 
    121127        newnode->assert.condition = maybeClone( assert.condition );
    122         newnode->assert.message = maybeClone( assert.message );
     128        newnode->assert.message = maybeCopy( assert.message );
    123129        return newnode;
    124130} // DeclarationNode::clone
     
    130136        } // if
    131137
    132         if ( linkage != LinkageSpec::Cforall ) {
    133                 os << LinkageSpec::name( linkage ) << " ";
    134         } // if
    135 
    136         storageClasses.print( os );
    137         funcSpecs.print( os );
     138        if ( linkage != ast::Linkage::Cforall ) {
     139                os << ast::Linkage::name( linkage ) << " ";
     140        } // if
     141
     142        ast::print( os, storageClasses );
     143        ast::print( os, funcSpecs );
    138144
    139145        if ( type ) {
     
    154160        } // if
    155161
    156         for ( Attribute * attr: reverseIterate( attributes ) ) {
    157                 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str();
    158         } // for
     162        if ( ! attributes.empty() ) {
     163                os << string( indent + 2, ' ' ) << "with attributes " << endl;
     164                for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) {
     165                        os << string( indent + 4, ' ' ) << attr->name.c_str() << endl;
     166                } // for
     167        } // if
    159168
    160169        os << endl;
     
    168177}
    169178
    170 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {
     179DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {
    171180        DeclarationNode * newnode = new DeclarationNode;
    172181        newnode->storageClasses = sc;
     
    174183} // DeclarationNode::newStorageClass
    175184
    176 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {
     185DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {
    177186        DeclarationNode * newnode = new DeclarationNode;
    178187        newnode->funcSpecs = fs;
     
    180189} // DeclarationNode::newFuncSpecifier
    181190
    182 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {
     191DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {
    183192        DeclarationNode * newnode = new DeclarationNode;
    184193        newnode->type = new TypeData();
     
    240249}
    241250
    242 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
     251DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    243252        DeclarationNode * newnode = new DeclarationNode;
    244253        newnode->type = new TypeData( TypeData::Aggregate );
    245254        newnode->type->aggregate.kind = kind;
    246         newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
     255        newnode->type->aggregate.anon = name == nullptr;
     256        newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
    247257        newnode->type->aggregate.actuals = actuals;
    248258        newnode->type->aggregate.fields = fields;
     
    250260        newnode->type->aggregate.tagged = false;
    251261        newnode->type->aggregate.parent = nullptr;
    252         newnode->type->aggregate.anon = name == nullptr;
    253262        return newnode;
    254263} // DeclarationNode::newAggregate
     
    257266        DeclarationNode * newnode = new DeclarationNode;
    258267        newnode->type = new TypeData( TypeData::Enum );
    259         newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
     268        newnode->type->enumeration.anon = name == nullptr;
     269        newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name;
    260270        newnode->type->enumeration.constants = constants;
    261271        newnode->type->enumeration.body = body;
    262         newnode->type->enumeration.anon = name == nullptr;
    263272        newnode->type->enumeration.typed = typed;
    264273        newnode->type->enumeration.hiding = hiding;
    265         if ( base && base->type)  {
     274        if ( base && base->type )  {
    266275                newnode->type->base = base->type;
    267276        } // if
     
    269278        return newnode;
    270279} // DeclarationNode::newEnum
    271 
    272 
    273280
    274281DeclarationNode * DeclarationNode::newName( const string * name ) {
     
    323330} // DeclarationNode::newFromTypeGen
    324331
    325 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {
     332DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {
    326333        DeclarationNode * newnode = newName( name );
    327334        newnode->type = nullptr;
     
    335342        newnode->type = new TypeData( TypeData::Aggregate );
    336343        newnode->type->aggregate.name = name;
    337         newnode->type->aggregate.kind = AggregateDecl::Trait;
     344        newnode->type->aggregate.kind = ast::AggregateDecl::Trait;
    338345        newnode->type->aggregate.params = params;
    339346        newnode->type->aggregate.fields = asserts;
     
    345352        newnode->type = new TypeData( TypeData::AggregateInst );
    346353        newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
    347         newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;
     354        newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;
    348355        newnode->type->aggInst.aggregate->aggregate.name = name;
    349356        newnode->type->aggInst.params = params;
     
    380387        newnode->type->array.dimension = size;
    381388        newnode->type->array.isStatic = isStatic;
    382         if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ConstantExpr * >() ) {
     389        if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) {
    383390                newnode->type->array.isVarLen = false;
    384391        } else {
     
    450457        DeclarationNode * newnode = new DeclarationNode;
    451458        newnode->type = nullptr;
    452         std::list< Expression * > exprs;
     459        std::vector<ast::ptr<ast::Expr>> exprs;
    453460        buildList( expr, exprs );
    454         newnode->attributes.push_back( new Attribute( *name, exprs ) );
     461        newnode->attributes.push_back(
     462                new ast::Attribute( *name, std::move( exprs ) ) );
    455463        delete name;
    456464        return newnode;
     
    469477}
    470478
    471 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) {
     479DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) {
    472480        DeclarationNode * newnode = new DeclarationNode;
    473481        newnode->assert.condition = condition;
     
    476484}
    477485
    478 
    479 void appendError( string & dst, const string & src ) {
     486static void appendError( string & dst, const string & src ) {
    480487        if ( src.empty() ) return;
    481488        if ( dst.empty() ) { dst = src; return; }
     
    484491
    485492void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
    486         const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
    487 
    488         if ( (qsrc & qdst).any() ) {                                            // duplicates ?
    489                 for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates
    490                         if ( qsrc[i] && qdst[i] ) {
    491                                 appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] );
    492                         } // if
    493                 } // for
     493        const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
     494        const ast::CV::Qualifiers duplicates = qsrc & qdst;
     495
     496        if ( duplicates.any() ) {
     497                std::stringstream str;
     498                str << "duplicate ";
     499                ast::print( str, duplicates );
     500                str << "qualifier(s)";
     501                appendError( error, str.str() );
    494502        } // for
    495503} // DeclarationNode::checkQualifiers
    496504
    497505void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
    498         if ( (funcSpecs & src->funcSpecs).any() ) {                     // duplicates ?
    499                 for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates
    500                         if ( funcSpecs[i] && src->funcSpecs[i] ) {
    501                                 appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] );
    502                         } // if
    503                 } // for
    504         } // if
    505 
    506         if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ?
    507                 if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ?
    508                         for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates
    509                                 if ( storageClasses[i] && src->storageClasses[i] ) {
    510                                         appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] );
    511                                 } // if
    512                         } // for
    513                         // src is the new item being added and has a single bit
    514                 } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ?
    515                         appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] +
    516                                                  " & " + Type::StorageClassesNames[src->storageClasses.ffs()] );
    517                         src->storageClasses.reset();                            // FIX to preserve invariant of one basic storage specifier
    518                 } // if
     506        ast::Function::Specs fsDups = funcSpecs & src->funcSpecs;
     507        if ( fsDups.any() ) {
     508                std::stringstream str;
     509                str << "duplicate ";
     510                ast::print( str, fsDups );
     511                str << "function specifier(s)";
     512                appendError( error, str.str() );
     513        } // if
     514
     515        // Skip if everything is unset.
     516        if ( storageClasses.any() && src->storageClasses.any() ) {
     517                ast::Storage::Classes dups = storageClasses & src->storageClasses;
     518                // Check for duplicates.
     519                if ( dups.any() ) {
     520                        std::stringstream str;
     521                        str << "duplicate ";
     522                        ast::print( str, dups );
     523                        str << "storage class(es)";
     524                        appendError( error, str.str() );
     525                // Check for conflicts.
     526                } else if ( !src->storageClasses.is_threadlocal_any() ) {
     527                        std::stringstream str;
     528                        str << "conflicting ";
     529                        ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) );
     530                        str << "& ";
     531                        ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) );
     532                        str << "storage classes";
     533                        appendError( error, str.str() );
     534                        // FIX to preserve invariant of one basic storage specifier
     535                        src->storageClasses.reset();
     536                }
    519537        } // if
    520538
     
    526544        storageClasses |= q->storageClasses;
    527545
    528         for ( Attribute * attr: reverseIterate( q->attributes ) ) {
    529                 attributes.push_front( attr->clone() );
    530         } // for
     546        std::vector<ast::ptr<ast::Attribute>> tmp;
     547        tmp.reserve( q->attributes.size() );
     548        for ( auto const & attr : q->attributes ) {
     549                tmp.emplace_back( ast::shallowCopy( attr.get() ) );
     550        }
     551        spliceBegin( attributes, tmp );
     552
    531553        return this;
    532554} // DeclarationNode::copySpecifiers
     
    576598
    577599        checkQualifiers( type, q->type );
    578         if ( (builtin == Zero || builtin == One) && q->type->qualifiers.val != 0 && error.length() == 0 ) {
    579                 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, Type::QualifiersNames[ilog2( q->type->qualifiers.val )], builtinTypeNames[builtin] );
     600        if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) {
     601                SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );
    580602        } // if
    581603        addQualifiersToType( q->type, type );
     
    598620        } else {
    599621                switch ( dst->kind ) {
    600                   case TypeData::Unknown:
     622                case TypeData::Unknown:
    601623                        src->qualifiers |= dst->qualifiers;
    602624                        dst = src;
    603625                        src = nullptr;
    604626                        break;
    605                   case TypeData::Basic:
     627                case TypeData::Basic:
    606628                        dst->qualifiers |= src->qualifiers;
    607629                        if ( src->kind != TypeData::Unknown ) {
     
    631653                        } // if
    632654                        break;
    633                   default:
     655                default:
    634656                        switch ( src->kind ) {
    635                           case TypeData::Aggregate:
    636                           case TypeData::Enum:
     657                        case TypeData::Aggregate:
     658                        case TypeData::Enum:
    637659                                dst->base = new TypeData( TypeData::AggregateInst );
    638660                                dst->base->aggInst.aggregate = src;
     
    643665                                src = nullptr;
    644666                                break;
    645                           default:
     667                        default:
    646668                                if ( dst->forall ) {
    647669                                        dst->forall->appendList( src->forall );
     
    714736
    715737DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
    716         if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
    717                 if ( variable.assertions ) {
    718                         variable.assertions->appendList( assertions );
    719                 } else {
    720                         variable.assertions = assertions;
    721                 } // if
    722                 return this;
     738        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
     739                if ( variable.assertions ) {
     740                        variable.assertions->appendList( assertions );
     741                } else {
     742                        variable.assertions = assertions;
     743                } // if
     744                return this;
    723745        } // if
    724746
    725747        assert( type );
    726748        switch ( type->kind ) {
    727           case TypeData::Symbolic:
     749        case TypeData::Symbolic:
    728750                if ( type->symbolic.assertions ) {
    729751                        type->symbolic.assertions->appendList( assertions );
     
    732754                } // if
    733755                break;
    734           default:
     756        default:
    735757                assert( false );
    736758        } // switch
     
    796818DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) {
    797819        if ( a ) {
    798                 for ( Attribute *attr: reverseIterate( a->attributes ) ) {
    799                         attributes.push_front( attr );
    800                 } // for
     820                spliceBegin( attributes, a->attributes );
    801821                a->attributes.clear();
    802822        } // if
     
    831851                if ( type ) {
    832852                        switch ( type->kind ) {
    833                           case TypeData::Aggregate:
    834                           case TypeData::Enum:
     853                        case TypeData::Aggregate:
     854                        case TypeData::Enum:
    835855                                p->type->base = new TypeData( TypeData::AggregateInst );
    836856                                p->type->base->aggInst.aggregate = type;
     
    841861                                break;
    842862
    843                           default:
     863                        default:
    844864                                p->type->base = type;
    845865                        } // switch
     
    863883
    864884DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) {
    865   if ( ! a ) return this;
     885        if ( ! a ) return this;
    866886        assert( a->type->kind == TypeData::Array );
    867887        TypeData * lastArray = findLast( a->type );
    868888        if ( type ) {
    869889                switch ( type->kind ) {
    870                   case TypeData::Aggregate:
    871                   case TypeData::Enum:
     890                case TypeData::Aggregate:
     891                case TypeData::Enum:
    872892                        lastArray->base = new TypeData( TypeData::AggregateInst );
    873893                        lastArray->base->aggInst.aggregate = type;
     
    877897                        lastArray->base->qualifiers |= type->qualifiers;
    878898                        break;
    879                   default:
     899                default:
    880900                        lastArray->base = type;
    881901                } // switch
     
    919939
    920940DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
    921         assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
     941        assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
    922942        variable.initializer = init;
    923943        return this;
     
    9831003}
    9841004
    985 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {
     1005// If a typedef wraps an anonymous declaration, name the inner declaration
     1006// so it has a consistent name across translation units.
     1007static void nameTypedefedDecl(
     1008                DeclarationNode * innerDecl,
     1009                const DeclarationNode * outerDecl ) {
     1010        TypeData * outer = outerDecl->type;
     1011        assert( outer );
     1012        // First make sure this is a typedef:
     1013        if ( outer->kind != TypeData::Symbolic || !outer->symbolic.isTypedef ) {
     1014                return;
     1015        }
     1016        TypeData * inner = innerDecl->type;
     1017        assert( inner );
     1018        // Always clear any CVs associated with the aggregate:
     1019        inner->qualifiers.reset();
     1020        // Handle anonymous aggregates: typedef struct { int i; } foo
     1021        if ( inner->kind == TypeData::Aggregate && inner->aggregate.anon ) {
     1022                delete inner->aggregate.name;
     1023                inner->aggregate.name = new string( "__anonymous_" + *outerDecl->name );
     1024                inner->aggregate.anon = false;
     1025                assert( outer->base );
     1026                delete outer->base->aggInst.aggregate->aggregate.name;
     1027                outer->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *outerDecl->name );
     1028                outer->base->aggInst.aggregate->aggregate.anon = false;
     1029                outer->base->aggInst.aggregate->qualifiers.reset();
     1030        // Handle anonymous enumeration: typedef enum { A, B, C } foo
     1031        } else if ( inner->kind == TypeData::Enum && inner->enumeration.anon ) {
     1032                delete inner->enumeration.name;
     1033                inner->enumeration.name = new string( "__anonymous_" + *outerDecl->name );
     1034                inner->enumeration.anon = false;
     1035                assert( outer->base );
     1036                delete outer->base->aggInst.aggregate->enumeration.name;
     1037                outer->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *outerDecl->name );
     1038                outer->base->aggInst.aggregate->enumeration.anon = false;
     1039                // No qualifiers.reset() here.
     1040        }
     1041}
     1042
     1043// This code handles a special issue with the attribute transparent_union.
     1044//
     1045//    typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union ))
     1046//
     1047// Here the attribute aligned goes with the typedef_name, so variables declared of this type are
     1048// aligned.  However, the attribute transparent_union must be moved from the typedef_name to
     1049// alias union U.  Currently, this is the only know attribute that must be moved from typedef to
     1050// alias.
     1051static void moveUnionAttribute( ast::Decl * decl, ast::UnionDecl * unionDecl ) {
     1052        if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) {
     1053                // Is the typedef alias a union aggregate?
     1054                if ( nullptr == unionDecl ) return;
     1055
     1056                // If typedef is an alias for a union, then its alias type was hoisted above and remembered.
     1057                if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) {
     1058                        auto instType = ast::mutate( unionInstType );
     1059                        // Remove all transparent_union attributes from typedef and move to alias union.
     1060                        for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) {
     1061                                assert( *attr );
     1062                                if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {
     1063                                        unionDecl->attributes.emplace_back( attr->release() );
     1064                                        attr = instType->attributes.erase( attr );
     1065                                } else {
     1066                                        attr++;
     1067                                }
     1068                        }
     1069                        typedefDecl->base = instType;
     1070                }
     1071        }
     1072}
     1073
     1074// Get the non-anonymous name of the instance type of the declaration,
     1075// if one exists.
     1076static const std::string * getInstTypeOfName( ast::Decl * decl ) {
     1077        if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
     1078                if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) {
     1079                        if ( aggr->name.find("anonymous") == std::string::npos ) {
     1080                                return &aggr->name;
     1081                        }
     1082                }
     1083        }
     1084        return nullptr;
     1085}
     1086
     1087void buildList( DeclarationNode * firstNode,
     1088                std::vector<ast::ptr<ast::Decl>> & outputList ) {
    9861089        SemanticErrorException errors;
    987         std::back_insert_iterator< std::list< Declaration * > > out( outputList );
    988 
    989         for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
     1090        std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
     1091
     1092        for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
    9901093                try {
    991                         bool extracted = false;
    992                         bool anon = false;
     1094                        bool extracted_named = false;
     1095                        ast::UnionDecl * unionDecl = nullptr;
     1096
    9931097                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
    994                                 // handle the case where a structure declaration is contained within an object or type declaration
    995                                 Declaration * decl = extr->build();
    996                                 if ( decl ) {
    997                                         // hoist the structure declaration
    998                                         decl->location = cur->location;
    999                                         * out++ = decl;
     1098                                assert( cur->type );
     1099                                nameTypedefedDecl( extr, cur );
     1100
     1101                                if ( ast::Decl * decl = extr->build() ) {
     1102                                        // Remember the declaration if it is a union aggregate ?
     1103                                        unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
     1104
     1105                                        *out++ = decl;
    10001106
    10011107                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
    1002                                         extracted = true;
    10031108                                        assert( extr->type );
    10041109                                        if ( extr->type->kind == TypeData::Aggregate ) {
    1005                                                 anon = extr->type->aggregate.anon;
     1110                                                // typedef struct { int A } B is the only case?
     1111                                                extracted_named = !extr->type->aggregate.anon;
    10061112                                        } else if ( extr->type->kind == TypeData::Enum ) {
    1007                                                 // xxx - is it useful to have an implicit anonymous enum member?
    1008                                                 anon = extr->type->enumeration.anon;
     1113                                                // typedef enum { A } B is the only case?
     1114                                                extracted_named = !extr->type->enumeration.anon;
     1115                                        } else {
     1116                                                extracted_named = true;
    10091117                                        }
    10101118                                } // if
     
    10121120                        } // if
    10131121
    1014                         Declaration * decl = cur->build();
    1015                         if ( decl ) {
    1016                                 // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.:
    1017                                 // struct S {
    1018                                 //   struct T { int x; }; // no anonymous member
    1019                                 //   struct { int y; };   // anonymous member
    1020                                 //   struct T;            // anonymous member
    1021                                 // };
    1022                                 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) {
    1023                                         if ( decl->name == "" ) {
    1024                                                 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) {
    1025                                                         if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) {
    1026                                                                 if ( aggr->name.find("anonymous") == std::string::npos ) {
    1027                                                                         if ( ! cur->get_inLine() ) {
    1028                                                                                 // temporary: warn about anonymous member declarations of named types, since
    1029                                                                                 // this conflicts with the syntax for the forward declaration of an anonymous type
    1030                                                                                 SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() );
    1031                                                                         } // if
    1032                                                                 } // if
    1033                                                         } // if
    1034                                                 } // if
    1035                                         } // if
    1036                                         decl->location = cur->location;
    1037                                         *out++ = decl;
     1122                        if ( ast::Decl * decl = cur->build() ) {
     1123                                moveUnionAttribute( decl, unionDecl );
     1124
     1125                                if ( "" == decl->name && !cur->get_inLine() ) {
     1126                                        // Don't include anonymous declaration for named aggregates,
     1127                                        // but do include them for anonymous aggregates, e.g.:
     1128                                        // struct S {
     1129                                        //   struct T { int x; }; // no anonymous member
     1130                                        //   struct { int y; };   // anonymous member
     1131                                        //   struct T;            // anonymous member
     1132                                        // };
     1133                                        if ( extracted_named ) {
     1134                                                continue;
     1135                                        }
     1136
     1137                                        if ( auto name = getInstTypeOfName( decl ) ) {
     1138                                                // Temporary: warn about anonymous member declarations of named types, since
     1139                                                // this conflicts with the syntax for the forward declaration of an anonymous type.
     1140                                                SemanticWarning( cur->location, Warning::AggrForwardDecl, name->c_str() );
     1141                                        }
    10381142                                } // if
     1143                                *out++ = decl;
    10391144                        } // if
    1040                 } catch( SemanticErrorException & e ) {
     1145                } catch ( SemanticErrorException & e ) {
    10411146                        errors.append( e );
    10421147                } // try
     
    10491154
    10501155// currently only builds assertions, function parameters, and return values
    1051 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) {
     1156void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
    10521157        SemanticErrorException errors;
    1053         std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList );
    1054 
    1055         for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
     1158        std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
     1159
     1160        for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
    10561161                try {
    1057                         Declaration * decl = cur->build();
    1058                         assert( decl );
    1059                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     1162                        ast::Decl * decl = cur->build();
     1163                        assertf( decl, "buildList: build for ast::DeclWithType." );
     1164                        if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
    10601165                                dwt->location = cur->location;
    10611166                                *out++ = dwt;
    1062                         } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
     1167                        } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {
    10631168                                // e.g., int foo(struct S) {}
    1064                                 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name );
    1065                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1066                                 obj->location = cur->location;
     1169                                auto inst = new ast::StructInstType( agg->name );
     1170                                auto obj = new ast::ObjectDecl( cur->location, "", inst );
     1171                                obj->linkage = linkage;
    10671172                                *out++ = obj;
    10681173                                delete agg;
    1069                         } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
     1174                        } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {
    10701175                                // e.g., int foo(union U) {}
    1071                                 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name );
    1072                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1073                                 obj->location = cur->location;
     1176                                auto inst = new ast::UnionInstType( agg->name );
     1177                                auto obj = new ast::ObjectDecl( cur->location,
     1178                                        "", inst, nullptr, ast::Storage::Classes(),
     1179                                        linkage );
    10741180                                *out++ = obj;
    1075                         } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
     1181                        } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {
    10761182                                // e.g., int foo(enum E) {}
    1077                                 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name );
    1078                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1079                                 obj->location = cur->location;
     1183                                auto inst = new ast::EnumInstType( agg->name );
     1184                                auto obj = new ast::ObjectDecl( cur->location,
     1185                                        "",
     1186                                        inst,
     1187                                        nullptr,
     1188                                        ast::Storage::Classes(),
     1189                                        linkage
     1190                                );
    10801191                                *out++ = obj;
     1192                        } else {
     1193                                assertf( false, "buildList: Could not convert to ast::DeclWithType." );
    10811194                        } // if
    1082                 } catch( SemanticErrorException & e ) {
     1195                } catch ( SemanticErrorException & e ) {
    10831196                        errors.append( e );
    10841197                } // try
     
    10901203} // buildList
    10911204
    1092 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) {
     1205void buildTypeList( const DeclarationNode * firstNode,
     1206                std::vector<ast::ptr<ast::Type>> & outputList ) {
    10931207        SemanticErrorException errors;
    1094         std::back_insert_iterator< std::list< Type * > > out( outputList );
    1095         const DeclarationNode * cur = firstNode;
    1096 
    1097         while ( cur ) {
     1208        std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
     1209
     1210        for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
    10981211                try {
    10991212                        * out++ = cur->buildType();
    1100                 } catch( SemanticErrorException & e ) {
     1213                } catch ( SemanticErrorException & e ) {
    11011214                        errors.append( e );
    11021215                } // try
    1103                 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
    1104         } // while
     1216        } // for
    11051217
    11061218        if ( ! errors.isEmpty() ) {
     
    11091221} // buildTypeList
    11101222
    1111 Declaration * DeclarationNode::build() const {
     1223ast::Decl * DeclarationNode::build() const {
    11121224        if ( ! error.empty() ) SemanticError( this, error + " in declaration of " );
    11131225
    11141226        if ( asmStmt ) {
    1115                 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) );
     1227                auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() );
     1228                return new ast::AsmDecl( stmt->location, stmt );
    11161229        } // if
    11171230        if ( directiveStmt ) {
    1118                 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) );
    1119         } // if
    1120 
    1121         if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
     1231                auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() );
     1232                return new ast::DirectiveDecl( stmt->location, stmt );
     1233        } // if
     1234
     1235        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
    11221236                // otype is internally converted to dtype + otype parameters
    1123                 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension };
    1124                 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
     1237                static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension };
     1238                static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
    11251239                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
    1126                 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::DStype, variable.initializer ? variable.initializer->buildType() : nullptr );
    1127                 buildList( variable.assertions, ret->get_assertions() );
     1240                ast::TypeDecl * ret = new ast::TypeDecl( location,
     1241                        *name,
     1242                        ast::Storage::Classes(),
     1243                        (ast::Type *)nullptr,
     1244                        kindMap[ variable.tyClass ],
     1245                        variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype,
     1246                        variable.initializer ? variable.initializer->buildType() : nullptr
     1247                );
     1248                buildList( variable.assertions, ret->assertions );
    11281249                return ret;
    11291250        } // if
     
    11471268                } // if
    11481269                bool isDelete = initializer && initializer->get_isDelete();
    1149                 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension );
     1270                ast::Decl * decl = buildDecl(
     1271                        type,
     1272                        name ? *name : string( "" ),
     1273                        storageClasses,
     1274                        maybeBuild( bitfieldWidth ),
     1275                        funcSpecs,
     1276                        linkage,
     1277                        asmName,
     1278                        isDelete ? nullptr : maybeBuild( initializer ),
     1279                        copy( attributes )
     1280                )->set_extension( extension );
    11501281                if ( isDelete ) {
    1151                         DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );
     1282                        auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );
    11521283                        dwt->isDeleted = true;
    11531284                }
     
    11561287
    11571288        if ( assert.condition ) {
    1158                 return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) );
     1289                auto cond = maybeBuild( assert.condition );
     1290                auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) );
     1291                return new ast::StaticAssertDecl( location, cond, msg );
    11591292        }
    11601293
     
    11671300        } // if
    11681301        if ( enumInLine ) {
    1169                 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr );
     1302                return new ast::InlineMemberDecl( location,
     1303                        *name, (ast::Type*)nullptr, storageClasses, linkage );
    11701304        } // if
    11711305        assertf( name, "ObjectDecl must a have name\n" );
    1172         return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension );
    1173 }
    1174 
    1175 Type * DeclarationNode::buildType() const {
     1306        auto ret = new ast::ObjectDecl( location,
     1307                *name,
     1308                (ast::Type*)nullptr,
     1309                maybeBuild( initializer ),
     1310                storageClasses,
     1311                linkage,
     1312                maybeBuild( bitfieldWidth )
     1313        );
     1314        ret->asmName = asmName;
     1315        ret->extension = extension;
     1316        return ret;
     1317}
     1318
     1319ast::Type * DeclarationNode::buildType() const {
    11761320        assert( type );
    11771321
    1178         if ( attr.expr ) {
    1179                 return new AttrType( buildQualifiers( type ), *name, attr.expr->build(), attributes );
    1180         } else if ( attr.type ) {
    1181                 return new AttrType( buildQualifiers( type ), *name, attr.type->buildType(), attributes );
    1182         } // if
    1183 
    11841322        switch ( type->kind ) {
    1185           case TypeData::Enum:
    1186           case TypeData::Aggregate: {
    1187                   ReferenceToType * ret = buildComAggInst( type, attributes, linkage );
    1188                   buildList( type->aggregate.actuals, ret->get_parameters() );
    1189                   return ret;
    1190           }
    1191           case TypeData::Symbolic: {
    1192                   TypeInstType * ret = new TypeInstType( buildQualifiers( type ), *type->symbolic.name, false, attributes );
    1193                   buildList( type->symbolic.actuals, ret->get_parameters() );
    1194                   return ret;
    1195           }
    1196           default:
    1197                 Type * simpletypes = typebuild( type );
    1198                 simpletypes->get_attributes() = attributes;             // copy because member is const
     1323        case TypeData::Enum:
     1324        case TypeData::Aggregate: {
     1325                ast::BaseInstType * ret =
     1326                        buildComAggInst( type, copy( attributes ), linkage );
     1327                buildList( type->aggregate.actuals, ret->params );
     1328                return ret;
     1329        }
     1330        case TypeData::Symbolic: {
     1331                ast::TypeInstType * ret = new ast::TypeInstType(
     1332                        *type->symbolic.name,
     1333                        // This is just a default, the true value is not known yet.
     1334                        ast::TypeDecl::Dtype,
     1335                        buildQualifiers( type ),
     1336                        copy( attributes ) );
     1337                buildList( type->symbolic.actuals, ret->params );
     1338                return ret;
     1339        }
     1340        default:
     1341                ast::Type * simpletypes = typebuild( type );
     1342                // copy because member is const
     1343                simpletypes->attributes = attributes;
    11991344                return simpletypes;
    12001345        } // switch
  • src/Parser/ExpressionNode.cc

    r34b4268 r24d6572  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 13:17:07 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug  7 09:18:56 2021
    13 // Update Count     : 1077
    14 //
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 11:07:00 2023
     13// Update Count     : 1083
     14//
     15
     16#include "ExpressionNode.h"
    1517
    1618#include <cassert>                 // for assert
     
    2123#include <string>                  // for string, operator+, operator==
    2224
     25#include "AST/Expr.hpp"            // for NameExpr
     26#include "AST/Type.hpp"            // for BaseType, SueInstType
    2327#include "Common/SemanticError.h"  // for SemanticError
    2428#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild, CodeLo...
    25 #include "ParseNode.h"             // for ExpressionNode, maybeMoveBuildType
    26 #include "SynTree/Constant.h"      // for Constant
    27 #include "SynTree/Declaration.h"   // for EnumDecl, StructDecl, UnionDecl
    28 #include "SynTree/Expression.h"    // for Expression, ConstantExpr, NameExpr
    29 #include "SynTree/Statement.h"     // for CompoundStmt, Statement
    30 #include "SynTree/Type.h"          // for BasicType, Type, Type::Qualifiers
     29#include "DeclarationNode.h"       // for DeclarationNode
     30#include "InitializerNode.h"       // for InitializerNode
    3131#include "parserutility.h"         // for notZeroExpr
    32 
    33 class Initializer;
    3432
    3533using namespace std;
     
    4846// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
    4947// type.
    50 
    51 extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
    5248
    5349// static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
     
    7167        size_t end = str.length() - 1;
    7268        if ( posn == end ) { type = 3; return; }                        // no length after 'l' => long
    73        
     69
    7470        string::size_type next = posn + 1;                                      // advance to length
    7571        if ( str[next] == '3' ) {                                                       // 32
     
    122118                if ( str[i] == '1' ) v |= 1;
    123119                i += 1;
    124           if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
     120                if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
    125121                v <<= 1;
    126122        } // for
    127123} // scanbin
    128124
    129 Expression * build_constantInteger( string & str ) {
    130         static const BasicType::Kind kind[2][6] = {
     125ast::Expr * build_constantInteger(
     126                const CodeLocation & location, string & str ) {
     127        static const ast::BasicType::Kind kind[2][6] = {
    131128                // short (h) must be before char (hh) because shorter type has the longer suffix
    132                 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ BasicType::LongLongSignedInt, },
    133                 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ BasicType::LongLongUnsignedInt, },
     129                { ast::BasicType::ShortSignedInt, ast::BasicType::SignedChar, ast::BasicType::SignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ ast::BasicType::LongLongSignedInt, },
     130                { ast::BasicType::ShortUnsignedInt, ast::BasicType::UnsignedChar, ast::BasicType::UnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ ast::BasicType::LongLongUnsignedInt, },
    134131        };
    135132
     
    141138        string str2( "0x0" );
    142139        unsigned long long int v, v2 = 0;                                       // converted integral value
    143         Expression * ret, * ret2;
     140        ast::Expr * ret, * ret2;
    144141
    145142        int type = -1;                                                                          // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     
    149146        // special constants
    150147        if ( str == "0" ) {
    151                 ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ) );
     148                ret = new ast::ConstantExpr( location, new ast::ZeroType(), str, 0 );
    152149                goto CLEANUP;
    153150        } // if
    154151        if ( str == "1" ) {
    155                 ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ) );
     152                ret = new ast::ConstantExpr( location, new ast::OneType(), str, 1 );
    156153                goto CLEANUP;
    157154        } // if
    158 
    159         string::size_type posn;
    160155
    161156        // 'u' can appear before or after length suffix
     
    166161        } else {
    167162                // At least one digit in integer constant, so safe to backup while looking for suffix.
    168 
    169                 posn = str.find_last_of( "pP" );                                // pointer value
    170                 if ( posn != string::npos ) { ltype = 5; str.erase( posn, 1 ); goto FINI; }
    171 
    172                 posn = str.find_last_of( "zZ" );                                // size_t
    173                 if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
    174 
    175                 posn = str.rfind( "hh" );                                               // char
    176                 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
    177 
    178                 posn = str.rfind( "HH" );                                               // char
    179                 if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
    180 
    181                 posn = str.find_last_of( "hH" );                                // short
    182                 if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; }
    183 
    184                 posn = str.find_last_of( "nN" );                                // int (natural number)
    185                 if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; }
    186 
    187                 if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; }
    188 
    189                 lnthSuffix( str, type, ltype );                                 // must be after check for "ll"
    190           FINI: ;
     163                // This declaration and the comma expressions in the conditions mimic
     164                // the declare and check pattern allowed in later compiler versions.
     165                // (Only some early compilers/C++ standards do not support it.)
     166                string::size_type posn;
     167                // pointer value
     168                if ( posn = str.find_last_of( "pP" ), posn != string::npos ) {
     169                        ltype = 5; str.erase( posn, 1 );
     170                // size_t
     171                } else if ( posn = str.find_last_of( "zZ" ), posn != string::npos ) {
     172                        Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 );
     173                // signed char
     174                } else if ( posn = str.rfind( "hh" ), posn != string::npos ) {
     175                        type = 1; str.erase( posn, 2 );
     176                // signed char
     177                } else if ( posn = str.rfind( "HH" ), posn != string::npos ) {
     178                        type = 1; str.erase( posn, 2 );
     179                // short
     180                } else if ( posn = str.find_last_of( "hH" ), posn != string::npos ) {
     181                        type = 0; str.erase( posn, 1 );
     182                // int (natural number)
     183                } else if ( posn = str.find_last_of( "nN" ), posn != string::npos ) {
     184                        type = 2; str.erase( posn, 1 );
     185                } else if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) {
     186                        type = 4;
     187                } else {
     188                        lnthSuffix( str, type, ltype );
     189                } // if
    191190        } // if
    192191
     
    196195        if ( type == 5 ) SemanticError( yylloc, "int128 constant is not supported on this target " + str );
    197196#endif // ! __SIZEOF_INT128__
    198        
     197
    199198        if ( str[0] == '0' ) {                                                          // radix character ?
    200199                dec = false;
     
    206205                                unsigned int len = str.length();
    207206                                if ( len > (2 + 16 + 16) ) SemanticError( yylloc, "128-bit hexadecimal constant to large " + str );
    208                           if ( len <= (2 + 16) ) goto FHEX1;            // hex digits < 2^64
    209                                 str2 = "0x" + str.substr( len - 16 );
    210                                 sscanf( (char *)str2.c_str(), "%llx", &v2 );
    211                                 str = str.substr( 0, len - 16 );
    212                           FHEX1: ;
     207                                // hex digits < 2^64
     208                                if ( len > (2 + 16) ) {
     209                                        str2 = "0x" + str.substr( len - 16 );
     210                                        sscanf( (char *)str2.c_str(), "%llx", &v2 );
     211                                        str = str.substr( 0, len - 16 );
     212                                } // if
    213213                                sscanf( (char *)str.c_str(), "%llx", &v );
    214214#endif // __SIZEOF_INT128__
     
    301301
    302302        // Constant type is correct for overload resolving.
    303         ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) );
     303        ret = new ast::ConstantExpr( location,
     304                new ast::BasicType( kind[Unsigned][type] ), str, v );
    304305        if ( Unsigned && type < 2 ) {                                           // hh or h, less than int ?
    305306                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
    306                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
     307                ret = new ast::CastExpr( location,
     308                        ret,
     309                        new ast::BasicType( kind[Unsigned][type] ),
     310                        ast::ExplicitCast );
    307311        } else if ( ltype != -1 ) {                                                     // explicit length ?
    308312                if ( ltype == 6 ) {                                                             // int128, (int128)constant
    309 //                      ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    310                         ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) );
    311                         ret = build_compoundLiteral( DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ),
    312                                                                                  new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) );
     313                        ret2 = new ast::ConstantExpr( location,
     314                                new ast::BasicType( ast::BasicType::LongLongSignedInt ),
     315                                str2,
     316                                v2 );
     317                        ret = build_compoundLiteral( location,
     318                                DeclarationNode::newBasicType(
     319                                        DeclarationNode::Int128
     320                                )->addType(
     321                                        DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ),
     322                                new InitializerNode(
     323                                        (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true )
     324                        );
    313325                } else {                                                                                // explicit length, (length_type)constant
    314                         ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false );
     326                        ret = new ast::CastExpr( location,
     327                                ret,
     328                                new ast::TypeInstType( lnthsInt[Unsigned][ltype], ast::TypeDecl::Dtype ),
     329                                ast::ExplicitCast );
    315330                        if ( ltype == 5 ) {                                                     // pointer, intptr( (uintptr_t)constant )
    316                                 ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) );
     331                                ret = build_func( location,
     332                                        new ExpressionNode(
     333                                                build_varref( location, new string( "intptr" ) ) ),
     334                                        new ExpressionNode( ret ) );
    317335                        } // if
    318336                } // if
     
    358376
    359377
    360 Expression * build_constantFloat( string & str ) {
    361         static const BasicType::Kind kind[2][12] = {
    362                 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x },
    363                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex },
     378ast::Expr * build_constantFloat(
     379                const CodeLocation & location, string & str ) {
     380        static const ast::BasicType::Kind kind[2][12] = {
     381                { ast::BasicType::Float, ast::BasicType::Double, ast::BasicType::LongDouble, ast::BasicType::uuFloat80, ast::BasicType::uuFloat128, ast::BasicType::uFloat16, ast::BasicType::uFloat32, ast::BasicType::uFloat32x, ast::BasicType::uFloat64, ast::BasicType::uFloat64x, ast::BasicType::uFloat128, ast::BasicType::uFloat128x },
     382                { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, ast::BasicType::NUMBER_OF_BASIC_TYPES, ast::BasicType::NUMBER_OF_BASIC_TYPES, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex },
    364383        };
    365384
     
    398417
    399418        assert( 0 <= type && type < 12 );
    400         Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) );
    401         if ( explnth ) {                                                                        // explicit length ?
    402                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false );
     419        ast::Expr * ret = new ast::ConstantExpr( location,
     420                new ast::BasicType( kind[complx][type] ),
     421                str,
     422                v );
     423        // explicit length ?
     424        if ( explnth ) {
     425                ret = new ast::CastExpr( location,
     426                        ret,
     427                        new ast::BasicType( kind[complx][type] ),
     428                        ast::ExplicitCast );
    403429        } // if
    404430
     
    415441} // sepString
    416442
    417 Expression * build_constantChar( string & str ) {
     443ast::Expr * build_constantChar( const CodeLocation & location, string & str ) {
    418444        string units;                                                                           // units
    419445        sepString( str, units, '\'' );                                          // separate constant from units
    420446
    421         Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
     447        ast::Expr * ret = new ast::ConstantExpr( location,
     448                new ast::BasicType( ast::BasicType::Char ),
     449                str,
     450                (unsigned long long int)(unsigned char)str[1] );
    422451        if ( units.length() != 0 ) {
    423                 ret = new UntypedExpr( new NameExpr( units ), { ret } );
     452                ret = new ast::UntypedExpr( location,
     453                        new ast::NameExpr( location, units ),
     454                        { ret } );
    424455        } // if
    425456
     
    428459} // build_constantChar
    429460
    430 Expression * build_constantStr( string & str ) {
     461ast::Expr * build_constantStr(
     462                const CodeLocation & location,
     463                string & str ) {
    431464        assert( str.length() > 0 );
    432465        string units;                                                                           // units
    433466        sepString( str, units, '"' );                                           // separate constant from units
    434467
    435         Type * strtype;
     468        ast::Type * strtype;
    436469        switch ( str[0] ) {                                                                     // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1
    437           case 'u':
     470        case 'u':
    438471                if ( str[1] == '8' ) goto Default;                              // utf-8 characters => array of char
    439472                // lookup type of associated typedef
    440                 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false );
     473                strtype = new ast::TypeInstType( "char16_t", ast::TypeDecl::Dtype );
    441474                break;
    442           case 'U':
    443                 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false );
     475        case 'U':
     476                strtype = new ast::TypeInstType( "char32_t", ast::TypeDecl::Dtype );
    444477                break;
    445           case 'L':
    446                 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false );
     478        case 'L':
     479                strtype = new ast::TypeInstType( "wchar_t", ast::TypeDecl::Dtype );
    447480                break;
    448           Default:                                                                                      // char default string type
    449           default:
    450                 strtype = new BasicType( Type::Qualifiers( ), BasicType::Char );
     481        Default:                                                                                        // char default string type
     482        default:
     483                strtype = new ast::BasicType( ast::BasicType::Char );
    451484        } // switch
    452         ArrayType * at = new ArrayType( noQualifiers, strtype,
    453                                                                         new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
    454                                                                         false, false );
    455         Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) );
     485        ast::ArrayType * at = new ast::ArrayType(
     486                strtype,
     487                // Length is adjusted: +1 for '\0' and -2 for '"'
     488                ast::ConstantExpr::from_ulong( location, str.size() + 1 - 2 ),
     489                ast::FixedLen,
     490                ast::DynamicDim );
     491        ast::Expr * ret = new ast::ConstantExpr( location, at, str, std::nullopt );
    456492        if ( units.length() != 0 ) {
    457                 ret = new UntypedExpr( new NameExpr( units ), { ret } );
     493                ret = new ast::UntypedExpr( location,
     494                        new ast::NameExpr( location, units ),
     495                        { ret } );
    458496        } // if
    459497
     
    462500} // build_constantStr
    463501
    464 Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
     502ast::Expr * build_field_name_FLOATING_FRACTIONconstant(
     503                const CodeLocation & location, const string & str ) {
    465504        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) SemanticError( yylloc, "invalid tuple index " + str );
    466         Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
     505        ast::Expr * ret = build_constantInteger( location,
     506                *new string( str.substr(1) ) );
    467507        delete &str;
    468508        return ret;
    469509} // build_field_name_FLOATING_FRACTIONconstant
    470510
    471 Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
     511ast::Expr * build_field_name_FLOATING_DECIMALconstant(
     512                const CodeLocation & location, const string & str ) {
    472513        if ( str[str.size() - 1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str );
    473         Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
     514        ast::Expr * ret = build_constantInteger(
     515                location, *new string( str.substr( 0, str.size()-1 ) ) );
    474516        delete &str;
    475517        return ret;
    476518} // build_field_name_FLOATING_DECIMALconstant
    477519
    478 Expression * build_field_name_FLOATINGconstant( const string & str ) {
     520ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation & location,
     521                const string & str ) {
    479522        // str is of the form A.B -> separate at the . and return member expression
    480523        int a, b;
     
    482525        stringstream ss( str );
    483526        ss >> a >> dot >> b;
    484         UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
     527        auto ret = new ast::UntypedMemberExpr( location,
     528                ast::ConstantExpr::from_int( location, b ),
     529                ast::ConstantExpr::from_int( location, a )
     530        );
    485531        delete &str;
    486532        return ret;
    487533} // build_field_name_FLOATINGconstant
    488534
    489 Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) {
    490         if ( fracts ) {
    491                 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) {
    492                         memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) );
    493                         return memberExpr;
    494                 } else {
    495                         return new UntypedMemberExpr( fracts, fieldName );
    496                 } // if
    497         } // if
    498         return fieldName;
     535ast::Expr * make_field_name_fraction_constants( const CodeLocation & location,
     536                ast::Expr * fieldName,
     537                ast::Expr * fracts ) {
     538        if ( nullptr == fracts ) {
     539                return fieldName;
     540        } else if ( auto memberExpr = dynamic_cast<ast::UntypedMemberExpr *>( fracts ) ) {
     541                memberExpr->member = make_field_name_fraction_constants( location,
     542                        fieldName,
     543                        ast::mutate( memberExpr->aggregate.get() ) );
     544                return memberExpr;
     545        } else {
     546                return new ast::UntypedMemberExpr( location, fracts, fieldName );
     547        } // if
    499548} // make_field_name_fraction_constants
    500549
    501 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) {
    502         return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
     550ast::Expr * build_field_name_fraction_constants( const CodeLocation & location,
     551                ast::Expr * fieldName,
     552                ExpressionNode * fracts ) {
     553        return make_field_name_fraction_constants( location, fieldName, maybeMoveBuild( fracts ) );
    503554} // build_field_name_fraction_constants
    504555
    505 NameExpr * build_varref( const string * name ) {
    506         NameExpr * expr = new NameExpr( *name );
     556ast::NameExpr * build_varref( const CodeLocation & location,
     557                const string * name ) {
     558        ast::NameExpr * expr = new ast::NameExpr( location, *name );
    507559        delete name;
    508560        return expr;
    509561} // build_varref
    510562
    511 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) {
    512         Declaration * newDecl = maybeBuild< Declaration >(decl_node);
    513         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) {
    514                 const Type * t = newDeclWithType->get_type();
    515                 if ( t ) {
    516                         if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) {
    517                                 newDecl= new EnumDecl( typeInst->name );
     563ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location,
     564                const DeclarationNode * decl_node,
     565                const ast::NameExpr * name ) {
     566        ast::Decl * newDecl = maybeBuild( decl_node );
     567        if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) {
     568                if ( const ast::Type * t = newDeclWithType->get_type() ) {
     569                        if ( auto typeInst = dynamic_cast<const ast::TypeInstType *>( t ) ) {
     570                                newDecl = new ast::EnumDecl( location, typeInst->name );
    518571                        }
    519572                }
    520573        }
    521         return new QualifiedNameExpr( newDecl, name->name );
     574        return new ast::QualifiedNameExpr( location, newDecl, name->name );
    522575}
    523576
    524 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) {
    525         EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node );
    526         return new QualifiedNameExpr( newDecl, name->name );
     577ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location,
     578                const ast::EnumDecl * decl,
     579                const ast::NameExpr * name ) {
     580        return new ast::QualifiedNameExpr( location, decl, name->name );
    527581}
    528582
    529 DimensionExpr * build_dimensionref( const string * name ) {
    530         DimensionExpr * expr = new DimensionExpr( *name );
     583ast::DimensionExpr * build_dimensionref( const CodeLocation & location,
     584                const string * name ) {
     585        ast::DimensionExpr * expr = new ast::DimensionExpr( location, *name );
    531586        delete name;
    532587        return expr;
     
    544599}; // OperName
    545600
    546 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node, CastExpr::CastKind kind ) {
    547         Type * targetType = maybeMoveBuildType( decl_node );
    548         if ( dynamic_cast< VoidType * >( targetType ) ) {
     601ast::Expr * build_cast( const CodeLocation & location,
     602                DeclarationNode * decl_node,
     603                ExpressionNode * expr_node,
     604                ast::CastExpr::CastKind kind ) {
     605        ast::Type * targetType = maybeMoveBuildType( decl_node );
     606        if ( dynamic_cast<ast::VoidType *>( targetType ) ) {
    549607                delete targetType;
    550                 return new CastExpr( maybeMoveBuild< Expression >(expr_node), false, kind );
     608                return new ast::CastExpr( location,
     609                        maybeMoveBuild( expr_node ),
     610                        ast::ExplicitCast, kind );
    551611        } else {
    552                 return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType, false, kind );
     612                return new ast::CastExpr( location,
     613                        maybeMoveBuild( expr_node ),
     614                        targetType,
     615                        ast::ExplicitCast, kind );
    553616        } // if
    554617} // build_cast
    555618
    556 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) {
    557         return new KeywordCastExpr( maybeMoveBuild< Expression >(expr_node), target );
     619ast::Expr * build_keyword_cast( const CodeLocation & location,
     620                ast::AggregateDecl::Aggregate target,
     621                ExpressionNode * expr_node ) {
     622        return new ast::KeywordCastExpr( location,
     623                maybeMoveBuild( expr_node ),
     624                target
     625        );
    558626}
    559627
    560 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
    561         return new VirtualCastExpr( maybeMoveBuild< Expression >( expr_node ), maybeMoveBuildType( decl_node ) );
     628ast::Expr * build_virtual_cast( const CodeLocation & location,
     629                DeclarationNode * decl_node,
     630                ExpressionNode * expr_node ) {
     631        return new ast::VirtualCastExpr( location,
     632                maybeMoveBuild( expr_node ),
     633                maybeMoveBuildType( decl_node )
     634        );
    562635} // build_virtual_cast
    563636
    564 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) {
    565         return new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) );
     637ast::Expr * build_fieldSel( const CodeLocation & location,
     638                ExpressionNode * expr_node,
     639                ast::Expr * member ) {
     640        return new ast::UntypedMemberExpr( location,
     641                member,
     642                maybeMoveBuild( expr_node )
     643        );
    566644} // build_fieldSel
    567645
    568 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) {
    569         UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
     646ast::Expr * build_pfieldSel( const CodeLocation & location,
     647                ExpressionNode * expr_node,
     648                ast::Expr * member ) {
     649        auto deref = new ast::UntypedExpr( location,
     650                new ast::NameExpr( location, "*?" )
     651        );
    570652        deref->location = expr_node->location;
    571         deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) );
    572         UntypedMemberExpr * ret = new UntypedMemberExpr( member, deref );
     653        deref->args.push_back( maybeMoveBuild( expr_node ) );
     654        auto ret = new ast::UntypedMemberExpr( location, member, deref );
    573655        return ret;
    574656} // build_pfieldSel
    575657
    576 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) {
    577         Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() );
     658ast::Expr * build_offsetOf( const CodeLocation & location,
     659                DeclarationNode * decl_node,
     660                ast::NameExpr * member ) {
     661        ast::Expr * ret = new ast::UntypedOffsetofExpr( location,
     662                maybeMoveBuildType( decl_node ),
     663                member->name
     664        );
     665        ret->result = new ast::BasicType( ast::BasicType::LongUnsignedInt );
    578666        delete member;
    579667        return ret;
    580668} // build_offsetOf
    581669
    582 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ) {
    583         return new LogicalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), notZeroExpr( maybeMoveBuild< Expression >(expr_node2) ), kind );
     670ast::Expr * build_and_or( const CodeLocation & location,
     671                ExpressionNode * expr_node1,
     672                ExpressionNode * expr_node2,
     673                ast::LogicalFlag flag ) {
     674        return new ast::LogicalExpr( location,
     675                notZeroExpr( maybeMoveBuild( expr_node1 ) ),
     676                notZeroExpr( maybeMoveBuild( expr_node2 ) ),
     677                flag
     678        );
    584679} // build_and_or
    585680
    586 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) {
    587         list< Expression * > args;
    588         args.push_back( maybeMoveBuild< Expression >(expr_node) );
    589         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     681ast::Expr * build_unary_val( const CodeLocation & location,
     682                OperKinds op,
     683                ExpressionNode * expr_node ) {
     684        std::vector<ast::ptr<ast::Expr>> args;
     685        args.push_back( maybeMoveBuild( expr_node ) );
     686        return new ast::UntypedExpr( location,
     687                new ast::NameExpr( location, OperName[ (int)op ] ),
     688                std::move( args )
     689        );
    590690} // build_unary_val
    591691
    592 Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) {
    593         list< Expression * > args;
    594         args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
    595         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    596 } // build_unary_ptr
    597 
    598 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    599         list< Expression * > args;
    600         args.push_back( maybeMoveBuild< Expression >(expr_node1) );
    601         args.push_back( maybeMoveBuild< Expression >(expr_node2) );
    602         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     692ast::Expr * build_binary_val( const CodeLocation & location,
     693                OperKinds op,
     694                ExpressionNode * expr_node1,
     695                ExpressionNode * expr_node2 ) {
     696        std::vector<ast::ptr<ast::Expr>> args;
     697        args.push_back( maybeMoveBuild( expr_node1 ) );
     698        args.push_back( maybeMoveBuild( expr_node2 ) );
     699        return new ast::UntypedExpr( location,
     700                new ast::NameExpr( location, OperName[ (int)op ] ),
     701                std::move( args )
     702        );
    603703} // build_binary_val
    604704
    605 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    606         list< Expression * > args;
    607         args.push_back( maybeMoveBuild< Expression >(expr_node1) );
    608         args.push_back( maybeMoveBuild< Expression >(expr_node2) );
    609         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
    610 } // build_binary_ptr
    611 
    612 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ) {
    613         return new ConditionalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), maybeMoveBuild< Expression >(expr_node2), maybeMoveBuild< Expression >(expr_node3) );
     705ast::Expr * build_cond( const CodeLocation & location,
     706                ExpressionNode * expr_node1,
     707                ExpressionNode * expr_node2,
     708                ExpressionNode * expr_node3 ) {
     709        return new ast::ConditionalExpr( location,
     710                notZeroExpr( maybeMoveBuild( expr_node1 ) ),
     711                maybeMoveBuild( expr_node2 ),
     712                maybeMoveBuild( expr_node3 )
     713        );
    614714} // build_cond
    615715
    616 Expression * build_tuple( ExpressionNode * expr_node ) {
    617         list< Expression * > exprs;
     716ast::Expr * build_tuple( const CodeLocation & location,
     717                ExpressionNode * expr_node ) {
     718        std::vector<ast::ptr<ast::Expr>> exprs;
    618719        buildMoveList( expr_node, exprs );
    619         return new UntypedTupleExpr( exprs );;
     720        return new ast::UntypedTupleExpr( location, std::move( exprs ) );
    620721} // build_tuple
    621722
    622 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
    623         list< Expression * > args;
     723ast::Expr * build_func( const CodeLocation & location,
     724                ExpressionNode * function,
     725                ExpressionNode * expr_node ) {
     726        std::vector<ast::ptr<ast::Expr>> args;
    624727        buildMoveList( expr_node, args );
    625         return new UntypedExpr( maybeMoveBuild< Expression >(function), args );
     728        return new ast::UntypedExpr( location,
     729                maybeMoveBuild( function ),
     730                std::move( args )
     731        );
    626732} // build_func
    627733
    628 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ) {
    629         Declaration * newDecl = maybeBuild< Declaration >(decl_node); // compound literal type
    630         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
    631                 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild< Initializer >(kids) );
     734ast::Expr * build_compoundLiteral( const CodeLocation & location,
     735                DeclarationNode * decl_node,
     736                InitializerNode * kids ) {
     737        // compound literal type
     738        ast::Decl * newDecl = maybeBuild( decl_node );
     739        // non-sue compound-literal type
     740        if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) {
     741                return new ast::CompoundLiteralExpr( location,
     742                        newDeclWithType->get_type(),
     743                        maybeMoveBuild( kids ) );
    632744        // these types do not have associated type information
    633         } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
    634                 if ( newDeclStructDecl->has_body() ) {
    635                         return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild< Initializer >(kids) );
     745        } else if ( auto newDeclStructDecl = dynamic_cast<ast::StructDecl *>( newDecl ) ) {
     746                if ( newDeclStructDecl->body ) {
     747                        return new ast::CompoundLiteralExpr( location,
     748                                new ast::StructInstType( newDeclStructDecl ),
     749                                maybeMoveBuild( kids ) );
    636750                } else {
    637                         return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
    638                 } // if
    639         } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
    640                 if ( newDeclUnionDecl->has_body() ) {
    641                         return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild< Initializer >(kids) );
     751                        return new ast::CompoundLiteralExpr( location,
     752                                new ast::StructInstType( newDeclStructDecl->name ),
     753                                maybeMoveBuild( kids ) );
     754                } // if
     755        } else if ( auto newDeclUnionDecl = dynamic_cast<ast::UnionDecl *>( newDecl )  ) {
     756                if ( newDeclUnionDecl->body ) {
     757                        return new ast::CompoundLiteralExpr( location,
     758                                new ast::UnionInstType( newDeclUnionDecl ),
     759                                maybeMoveBuild( kids ) );
    642760                } else {
    643                         return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
    644                 } // if
    645         } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
    646                 if ( newDeclEnumDecl->has_body() ) {
    647                         return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild< Initializer >(kids) );
     761                        return new ast::CompoundLiteralExpr( location,
     762                                new ast::UnionInstType( newDeclUnionDecl->name ),
     763                                maybeMoveBuild( kids ) );
     764                } // if
     765        } else if ( auto newDeclEnumDecl = dynamic_cast<ast::EnumDecl *>( newDecl )  ) {
     766                if ( newDeclEnumDecl->body ) {
     767                        return new ast::CompoundLiteralExpr( location,
     768                                new ast::EnumInstType( newDeclEnumDecl ),
     769                                maybeMoveBuild( kids ) );
    648770                } else {
    649                         return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
     771                        return new ast::CompoundLiteralExpr( location,
     772                                new ast::EnumInstType( newDeclEnumDecl->name ),
     773                                maybeMoveBuild( kids ) );
    650774                } // if
    651775        } else {
     
    656780// Local Variables: //
    657781// tab-width: 4 //
    658 // mode: c++ //
    659 // compile-command: "make install" //
    660782// End: //
  • src/Parser/InitializerNode.cc

    r34b4268 r24d6572  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:20:24 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 28 23:27:20 2017
    13 // Update Count     : 26
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 11:18:00 2023
     13// Update Count     : 27
    1414//
     15
     16#include "InitializerNode.h"
    1517
    1618#include <iostream>                // for operator<<, ostream, basic_ostream
     
    1820#include <string>                  // for operator<<, string
    1921
     22#include "AST/Expr.hpp"            // for Expr
     23#include "AST/Init.hpp"            // for Designator, Init, ListInit, Sing...
     24#include "Common/SemanticError.h"  // for SemanticError
     25#include "Common/utility.h"        // for maybeBuild
     26#include "ExpressionNode.h"        // for ExpressionNode
     27#include "DeclarationNode.h"       // for buildList
     28
    2029using namespace std;
    2130
    22 #include "Common/SemanticError.h"  // for SemanticError
    23 #include "Common/utility.h"        // for maybeBuild
    24 #include "ParseNode.h"             // for InitializerNode, ExpressionNode
    25 #include "SynTree/Expression.h"    // for Expression
    26 #include "SynTree/Initializer.h"   // for Initializer, ListInit, SingleInit
     31static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) {
     32        return maybeConstructed ? ast::MaybeConstruct : ast::NoConstruct;
     33}
    2734
    2835InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des )
     
    3340        if ( kids )
    3441                set_last( nullptr );
    35 } // InitializerNode::InitializerNode
     42} // InitializerNode::InitializerNode
    3643
    3744InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des )
     
    8592} // InitializerNode::printOneLine
    8693
    87 Initializer * InitializerNode::build() const {
     94ast::Init * InitializerNode::build() const {
    8895        assertf( ! isDelete, "Should not build delete stmt InitializerNode" );
    8996        if ( aggregate ) {
    9097                // steal designators from children
    91                 std::list< Designation * > designlist;
     98                std::vector<ast::ptr<ast::Designation>> designlist;
    9299                InitializerNode * child = next_init();
    93                 for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
    94                         std::list< Expression * > desList;
    95                         buildList< Expression, ExpressionNode >( child->designator, desList );
    96                         designlist.push_back( new Designation( desList ) );
     100                for ( ; child != nullptr ; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
     101                        std::deque<ast::ptr<ast::Expr>> desList;
     102                        buildList( child->designator, desList );
     103                        designlist.push_back(
     104                                new ast::Designation( location, std::move( desList ) ) );
    97105                } // for
    98                 std::list< Initializer * > initlist;
    99                 buildList< Initializer, InitializerNode >( next_init(), initlist );
    100                 return new ListInit( initlist, designlist, maybeConstructed );
    101         } else {
    102                 if ( get_expression() ) {
    103                         assertf( get_expression()->expr, "The expression of initializer must have value" );
    104                         return new SingleInit( maybeBuild< Expression >( get_expression() ), maybeConstructed );
    105                 } // if
     106                std::vector<ast::ptr<ast::Init>> initlist;
     107                buildList( next_init(), initlist );
     108                return new ast::ListInit( location,
     109                        std::move( initlist ),
     110                        std::move( designlist ),
     111                        toConstructFlag( maybeConstructed )
     112                );
     113        } else if ( get_expression() ) {
     114                assertf( get_expression()->expr, "The expression of initializer must have value" );
     115                return new ast::SingleInit( location,
     116                        maybeBuild( get_expression() ),
     117                        toConstructFlag( maybeConstructed )
     118                );
    106119        } // if
    107120        return nullptr;
  • src/Parser/ParseNode.h

    r34b4268 r24d6572  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:28:16 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Nov  2 21:27:07 2022
    13 // Update Count     : 939
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Apr  3 17:55:00 2023
     13// Update Count     : 942
    1414//
    1515
     
    2424#include <string>                  // for string
    2525
     26#include "AST/Expr.hpp"            // for Expr, NameExpr LogicalFlag
     27#include "AST/Fwd.hpp"             // for ptr, Decl, DeclWithType,
     28#include "AST/Stmt.hpp"            // for Stmt
    2629#include "Common/CodeLocation.h"   // for CodeLocation
    2730#include "Common/SemanticError.h"  // for SemanticError
    2831#include "Common/UniqueName.h"     // for UniqueName
    29 #include "Common/utility.h"        // for maybeClone, maybeBuild
    30 #include "SynTree/LinkageSpec.h"   // for Spec
    31 #include "SynTree/Declaration.h"   // for Aggregate
    32 #include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
    33 #include "SynTree/Label.h"         // for Label
    34 #include "SynTree/Statement.h"     // for Statement, BranchStmt, BranchStmt:...
    35 #include "SynTree/Type.h"          // for Type, Type::FuncSpecifiers, Type::...
     32#include "Common/utility.h"        // for maybeClone
     33#include "Parser/parserutility.h"  // for maybeBuild, maybeCopy
    3634
    3735class Attribute;
     
    4038class DeclarationWithType;
    4139class Initializer;
     40class InitializerNode;
    4241class ExpressionNode;
    4342struct StatementNode;
     
    8281}; // ParseNode
    8382
    84 //##############################################################################
    85 
    86 class InitializerNode : public ParseNode {
    87   public:
    88         InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );
    89         InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );
    90         InitializerNode( bool isDelete );
    91         ~InitializerNode();
    92         virtual InitializerNode * clone() const { assert( false ); return nullptr; }
    93 
    94         ExpressionNode * get_expression() const { return expr; }
    95 
    96         InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }
    97         ExpressionNode * get_designators() const { return designator; }
    98 
    99         InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
    100         bool get_maybeConstructed() const { return maybeConstructed; }
    101 
    102         bool get_isDelete() const { return isDelete; }
    103 
    104         InitializerNode * next_init() const { return kids; }
    105 
    106         void print( std::ostream & os, int indent = 0 ) const;
    107         void printOneLine( std::ostream & ) const;
    108 
    109         virtual Initializer * build() const;
    110   private:
    111         ExpressionNode * expr;
    112         bool aggregate;
    113         ExpressionNode * designator;                                            // may be list
    114         InitializerNode * kids;
    115         bool maybeConstructed;
    116         bool isDelete;
    117 }; // InitializerNode
    118 
    119 //##############################################################################
    120 
    121 class ExpressionNode final : public ParseNode {
    122   public:
    123         ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
    124         virtual ~ExpressionNode() {}
    125         virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
    126 
    127         bool get_extension() const { return extension; }
    128         ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
    129 
    130         virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
    131                 os << expr.get();
    132         }
    133         void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
    134 
    135         template<typename T>
    136         bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
    137 
    138         Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
    139 
    140         std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
    141   private:
    142         bool extension = false;
    143 }; // ExpressionNode
    144 
    145 template< typename T >
    146 struct maybeBuild_t< Expression, T > {
    147         static inline Expression * doit( const T * orig ) {
    148                 if ( orig ) {
    149                         Expression * p = orig->build();
    150                         p->set_extension( orig->get_extension() );
    151                         p->location = orig->location;
    152                         return p;
    153                 } else {
    154                         return nullptr;
    155                 } // if
    156         }
    157 };
    158 
    15983// Must harmonize with OperName.
    16084enum class OperKinds {
     
    17296
    17397struct LabelNode {
    174         std::list< Label > labels;
     98        std::vector<ast::Label> labels;
    17599};
    176100
    177 Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
    178 Expression * build_constantFloat( std::string & str );
    179 Expression * build_constantChar( std::string & str );
    180 Expression * build_constantStr( std::string & str );
    181 Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
    182 Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
    183 Expression * build_field_name_FLOATINGconstant( const std::string & str );
    184 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
    185 
    186 NameExpr * build_varref( const std::string * name );
    187 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
    188 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
    189 DimensionExpr * build_dimensionref( const std::string * name );
    190 
    191 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node, CastExpr::CastKind kind = CastExpr::Default );
    192 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
    193 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
    194 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
    195 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
    196 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
    197 Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    198 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
    199 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
    200 Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node );
    201 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    202 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    203 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
    204 Expression * build_tuple( ExpressionNode * expr_node = nullptr );
    205 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
    206 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
    207 
    208 //##############################################################################
    209 
    210 struct TypeData;
    211 
    212 struct DeclarationNode : public ParseNode {
    213         // These enumerations must harmonize with their names in DeclarationNode.cc.
    214         enum BasicType { Void, Bool, Char, Int, Int128,
    215                                          Float, Double, LongDouble, uuFloat80, uuFloat128,
    216                                          uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
    217         static const char * basicTypeNames[];
    218         enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
    219         static const char * complexTypeNames[];
    220         enum Signedness { Signed, Unsigned, NoSignedness };
    221         static const char * signednessNames[];
    222         enum Length { Short, Long, LongLong, NoLength };
    223         static const char * lengthNames[];
    224         enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
    225         static const char * builtinTypeNames[];
    226 
    227         static DeclarationNode * newStorageClass( Type::StorageClasses );
    228         static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
    229         static DeclarationNode * newTypeQualifier( Type::Qualifiers );
    230         static DeclarationNode * newBasicType( BasicType );
    231         static DeclarationNode * newComplexType( ComplexType );
    232         static DeclarationNode * newSignedNess( Signedness );
    233         static DeclarationNode * newLength( Length );
    234         static DeclarationNode * newBuiltinType( BuiltinType );
    235         static DeclarationNode * newForall( DeclarationNode * );
    236         static DeclarationNode * newFromTypedef( const std::string * );
    237         static DeclarationNode * newFromGlobalScope();
    238         static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
    239         static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    240         static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
    241         static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
    242         static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
    243         static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
    244         static DeclarationNode * newEnumInLine( const std::string name );
    245         static DeclarationNode * newName( const std::string * );
    246         static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
    247         static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
    248         static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
    249         static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
    250         static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
    251         static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
    252         static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
    253         static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
    254         static DeclarationNode * newBitfield( ExpressionNode * size );
    255         static DeclarationNode * newTuple( DeclarationNode * members );
    256         static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
    257         static DeclarationNode * newVtableType( DeclarationNode * expr );
    258         static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
    259         static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
    260         static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
    261         static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
    262 
    263         DeclarationNode();
    264         ~DeclarationNode();
    265         DeclarationNode * clone() const override;
    266 
    267         DeclarationNode * addQualifiers( DeclarationNode * );
    268         void checkQualifiers( const TypeData *, const TypeData * );
    269         void checkSpecifiers( DeclarationNode * );
    270         DeclarationNode * copySpecifiers( DeclarationNode * );
    271         DeclarationNode * addType( DeclarationNode * );
    272         DeclarationNode * addTypedef();
    273         DeclarationNode * addEnumBase( DeclarationNode * );
    274         DeclarationNode * addAssertions( DeclarationNode * );
    275         DeclarationNode * addName( std::string * );
    276         DeclarationNode * addAsmName( DeclarationNode * );
    277         DeclarationNode * addBitfield( ExpressionNode * size );
    278         DeclarationNode * addVarArgs();
    279         DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
    280         DeclarationNode * addOldDeclList( DeclarationNode * list );
    281         DeclarationNode * setBase( TypeData * newType );
    282         DeclarationNode * copyAttribute( DeclarationNode * attr );
    283         DeclarationNode * addPointer( DeclarationNode * qualifiers );
    284         DeclarationNode * addArray( DeclarationNode * array );
    285         DeclarationNode * addNewPointer( DeclarationNode * pointer );
    286         DeclarationNode * addNewArray( DeclarationNode * array );
    287         DeclarationNode * addParamList( DeclarationNode * list );
    288         DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
    289         DeclarationNode * addInitializer( InitializerNode * init );
    290         DeclarationNode * addTypeInitializer( DeclarationNode * init );
    291 
    292         DeclarationNode * cloneType( std::string * newName );
    293         DeclarationNode * cloneBaseType( DeclarationNode * newdecl );
    294 
    295         DeclarationNode * appendList( DeclarationNode * node ) {
    296                 return (DeclarationNode *)set_last( node );
    297         }
    298 
    299         virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
    300         virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
    301 
    302         Declaration * build() const;
    303         Type * buildType() const;
    304 
    305         LinkageSpec::Spec get_linkage() const { return linkage; }
    306         DeclarationNode * extractAggregate() const;
    307         bool has_enumeratorValue() const { return (bool)enumeratorValue; }
    308         ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
    309 
    310         bool get_extension() const { return extension; }
    311         DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
    312 
    313         bool get_inLine() const { return inLine; }
    314         DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
    315 
    316         DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
    317 
    318         struct Variable_t {
    319 //              const std::string * name;
    320                 TypeDecl::Kind tyClass;
    321                 DeclarationNode * assertions;
    322                 DeclarationNode * initializer;
    323         };
    324         Variable_t variable;
    325 
    326         struct Attr_t {
    327 //              const std::string * name;
    328                 ExpressionNode * expr;
    329                 DeclarationNode * type;
    330         };
    331         Attr_t attr;
    332 
    333         struct StaticAssert_t {
    334                 ExpressionNode * condition;
    335                 Expression * message;
    336         };
    337         StaticAssert_t assert;
    338 
    339         BuiltinType builtin = NoBuiltinType;
    340 
    341         TypeData * type = nullptr;
    342 
    343         bool inLine = false;
    344         bool enumInLine = false;
    345         Type::FuncSpecifiers funcSpecs;
    346         Type::StorageClasses storageClasses;
    347 
    348         ExpressionNode * bitfieldWidth = nullptr;
    349         std::unique_ptr<ExpressionNode> enumeratorValue;
    350         bool hasEllipsis = false;
    351         LinkageSpec::Spec linkage;
    352         Expression * asmName = nullptr;
    353         std::list< Attribute * > attributes;
    354         InitializerNode * initializer = nullptr;
    355         bool extension = false;
    356         std::string error;
    357         StatementNode * asmStmt = nullptr;
    358         StatementNode * directiveStmt = nullptr;
    359 
    360         static UniqueName anonymous;
    361 }; // DeclarationNode
    362 
    363 Type * buildType( TypeData * type );
    364 
    365 static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
    366         Type * ret = orig ? orig->buildType() : nullptr;
    367         delete orig;
    368         return ret;
    369 }
    370 
    371 //##############################################################################
    372 
    373 struct StatementNode final : public ParseNode {
    374         StatementNode() { stmt = nullptr; }
    375         StatementNode( Statement * stmt ) : stmt( stmt ) {}
    376         StatementNode( DeclarationNode * decl );
    377         virtual ~StatementNode() {}
    378 
    379         virtual StatementNode * clone() const final { assert( false ); return nullptr; }
    380         Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
    381 
    382         virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
    383                 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
    384                 delete attr;
    385                 delete name;
    386                 return this;
    387         }
    388 
    389         virtual StatementNode * append_last_case( StatementNode * );
    390 
    391         virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
    392                 os << stmt.get() << std::endl;
    393         }
    394 
    395         std::unique_ptr<Statement> stmt;
    396 }; // StatementNode
    397 
    398 Statement * build_expr( ExpressionNode * ctl );
    399 
    400 struct CondCtl {
    401         CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :
    402                 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
    403 
    404         StatementNode * init;
    405         ExpressionNode * condition;
    406 };
    407 
    408 struct ForCtrl {
    409         ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
    410                 init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
    411         ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
    412                 init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
    413 
    414         StatementNode * init;
    415         ExpressionNode * condition;
    416         ExpressionNode * change;
    417 };
    418 
    419 Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
    420 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
    421 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
    422 Statement * build_case( ExpressionNode * ctl );
    423 Statement * build_default();
    424 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    425 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    426 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    427 Statement * build_branch( BranchStmt::Type kind );
    428 Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
    429 Statement * build_computedgoto( ExpressionNode * ctl );
    430 Statement * build_return( ExpressionNode * ctl );
    431 Statement * build_throw( ExpressionNode * ctl );
    432 Statement * build_resume( ExpressionNode * ctl );
    433 Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
    434 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
    435 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
    436 Statement * build_finally( StatementNode * stmt );
    437 Statement * build_compound( StatementNode * first );
    438 StatementNode * maybe_build_compound( StatementNode * first );
    439 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
    440 Statement * build_directive( std::string * directive );
    441 SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
    442 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
    443 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
    444 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
    445 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
    446 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
    447 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
    448 
    449 //##############################################################################
    450 
    451 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
    452 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
    453         SemanticErrorException errors;
    454         std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
    455         const NodeType * cur = firstNode;
    456 
    457         while ( cur ) {
    458                 try {
    459                         SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild< typename std::pointer_traits< decltype(cur->build())>::element_type >( cur ) );
    460                         if ( result ) {
    461                                 result->location = cur->location;
    462                                 * out++ = result;
    463                         } else {
    464                                 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
    465                         } // if
    466                 } catch( SemanticErrorException & e ) {
    467                         errors.append( e );
    468                 } // try
    469                 const ParseNode * temp = (cur->get_next());
    470                 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
    471                 if ( ! cur && temp ) {                                                  // non-homogeneous nodes ?
    472                         SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
    473                 } // if
    474         } // while
    475         if ( ! errors.isEmpty() ) {
    476                 throw errors;
    477         } // if
    478 }
    479 
    480 // in DeclarationNode.cc
    481 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
    482 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
    483 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
    484 
    485 template< typename SynTreeType, typename NodeType >
    486 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
    487         buildList( firstNode, outputList );
    488         delete firstNode;
    489 }
    490 
    491 // in ParseNode.cc
    492101std::ostream & operator<<( std::ostream & out, const ParseNode * node );
    493102
  • src/Parser/ParserTypes.h

    r34b4268 r24d6572  
    44// The contents of this file are covered under the licence agreement in the
    55// file "LICENCE" distributed with Cforall.
    6 // 
    7 // parser.hh -- 
    8 // 
     6//
     7// parser.hh --
     8//
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep 22 08:58:10 2001
  • src/Parser/StatementNode.cc

    r34b4268 r24d6572  
    1010// Author           : Rodolfo G. Esteves
    1111// Created On       : Sat May 16 14:59:41 2015
    12 // Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Feb  2 20:29:30 2022
    14 // Update Count     : 425
     12// Last Modified By : Andrew Beach
     13// Last Modified On : Tue Apr 11 10:16:00 2023
     14// Update Count     : 428
    1515//
    1616
     17#include "StatementNode.h"
     18
    1719#include <cassert>                 // for assert, strict_dynamic_cast, assertf
    18 #include <list>                    // for list
    1920#include <memory>                  // for unique_ptr
    2021#include <string>                  // for string
    2122
     23#include "AST/Label.hpp"           // for Label
     24#include "AST/Stmt.hpp"            // for Stmt, AsmStmt, BranchStmt, CaseCla...
    2225#include "Common/SemanticError.h"  // for SemanticError
    2326#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild
    24 #include "ParseNode.h"             // for StatementNode, ExpressionNode, bui...
    25 #include "SynTree/Expression.h"    // for Expression, ConstantExpr
    26 #include "SynTree/Label.h"         // for Label, noLabels
    27 #include "SynTree/Declaration.h"
    28 #include "SynTree/Statement.h"     // for Statement, BranchStmt, CaseStmt
     27#include "DeclarationNode.h"       // for DeclarationNode
     28#include "ExpressionNode.h"        // for ExpressionNode
    2929#include "parserutility.h"         // for notZeroExpr
    3030
     
    3333using namespace std;
    3434
     35// Some helpers for cases that really want a single node but check for lists.
     36static const ast::Stmt * buildMoveSingle( StatementNode * node ) {
     37        std::vector<ast::ptr<ast::Stmt>> list;
     38        buildMoveList( node, list );
     39        assertf( list.size() == 1, "CFA Internal Error: Extra/Missing Nodes" );
     40        return list.front().release();
     41}
     42
     43static const ast::Stmt * buildMoveOptional( StatementNode * node ) {
     44        std::vector<ast::ptr<ast::Stmt>> list;
     45        buildMoveList( node, list );
     46        assertf( list.size() <= 1, "CFA Internal Error: Extra Nodes" );
     47        return list.empty() ? nullptr : list.front().release();
     48}
    3549
    3650StatementNode::StatementNode( DeclarationNode * decl ) {
     
    3852        DeclarationNode * agg = decl->extractAggregate();
    3953        if ( agg ) {
    40                 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild< Declaration >( decl ) ) );
     54                StatementNode * nextStmt = new StatementNode(
     55                        new ast::DeclStmt( decl->location, maybeBuild( decl ) ) );
    4156                set_next( nextStmt );
    4257                if ( decl->get_next() ) {
     
    5166                agg = decl;
    5267        } // if
    53         stmt.reset( new DeclStmt( maybeMoveBuild< Declaration >(agg) ) );
     68        // Local copy to avoid accessing the pointer after it is moved from.
     69        CodeLocation declLocation = agg->location;
     70        stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) );
    5471} // StatementNode::StatementNode
    5572
    56 StatementNode * StatementNode::append_last_case( StatementNode * stmt ) {
    57         StatementNode * prev = this;
     73StatementNode * StatementNode::add_label(
     74                const CodeLocation & location,
     75                const std::string * name,
     76                DeclarationNode * attr ) {
     77        stmt->labels.emplace_back( location,
     78                *name,
     79                attr ? std::move( attr->attributes )
     80                        : std::vector<ast::ptr<ast::Attribute>>{} );
     81        delete attr;
     82        delete name;
     83        return this;
     84}
     85
     86ClauseNode * ClauseNode::append_last_case( StatementNode * stmt ) {
     87        ClauseNode * prev = this;
    5888        // find end of list and maintain previous pointer
    59         for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {
    60                 StatementNode * node = strict_dynamic_cast< StatementNode * >(curr);
    61                 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) );
     89        for ( ClauseNode * curr = prev; curr != nullptr; curr = (ClauseNode *)curr->get_next() ) {
     90                ClauseNode * node = strict_dynamic_cast< ClauseNode * >(curr);
     91                assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) );
    6292                prev = curr;
    6393        } // for
     94        ClauseNode * node = dynamic_cast< ClauseNode * >(prev);
    6495        // convert from StatementNode list to Statement list
    65         StatementNode * node = dynamic_cast< StatementNode * >(prev);
    66         list< Statement * > stmts;
     96        std::vector<ast::ptr<ast::Stmt>> stmts;
    6797        buildMoveList( stmt, stmts );
    6898        // splice any new Statements to end of current Statements
    69         CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get());
    70         caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts );
     99        auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() );
     100        for ( auto const & newStmt : stmts ) {
     101                caseStmt->stmts.emplace_back( newStmt );
     102        }
     103        stmts.clear();
    71104        return this;
    72 } // StatementNode::append_last_case
    73 
    74 Statement * build_expr( ExpressionNode * ctl ) {
    75         Expression * e = maybeMoveBuild< Expression >( ctl );
    76 
    77         if ( e ) return new ExprStmt( e );
    78         else return new NullStmt();
     105} // ClauseNode::append_last_case
     106
     107ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) {
     108        if ( ast::Expr * e = maybeMoveBuild( ctl ) ) {
     109                return new ast::ExprStmt( location, e );
     110        } else {
     111                return new ast::NullStmt( location );
     112        }
    79113} // build_expr
    80114
    81 Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) {
    82         if ( ctl->init != 0 ) {
    83                 buildMoveList( ctl->init, init );
     115static ast::Expr * build_if_control( CondCtl * ctl,
     116                std::vector<ast::ptr<ast::Stmt>> & inits ) {
     117        assert( inits.empty() );
     118        if ( nullptr != ctl->init ) {
     119                buildMoveList( ctl->init, inits );
    84120        } // if
    85121
    86         Expression * cond = nullptr;
     122        ast::Expr * cond = nullptr;
    87123        if ( ctl->condition ) {
    88124                // compare the provided condition against 0
    89                 cond = notZeroExpr( maybeMoveBuild< Expression >(ctl->condition) );
     125                cond = notZeroExpr( maybeMoveBuild( ctl->condition ) );
    90126        } else {
    91                 for ( Statement * stmt : init ) {
     127                for ( ast::ptr<ast::Stmt> & stmt : inits ) {
    92128                        // build the && of all of the declared variables compared against 0
    93                         DeclStmt * declStmt = strict_dynamic_cast< DeclStmt * >( stmt );
    94                         DeclarationWithType * dwt = strict_dynamic_cast< DeclarationWithType * >( declStmt->decl );
    95                         Expression * nze = notZeroExpr( new VariableExpr( dwt ) );
    96                         cond = cond ? new LogicalExpr( cond, nze, true ) : nze;
     129                        auto declStmt = stmt.strict_as<ast::DeclStmt>();
     130                        auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();
     131                        ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) );
     132                        cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze;
    97133                }
    98134        }
     
    101137} // build_if_control
    102138
    103 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
    104         list< Statement * > astinit;                                            // maybe empty
    105         Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    106 
    107         Statement * astthen, * astelse = nullptr;
    108         list< Statement * > aststmt;
    109         buildMoveList< Statement, StatementNode >( then, aststmt );
    110         assert( aststmt.size() == 1 );
    111         astthen = aststmt.front();
    112 
    113         if ( else_ ) {
    114                 list< Statement * > aststmt;
    115                 buildMoveList< Statement, StatementNode >( else_, aststmt );
    116                 assert( aststmt.size() == 1 );
    117                 astelse = aststmt.front();
    118         } // if
    119 
    120         return new IfStmt( astcond, astthen, astelse, astinit );
     139ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
     140        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     141        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
     142
     143        ast::Stmt const * astthen = buildMoveSingle( then );
     144        ast::Stmt const * astelse = buildMoveOptional( else_ );
     145
     146        return new ast::IfStmt( location, astcond, astthen, astelse,
     147                std::move( astinit )
     148        );
    121149} // build_if
    122150
    123 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
    124         list< Statement * > aststmt;
    125         buildMoveList< Statement, StatementNode >( stmt, aststmt );
    126         if ( ! isSwitch ) {                                                                     // choose statement
    127                 for ( Statement * stmt : aststmt ) {
    128                         CaseStmt * caseStmt = strict_dynamic_cast< CaseStmt * >( stmt );
    129                         if ( ! caseStmt->stmts.empty() ) {                      // code after "case" => end of case list
    130                                 CompoundStmt * block = strict_dynamic_cast< CompoundStmt * >( caseStmt->stmts.front() );
    131                                 block->kids.push_back( new BranchStmt( "", BranchStmt::Break ) );
     151ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, ClauseNode * stmt ) {
     152        std::vector<ast::ptr<ast::CaseClause>> aststmt;
     153        buildMoveList( stmt, aststmt );
     154        // If it is not a switch it is a choose statement.
     155        if ( ! isSwitch ) {
     156                for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) {
     157                        // Code after "case" is the end of case list.
     158                        if ( !stmt->stmts.empty() ) {
     159                                auto mutStmt = ast::mutate( stmt.get() );
     160                                // I believe the stmts are actually always one block.
     161                                auto stmts = mutStmt->stmts.front().get_and_mutate();
     162                                auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts );
     163                                block->kids.push_back( new ast::BranchStmt( block->location,
     164                                        ast::BranchStmt::Break,
     165                                        ast::Label( block->location ) ) );
     166                                stmt = mutStmt;
    132167                        } // if
    133168                } // for
    134169        } // if
    135170        // aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements
    136         return new SwitchStmt( maybeMoveBuild< Expression >(ctl), aststmt );
     171        return new ast::SwitchStmt( location,
     172                maybeMoveBuild( ctl ), std::move( aststmt ) );
    137173} // build_switch
    138174
    139 Statement * build_case( ExpressionNode * ctl ) {
    140         return new CaseStmt( maybeMoveBuild< Expression >(ctl), {} ); // stmt starts empty and then added to
     175ast::CaseClause * build_case( const CodeLocation & location, ExpressionNode * ctl ) {
     176        // stmt starts empty and then added to
     177        auto expr = maybeMoveBuild( ctl );
     178        return new ast::CaseClause( location, expr, {} );
    141179} // build_case
    142180
    143 Statement * build_default() {
    144         return new CaseStmt( nullptr, {}, true );                       // stmt starts empty and then added to
     181ast::CaseClause * build_default( const CodeLocation & location ) {
     182        // stmt starts empty and then added to
     183        return new ast::CaseClause( location, nullptr, {} );
    145184} // build_default
    146185
    147 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
    148         list< Statement * > astinit;                                            // maybe empty
    149         Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    150 
    151         list< Statement * > aststmt;                                            // loop body, compound created if empty
    152         buildMoveList< Statement, StatementNode >( stmt, aststmt );
    153         assert( aststmt.size() == 1 );
    154 
    155         list< Statement * > astelse;                                            // else clause, maybe empty
    156         buildMoveList< Statement, StatementNode >( else_, astelse );
    157 
    158         return new WhileDoStmt( astcond, aststmt.front(), astelse.front(), astinit, false );
     186ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
     187        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     188        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
     189
     190        return new ast::WhileDoStmt( location,
     191                astcond,
     192                buildMoveSingle( stmt ),
     193                buildMoveOptional( else_ ),
     194                std::move( astinit ),
     195                ast::While
     196        );
    159197} // build_while
    160198
    161 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
    162         list< Statement * > aststmt;                                            // loop body, compound created if empty
    163         buildMoveList< Statement, StatementNode >( stmt, aststmt );
    164         assert( aststmt.size() == 1 );                                          // compound created if empty
    165 
    166         list< Statement * > astelse;                                            // else clause, maybe empty
    167         buildMoveList< Statement, StatementNode >( else_, astelse );
    168 
     199ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
    169200        // do-while cannot have declarations in the contitional, so init is always empty
    170         return new WhileDoStmt( notZeroExpr( maybeMoveBuild< Expression >(ctl) ), aststmt.front(), astelse.front(), {}, true );
     201        return new ast::WhileDoStmt( location,
     202                notZeroExpr( maybeMoveBuild( ctl ) ),
     203                buildMoveSingle( stmt ),
     204                buildMoveOptional( else_ ),
     205                {},
     206                ast::DoWhile
     207        );
    171208} // build_do_while
    172209
    173 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
    174         list< Statement * > astinit;                                            // maybe empty
     210ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
     211        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
    175212        buildMoveList( forctl->init, astinit );
    176213
    177         Expression * astcond = nullptr;                                         // maybe empty
    178         astcond = notZeroExpr( maybeMoveBuild< Expression >(forctl->condition) );
    179 
    180         Expression * astincr = nullptr;                                         // maybe empty
    181         astincr = maybeMoveBuild< Expression >(forctl->change);
     214        ast::Expr * astcond = nullptr;                                          // maybe empty
     215        astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) );
     216
     217        ast::Expr * astincr = nullptr;                                          // maybe empty
     218        astincr = maybeMoveBuild( forctl->change );
    182219        delete forctl;
    183220
    184         list< Statement * > aststmt;                                            // loop body, compound created if empty
    185         buildMoveList< Statement, StatementNode >( stmt, aststmt );
    186         assert( aststmt.size() == 1 );
    187 
    188         list< Statement * > astelse;                                            // else clause, maybe empty
    189         buildMoveList< Statement, StatementNode >( else_, astelse );
    190 
    191         return new ForStmt( astinit, astcond, astincr, aststmt.front(), astelse.front() );
     221        return new ast::ForStmt( location,
     222                std::move( astinit ),
     223                astcond,
     224                astincr,
     225                buildMoveSingle( stmt ),
     226                buildMoveOptional( else_ )
     227        );
    192228} // build_for
    193229
    194 Statement * build_branch( BranchStmt::Type kind ) {
    195         Statement * ret = new BranchStmt( "", kind );
    196         return ret;
     230ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) {
     231        return new ast::BranchStmt( location,
     232                kind,
     233                ast::Label( location )
     234        );
    197235} // build_branch
    198236
    199 Statement * build_branch( string * identifier, BranchStmt::Type kind ) {
    200         Statement * ret = new BranchStmt( * identifier, kind );
     237ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) {
     238        ast::Stmt * ret = new ast::BranchStmt( location,
     239                kind,
     240                ast::Label( location, *identifier )
     241        );
    201242        delete identifier;                                                                      // allocated by lexer
    202243        return ret;
    203244} // build_branch
    204245
    205 Statement * build_computedgoto( ExpressionNode * ctl ) {
    206         return new BranchStmt( maybeMoveBuild< Expression >(ctl), BranchStmt::Goto );
     246ast::Stmt * build_computedgoto( ExpressionNode * ctl ) {
     247        ast::Expr * expr = maybeMoveBuild( ctl );
     248        return new ast::BranchStmt( expr->location, expr );
    207249} // build_computedgoto
    208250
    209 Statement * build_return( ExpressionNode * ctl ) {
    210         list< Expression * > exps;
     251ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) {
     252        std::vector<ast::ptr<ast::Expr>> exps;
    211253        buildMoveList( ctl, exps );
    212         return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr );
     254        return new ast::ReturnStmt( location,
     255                exps.size() > 0 ? exps.back().release() : nullptr
     256        );
    213257} // build_return
    214258
    215 Statement * build_throw( ExpressionNode * ctl ) {
    216         list< Expression * > exps;
     259static ast::Stmt * build_throw_stmt(
     260                const CodeLocation & location,
     261                ExpressionNode * ctl,
     262                ast::ExceptionKind kind ) {
     263        std::vector<ast::ptr<ast::Expr>> exps;
    217264        buildMoveList( ctl, exps );
    218265        assertf( exps.size() < 2, "CFA internal error: leaking memory" );
    219         return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
     266        return new ast::ThrowStmt( location,
     267                kind,
     268                !exps.empty() ? exps.back().release() : nullptr,
     269                (ast::Expr *)nullptr
     270        );
     271}
     272
     273ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) {
     274        return build_throw_stmt( loc, ctl, ast::Terminate );
    220275} // build_throw
    221276
    222 Statement * build_resume( ExpressionNode * ctl ) {
    223         list< Expression * > exps;
    224         buildMoveList( ctl, exps );
    225         assertf( exps.size() < 2, "CFA internal error: leaking memory" );
    226         return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
     277ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) {
     278        return build_throw_stmt( loc, ctl, ast::Resume );
    227279} // build_resume
    228280
    229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
     281ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
    230282        (void)ctl;
    231283        (void)target;
     
    233285} // build_resume_at
    234286
    235 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
    236         list< CatchStmt * > aststmt;
    237         buildMoveList< CatchStmt, StatementNode >( catch_, aststmt );
    238         CompoundStmt * tryBlock = strict_dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(try_));
    239         FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >(maybeMoveBuild< Statement >(finally_) );
    240         return new TryStmt( tryBlock, aststmt, finallyBlock );
     287ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, ClauseNode * catch_, ClauseNode * finally_ ) {
     288        std::vector<ast::ptr<ast::CatchClause>> aststmt;
     289        buildMoveList( catch_, aststmt );
     290        ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) );
     291        ast::FinallyClause * finallyBlock = nullptr;
     292        if ( finally_ ) {
     293                finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() );
     294        }
     295        return new ast::TryStmt( location,
     296                tryBlock,
     297                std::move( aststmt ),
     298                finallyBlock
     299        );
    241300} // build_try
    242301
    243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
    244         list< Statement * > aststmt;
    245         buildMoveList< Statement, StatementNode >( body, aststmt );
    246         assert( aststmt.size() == 1 );
    247         return new CatchStmt( kind, maybeMoveBuild< Declaration >(decl), maybeMoveBuild< Expression >(cond), aststmt.front() );
     302ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
     303        return new ast::CatchClause( location,
     304                kind,
     305                maybeMoveBuild( decl ),
     306                maybeMoveBuild( cond ),
     307                buildMoveSingle( body )
     308        );
    248309} // build_catch
    249310
    250 Statement * build_finally( StatementNode * stmt ) {
    251         list< Statement * > aststmt;
    252         buildMoveList< Statement, StatementNode >( stmt, aststmt );
    253         assert( aststmt.size() == 1 );
    254         return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) );
     311ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) {
     312        return new ast::FinallyClause( location,
     313                strict_dynamic_cast<const ast::CompoundStmt *>(
     314                        buildMoveSingle( stmt )
     315                )
     316        );
    255317} // build_finally
    256318
    257 SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) {
    258         auto node = new SuspendStmt();
    259 
    260         node->type = type;
    261 
    262         list< Statement * > stmts;
    263         buildMoveList< Statement, StatementNode >( then, stmts );
    264         if(!stmts.empty()) {
    265                 assert( stmts.size() == 1 );
    266                 node->then = dynamic_cast< CompoundStmt * >( stmts.front() );
    267         }
    268 
    269         return node;
    270 }
    271 
    272 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) {
    273         auto node = new WaitForStmt();
    274 
    275         WaitForStmt::Target target;
    276         target.function = maybeBuild<Expression>( targetExpr );
     319ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Kind kind ) {
     320        return new ast::SuspendStmt( location,
     321                strict_dynamic_cast<const ast::CompoundStmt *, nullptr>(
     322                        buildMoveOptional( then )
     323                ),
     324                kind
     325        );
     326} // build_suspend
     327
     328ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
     329        auto clause = new ast::WaitForClause( location );
     330        clause->target = maybeBuild( targetExpr );
     331        clause->stmt = maybeMoveBuild( stmt );
     332        clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
    277333
    278334        ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
    279335        targetExpr->set_next( nullptr );
    280         buildMoveList< Expression >( next, target.arguments );
     336        buildMoveList( next, clause->target_args );
    281337
    282338        delete targetExpr;
    283339
    284         node->clauses.push_back( WaitForStmt::Clause{
    285                 target,
    286                 maybeMoveBuild<Statement >( stmt ),
    287                 notZeroExpr( maybeMoveBuild<Expression>( when ) )
    288         });
    289 
    290         return node;
     340        existing->clauses.insert( existing->clauses.begin(), clause );
     341
     342        return existing;
    291343} // build_waitfor
    292344
    293 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) {
    294         WaitForStmt::Target target;
    295         target.function = maybeBuild<Expression>( targetExpr );
    296 
    297         ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
    298         targetExpr->set_next( nullptr );
    299         buildMoveList< Expression >( next, target.arguments );
    300 
    301         delete targetExpr;
    302 
    303         node->clauses.insert( node->clauses.begin(), WaitForStmt::Clause{
    304                 std::move( target ),
    305                 maybeMoveBuild<Statement >( stmt ),
    306                 notZeroExpr( maybeMoveBuild<Expression>( when ) )
    307         });
    308 
    309         return node;
    310 } // build_waitfor
    311 
    312 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when ) {
    313         auto node = new WaitForStmt();
    314 
    315         if( timeout ) {
    316                 node->timeout.time      = maybeMoveBuild<Expression>( timeout );
    317                 node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
    318                 node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    319         } else {
    320                 node->orelse.statement  = maybeMoveBuild<Statement >( stmt );
    321                 node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    322         } // if
    323 
    324         return node;
     345ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
     346        existing->else_stmt = maybeMoveBuild( stmt );
     347        existing->else_cond = notZeroExpr( maybeMoveBuild( when ) );
     348
     349        (void)location;
     350        return existing;
     351} // build_waitfor_else
     352
     353ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
     354        existing->timeout_time = maybeMoveBuild( timeout );
     355        existing->timeout_stmt = maybeMoveBuild( stmt );
     356        existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) );
     357
     358        (void)location;
     359        return existing;
    325360} // build_waitfor_timeout
    326361
    327 WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when,  StatementNode * else_, ExpressionNode * else_when ) {
    328         auto node = new WaitForStmt();
    329 
    330         node->timeout.time      = maybeMoveBuild<Expression>( timeout );
    331         node->timeout.statement = maybeMoveBuild<Statement >( stmt    );
    332         node->timeout.condition = notZeroExpr( maybeMoveBuild<Expression>( when ) );
    333 
    334         node->orelse.statement  = maybeMoveBuild<Statement >( else_ );
    335         node->orelse.condition  = notZeroExpr( maybeMoveBuild<Expression>( else_when ) );
    336 
    337         return node;
    338 } // build_waitfor_timeout
    339 
    340 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
    341         list< Expression * > e;
     362ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
     363    ast::WhenClause * clause = new ast::WhenClause( loc );
     364    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     365    clause->stmt = maybeMoveBuild( stmt );
     366    clause->target = maybeMoveBuild( targetExpr );
     367    return new ast::WaitUntilStmt::ClauseNode( clause );
     368}
     369ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) {
     370    ast::WhenClause * clause = new ast::WhenClause( loc );
     371    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     372    clause->stmt = maybeMoveBuild( stmt );
     373    return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause );
     374}
     375ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
     376    ast::WhenClause * clause = new ast::WhenClause( loc );
     377    clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     378    clause->stmt = maybeMoveBuild( stmt );
     379    clause->target = maybeMoveBuild( timeout );
     380    return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::TIMEOUT, clause );
     381}
     382
     383ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation & loc, ast::WaitUntilStmt::ClauseNode * root ) {
     384    ast::WaitUntilStmt * retStmt = new ast::WaitUntilStmt( loc );
     385    retStmt->predicateTree = root;
     386   
     387    // iterative tree traversal
     388    std::vector<ast::WaitUntilStmt::ClauseNode *> nodeStack; // stack needed for iterative traversal
     389    ast::WaitUntilStmt::ClauseNode * currNode = nullptr;
     390    ast::WaitUntilStmt::ClauseNode * lastInternalNode = nullptr;
     391    ast::WaitUntilStmt::ClauseNode * cleanup = nullptr; // used to cleanup removed else/timeout
     392    nodeStack.push_back(root);
     393
     394    do {
     395        currNode = nodeStack.back();
     396        nodeStack.pop_back(); // remove node since it will be processed
     397
     398        switch (currNode->op) {
     399            case ast::WaitUntilStmt::ClauseNode::LEAF:
     400                retStmt->clauses.push_back(currNode->leaf);
     401                break;
     402            case ast::WaitUntilStmt::ClauseNode::ELSE:
     403                retStmt->else_stmt = currNode->leaf->stmt
     404                    ? ast::deepCopy( currNode->leaf->stmt )
     405                    : nullptr;
     406               
     407                retStmt->else_cond = currNode->leaf->when_cond
     408                    ? ast::deepCopy( currNode->leaf->when_cond )
     409                    : nullptr;
     410
     411                delete currNode->leaf;
     412                break;
     413            case ast::WaitUntilStmt::ClauseNode::TIMEOUT:
     414                retStmt->timeout_time = currNode->leaf->target
     415                    ? ast::deepCopy( currNode->leaf->target )
     416                    : nullptr;
     417                retStmt->timeout_stmt = currNode->leaf->stmt
     418                    ? ast::deepCopy( currNode->leaf->stmt )
     419                    : nullptr;
     420                retStmt->timeout_cond = currNode->leaf->when_cond
     421                    ? ast::deepCopy( currNode->leaf->when_cond )
     422                    : nullptr;
     423
     424                delete currNode->leaf;
     425                break;
     426            default:
     427                nodeStack.push_back( currNode->right ); // process right after left
     428                nodeStack.push_back( currNode->left );
     429
     430                // Cut else/timeout out of the tree
     431                if ( currNode->op == ast::WaitUntilStmt::ClauseNode::LEFT_OR ) {
     432                    if ( lastInternalNode )
     433                        lastInternalNode->right = currNode->left;
     434                    else    // if not set then root is LEFT_OR
     435                        retStmt->predicateTree = currNode->left;
     436   
     437                    currNode->left = nullptr;
     438                    cleanup = currNode;
     439                }
     440               
     441                lastInternalNode = currNode;
     442                break;
     443        }
     444    } while ( !nodeStack.empty() );
     445
     446    if ( cleanup ) delete cleanup;
     447
     448    return retStmt;
     449}
     450
     451ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
     452        std::vector<ast::ptr<ast::Expr>> e;
    342453        buildMoveList( exprs, e );
    343         Statement * s = maybeMoveBuild<Statement>( stmt );
    344         return new DeclStmt( new WithStmt( e, s ) );
     454        ast::Stmt * s = maybeMoveBuild( stmt );
     455        return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) );
    345456} // build_with
    346457
    347 Statement * build_compound( StatementNode * first ) {
    348         CompoundStmt * cs = new CompoundStmt();
    349         buildMoveList( first, cs->get_kids() );
     458ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) {
     459        auto cs = new ast::CompoundStmt( location );
     460        buildMoveList( first, cs->kids );
    350461        return cs;
    351462} // build_compound
     
    355466// statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a
    356467// conical form for code generation.
    357 StatementNode * maybe_build_compound( StatementNode * first ) {
     468StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) {
    358469        // Optimization: if the control-structure statement is a compound statement, do not wrap it.
    359470        // e.g., if (...) {...} do not wrap the existing compound statement.
    360         if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
    361                 CompoundStmt * cs = new CompoundStmt();
    362                 buildMoveList( first, cs->get_kids() );
    363                 return new StatementNode( cs );
     471        if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
     472                return new StatementNode( build_compound( location, first ) );
    364473        } // if
    365474        return first;
     
    367476
    368477// Question
    369 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
    370         list< Expression * > out, in;
    371         list< ConstantExpr * > clob;
     478ast::Stmt * build_asm( const CodeLocation & location, bool is_volatile, ExpressionNode * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
     479        std::vector<ast::ptr<ast::Expr>> out, in;
     480        std::vector<ast::ptr<ast::ConstantExpr>> clob;
    372481
    373482        buildMoveList( output, out );
    374483        buildMoveList( input, in );
    375484        buildMoveList( clobber, clob );
    376         return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );
     485        return new ast::AsmStmt( location,
     486                is_volatile,
     487                maybeMoveBuild( instruction ),
     488                std::move( out ),
     489                std::move( in ),
     490                std::move( clob ),
     491                gotolabels ? gotolabels->labels : std::vector<ast::Label>()
     492        );
    377493} // build_asm
    378494
    379 Statement * build_directive( string * directive ) {
    380         return new DirectiveStmt( *directive );
     495ast::Stmt * build_directive( const CodeLocation & location, string * directive ) {
     496        auto stmt = new ast::DirectiveStmt( location, *directive );
     497        delete directive;
     498        return stmt;
    381499} // build_directive
    382500
    383 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt ) {
    384         list< Expression * > expList;
     501ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
     502        std::vector<ast::ptr<ast::Expr>> expList;
    385503        buildMoveList( exprs, expList );
    386         Statement * body = maybeMoveBuild<Statement>( stmt );
    387         return new MutexStmt( body, expList );
     504        ast::Stmt * body = maybeMoveBuild( stmt );
     505        return new ast::MutexStmt( location, body, std::move( expList ) );
    388506} // build_mutex
    389507
  • src/Parser/TypeData.cc

    r34b4268 r24d6572  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:12:51 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 10 22:36:52 2022
    13 // Update Count     : 677
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 13:39:00 2023
     13// Update Count     : 680
    1414//
     15
     16#include "TypeData.h"
    1517
    1618#include <cassert>                 // for assert
    1719#include <ostream>                 // for operator<<, ostream, basic_ostream
    1820
     21#include "AST/Decl.hpp"            // for AggregateDecl, ObjectDecl, TypeDe...
     22#include "AST/Init.hpp"            // for SingleInit, ListInit
     23#include "AST/Print.hpp"           // for print
    1924#include "Common/SemanticError.h"  // for SemanticError
    20 #include "Common/utility.h"        // for maybeClone, maybeBuild, maybeMoveB...
    21 #include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
    22 #include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, FunctionDecl
    23 #include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
    24 #include "SynTree/Initializer.h"   // for SingleInit, Initializer (ptr only)
    25 #include "SynTree/Statement.h"     // for CompoundStmt, Statement
    26 #include "SynTree/Type.h"          // for BasicType, Type, Type::ForallList
    27 #include "TypeData.h"
     25#include "Common/utility.h"        // for splice, spliceBegin
     26#include "Parser/ExpressionNode.h" // for ExpressionNode
     27#include "Parser/StatementNode.h"  // for StatementNode
    2828
    2929class Attribute;
     
    3333TypeData::TypeData( Kind k ) : location( yylloc ), kind( k ), base( nullptr ), forall( nullptr ) /*, PTR1( (void*)(0xdeadbeefdeadbeef)), PTR2( (void*)(0xdeadbeefdeadbeef) ) */ {
    3434        switch ( kind ) {
    35           case Unknown:
    36           case Pointer:
    37           case Reference:
    38           case EnumConstant:
    39           case GlobalScope:
    40                 // nothing else to initialize
    41                 break;
    42           case Basic:
    43                 // basic = new Basic_t;
    44                 break;
    45           case Array:
    46                 // array = new Array_t;
     35        case Unknown:
     36        case Pointer:
     37        case Reference:
     38        case EnumConstant:
     39        case GlobalScope:
     40        case Basic:
     41                // No unique data to initialize.
     42                break;
     43        case Array:
    4744                array.dimension = nullptr;
    4845                array.isVarLen = false;
    4946                array.isStatic = false;
    5047                break;
    51           case Function:
    52                 // function = new Function_t;
     48        case Function:
    5349                function.params = nullptr;
    5450                function.idList = nullptr;
     
    5753                function.withExprs = nullptr;
    5854                break;
    59                 // Enum is an Aggregate, so both structures are initialized together.
    60           case Enum:
    61                 // enumeration = new Enumeration_t;
     55        case Enum:
    6256                enumeration.name = nullptr;
    6357                enumeration.constants = nullptr;
     
    6559                enumeration.anon = false;
    6660                break;
    67           case Aggregate:
    68                 // aggregate = new Aggregate_t;
    69                 aggregate.kind = AggregateDecl::NoAggregate;
     61        case Aggregate:
     62                aggregate.kind = ast::AggregateDecl::NoAggregate;
    7063                aggregate.name = nullptr;
    7164                aggregate.params = nullptr;
     
    7770                aggregate.anon = false;
    7871                break;
    79           case AggregateInst:
    80                 // aggInst = new AggInst_t;
     72        case AggregateInst:
    8173                aggInst.aggregate = nullptr;
    8274                aggInst.params = nullptr;
    8375                aggInst.hoistType = false;
    8476                break;
    85           case Symbolic:
    86           case SymbolicInst:
    87                 // symbolic = new Symbolic_t;
     77        case Symbolic:
     78        case SymbolicInst:
    8879                symbolic.name = nullptr;
    8980                symbolic.params = nullptr;
     
    9182                symbolic.assertions = nullptr;
    9283                break;
    93           case Tuple:
    94                 // tuple = new Tuple_t;
     84        case Tuple:
    9585                tuple = nullptr;
    9686                break;
    97           case Typeof:
    98           case Basetypeof:
    99                 // typeexpr = new Typeof_t;
     87        case Typeof:
     88        case Basetypeof:
    10089                typeexpr = nullptr;
    10190                break;
    102           case Vtable:
    103                 break;
    104           case Builtin:
    105                 // builtin = new Builtin_t;
    106                 case Qualified:
     91        case Vtable:
     92        case Builtin:
     93                // No unique data to initialize.
     94                break;
     95        case Qualified:
    10796                qualified.parent = nullptr;
    10897                qualified.child = nullptr;
     
    117106
    118107        switch ( kind ) {
    119           case Unknown:
    120           case Pointer:
    121           case Reference:
    122           case EnumConstant:
    123           case GlobalScope:
    124                 // nothing to destroy
    125                 break;
    126           case Basic:
    127                 // delete basic;
    128                 break;
    129           case Array:
     108        case Unknown:
     109        case Pointer:
     110        case Reference:
     111        case EnumConstant:
     112        case GlobalScope:
     113        case Basic:
     114                // No unique data to deconstruct.
     115                break;
     116        case Array:
    130117                delete array.dimension;
    131                 // delete array;
    132                 break;
    133           case Function:
     118                break;
     119        case Function:
    134120                delete function.params;
    135121                delete function.idList;
     
    137123                delete function.body;
    138124                delete function.withExprs;
    139                 // delete function;
    140                 break;
    141           case Aggregate:
     125                break;
     126        case Aggregate:
    142127                delete aggregate.name;
    143128                delete aggregate.params;
    144129                delete aggregate.actuals;
    145130                delete aggregate.fields;
    146                 // delete aggregate;
    147                 break;
    148           case AggregateInst:
     131                break;
     132        case AggregateInst:
    149133                delete aggInst.aggregate;
    150134                delete aggInst.params;
    151                 // delete aggInst;
    152                 break;
    153           case Enum:
     135                break;
     136        case Enum:
    154137                delete enumeration.name;
    155138                delete enumeration.constants;
    156                 // delete enumeration;
    157                 break;
    158           case Symbolic:
    159           case SymbolicInst:
     139                break;
     140        case Symbolic:
     141        case SymbolicInst:
    160142                delete symbolic.name;
    161143                delete symbolic.params;
    162144                delete symbolic.actuals;
    163145                delete symbolic.assertions;
    164                 // delete symbolic;
    165                 break;
    166           case Tuple:
    167                 // delete tuple->members;
     146                break;
     147        case Tuple:
    168148                delete tuple;
    169149                break;
    170           case Typeof:
    171           case Basetypeof:
    172                 // delete typeexpr->expr;
     150        case Typeof:
     151        case Basetypeof:
    173152                delete typeexpr;
    174153                break;
    175           case Vtable:
    176                 break;
    177           case Builtin:
    178                 // delete builtin;
    179                 break;
    180           case Qualified:
     154        case Vtable:
     155        case Builtin:
     156                // No unique data to deconstruct.
     157                break;
     158        case Qualified:
    181159                delete qualified.parent;
    182160                delete qualified.child;
     161                break;
    183162        } // switch
    184163} // TypeData::~TypeData
     
    192171
    193172        switch ( kind ) {
    194           case Unknown:
    195           case EnumConstant:
    196           case Pointer:
    197           case Reference:
    198           case GlobalScope:
     173        case Unknown:
     174        case EnumConstant:
     175        case Pointer:
     176        case Reference:
     177        case GlobalScope:
    199178                // nothing else to copy
    200179                break;
    201           case Basic:
     180        case Basic:
    202181                newtype->basictype = basictype;
    203182                newtype->complextype = complextype;
     
    205184                newtype->length = length;
    206185                break;
    207           case Array:
     186        case Array:
    208187                newtype->array.dimension = maybeClone( array.dimension );
    209188                newtype->array.isVarLen = array.isVarLen;
    210189                newtype->array.isStatic = array.isStatic;
    211190                break;
    212           case Function:
     191        case Function:
    213192                newtype->function.params = maybeClone( function.params );
    214193                newtype->function.idList = maybeClone( function.idList );
     
    217196                newtype->function.withExprs = maybeClone( function.withExprs );
    218197                break;
    219           case Aggregate:
     198        case Aggregate:
    220199                newtype->aggregate.kind = aggregate.kind;
    221200                newtype->aggregate.name = aggregate.name ? new string( *aggregate.name ) : nullptr;
     
    228207                newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr;
    229208                break;
    230           case AggregateInst:
     209        case AggregateInst:
    231210                newtype->aggInst.aggregate = maybeClone( aggInst.aggregate );
    232211                newtype->aggInst.params = maybeClone( aggInst.params );
    233212                newtype->aggInst.hoistType = aggInst.hoistType;
    234213                break;
    235           case Enum:
     214        case Enum:
    236215                newtype->enumeration.name = enumeration.name ? new string( *enumeration.name ) : nullptr;
    237216                newtype->enumeration.constants = maybeClone( enumeration.constants );
     
    239218                newtype->enumeration.anon = enumeration.anon;
    240219                break;
    241           case Symbolic:
    242           case SymbolicInst:
     220        case Symbolic:
     221        case SymbolicInst:
    243222                newtype->symbolic.name = symbolic.name ? new string( *symbolic.name ) : nullptr;
    244223                newtype->symbolic.params = maybeClone( symbolic.params );
     
    247226                newtype->symbolic.isTypedef = symbolic.isTypedef;
    248227                break;
    249           case Tuple:
     228        case Tuple:
    250229                newtype->tuple = maybeClone( tuple );
    251230                break;
    252           case Typeof:
    253           case Basetypeof:
     231        case Typeof:
     232        case Basetypeof:
    254233                newtype->typeexpr = maybeClone( typeexpr );
    255234                break;
    256           case Vtable:
    257                 break;
    258           case Builtin:
     235        case Vtable:
     236                break;
     237        case Builtin:
    259238                assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One );
    260239                newtype->builtintype = builtintype;
    261240                break;
    262                 case Qualified:
     241        case Qualified:
    263242                newtype->qualified.parent = maybeClone( qualified.parent );
    264243                newtype->qualified.child = maybeClone( qualified.child );
     
    270249
    271250void TypeData::print( ostream &os, int indent ) const {
    272         for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) {
    273                 if ( qualifiers[i] ) os << Type::QualifiersNames[ i ] << ' ';
    274         } // for
     251        ast::print( os, qualifiers );
    275252
    276253        if ( forall ) {
     
    280257
    281258        switch ( kind ) {
    282           case Basic:
     259        case Basic:
    283260                if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " ";
    284261                if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " ";
     
    286263                if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " ";
    287264                break;
    288           case Pointer:
     265        case Pointer:
    289266                os << "pointer ";
    290267                if ( base ) {
     
    293270                } // if
    294271                break;
    295           case Reference:
     272        case Reference:
    296273                os << "reference ";
    297274                if ( base ) {
     
    300277                } // if
    301278                break;
    302           case Array:
     279        case Array:
    303280                if ( array.isStatic ) {
    304281                        os << "static ";
     
    316293                } // if
    317294                break;
    318           case Function:
     295        case Function:
    319296                os << "function" << endl;
    320297                if ( function.params ) {
     
    344321                } // if
    345322                break;
    346           case Aggregate:
    347                 os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
     323        case Aggregate:
     324                os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
    348325                if ( aggregate.params ) {
    349326                        os << string( indent + 2, ' ' ) << "with type parameters" << endl;
     
    362339                } // if
    363340                break;
    364           case AggregateInst:
     341        case AggregateInst:
    365342                if ( aggInst.aggregate ) {
    366343                        os << "instance of " ;
     
    374351                } // if
    375352                break;
    376           case Enum:
    377                 os << "enumeration ";
     353        case Enum:
     354                os << "enumeration " << *enumeration.name << endl;;
    378355                if ( enumeration.constants ) {
    379356                        os << "with constants" << endl;
     
    388365                } // if
    389366                break;
    390           case EnumConstant:
     367        case EnumConstant:
    391368                os << "enumeration constant ";
    392369                break;
    393           case Symbolic:
     370        case Symbolic:
    394371                if ( symbolic.isTypedef ) {
    395372                        os << "typedef definition ";
     
    411388                } // if
    412389                break;
    413           case SymbolicInst:
     390        case SymbolicInst:
    414391                os << *symbolic.name;
    415392                if ( symbolic.actuals ) {
     
    419396                } // if
    420397                break;
    421           case Tuple:
     398        case Tuple:
    422399                os << "tuple ";
    423400                if ( tuple ) {
     
    426403                } // if
    427404                break;
    428           case Basetypeof:
     405        case Basetypeof:
    429406                os << "base-";
    430407                #if defined(__GNUC__) && __GNUC__ >= 7
     
    432409                #endif
    433410                // FALL THROUGH
    434           case Typeof:
     411        case Typeof:
    435412                os << "type-of expression ";
    436413                if ( typeexpr ) {
     
    438415                } // if
    439416                break;
    440           case Vtable:
     417        case Vtable:
    441418                os << "vtable";
    442419                break;
    443           case Builtin:
     420        case Builtin:
    444421                os << DeclarationNode::builtinTypeNames[builtintype];
    445422                break;
    446           case GlobalScope:
    447                 break;
    448           case Qualified:
     423        case GlobalScope:
     424                break;
     425        case Qualified:
    449426                qualified.parent->print( os );
    450427                os << ".";
    451428                qualified.child->print( os );
    452429                break;
    453           case Unknown:
     430        case Unknown:
    454431                os << "entity of unknown type ";
    455432                break;
    456           default:
     433        default:
    457434                os << "internal error: TypeData::print " << kind << endl;
    458435                assert( false );
     
    462439const std::string * TypeData::leafName() const {
    463440        switch ( kind ) {
    464           case Unknown:
    465           case Pointer:
    466           case Reference:
    467           case EnumConstant:
    468           case GlobalScope:
    469           case Array:
    470           case Basic:
    471           case Function:
    472           case AggregateInst:
    473           case Tuple:
    474           case Typeof:
    475           case Basetypeof:
    476           case Builtin:
    477           case Vtable:
     441        case Unknown:
     442        case Pointer:
     443        case Reference:
     444        case EnumConstant:
     445        case GlobalScope:
     446        case Array:
     447        case Basic:
     448        case Function:
     449        case AggregateInst:
     450        case Tuple:
     451        case Typeof:
     452        case Basetypeof:
     453        case Builtin:
     454        case Vtable:
    478455                assertf(false, "Tried to get leaf name from kind without a name: %d", kind);
    479456                break;
    480           case Aggregate:
     457        case Aggregate:
    481458                return aggregate.name;
    482           case Enum:
     459        case Enum:
    483460                return enumeration.name;
    484           case Symbolic:
    485           case SymbolicInst:
     461        case Symbolic:
     462        case SymbolicInst:
    486463                return symbolic.name;
    487           case Qualified:
     464        case Qualified:
    488465                return qualified.child->leafName();
    489466        } // switch
     
    492469
    493470
    494 template< typename ForallList >
    495 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
    496         buildList( firstNode, outputList );
     471void buildForall(
     472                const DeclarationNode * firstNode,
     473                std::vector<ast::ptr<ast::TypeInstType>> &outputList ) {
     474        {
     475                std::vector<ast::ptr<ast::Type>> tmpList;
     476                buildTypeList( firstNode, tmpList );
     477                for ( auto tmp : tmpList ) {
     478                        outputList.emplace_back(
     479                                strict_dynamic_cast<const ast::TypeInstType *>(
     480                                        tmp.release() ) );
     481                }
     482        }
    497483        auto n = firstNode;
    498         for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) {
    499                 TypeDecl * td = static_cast<TypeDecl *>(*i);
    500                 if ( n->variable.tyClass == TypeDecl::Otype ) {
    501                         // add assertion parameters to `type' tyvars in reverse order
    502                         // add dtor:  void ^?{}(T *)
    503                         FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
    504                         dtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    505                         td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) );
    506 
    507                         // add copy ctor:  void ?{}(T *, T)
    508                         FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
    509                         copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    510                         copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    511                         td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) );
    512 
    513                         // add default ctor:  void ?{}(T *)
    514                         FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
    515                         ctorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    516                         td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) );
    517 
    518                         // add assignment operator:  T * ?=?(T *, T)
    519                         FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
    520                         assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    521                         assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    522                         assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    523                         td->get_assertions().push_front( new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Cforall, assignType, nullptr ) );
    524                 } // if
     484        for ( auto i = outputList.begin() ;
     485                        i != outputList.end() ;
     486                        ++i, n = (DeclarationNode*)n->get_next() ) {
     487                // Only the object type class adds additional assertions.
     488                if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
     489                        continue;
     490                }
     491
     492                ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
     493                std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
     494                auto mutTypeDecl = ast::mutate( td );
     495                const CodeLocation & location = mutTypeDecl->location;
     496                *i = mutTypeDecl;
     497
     498                // add assertion parameters to `type' tyvars in reverse order
     499                // add assignment operator:  T * ?=?(T *, T)
     500                newAssertions.push_back( new ast::FunctionDecl(
     501                        location,
     502                        "?=?",
     503                        {}, // forall
     504                        {}, // assertions
     505                        {
     506                                new ast::ObjectDecl(
     507                                        location,
     508                                        "",
     509                                        new ast::ReferenceType( i->get() ),
     510                                        (ast::Init *)nullptr,
     511                                        ast::Storage::Classes(),
     512                                        ast::Linkage::Cforall,
     513                                        (ast::Expr *)nullptr
     514                                ),
     515                                new ast::ObjectDecl(
     516                                        location,
     517                                        "",
     518                                        i->get(),
     519                                        (ast::Init *)nullptr,
     520                                        ast::Storage::Classes(),
     521                                        ast::Linkage::Cforall,
     522                                        (ast::Expr *)nullptr
     523                                ),
     524                        }, // params
     525                        {
     526                                new ast::ObjectDecl(
     527                                        location,
     528                                        "",
     529                                        i->get(),
     530                                        (ast::Init *)nullptr,
     531                                        ast::Storage::Classes(),
     532                                        ast::Linkage::Cforall,
     533                                        (ast::Expr *)nullptr
     534                                ),
     535                        }, // returns
     536                        (ast::CompoundStmt *)nullptr,
     537                        ast::Storage::Classes(),
     538                        ast::Linkage::Cforall
     539                ) );
     540
     541                // add default ctor:  void ?{}(T *)
     542                newAssertions.push_back( new ast::FunctionDecl(
     543                        location,
     544                        "?{}",
     545                        {}, // forall
     546                        {}, // assertions
     547                        {
     548                                new ast::ObjectDecl(
     549                                        location,
     550                                        "",
     551                                        new ast::ReferenceType( i->get() ),
     552                                        (ast::Init *)nullptr,
     553                                        ast::Storage::Classes(),
     554                                        ast::Linkage::Cforall,
     555                                        (ast::Expr *)nullptr
     556                                ),
     557                        }, // params
     558                        {}, // returns
     559                        (ast::CompoundStmt *)nullptr,
     560                        ast::Storage::Classes(),
     561                        ast::Linkage::Cforall
     562                ) );
     563
     564                // add copy ctor:  void ?{}(T *, T)
     565                newAssertions.push_back( new ast::FunctionDecl(
     566                        location,
     567                        "?{}",
     568                        {}, // forall
     569                        {}, // assertions
     570                        {
     571                                new ast::ObjectDecl(
     572                                        location,
     573                                        "",
     574                                        new ast::ReferenceType( i->get() ),
     575                                        (ast::Init *)nullptr,
     576                                        ast::Storage::Classes(),
     577                                        ast::Linkage::Cforall,
     578                                        (ast::Expr *)nullptr
     579                                ),
     580                                new ast::ObjectDecl(
     581                                        location,
     582                                        "",
     583                                        i->get(),
     584                                        (ast::Init *)nullptr,
     585                                        ast::Storage::Classes(),
     586                                        ast::Linkage::Cforall,
     587                                        (ast::Expr *)nullptr
     588                                ),
     589                        }, // params
     590                        {}, // returns
     591                        (ast::CompoundStmt *)nullptr,
     592                        ast::Storage::Classes(),
     593                        ast::Linkage::Cforall
     594                ) );
     595
     596                // add dtor:  void ^?{}(T *)
     597                newAssertions.push_back( new ast::FunctionDecl(
     598                        location,
     599                        "^?{}",
     600                        {}, // forall
     601                        {}, // assertions
     602                        {
     603                                new ast::ObjectDecl(
     604                                        location,
     605                                        "",
     606                                        new ast::ReferenceType( i->get() ),
     607                                        (ast::Init *)nullptr,
     608                                        ast::Storage::Classes(),
     609                                        ast::Linkage::Cforall,
     610                                        (ast::Expr *)nullptr
     611                                ),
     612                        }, // params
     613                        {}, // returns
     614                        (ast::CompoundStmt *)nullptr,
     615                        ast::Storage::Classes(),
     616                        ast::Linkage::Cforall
     617                ) );
     618
     619                spliceBegin( mutTypeDecl->assertions, newAssertions );
     620        } // for
     621}
     622
     623
     624void buildForall(
     625                const DeclarationNode * firstNode,
     626                std::vector<ast::ptr<ast::TypeDecl>> &outputForall ) {
     627        buildList( firstNode, outputForall );
     628        auto n = firstNode;
     629        for ( auto i = outputForall.begin() ;
     630                        i != outputForall.end() ;
     631                        ++i, n = (DeclarationNode*)n->get_next() ) {
     632                // Only the object type class adds additional assertions.
     633                if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
     634                        continue;
     635                }
     636
     637                ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
     638                std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
     639                auto mutTypeDecl = ast::mutate( td );
     640                const CodeLocation & location = mutTypeDecl->location;
     641                *i = mutTypeDecl;
     642
     643                // add assertion parameters to `type' tyvars in reverse order
     644                // add assignment operator:  T * ?=?(T *, T)
     645                newAssertions.push_back( new ast::FunctionDecl(
     646                        location,
     647                        "?=?",
     648                        {}, // forall
     649                        {}, // assertions
     650                        {
     651                                new ast::ObjectDecl(
     652                                        location,
     653                                        "",
     654                                        new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
     655                                        (ast::Init *)nullptr,
     656                                        ast::Storage::Classes(),
     657                                        ast::Linkage::Cforall,
     658                                        (ast::Expr *)nullptr
     659                                ),
     660                                new ast::ObjectDecl(
     661                                        location,
     662                                        "",
     663                                        new ast::TypeInstType( td->name, *i ),
     664                                        (ast::Init *)nullptr,
     665                                        ast::Storage::Classes(),
     666                                        ast::Linkage::Cforall,
     667                                        (ast::Expr *)nullptr
     668                                ),
     669                        }, // params
     670                        {
     671                                new ast::ObjectDecl(
     672                                        location,
     673                                        "",
     674                                        new ast::TypeInstType( td->name, *i ),
     675                                        (ast::Init *)nullptr,
     676                                        ast::Storage::Classes(),
     677                                        ast::Linkage::Cforall,
     678                                        (ast::Expr *)nullptr
     679                                ),
     680                        }, // returns
     681                        (ast::CompoundStmt *)nullptr,
     682                        ast::Storage::Classes(),
     683                        ast::Linkage::Cforall
     684                ) );
     685
     686                // add default ctor:  void ?{}(T *)
     687                newAssertions.push_back( new ast::FunctionDecl(
     688                        location,
     689                        "?{}",
     690                        {}, // forall
     691                        {}, // assertions
     692                        {
     693                                new ast::ObjectDecl(
     694                                        location,
     695                                        "",
     696                                        new ast::ReferenceType(
     697                                                new ast::TypeInstType( td->name, i->get() ) ),
     698                                        (ast::Init *)nullptr,
     699                                        ast::Storage::Classes(),
     700                                        ast::Linkage::Cforall,
     701                                        (ast::Expr *)nullptr
     702                                ),
     703                        }, // params
     704                        {}, // returns
     705                        (ast::CompoundStmt *)nullptr,
     706                        ast::Storage::Classes(),
     707                        ast::Linkage::Cforall
     708                ) );
     709
     710                // add copy ctor:  void ?{}(T *, T)
     711                newAssertions.push_back( new ast::FunctionDecl(
     712                        location,
     713                        "?{}",
     714                        {}, // forall
     715                        {}, // assertions
     716                        {
     717                                new ast::ObjectDecl(
     718                                        location,
     719                                        "",
     720                                        new ast::ReferenceType(
     721                                                new ast::TypeInstType( td->name, *i ) ),
     722                                        (ast::Init *)nullptr,
     723                                        ast::Storage::Classes(),
     724                                        ast::Linkage::Cforall,
     725                                        (ast::Expr *)nullptr
     726                                ),
     727                                new ast::ObjectDecl(
     728                                        location,
     729                                        "",
     730                                        new ast::TypeInstType( td->name, *i ),
     731                                        (ast::Init *)nullptr,
     732                                        ast::Storage::Classes(),
     733                                        ast::Linkage::Cforall,
     734                                        (ast::Expr *)nullptr
     735                                ),
     736                        }, // params
     737                        {}, // returns
     738                        (ast::CompoundStmt *)nullptr,
     739                        ast::Storage::Classes(),
     740                        ast::Linkage::Cforall
     741                ) );
     742
     743                // add dtor:  void ^?{}(T *)
     744                newAssertions.push_back( new ast::FunctionDecl(
     745                        location,
     746                        "^?{}",
     747                        {}, // forall
     748                        {}, // assertions
     749                        {
     750                                new ast::ObjectDecl(
     751                                        location,
     752                                        "",
     753                                        new ast::ReferenceType(
     754                                                new ast::TypeInstType( i->get() )
     755                                        ),
     756                                        (ast::Init *)nullptr,
     757                                        ast::Storage::Classes(),
     758                                        ast::Linkage::Cforall,
     759                                        (ast::Expr *)nullptr
     760                                ),
     761                        }, // params
     762                        {}, // returns
     763                        (ast::CompoundStmt *)nullptr,
     764                        ast::Storage::Classes(),
     765                        ast::Linkage::Cforall
     766                ) );
     767
     768                spliceBegin( mutTypeDecl->assertions, newAssertions );
    525769        } // for
    526770} // buildForall
    527771
    528772
    529 Type * typebuild( const TypeData * td ) {
     773ast::Type * typebuild( const TypeData * td ) {
    530774        assert( td );
    531775        switch ( td->kind ) {
    532           case TypeData::Unknown:
     776        case TypeData::Unknown:
    533777                // fill in implicit int
    534                 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
    535           case TypeData::Basic:
     778                return new ast::BasicType(
     779                        ast::BasicType::SignedInt,
     780                        buildQualifiers( td )
     781                );
     782        case TypeData::Basic:
    536783                return buildBasicType( td );
    537           case TypeData::Pointer:
     784        case TypeData::Pointer:
    538785                return buildPointer( td );
    539           case TypeData::Array:
     786        case TypeData::Array:
    540787                return buildArray( td );
    541           case TypeData::Reference:
     788        case TypeData::Reference:
    542789                return buildReference( td );
    543           case TypeData::Function:
    544                 return buildFunction( td );
    545           case TypeData::AggregateInst:
     790        case TypeData::Function:
     791                return buildFunctionType( td );
     792        case TypeData::AggregateInst:
    546793                return buildAggInst( td );
    547           case TypeData::EnumConstant:
    548                 return new EnumInstType( buildQualifiers( td ), "" );
    549           case TypeData::SymbolicInst:
     794        case TypeData::EnumConstant:
     795                return new ast::EnumInstType( "", buildQualifiers( td ) );
     796        case TypeData::SymbolicInst:
    550797                return buildSymbolicInst( td );
    551           case TypeData::Tuple:
     798        case TypeData::Tuple:
    552799                return buildTuple( td );
    553           case TypeData::Typeof:
    554           case TypeData::Basetypeof:
     800        case TypeData::Typeof:
     801        case TypeData::Basetypeof:
    555802                return buildTypeof( td );
    556           case TypeData::Vtable:
     803        case TypeData::Vtable:
    557804                return buildVtable( td );
    558           case TypeData::Builtin:
     805        case TypeData::Builtin:
    559806                switch ( td->builtintype ) {
    560                   case DeclarationNode::Zero:
    561                         return new ZeroType( noQualifiers );
    562                   case DeclarationNode::One:
    563                         return new OneType( noQualifiers );
    564                   default:
    565                         return new VarArgsType( buildQualifiers( td ) );
     807                case DeclarationNode::Zero:
     808                        return new ast::ZeroType();
     809                case DeclarationNode::One:
     810                        return new ast::OneType();
     811                default:
     812                        return new ast::VarArgsType( buildQualifiers( td ) );
    566813                } // switch
    567           case TypeData::GlobalScope:
    568                 return new GlobalScopeType();
    569           case TypeData::Qualified:
    570                 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
    571           case TypeData::Symbolic:
    572           case TypeData::Enum:
    573           case TypeData::Aggregate:
     814        case TypeData::GlobalScope:
     815                return new ast::GlobalScopeType();
     816        case TypeData::Qualified:
     817                return new ast::QualifiedType(
     818                        typebuild( td->qualified.parent ),
     819                        typebuild( td->qualified.child ),
     820                        buildQualifiers( td )
     821                );
     822        case TypeData::Symbolic:
     823        case TypeData::Enum:
     824        case TypeData::Aggregate:
    574825                assert( false );
    575826        } // switch
     
    583834
    584835        switch ( td->kind ) {
    585           case TypeData::Aggregate:
     836        case TypeData::Aggregate:
    586837                if ( ! toplevel && td->aggregate.body ) {
    587838                        ret = td->clone();
    588839                } // if
    589840                break;
    590           case TypeData::Enum:
     841        case TypeData::Enum:
    591842                if ( ! toplevel && td->enumeration.body ) {
    592843                        ret = td->clone();
    593844                } // if
    594845                break;
    595           case TypeData::AggregateInst:
     846        case TypeData::AggregateInst:
    596847                if ( td->aggInst.aggregate ) {
    597848                        ret = typeextractAggregate( td->aggInst.aggregate, false );
    598849                } // if
    599850                break;
    600           default:
     851        default:
    601852                if ( td->base ) {
    602853                        ret = typeextractAggregate( td->base, false );
     
    607858
    608859
    609 Type::Qualifiers buildQualifiers( const TypeData * td ) {
     860ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {
    610861        return td->qualifiers;
    611862} // buildQualifiers
     
    616867} // genTSError
    617868
    618 Type * buildBasicType( const TypeData * td ) {
    619         BasicType::Kind ret;
     869ast::Type * buildBasicType( const TypeData * td ) {
     870        ast::BasicType::Kind ret;
    620871
    621872        switch ( td->basictype ) {
    622           case DeclarationNode::Void:
     873        case DeclarationNode::Void:
    623874                if ( td->signedness != DeclarationNode::NoSignedness ) {
    624875                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
     
    627878                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
    628879                } // if
    629                 return new VoidType( buildQualifiers( td ) );
    630                 break;
    631 
    632           case DeclarationNode::Bool:
     880                return new ast::VoidType( buildQualifiers( td ) );
     881                break;
     882
     883        case DeclarationNode::Bool:
    633884                if ( td->signedness != DeclarationNode::NoSignedness ) {
    634885                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
     
    638889                } // if
    639890
    640                 ret = BasicType::Bool;
    641                 break;
    642 
    643           case DeclarationNode::Char:
     891                ret = ast::BasicType::Bool;
     892                break;
     893
     894        case DeclarationNode::Char:
    644895                // C11 Standard 6.2.5.15: The three types char, signed char, and unsigned char are collectively called the
    645896                // character types. The implementation shall define char to have the same range, representation, and behavior as
    646897                // either signed char or unsigned char.
    647                 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char };
     898                static ast::BasicType::Kind chartype[] = { ast::BasicType::SignedChar, ast::BasicType::UnsignedChar, ast::BasicType::Char };
    648899
    649900                if ( td->length != DeclarationNode::NoLength ) {
     
    654905                break;
    655906
    656           case DeclarationNode::Int:
    657                 static BasicType::Kind inttype[2][4] = {
    658                         { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt },
    659                         { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt },
     907        case DeclarationNode::Int:
     908                static ast::BasicType::Kind inttype[2][4] = {
     909                        { ast::BasicType::ShortSignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, ast::BasicType::SignedInt },
     910                        { ast::BasicType::ShortUnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, ast::BasicType::UnsignedInt },
    660911                };
    661912
    662           Integral: ;
     913        Integral: ;
    663914                if ( td->signedness == DeclarationNode::NoSignedness ) {
    664915                        const_cast<TypeData *>(td)->signedness = DeclarationNode::Signed;
     
    667918                break;
    668919
    669           case DeclarationNode::Int128:
    670                 ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
     920        case DeclarationNode::Int128:
     921                ret = td->signedness == DeclarationNode::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128;
    671922                if ( td->length != DeclarationNode::NoLength ) {
    672923                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
     
    674925                break;
    675926
    676           case DeclarationNode::Float:
    677           case DeclarationNode::Double:
    678           case DeclarationNode::LongDouble:                                     // not set until below
    679           case DeclarationNode::uuFloat80:
    680           case DeclarationNode::uuFloat128:
    681           case DeclarationNode::uFloat16:
    682           case DeclarationNode::uFloat32:
    683           case DeclarationNode::uFloat32x:
    684           case DeclarationNode::uFloat64:
    685           case DeclarationNode::uFloat64x:
    686           case DeclarationNode::uFloat128:
    687           case DeclarationNode::uFloat128x:
    688                 static BasicType::Kind floattype[2][12] = {
    689                         { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, (BasicType::Kind)-1, (BasicType::Kind)-1, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex, },
    690                         { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x, },
     927        case DeclarationNode::Float:
     928        case DeclarationNode::Double:
     929        case DeclarationNode::LongDouble:                                       // not set until below
     930        case DeclarationNode::uuFloat80:
     931        case DeclarationNode::uuFloat128:
     932        case DeclarationNode::uFloat16:
     933        case DeclarationNode::uFloat32:
     934        case DeclarationNode::uFloat32x:
     935        case DeclarationNode::uFloat64:
     936        case DeclarationNode::uFloat64x:
     937        case DeclarationNode::uFloat128:
     938        case DeclarationNode::uFloat128x:
     939                static ast::BasicType::Kind floattype[2][12] = {
     940                        { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, (ast::BasicType::Kind)-1, (ast::BasicType::Kind)-1, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex, },
     941                        { ast::BasicType::Float, ast::BasicType::Double, ast::BasicType::LongDouble, ast::BasicType::uuFloat80, ast::BasicType::uuFloat128, ast::BasicType::uFloat16, ast::BasicType::uFloat32, ast::BasicType::uFloat32x, ast::BasicType::uFloat64, ast::BasicType::uFloat64x, ast::BasicType::uFloat128, ast::BasicType::uFloat128x, },
    691942                };
    692943
    693           FloatingPoint: ;
     944        FloatingPoint: ;
    694945                if ( td->signedness != DeclarationNode::NoSignedness ) {
    695946                        genTSError( DeclarationNode::signednessNames[ td->signedness ], td->basictype );
     
    715966                break;
    716967
    717           case DeclarationNode::NoBasicType:
     968        case DeclarationNode::NoBasicType:
    718969                // No basic type in declaration => default double for Complex/Imaginary and int type for integral types
    719970                if ( td->complextype == DeclarationNode::Complex || td->complextype == DeclarationNode::Imaginary ) {
     
    724975                const_cast<TypeData *>(td)->basictype = DeclarationNode::Int;
    725976                goto Integral;
    726           default:
    727                 assertf( false, "unknown basic type" );
     977        default:
     978                assertf( false, "unknown basic type" );
    728979                return nullptr;
    729980        } // switch
    730981
    731         BasicType * bt = new BasicType( buildQualifiers( td ), ret );
    732         buildForall( td->forall, bt->get_forall() );
     982        ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
    733983        return bt;
    734984} // buildBasicType
    735985
    736986
    737 PointerType * buildPointer( const TypeData * td ) {
    738         PointerType * pt;
     987ast::PointerType * buildPointer( const TypeData * td ) {
     988        ast::PointerType * pt;
    739989        if ( td->base ) {
    740                 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
     990                pt = new ast::PointerType(
     991                        typebuild( td->base ),
     992                        buildQualifiers( td )
     993                );
    741994        } else {
    742                 pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     995                pt = new ast::PointerType(
     996                        new ast::BasicType( ast::BasicType::SignedInt ),
     997                        buildQualifiers( td )
     998                );
    743999        } // if
    744         buildForall( td->forall, pt->get_forall() );
    7451000        return pt;
    7461001} // buildPointer
    7471002
    7481003
    749 ArrayType * buildArray( const TypeData * td ) {
    750         ArrayType * at;
     1004ast::ArrayType * buildArray( const TypeData * td ) {
     1005        ast::ArrayType * at;
    7511006        if ( td->base ) {
    752                 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild< Expression >( td->array.dimension ),
    753                                                         td->array.isVarLen, td->array.isStatic );
     1007                at = new ast::ArrayType(
     1008                        typebuild( td->base ),
     1009                        maybeBuild( td->array.dimension ),
     1010                        td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
     1011                        td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
     1012                        buildQualifiers( td )
     1013                );
    7541014        } else {
    755                 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
    756                                                         maybeBuild< Expression >( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
     1015                at = new ast::ArrayType(
     1016                        new ast::BasicType( ast::BasicType::SignedInt ),
     1017                        maybeBuild( td->array.dimension ),
     1018                        td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
     1019                        td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
     1020                        buildQualifiers( td )
     1021                );
    7571022        } // if
    758         buildForall( td->forall, at->get_forall() );
    7591023        return at;
    7601024} // buildArray
    7611025
    7621026
    763 ReferenceType * buildReference( const TypeData * td ) {
    764         ReferenceType * rt;
     1027ast::ReferenceType * buildReference( const TypeData * td ) {
     1028        ast::ReferenceType * rt;
    7651029        if ( td->base ) {
    766                 rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) );
     1030                rt = new ast::ReferenceType(
     1031                        typebuild( td->base ),
     1032                        buildQualifiers( td )
     1033                );
    7671034        } else {
    768                 rt = new ReferenceType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     1035                rt = new ast::ReferenceType(
     1036                        new ast::BasicType( ast::BasicType::SignedInt ),
     1037                        buildQualifiers( td )
     1038                );
    7691039        } // if
    770         buildForall( td->forall, rt->get_forall() );
    7711040        return rt;
    7721041} // buildReference
    7731042
    7741043
    775 AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
     1044ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {
    7761045        assert( td->kind == TypeData::Aggregate );
    777         AggregateDecl * at;
     1046        ast::AggregateDecl * at;
    7781047        switch ( td->aggregate.kind ) {
    779           case AggregateDecl::Struct:
    780           case AggregateDecl::Coroutine:
    781           case AggregateDecl::Exception:
    782           case AggregateDecl::Generator:
    783           case AggregateDecl::Monitor:
    784           case AggregateDecl::Thread:
    785                 at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage );
    786                 buildForall( td->aggregate.params, at->get_parameters() );
    787                 break;
    788           case AggregateDecl::Union:
    789                 at = new UnionDecl( *td->aggregate.name, attributes, linkage );
    790                 buildForall( td->aggregate.params, at->get_parameters() );
    791                 break;
    792           case AggregateDecl::Trait:
    793                 at = new TraitDecl( *td->aggregate.name, attributes, linkage );
    794                 buildList( td->aggregate.params, at->get_parameters() );
    795                 break;
    796           default:
     1048        case ast::AggregateDecl::Struct:
     1049        case ast::AggregateDecl::Coroutine:
     1050        case ast::AggregateDecl::Exception:
     1051        case ast::AggregateDecl::Generator:
     1052        case ast::AggregateDecl::Monitor:
     1053        case ast::AggregateDecl::Thread:
     1054                at = new ast::StructDecl( td->location,
     1055                        *td->aggregate.name,
     1056                        td->aggregate.kind,
     1057                        std::move( attributes ),
     1058                        linkage
     1059                );
     1060                buildForall( td->aggregate.params, at->params );
     1061                break;
     1062        case ast::AggregateDecl::Union:
     1063                at = new ast::UnionDecl( td->location,
     1064                        *td->aggregate.name,
     1065                        std::move( attributes ),
     1066                        linkage
     1067                );
     1068                buildForall( td->aggregate.params, at->params );
     1069                break;
     1070        case ast::AggregateDecl::Trait:
     1071                at = new ast::TraitDecl( td->location,
     1072                        *td->aggregate.name,
     1073                        std::move( attributes ),
     1074                        linkage
     1075                );
     1076                buildList( td->aggregate.params, at->params );
     1077                break;
     1078        default:
    7971079                assert( false );
    7981080        } // switch
    7991081
    800         buildList( td->aggregate.fields, at->get_members() );
     1082        buildList( td->aggregate.fields, at->members );
    8011083        at->set_body( td->aggregate.body );
    8021084
     
    8051087
    8061088
    807 ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
     1089ast::BaseInstType * buildComAggInst(
     1090                const TypeData * type,
     1091                std::vector<ast::ptr<ast::Attribute>> && attributes,
     1092                ast::Linkage::Spec linkage ) {
    8081093        switch ( type->kind ) {
    809           case TypeData::Enum: {
    810                   if ( type->enumeration.body ) {
    811                           EnumDecl * typedecl = buildEnum( type, attributes, linkage );
    812                           return new EnumInstType( buildQualifiers( type ), typedecl );
    813                   } else {
    814                           return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
    815                   } // if
    816           }
    817           case TypeData::Aggregate: {
    818                   ReferenceToType * ret;
    819                   if ( type->aggregate.body ) {
    820                           AggregateDecl * typedecl = buildAggregate( type, attributes, linkage );
    821                           switch ( type->aggregate.kind ) {
    822                                 case AggregateDecl::Struct:
    823                                 case AggregateDecl::Coroutine:
    824                                 case AggregateDecl::Monitor:
    825                                 case AggregateDecl::Thread:
    826                                   ret = new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
    827                                   break;
    828                                 case AggregateDecl::Union:
    829                                   ret = new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
    830                                   break;
    831                                 case AggregateDecl::Trait:
    832                                   assert( false );
    833                                   //ret = new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
    834                                   break;
    835                                 default:
    836                                   assert( false );
    837                           } // switch
    838                   } else {
    839                           switch ( type->aggregate.kind ) {
    840                                 case AggregateDecl::Struct:
    841                                 case AggregateDecl::Coroutine:
    842                                 case AggregateDecl::Monitor:
    843                                 case AggregateDecl::Thread:
    844                                   ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
    845                                   break;
    846                                 case AggregateDecl::Union:
    847                                   ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
    848                                   break;
    849                                 case AggregateDecl::Trait:
    850                                   ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
    851                                   break;
    852                                 default:
    853                                   assert( false );
    854                           } // switch
    855                   } // if
    856                   return ret;
    857           }
    858           default:
     1094        case TypeData::Enum:
     1095                if ( type->enumeration.body ) {
     1096                        ast::EnumDecl * typedecl =
     1097                                buildEnum( type, std::move( attributes ), linkage );
     1098                        return new ast::EnumInstType(
     1099                                typedecl,
     1100                                buildQualifiers( type )
     1101                        );
     1102                } else {
     1103                        return new ast::EnumInstType(
     1104                                *type->enumeration.name,
     1105                                buildQualifiers( type )
     1106                        );
     1107                } // if
     1108                break;
     1109        case TypeData::Aggregate:
     1110                if ( type->aggregate.body ) {
     1111                        ast::AggregateDecl * typedecl =
     1112                                buildAggregate( type, std::move( attributes ), linkage );
     1113                        switch ( type->aggregate.kind ) {
     1114                        case ast::AggregateDecl::Struct:
     1115                        case ast::AggregateDecl::Coroutine:
     1116                        case ast::AggregateDecl::Monitor:
     1117                        case ast::AggregateDecl::Thread:
     1118                                return new ast::StructInstType(
     1119                                        strict_dynamic_cast<ast::StructDecl *>( typedecl ),
     1120                                        buildQualifiers( type )
     1121                                );
     1122                        case ast::AggregateDecl::Union:
     1123                                return new ast::UnionInstType(
     1124                                        strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
     1125                                        buildQualifiers( type )
     1126                                );
     1127                        case ast::AggregateDecl::Trait:
     1128                                assert( false );
     1129                                break;
     1130                        default:
     1131                                assert( false );
     1132                        } // switch
     1133                } else {
     1134                        switch ( type->aggregate.kind ) {
     1135                        case ast::AggregateDecl::Struct:
     1136                        case ast::AggregateDecl::Coroutine:
     1137                        case ast::AggregateDecl::Monitor:
     1138                        case ast::AggregateDecl::Thread:
     1139                                return new ast::StructInstType(
     1140                                        *type->aggregate.name,
     1141                                        buildQualifiers( type )
     1142                                );
     1143                        case ast::AggregateDecl::Union:
     1144                                return new ast::UnionInstType(
     1145                                        *type->aggregate.name,
     1146                                        buildQualifiers( type )
     1147                                );
     1148                        case ast::AggregateDecl::Trait:
     1149                                return new ast::TraitInstType(
     1150                                        *type->aggregate.name,
     1151                                        buildQualifiers( type )
     1152                                );
     1153                        default:
     1154                                assert( false );
     1155                        } // switch
     1156                        break;
     1157                } // if
     1158                break;
     1159        default:
    8591160                assert( false );
    8601161        } // switch
     1162        assert( false );
    8611163} // buildAggInst
    8621164
    8631165
    864 ReferenceToType * buildAggInst( const TypeData * td ) {
     1166ast::BaseInstType * buildAggInst( const TypeData * td ) {
    8651167        assert( td->kind == TypeData::AggregateInst );
    8661168
    867         // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() );
    868         ReferenceToType * ret = nullptr;
     1169        ast::BaseInstType * ret = nullptr;
    8691170        TypeData * type = td->aggInst.aggregate;
    8701171        switch ( type->kind ) {
    871           case TypeData::Enum: {
    872                   return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
    873           }
    874           case TypeData::Aggregate: {
    875                   switch ( type->aggregate.kind ) {
    876                         case AggregateDecl::Struct:
    877                         case AggregateDecl::Coroutine:
    878                         case AggregateDecl::Monitor:
    879                         case AggregateDecl::Thread:
    880                           ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
    881                           break;
    882                         case AggregateDecl::Union:
    883                           ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
    884                           break;
    885                         case AggregateDecl::Trait:
    886                           ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
    887                           break;
    888                         default:
    889                           assert( false );
    890                   } // switch
    891           }
    892           break;
    893           default:
     1172        case TypeData::Enum:
     1173                return new ast::EnumInstType(
     1174                        *type->enumeration.name,
     1175                        buildQualifiers( type )
     1176                );
     1177        case TypeData::Aggregate:
     1178                switch ( type->aggregate.kind ) {
     1179                case ast::AggregateDecl::Struct:
     1180                case ast::AggregateDecl::Coroutine:
     1181                case ast::AggregateDecl::Monitor:
     1182                case ast::AggregateDecl::Thread:
     1183                        ret = new ast::StructInstType(
     1184                                *type->aggregate.name,
     1185                                buildQualifiers( type )
     1186                        );
     1187                        break;
     1188                case ast::AggregateDecl::Union:
     1189                        ret = new ast::UnionInstType(
     1190                                *type->aggregate.name,
     1191                                buildQualifiers( type )
     1192                        );
     1193                        break;
     1194                case ast::AggregateDecl::Trait:
     1195                        ret = new ast::TraitInstType(
     1196                                *type->aggregate.name,
     1197                                buildQualifiers( type )
     1198                        );
     1199                        break;
     1200                default:
     1201                        assert( false );
     1202                } // switch
     1203                break;
     1204        default:
    8941205                assert( false );
    8951206        } // switch
    8961207
    897         ret->set_hoistType( td->aggInst.hoistType );
    898         buildList( td->aggInst.params, ret->get_parameters() );
    899         buildForall( td->forall, ret->get_forall() );
     1208        ret->hoistType = td->aggInst.hoistType;
     1209        buildList( td->aggInst.params, ret->params );
    9001210        return ret;
    9011211} // buildAggInst
    9021212
    9031213
    904 NamedTypeDecl * buildSymbolic( const TypeData * td, std::list< Attribute * > attributes, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) {
     1214ast::NamedTypeDecl * buildSymbolic(
     1215                const TypeData * td,
     1216                std::vector<ast::ptr<ast::Attribute>> attributes,
     1217                const std::string & name,
     1218                ast::Storage::Classes scs,
     1219                ast::Linkage::Spec linkage ) {
    9051220        assert( td->kind == TypeData::Symbolic );
    906         NamedTypeDecl * ret;
     1221        ast::NamedTypeDecl * ret;
    9071222        assert( td->base );
    9081223        if ( td->symbolic.isTypedef ) {
    909                 ret = new TypedefDecl( name, td->location, scs, typebuild( td->base ), linkage );
     1224                ret = new ast::TypedefDecl(
     1225                        td->location,
     1226                        name,
     1227                        scs,
     1228                        typebuild( td->base ),
     1229                        linkage
     1230                );
    9101231        } else {
    911                 ret = new TypeDecl( name, scs, typebuild( td->base ), TypeDecl::Dtype, true );
     1232                ret = new ast::TypeDecl(
     1233                        td->location,
     1234                        name,
     1235                        scs,
     1236                        typebuild( td->base ),
     1237                        ast::TypeDecl::Dtype,
     1238                        true
     1239                );
    9121240        } // if
    913         buildList( td->symbolic.assertions, ret->get_assertions() );
    914         ret->base->attributes.splice( ret->base->attributes.end(), attributes );
     1241        buildList( td->symbolic.assertions, ret->assertions );
     1242        splice( ret->base.get_and_mutate()->attributes, attributes );
    9151243        return ret;
    9161244} // buildSymbolic
    9171245
    9181246
    919 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
     1247ast::EnumDecl * buildEnum(
     1248                const TypeData * td,
     1249                std::vector<ast::ptr<ast::Attribute>> && attributes,
     1250                ast::Linkage::Spec linkage ) {
    9201251        assert( td->kind == TypeData::Enum );
    921         Type * baseType = td->base ? typebuild(td->base) : nullptr;
    922         EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType );
    923         buildList( td->enumeration.constants, ret->get_members() );
    924         list< Declaration * >::iterator members = ret->get_members().begin();
    925         ret->hide = td->enumeration.hiding == EnumHiding::Hide ? EnumDecl::EnumHiding::Hide : EnumDecl::EnumHiding::Visible;
     1252        ast::Type * baseType = td->base ? typebuild(td->base) : nullptr;
     1253        ast::EnumDecl * ret = new ast::EnumDecl(
     1254                td->location,
     1255                *td->enumeration.name,
     1256                td->enumeration.typed,
     1257                std::move( attributes ),
     1258                linkage,
     1259                baseType
     1260        );
     1261        buildList( td->enumeration.constants, ret->members );
     1262        auto members = ret->members.begin();
     1263        ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
    9261264        for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
    9271265                if ( cur->enumInLine ) {
     
    9301268                        SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
    9311269                } else if ( cur->has_enumeratorValue() ) {
    932                         ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
    933                         member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
     1270                        ast::Decl * member = members->get_and_mutate();
     1271                        ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
     1272                        object->init = new ast::SingleInit(
     1273                                td->location,
     1274                                maybeMoveBuild( cur->consume_enumeratorValue() ),
     1275                                ast::NoConstruct
     1276                        );
    9341277                } else if ( !cur->initializer ) {
    935                         if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) {
     1278                        if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) {
    9361279                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
    9371280                        }
     
    9401283                // if
    9411284        } // for
    942         ret->set_body( td->enumeration.body );
     1285        ret->body = td->enumeration.body;
    9431286        return ret;
    9441287} // buildEnum
    9451288
    9461289
    947 TypeInstType * buildSymbolicInst( const TypeData * td ) {
     1290ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
    9481291        assert( td->kind == TypeData::SymbolicInst );
    949         TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false );
    950         buildList( td->symbolic.actuals, ret->get_parameters() );
    951         buildForall( td->forall, ret->get_forall() );
     1292        ast::TypeInstType * ret = new ast::TypeInstType(
     1293                *td->symbolic.name,
     1294                ast::TypeDecl::Dtype,
     1295                buildQualifiers( td )
     1296        );
     1297        buildList( td->symbolic.actuals, ret->params );
    9521298        return ret;
    9531299} // buildSymbolicInst
    9541300
    9551301
    956 TupleType * buildTuple( const TypeData * td ) {
     1302ast::TupleType * buildTuple( const TypeData * td ) {
    9571303        assert( td->kind == TypeData::Tuple );
    958         std::list< Type * > types;
     1304        std::vector<ast::ptr<ast::Type>> types;
    9591305        buildTypeList( td->tuple, types );
    960         TupleType * ret = new TupleType( buildQualifiers( td ), types );
    961         buildForall( td->forall, ret->get_forall() );
     1306        ast::TupleType * ret = new ast::TupleType(
     1307                std::move( types ),
     1308                buildQualifiers( td )
     1309        );
    9621310        return ret;
    9631311} // buildTuple
    9641312
    9651313
    966 TypeofType * buildTypeof( const TypeData * td ) {
     1314ast::TypeofType * buildTypeof( const TypeData * td ) {
    9671315        assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
    9681316        assert( td->typeexpr );
    969         // assert( td->typeexpr->expr );
    970         return new TypeofType{ buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof };
     1317        return new ast::TypeofType(
     1318                td->typeexpr->build(),
     1319                td->kind == TypeData::Typeof
     1320                        ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof,
     1321                buildQualifiers( td )
     1322        );
    9711323} // buildTypeof
    9721324
    9731325
    974 VTableType * buildVtable( const TypeData * td ) {
     1326ast::VTableType * buildVtable( const TypeData * td ) {
    9751327        assert( td->base );
    976         return new VTableType{ buildQualifiers( td ), typebuild( td->base ) };
     1328        return new ast::VTableType(
     1329                typebuild( td->base ),
     1330                buildQualifiers( td )
     1331        );
    9771332} // buildVtable
    9781333
    9791334
    980 Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) {
     1335ast::FunctionDecl * buildFunctionDecl(
     1336                const TypeData * td,
     1337                const string &name,
     1338                ast::Storage::Classes scs,
     1339                ast::Function::Specs funcSpec,
     1340                ast::Linkage::Spec linkage,
     1341                ast::Expr * asmName,
     1342                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
     1343        assert( td->kind == TypeData::Function );
     1344        // For some reason FunctionDecl takes a bool instead of an ArgumentFlag.
     1345        bool isVarArgs = !td->function.params || td->function.params->hasEllipsis;
     1346        ast::CV::Qualifiers cvq = buildQualifiers( td );
     1347        std::vector<ast::ptr<ast::TypeDecl>> forall;
     1348        std::vector<ast::ptr<ast::DeclWithType>> assertions;
     1349        std::vector<ast::ptr<ast::DeclWithType>> params;
     1350        std::vector<ast::ptr<ast::DeclWithType>> returns;
     1351        buildList( td->function.params, params );
     1352        buildForall( td->forall, forall );
     1353        // Functions do not store their assertions there anymore.
     1354        for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
     1355                auto mut = type_param.get_and_mutate();
     1356                splice( assertions, mut->assertions );
     1357        }
     1358        if ( td->base ) {
     1359                switch ( td->base->kind ) {
     1360                case TypeData::Tuple:
     1361                        buildList( td->base->tuple, returns );
     1362                        break;
     1363                default:
     1364                        returns.push_back( dynamic_cast<ast::DeclWithType *>(
     1365                                buildDecl(
     1366                                        td->base,
     1367                                        "",
     1368                                        ast::Storage::Classes(),
     1369                                        (ast::Expr *)nullptr, // bitfieldWidth
     1370                                        ast::Function::Specs(),
     1371                                        ast::Linkage::Cforall,
     1372                                        (ast::Expr *)nullptr // asmName
     1373                                )
     1374                        ) );
     1375                } // switch
     1376        } else {
     1377                returns.push_back( new ast::ObjectDecl(
     1378                        td->location,
     1379                        "",
     1380                        new ast::BasicType( ast::BasicType::SignedInt ),
     1381                        (ast::Init *)nullptr,
     1382                        ast::Storage::Classes(),
     1383                        ast::Linkage::Cforall
     1384                ) );
     1385        } // if
     1386        ast::Stmt * stmt = maybeBuild( td->function.body );
     1387        ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
     1388        ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
     1389                name,
     1390                std::move( forall ),
     1391                std::move( assertions ),
     1392                std::move( params ),
     1393                std::move( returns ),
     1394                body,
     1395                scs,
     1396                linkage,
     1397                std::move( attributes ),
     1398                funcSpec,
     1399                (isVarArgs) ? ast::VariableArgs : ast::FixedArgs
     1400        );
     1401        buildList( td->function.withExprs, decl->withExprs );
     1402        decl->asmName = asmName;
     1403        // This may be redundant on a declaration.
     1404        decl->type.get_and_mutate()->qualifiers = cvq;
     1405        return decl;
     1406} // buildFunctionDecl
     1407
     1408
     1409ast::Decl * buildDecl(
     1410                const TypeData * td,
     1411                const string &name,
     1412                ast::Storage::Classes scs,
     1413                ast::Expr * bitfieldWidth,
     1414                ast::Function::Specs funcSpec,
     1415                ast::Linkage::Spec linkage,
     1416                ast::Expr * asmName,
     1417                ast::Init * init,
     1418                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
    9811419        if ( td->kind == TypeData::Function ) {
    9821420                if ( td->function.idList ) {                                    // KR function ?
     
    9841422                } // if
    9851423
    986                 FunctionDecl * decl;
    987                 Statement * stmt = maybeBuild<Statement>( td->function.body );
    988                 CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt );
    989                 decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec );
    990                 buildList( td->function.withExprs, decl->withExprs );
    991                 return decl->set_asmName( asmName );
     1424                return buildFunctionDecl(
     1425                        td, name, scs, funcSpec, linkage,
     1426                        asmName, std::move( attributes ) );
    9921427        } else if ( td->kind == TypeData::Aggregate ) {
    993                 return buildAggregate( td, attributes, linkage );
     1428                return buildAggregate( td, std::move( attributes ), linkage );
    9941429        } else if ( td->kind == TypeData::Enum ) {
    995                 return buildEnum( td, attributes, linkage );
     1430                return buildEnum( td, std::move( attributes ), linkage );
    9961431        } else if ( td->kind == TypeData::Symbolic ) {
    997                 return buildSymbolic( td, attributes, name, scs, linkage );
     1432                return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
    9981433        } else {
    999                 return (new ObjectDecl( name, scs, linkage, bitfieldWidth, typebuild( td ), init, attributes ))->set_asmName( asmName );
     1434                auto ret = new ast::ObjectDecl( td->location,
     1435                        name,
     1436                        typebuild( td ),
     1437                        init,
     1438                        scs,
     1439                        linkage,
     1440                        bitfieldWidth,
     1441                        std::move( attributes )
     1442                );
     1443                ret->asmName = asmName;
     1444                return ret;
    10001445        } // if
    10011446        return nullptr;
     
    10031448
    10041449
    1005 FunctionType * buildFunction( const TypeData * td ) {
     1450ast::FunctionType * buildFunctionType( const TypeData * td ) {
    10061451        assert( td->kind == TypeData::Function );
    1007         FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis );
    1008         buildList( td->function.params, ft->parameters );
     1452        ast::FunctionType * ft = new ast::FunctionType(
     1453                ( !td->function.params || td->function.params->hasEllipsis )
     1454                        ? ast::VariableArgs : ast::FixedArgs,
     1455                buildQualifiers( td )
     1456        );
     1457        buildTypeList( td->function.params, ft->params );
    10091458        buildForall( td->forall, ft->forall );
    10101459        if ( td->base ) {
    10111460                switch ( td->base->kind ) {
    1012                   case TypeData::Tuple:
    1013                         buildList( td->base->tuple, ft->returnVals );
     1461                case TypeData::Tuple:
     1462                        buildTypeList( td->base->tuple, ft->returns );
    10141463                        break;
    1015                   default:
    1016                         ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType * >( buildDecl( td->base, "", Type::StorageClasses(), nullptr, Type::FuncSpecifiers(), LinkageSpec::Cforall, nullptr ) ) );
     1464                default:
     1465                        ft->returns.push_back( typebuild( td->base ) );
     1466                        break;
    10171467                } // switch
    10181468        } else {
    1019                 ft->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) );
     1469                ft->returns.push_back(
     1470                        new ast::BasicType( ast::BasicType::SignedInt ) );
    10201471        } // if
    10211472        return ft;
    1022 } // buildFunction
     1473} // buildFunctionType
    10231474
    10241475
     
    10511502                                param->type = decl->type;                               // set copy declaration type to parameter type
    10521503                                decl->type = nullptr;                                   // reset declaration type
    1053                                 param->attributes.splice( param->attributes.end(), decl->attributes ); // copy and reset attributes from declaration to parameter
     1504                                // Copy and reset attributes from declaration to parameter:
     1505                                splice( param->attributes, decl->attributes );
    10541506                        } // if
    10551507                } // for
  • src/Parser/TypeData.h

    r34b4268 r24d6572  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 15:18:36 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 10 22:18:49 2022
    13 // Update Count     : 203
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Mar  1 10:44:00 2023
     13// Update Count     : 206
    1414//
    1515
    1616#pragma once
    1717
    18 #include <iosfwd>                                                                               // for ostream
    19 #include <list>                                                                                 // for list
    20 #include <string>                                                                               // for string
     18#include <iosfwd>                                   // for ostream
     19#include <list>                                     // for list
     20#include <string>                                   // for string
    2121
    22 #include "ParseNode.h"                                                                  // for DeclarationNode, DeclarationNode::Ag...
    23 #include "SynTree/LinkageSpec.h"                                                // for Spec
    24 #include "SynTree/Type.h"                                                               // for Type, ReferenceToType (ptr only)
    25 #include "SynTree/SynTree.h"                                                    // for Visitor Nodes
     22#include "AST/Type.hpp"                             // for Type
     23#include "DeclarationNode.h"                        // for DeclarationNode
    2624
    2725struct TypeData {
     
    3028
    3129        struct Aggregate_t {
    32                 AggregateDecl::Aggregate kind;
     30                ast::AggregateDecl::Aggregate kind;
    3331                const std::string * name = nullptr;
    3432                DeclarationNode * params = nullptr;
     
    3735                bool body;
    3836                bool anon;
    39 
    4037                bool tagged;
    4138                const std::string * parent = nullptr;
     
    9491        DeclarationNode::BuiltinType builtintype = DeclarationNode::NoBuiltinType;
    9592
    96         Type::Qualifiers qualifiers;
     93        ast::CV::Qualifiers qualifiers;
    9794        DeclarationNode * forall = nullptr;
    9895
     
    115112};
    116113
    117 Type * typebuild( const TypeData * );
     114ast::Type * typebuild( const TypeData * );
    118115TypeData * typeextractAggregate( const TypeData * td, bool toplevel = true );
    119 Type::Qualifiers buildQualifiers( const TypeData * td );
    120 Type * buildBasicType( const TypeData * );
    121 PointerType * buildPointer( const TypeData * );
    122 ArrayType * buildArray( const TypeData * );
    123 ReferenceType * buildReference( const TypeData * );
    124 AggregateDecl * buildAggregate( const TypeData *, std::list< Attribute * > );
    125 ReferenceToType * buildComAggInst( const TypeData *, std::list< Attribute * > attributes, LinkageSpec::Spec linkage );
    126 ReferenceToType * buildAggInst( const TypeData * );
    127 TypeDecl * buildVariable( const TypeData * );
    128 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * >, LinkageSpec::Spec );
    129 TypeInstType * buildSymbolicInst( const TypeData * );
    130 TupleType * buildTuple( const TypeData * );
    131 TypeofType * buildTypeof( const TypeData * );
    132 VTableType * buildVtable( const TypeData * );
    133 Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName,
    134                                                  Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
    135 FunctionType * buildFunction( const TypeData * );
    136 Declaration * addEnumBase( Declaration *, const TypeData * );
     116ast::CV::Qualifiers buildQualifiers( const TypeData * td );
     117ast::Type * buildBasicType( const TypeData * );
     118ast::PointerType * buildPointer( const TypeData * );
     119ast::ArrayType * buildArray( const TypeData * );
     120ast::ReferenceType * buildReference( const TypeData * );
     121ast::AggregateDecl * buildAggregate( const TypeData *, std::vector<ast::ptr<ast::Attribute>> );
     122ast::BaseInstType * buildComAggInst( const TypeData *, std::vector<ast::ptr<ast::Attribute>> && attributes, ast::Linkage::Spec linkage );
     123ast::BaseInstType * buildAggInst( const TypeData * );
     124ast::TypeDecl * buildVariable( const TypeData * );
     125ast::EnumDecl * buildEnum( const TypeData *, std::vector<ast::ptr<ast::Attribute>> &&, ast::Linkage::Spec );
     126ast::TypeInstType * buildSymbolicInst( const TypeData * );
     127ast::TupleType * buildTuple( const TypeData * );
     128ast::TypeofType * buildTypeof( const TypeData * );
     129ast::VTableType * buildVtable( const TypeData * );
     130ast::Decl * buildDecl(
     131        const TypeData *, const std::string &, ast::Storage::Classes, ast::Expr *,
     132        ast::Function::Specs funcSpec, ast::Linkage::Spec, ast::Expr * asmName,
     133        ast::Init * init = nullptr, std::vector<ast::ptr<ast::Attribute>> && attributes = std::vector<ast::ptr<ast::Attribute>>() );
     134ast::FunctionType * buildFunctionType( const TypeData * );
     135ast::Decl * addEnumBase( Declaration *, const TypeData * );
    137136void buildKRFunction( const TypeData::Function_t & function );
    138137
  • src/Parser/TypedefTable.cc

    r34b4268 r24d6572  
    1616
    1717#include "TypedefTable.h"
    18 #include <cassert>                                                                              // for assert
    19 #include <iostream>
     18
     19#include <cassert>                                // for assert
     20#include <string>                                 // for string
     21#include <iostream>                               // for iostream
     22
     23#include "ExpressionNode.h"                       // for LabelNode
     24#include "ParserTypes.h"                          // for Token
     25#include "StatementNode.h"                        // for CondCtl, ForCtrl
     26// This (generated) header must come late as it is missing includes.
     27#include "parser.hh"              // for IDENTIFIER, TYPEDEFname, TYPEGENname
     28
    2029using namespace std;
    2130
    2231#if 0
    2332#define debugPrint( code ) code
     33
     34static const char *kindName( int kind ) {
     35        switch ( kind ) {
     36        case IDENTIFIER: return "identifier";
     37        case TYPEDIMname: return "typedim";
     38        case TYPEDEFname: return "typedef";
     39        case TYPEGENname: return "typegen";
     40        default:
     41                cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
     42                abort();
     43        } // switch
     44} // kindName
    2445#else
    2546#define debugPrint( code )
    2647#endif
    27 
    28 using namespace std;                                                                    // string, iostream
    29 
    30 debugPrint(
    31         static const char *kindName( int kind ) {
    32                 switch ( kind ) {
    33                   case IDENTIFIER: return "identifier";
    34                   case TYPEDIMname: return "typedim";
    35                   case TYPEDEFname: return "typedef";
    36                   case TYPEGENname: return "typegen";
    37                   default:
    38                         cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
    39                         abort();
    40                 } // switch
    41         } // kindName
    42 );
    4348
    4449TypedefTable::~TypedefTable() {
     
    7883                typedefTable.addToEnclosingScope( name, kind, "MTD" );
    7984        } // if
     85} // TypedefTable::makeTypedef
     86
     87void TypedefTable::makeTypedef( const string & name ) {
     88        return makeTypedef( name, TYPEDEFname );
    8089} // TypedefTable::makeTypedef
    8190
  • src/Parser/TypedefTable.h

    r34b4268 r24d6572  
    1919
    2020#include "Common/ScopedMap.h"                                                   // for ScopedMap
    21 #include "ParserTypes.h"
    22 #include "parser.hh"                                                                    // for IDENTIFIER, TYPEDEFname, TYPEGENname
    2321
    2422class TypedefTable {
    2523        struct Note { size_t level; bool forall; };
    2624        typedef ScopedMap< std::string, int, Note > KindTable;
    27         KindTable kindTable;   
     25        KindTable kindTable;
    2826        unsigned int level = 0;
    2927  public:
     
    3331        bool existsCurr( const std::string & identifier ) const;
    3432        int isKind( const std::string & identifier ) const;
    35         void makeTypedef( const std::string & name, int kind = TYPEDEFname );
     33        void makeTypedef( const std::string & name, int kind );
     34        void makeTypedef( const std::string & name );
    3635        void addToScope( const std::string & identifier, int kind, const char * );
    3736        void addToEnclosingScope( const std::string & identifier, int kind, const char * );
  • src/Parser/lex.ll

    r34b4268 r24d6572  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Oct 13 20:46:04 2022
    13  * Update Count     : 764
     12 * Last Modified On : Tue May  2 08:45:21 2023
     13 * Update Count     : 769
    1414 */
    1515
     
    2323// line-number directives) and C/C++ style comments, which are ignored.
    2424
    25 //**************************** Includes and Defines ****************************
     25// *************************** Includes and Defines ****************************
    2626
    2727#ifdef __clang__
     
    4444
    4545#include "config.h"                                                                             // configure info
     46#include "DeclarationNode.h"                            // for DeclarationNode
     47#include "ExpressionNode.h"                             // for LabelNode
     48#include "InitializerNode.h"                            // for InitializerNode
    4649#include "ParseNode.h"
     50#include "ParserTypes.h"                                // for Token
     51#include "StatementNode.h"                              // for CondCtl, ForCtrl
    4752#include "TypedefTable.h"
     53// This (generated) header must come late as it is missing includes.
     54#include "parser.hh"                                    // generated info
    4855
    4956string * build_postfix_name( string * name );
     
    214221__alignof               { KEYWORD_RETURN(ALIGNOF); }                    // GCC
    215222__alignof__             { KEYWORD_RETURN(ALIGNOF); }                    // GCC
     223and                             { QKEYWORD_RETURN(WAND); }                              // CFA
    216224asm                             { KEYWORD_RETURN(ASM); }
    217225__asm                   { KEYWORD_RETURN(ASM); }                                // GCC
     
    250258enable                  { KEYWORD_RETURN(ENABLE); }                             // CFA
    251259enum                    { KEYWORD_RETURN(ENUM); }
     260exception               { KEYWORD_RETURN(EXCEPTION); }                  // CFA
    252261__extension__   { KEYWORD_RETURN(EXTENSION); }                  // GCC
    253 exception               { KEYWORD_RETURN(EXCEPTION); }                  // CFA
    254262extern                  { KEYWORD_RETURN(EXTERN); }
    255263fallthrough             { KEYWORD_RETURN(FALLTHROUGH); }                // CFA
     
    340348vtable                  { KEYWORD_RETURN(VTABLE); }                             // CFA
    341349waitfor                 { KEYWORD_RETURN(WAITFOR); }                    // CFA
     350waituntil               { KEYWORD_RETURN(WAITUNTIL); }                  // CFA
    342351when                    { KEYWORD_RETURN(WHEN); }                               // CFA
    343352while                   { KEYWORD_RETURN(WHILE); }
     
    502511        SemanticErrorThrow = true;
    503512        cerr << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
    504                  << ": " << ErrorHelpers::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;
     513                 << ": " << ErrorHelpers::error_str() << errmsg << " before token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;
    505514}
    506515
  • src/Parser/module.mk

    r34b4268 r24d6572  
    2121SRC += \
    2222       Parser/DeclarationNode.cc \
     23       Parser/DeclarationNode.h \
    2324       Parser/ExpressionNode.cc \
     25       Parser/ExpressionNode.h \
    2426       Parser/InitializerNode.cc \
     27       Parser/InitializerNode.h \
    2528       Parser/lex.ll \
    2629       Parser/ParseNode.cc \
     
    3033       Parser/parserutility.cc \
    3134       Parser/parserutility.h \
     35       Parser/RunParser.cpp \
     36       Parser/RunParser.hpp \
    3237       Parser/StatementNode.cc \
     38       Parser/StatementNode.h \
    3339       Parser/TypeData.cc \
    3440       Parser/TypeData.h \
  • src/Parser/parser.yy

    r34b4268 r24d6572  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Nov 21 22:34:30 2022
    13 // Update Count     : 5848
     12// Last Modified On : Wed Apr 26 16:45:37 2023
     13// Update Count     : 6330
    1414//
    1515
     
    4444
    4545#include <cstdio>
     46#include <sstream>
    4647#include <stack>
    4748using namespace std;
    4849
    49 #include "SynTree/Declaration.h"
    50 #include "ParseNode.h"
     50#include "SynTree/Type.h"                               // for Type
     51#include "DeclarationNode.h"                            // for DeclarationNode, ...
     52#include "ExpressionNode.h"                             // for ExpressionNode, ...
     53#include "InitializerNode.h"                            // for InitializerNode, ...
     54#include "ParserTypes.h"
     55#include "StatementNode.h"                              // for build_...
    5156#include "TypedefTable.h"
    5257#include "TypeData.h"
    53 #include "SynTree/LinkageSpec.h"
    5458#include "Common/SemanticError.h"                                               // error_str
    5559#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
    5660
    57 #include "SynTree/Attribute.h"     // for Attribute
     61#include "SynTree/Attribute.h"                                                  // for Attribute
    5862
    5963// lex uses __null in a boolean context, it's fine.
     
    6367
    6468extern DeclarationNode * parseTree;
    65 extern LinkageSpec::Spec linkage;
     69extern ast::Linkage::Spec linkage;
    6670extern TypedefTable typedefTable;
    6771
    68 stack<LinkageSpec::Spec> linkageStack;
     72stack<ast::Linkage::Spec> linkageStack;
    6973
    7074bool appendStr( string & to, string & from ) {
     
    199203} // fieldDecl
    200204
    201 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
    202 #define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
     205#define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) )
     206#define NEW_ONE  new ExpressionNode( build_constantInteger( yylloc, *new string( "1" ) ) )
    203207#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    204208#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     
    206210#define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
    207211
    208 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     212static ForCtrl * makeForCtrl(
     213                const CodeLocation & location,
     214                DeclarationNode * init,
     215                enum OperKinds compop,
     216                ExpressionNode * comp,
     217                ExpressionNode * inc ) {
     218        // Wrap both comp/inc if they are non-null.
     219        if ( comp ) comp = new ExpressionNode( build_binary_val( location,
     220                compop,
     221                new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
     222                comp ) );
     223        if ( inc ) inc = new ExpressionNode( build_binary_val( location,
     224                // choose += or -= for upto/downto
     225                compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn,
     226                new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
     227                inc ) );
     228        // The StatementNode call frees init->name, it must happen later.
     229        return new ForCtrl( new StatementNode( init ), comp, inc );
     230}
     231
     232ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    209233        if ( index->initializer ) {
    210234                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    213237                SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
    214238        } // if
    215         return new ForCtrl( index->addInitializer( new InitializerNode( start ) ),
    216                 // NULL comp/inc => leave blank
    217                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr,
    218                 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    219                                                         OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr );
     239        DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) );
     240        return makeForCtrl( location, initDecl, compop, comp, inc );
    220241} // forCtrl
    221242
    222 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    223         ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
    224         if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
    225                 type = new ExpressionNode( new CastExpr( maybeMoveBuild<Expression>(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
     243ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     244        ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());
     245        if ( constant && (constant->rep == "0" || constant->rep == "1") ) {
     246                type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) );
    226247        } // if
    227 //      type = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__for_control_index_constraints__" ) ) ), type ) );
    228         return new ForCtrl(
    229                 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
    230                 // NULL comp/inc => leave blank
    231                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr,
    232                 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    233                                                         OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr );
     248        DeclarationNode * initDecl = distAttr(
     249                DeclarationNode::newTypeof( type, true ),
     250                DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) )
     251        );
     252        return makeForCtrl( location, initDecl, compop, comp, inc );
    234253} // forCtrl
    235254
    236 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    237         if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {
    238                 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
    239         } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {
    240                 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) {
    241                         return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     255ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     256        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {
     257                return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
     258        } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {
     259                if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
     260                        return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
    242261                } else {
    243262                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     
    281300%union {
    282301        Token tok;
    283         ParseNode * pn;
    284         ExpressionNode * en;
     302        ExpressionNode * expr;
    285303        DeclarationNode * decl;
    286         AggregateDecl::Aggregate aggKey;
    287         TypeDecl::Kind tclass;
    288         StatementNode * sn;
    289         WaitForStmt * wfs;
    290         Expression * constant;
     304        ast::AggregateDecl::Aggregate aggKey;
     305        ast::TypeDecl::Kind tclass;
     306        StatementNode * stmt;
     307        ClauseNode * clause;
     308        ast::WaitForStmt * wfs;
     309    ast::WaitUntilStmt::ClauseNode * wucn;
    291310        CondCtl * ifctl;
    292         ForCtrl * fctl;
    293         OperKinds compop;
    294         LabelNode * label;
    295         InitializerNode * in;
    296         OperKinds op;
     311        ForCtrl * forctl;
     312        LabelNode * labels;
     313        InitializerNode * init;
     314        OperKinds oper;
    297315        std::string * str;
    298         bool flag;
    299         EnumHiding hide;
    300         CatchStmt::Kind catch_kind;
    301         GenericExpr * genexpr;
     316        bool is_volatile;
     317        EnumHiding enum_hiding;
     318        ast::ExceptionKind except_kind;
     319        ast::GenericExpr * genexpr;
    302320}
    303321
    304 //************************* TERMINAL TOKENS ********************************
     322// ************************ TERMINAL TOKENS ********************************
    305323
    306324// keywords
     
    331349%token ATTRIBUTE EXTENSION                                                              // GCC
    332350%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
    333 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR    // CFA
     351%token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR WAITUNTIL // CFA
    334352%token DISABLE ENABLE TRY THROW THROWRESUME AT                  // CFA
    335353%token ASM                                                                                              // C99, extension ISO/IEC 9899:1999 Section J.5.10(1)
     
    337355
    338356// names and constants: lexer differentiates between identifier and typedef names
    339 %token<tok> IDENTIFIER          QUOTED_IDENTIFIER       TYPEDIMname             TYPEDEFname             TYPEGENname
    340 %token<tok> TIMEOUT                     WOR                                     CATCH                   RECOVER                 CATCHRESUME             FIXUP           FINALLY         // CFA
     357%token<tok> IDENTIFIER          TYPEDIMname             TYPEDEFname             TYPEGENname
     358%token<tok> TIMEOUT                     WAND    WOR                     CATCH                   RECOVER                 CATCHRESUME             FIXUP           FINALLY         // CFA
    341359%token<tok> INTEGERconstant     CHARACTERconstant       STRINGliteral
    342360%token<tok> DIRECTIVE
     
    364382%type<tok> identifier                                   identifier_at                           identifier_or_type_name         attr_name
    365383%type<tok> quasi_keyword
    366 %type<constant> string_literal
     384%type<expr> string_literal
    367385%type<str> string_literal_list
    368386
    369 %type<hide> hide_opt                                    visible_hide_opt
     387%type<enum_hiding> hide_opt                                     visible_hide_opt
    370388
    371389// expressions
    372 %type<en> constant
    373 %type<en> tuple                                                 tuple_expression_list
    374 %type<op> ptrref_operator                               unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
    375 %type<en> primary_expression                    postfix_expression                      unary_expression
    376 %type<en> cast_expression_list                  cast_expression                         exponential_expression          multiplicative_expression       additive_expression
    377 %type<en> shift_expression                              relational_expression           equality_expression
    378 %type<en> AND_expression                                exclusive_OR_expression         inclusive_OR_expression
    379 %type<en> logical_AND_expression                logical_OR_expression
    380 %type<en> conditional_expression                constant_expression                     assignment_expression           assignment_expression_opt
    381 %type<en> comma_expression                              comma_expression_opt
    382 %type<en> argument_expression_list_opt  argument_expression_list        argument_expression                     default_initializer_opt
     390%type<expr> constant
     391%type<expr> tuple                                                       tuple_expression_list
     392%type<oper> ptrref_operator                             unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
     393%type<expr> primary_expression                  postfix_expression                      unary_expression
     394%type<expr> cast_expression_list                        cast_expression                         exponential_expression          multiplicative_expression       additive_expression
     395%type<expr> shift_expression                            relational_expression           equality_expression
     396%type<expr> AND_expression                              exclusive_OR_expression         inclusive_OR_expression
     397%type<expr> logical_AND_expression              logical_OR_expression
     398%type<expr> conditional_expression              constant_expression                     assignment_expression           assignment_expression_opt
     399%type<expr> comma_expression                            comma_expression_opt
     400%type<expr> argument_expression_list_opt        argument_expression_list        argument_expression                     default_initializer_opt
    383401%type<ifctl> conditional_declaration
    384 %type<fctl> for_control_expression              for_control_expression_list
    385 %type<compop> upupeq updown updowneq downupdowneq
    386 %type<en> subrange
     402%type<forctl> for_control_expression            for_control_expression_list
     403%type<oper> upupeq updown updowneq downupdowneq
     404%type<expr> subrange
    387405%type<decl> asm_name_opt
    388 %type<en> asm_operands_opt                              asm_operands_list                       asm_operand
    389 %type<label> label_list
    390 %type<en> asm_clobbers_list_opt
    391 %type<flag> asm_volatile_opt
    392 %type<en> handler_predicate_opt
     406%type<expr> asm_operands_opt                            asm_operands_list                       asm_operand
     407%type<labels> label_list
     408%type<expr> asm_clobbers_list_opt
     409%type<is_volatile> asm_volatile_opt
     410%type<expr> handler_predicate_opt
    393411%type<genexpr> generic_association              generic_assoc_list
    394412
    395413// statements
    396 %type<sn> statement                                             labeled_statement                       compound_statement
    397 %type<sn> statement_decl                                statement_decl_list                     statement_list_nodecl
    398 %type<sn> selection_statement                   if_statement
    399 %type<sn> switch_clause_list_opt                switch_clause_list
    400 %type<en> case_value
    401 %type<sn> case_clause                                   case_value_list                         case_label                                      case_label_list
    402 %type<sn> iteration_statement                   jump_statement
    403 %type<sn> expression_statement                  asm_statement
    404 %type<sn> with_statement
    405 %type<en> with_clause_opt
    406 %type<sn> exception_statement                   handler_clause                          finally_clause
    407 %type<catch_kind> handler_key
    408 %type<sn> mutex_statement
    409 %type<en> when_clause                                   when_clause_opt                         waitfor                                         timeout
    410 %type<sn> waitfor_statement
    411 %type<wfs> waitfor_clause
     414%type<stmt> statement                                           labeled_statement                       compound_statement
     415%type<stmt> statement_decl                              statement_decl_list                     statement_list_nodecl
     416%type<stmt> selection_statement                 if_statement
     417%type<clause> switch_clause_list_opt            switch_clause_list
     418%type<expr> case_value
     419%type<clause> case_clause                               case_value_list                         case_label                                      case_label_list
     420%type<stmt> iteration_statement                 jump_statement
     421%type<stmt> expression_statement                        asm_statement
     422%type<stmt> with_statement
     423%type<expr> with_clause_opt
     424%type<stmt> exception_statement
     425%type<clause> handler_clause                    finally_clause
     426%type<except_kind> handler_key
     427%type<stmt> mutex_statement
     428%type<expr> when_clause                                 when_clause_opt                         waitfor         waituntil               timeout
     429%type<stmt> waitfor_statement                           waituntil_statement
     430%type<wfs> wor_waitfor_clause
     431%type<wucn> waituntil_clause                    wand_waituntil_clause       wor_waituntil_clause
    412432
    413433// declarations
     
    421441%type<decl> assertion assertion_list assertion_list_opt
    422442
    423 %type<en> bit_subrange_size_opt bit_subrange_size
     443%type<expr> bit_subrange_size_opt bit_subrange_size
    424444
    425445%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     
    434454
    435455%type<decl> enumerator_list enum_type enum_type_nobody
    436 %type<in> enumerator_value_opt
     456%type<init> enumerator_value_opt
    437457
    438458%type<decl> external_definition external_definition_list external_definition_list_opt
     
    441461
    442462%type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract
    443 %type<en> field field_name_list field_name fraction_constants_opt
     463%type<expr> field field_name_list field_name fraction_constants_opt
    444464
    445465%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    482502%type<decl> typedef_name typedef_declaration typedef_expression
    483503
    484 %type<decl> variable_type_redeclarator type_ptr type_array type_function
     504%type<decl> variable_type_redeclarator variable_type_ptr variable_type_array variable_type_function
     505%type<decl> general_function_declarator function_type_redeclarator function_type_array function_type_no_ptr function_type_ptr
    485506
    486507%type<decl> type_parameter_redeclarator type_parameter_ptr type_parameter_array type_parameter_function
     
    489510%type<decl> type_parameter type_parameter_list type_initializer_opt
    490511
    491 %type<en> type_parameters_opt type_list array_type_list
     512%type<expr> type_parameters_opt type_list array_type_list
    492513
    493514%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    500521
    501522// initializers
    502 %type<in>  initializer initializer_list_opt initializer_opt
     523%type<init>  initializer initializer_list_opt initializer_opt
    503524
    504525// designators
    505 %type<en>  designator designator_list designation
     526%type<expr>  designator designator_list designation
    506527
    507528
     
    512533// Similar issues exit with the waitfor statement.
    513534
    514 // Order of these lines matters (low-to-high precedence). THEN is left associative over WOR/TIMEOUT/ELSE, WOR is left
    515 // associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.
     535// Order of these lines matters (low-to-high precedence). THEN is left associative over WAND/WOR/TIMEOUT/ELSE, WAND/WOR
     536// is left associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE.
    516537%precedence THEN                // rule precedence for IF/WAITFOR statement
     538%precedence ANDAND              // token precedence for start of WAND in WAITFOR statement
     539%precedence WAND                // token precedence for start of WAND in WAITFOR statement
     540%precedence OROR                // token precedence for start of WOR in WAITFOR statement
    517541%precedence WOR                 // token precedence for start of WOR in WAITFOR statement
    518542%precedence TIMEOUT             // token precedence for start of TIMEOUT in WAITFOR statement
     
    592616constant:
    593617                // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
    594         INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }
    595         | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    596         | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    597         | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    598         | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( *$1 ) ); }
     618        INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( yylloc, *$1 ) ); }
     619        | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     620        | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     621        | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     622        | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( yylloc, *$1 ) ); }
    599623        ;
    600624
    601625quasi_keyword:                                                                                  // CFA
    602626        TIMEOUT
     627        | WAND
    603628        | WOR
    604629        | CATCH
     
    621646
    622647string_literal:
    623         string_literal_list                                                     { $$ = build_constantStr( *$1 ); }
     648        string_literal_list                                                     { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 ) ); }
    624649        ;
    625650
     
    638663primary_expression:
    639664        IDENTIFIER                                                                                      // typedef name cannot be used as a variable name
    640                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     665                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    641666        | quasi_keyword
    642                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     667                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    643668        | TYPEDIMname                                                                           // CFA, generic length argument
    644669                // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); }
    645670                // { $$ = new ExpressionNode( build_varref( $1 ) ); }
    646                 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }
     671                { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); }
    647672        | tuple
    648673        | '(' comma_expression ')'
    649674                { $$ = $2; }
    650675        | '(' compound_statement ')'                                            // GCC, lambda expression
    651                 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }
     676                { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); }
    652677        | type_name '.' identifier                                                      // CFA, nested type
    653                 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
     678                { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    654679        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    655680                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    657682                {
    658683                        // add the missing control expression to the GenericExpr and return it
    659                         $5->control = maybeMoveBuild<Expression>( $3 );
     684                        $5->control = maybeMoveBuild( $3 );
    660685                        $$ = new ExpressionNode( $5 );
    661686                }
     
    683708                {
    684709                        // steal the association node from the singleton and delete the wrapper
    685                         $1->associations.splice($1->associations.end(), $3->associations);
     710                        assert( 1 == $3->associations.size() );
     711                        $1->associations.push_back( $3->associations.front() );
    686712                        delete $3;
    687713                        $$ = $1;
     
    693719                {
    694720                        // create a GenericExpr wrapper with one association pair
    695                         $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild<Expression>( $3 ) } } );
     721                        $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );
    696722                }
    697723        | DEFAULT ':' assignment_expression
    698                 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild<Expression>( $3 ) } } ); }
     724                { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }
    699725        ;
    700726
     
    705731                // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
    706732                // Current: Commas in subscripts make tuples.
    707                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
     733                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
    708734        | postfix_expression '[' assignment_expression ']'
    709735                // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
     
    711737                // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
    712738                // equivalent to the old x[i,j].
    713                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     739                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    714740        | constant '[' assignment_expression ']'                        // 3[a], 'a'[a], 3.5[a]
    715                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     741                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    716742        | string_literal '[' assignment_expression ']'          // "abc"[3], 3["abc"]
    717                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
     743                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    718744        | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call
    719745                {
    720746                        Token fn;
    721747                        fn.str = new std::string( "?{}" );                      // location undefined - use location of '{'?
    722                         $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
     748                        $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
    723749                }
    724750        | postfix_expression '(' argument_expression_list_opt ')'
    725                 { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
     751                { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); }
    726752        | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')'
    727753                // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; }
    728                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ),
     754                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, new string( "__builtin_va_arg") ) ),
    729755                                                                                           (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); }
    730756        | postfix_expression '`' identifier                                     // CFA, postfix call
    731                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     757                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    732758        | constant '`' identifier                                                       // CFA, postfix call
    733                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     759                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    734760        | string_literal '`' identifier                                         // CFA, postfix call
    735                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
     761                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    736762        | postfix_expression '.' identifier
    737                 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
     763                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    738764        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
    739                 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); }
     765                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    740766        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    741                 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
     767                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ) ) ); }
    742768        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    743                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     769                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    744770        | postfix_expression '.' aggregate_control
    745                 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
     771                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); }
    746772        | postfix_expression ARROW identifier
    747                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
     773                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    748774        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    749                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
     775                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    750776        | postfix_expression ARROW '[' field_name_list ']'      // CFA, tuple field selector
    751                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     777                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    752778        | postfix_expression ICR
    753                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
     779                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); }
    754780        | postfix_expression DECR
    755                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::DecrPost, $1 ) ); }
     781                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); }
    756782        | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
    757                 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
     783                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); }
    758784        | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
    759                 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
     785                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
    760786        | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call
    761787                {
    762788                        Token fn;
    763789                        fn.str = new string( "^?{}" );                          // location undefined
    764                         $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
     790                        $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
    765791                }
    766792        ;
     
    781807        '@'                                                                                                     // CFA, default parameter
    782808                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
    783                 // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
     809                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
    784810        | assignment_expression
    785811        ;
     
    793819        field_name
    794820        | FLOATING_DECIMALconstant field
    795                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
     821                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); }
    796822        | FLOATING_DECIMALconstant '[' field_name_list ']'
    797                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
     823                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc, $3 ) ) ); }
    798824        | field_name '.' field
    799                 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     825                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    800826        | field_name '.' '[' field_name_list ']'
    801                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     827                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    802828        | field_name ARROW field
    803                 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     829                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    804830        | field_name ARROW '[' field_name_list ']'
    805                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     831                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    806832        ;
    807833
    808834field_name:
    809835        INTEGERconstant fraction_constants_opt
    810                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }
     836                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc, *$1 ), $2 ) ); }
    811837        | FLOATINGconstant fraction_constants_opt
    812                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
     838                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc, *$1 ), $2 ) ); }
    813839        | identifier_at fraction_constants_opt                          // CFA, allow anonymous fields
    814840                {
    815                         $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
     841                        $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc, $1 ), $2 ) );
    816842                }
    817843        ;
     
    822848        | fraction_constants_opt FLOATING_FRACTIONconstant
    823849                {
    824                         Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
    825                         $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant );
     850                        ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 );
     851                        $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1, constant ) ) : new ExpressionNode( constant );
    826852                }
    827853        ;
     
    833859        | constant
    834860        | string_literal
    835                 { $$ = new ExpressionNode( $1 ); }
     861                { $$ = $1; }
    836862        | EXTENSION cast_expression                                                     // GCC
    837863                { $$ = $2->set_extension( true ); }
     
    842868                {
    843869                        switch ( $1 ) {
    844                           case OperKinds::AddressOf:
    845                                 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) );
     870                        case OperKinds::AddressOf:
     871                                $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );
    846872                                break;
    847                           case OperKinds::PointTo:
    848                                 $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
     873                        case OperKinds::PointTo:
     874                                $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) );
    849875                                break;
    850                           case OperKinds::And:
    851                                 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild<Expression>( $2 ) ) ) );
     876                        case OperKinds::And:
     877                                $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );
    852878                                break;
    853                           default:
     879                        default:
    854880                                assert( false );
    855881                        }
    856882                }
    857883        | unary_operator cast_expression
    858                 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }
     884                { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); }
    859885        | ICR unary_expression
    860                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Incr, $2 ) ); }
     886                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); }
    861887        | DECR unary_expression
    862                 { $$ = new ExpressionNode( build_unary_ptr( OperKinds::Decr, $2 ) ); }
     888                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); }
    863889        | SIZEOF unary_expression
    864                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
     890                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    865891        | SIZEOF '(' type_no_function ')'
    866                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); }
     892                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    867893        | ALIGNOF unary_expression                                                      // GCC, variable alignment
    868                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild<Expression>( $2 ) ) ); }
     894                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    869895        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    870                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
     896                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    871897        | OFFSETOF '(' type_no_function ',' identifier ')'
    872                 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
     898                { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); }
    873899        | TYPEID '(' type_no_function ')'
    874900                {
     
    895921        unary_expression
    896922        | '(' type_no_function ')' cast_expression
    897                 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     923                { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    898924        | '(' aggregate_control '&' ')' cast_expression         // CFA
    899                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     925                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    900926        | '(' aggregate_control '*' ')' cast_expression         // CFA
    901                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     927                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    902928        | '(' VIRTUAL ')' cast_expression                                       // CFA
    903                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     929                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    904930        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    905                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild<Expression>( $5 ), maybeMoveBuildType( $3 ) ) ); }
     931                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
    906932        | '(' RETURN type_no_function ')' cast_expression       // CFA
    907                 { $$ = new ExpressionNode( build_cast( $3, $5, CastExpr::Return ) ); }
     933                { $$ = new ExpressionNode( build_cast( yylloc, $3, $5, ast::CastExpr::Return ) ); }
    908934        | '(' COERCE type_no_function ')' cast_expression       // CFA
    909935                { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
     
    911937                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    912938//      | '(' type_no_function ')' tuple
    913 //              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     939//              { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    914940        ;
    915941
     
    929955        cast_expression
    930956        | exponential_expression '\\' cast_expression
    931                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }
     957                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); }
    932958        ;
    933959
     
    935961        exponential_expression
    936962        | multiplicative_expression '*' exponential_expression
    937                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }
     963                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); }
    938964        | multiplicative_expression '/' exponential_expression
    939                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }
     965                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); }
    940966        | multiplicative_expression '%' exponential_expression
    941                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }
     967                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); }
    942968        ;
    943969
     
    945971        multiplicative_expression
    946972        | additive_expression '+' multiplicative_expression
    947                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }
     973                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); }
    948974        | additive_expression '-' multiplicative_expression
    949                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }
     975                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); }
    950976        ;
    951977
     
    953979        additive_expression
    954980        | shift_expression LS additive_expression
    955                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }
     981                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); }
    956982        | shift_expression RS additive_expression
    957                 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }
     983                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); }
    958984        ;
    959985
     
    961987        shift_expression
    962988        | relational_expression '<' shift_expression
    963                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }
     989                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); }
    964990        | relational_expression '>' shift_expression
    965                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }
     991                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); }
    966992        | relational_expression LE shift_expression
    967                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }
     993                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); }
    968994        | relational_expression GE shift_expression
    969                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }
     995                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); }
    970996        ;
    971997
     
    973999        relational_expression
    9741000        | equality_expression EQ relational_expression
    975                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }
     1001                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); }
    9761002        | equality_expression NE relational_expression
    977                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }
     1003                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); }
    9781004        ;
    9791005
     
    9811007        equality_expression
    9821008        | AND_expression '&' equality_expression
    983                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }
     1009                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); }
    9841010        ;
    9851011
     
    9871013        AND_expression
    9881014        | exclusive_OR_expression '^' AND_expression
    989                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }
     1015                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); }
    9901016        ;
    9911017
     
    9931019        exclusive_OR_expression
    9941020        | inclusive_OR_expression '|' exclusive_OR_expression
    995                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }
     1021                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); }
    9961022        ;
    9971023
     
    9991025        inclusive_OR_expression
    10001026        | logical_AND_expression ANDAND inclusive_OR_expression
    1001                 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); }
     1027                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); }
    10021028        ;
    10031029
     
    10051031        logical_AND_expression
    10061032        | logical_OR_expression OROR logical_AND_expression
    1007                 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); }
     1033                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); }
    10081034        ;
    10091035
     
    10111037        logical_OR_expression
    10121038        | logical_OR_expression '?' comma_expression ':' conditional_expression
    1013                 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
     1039                { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); }
    10141040                // FIX ME: computes $1 twice
    10151041        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    1016                 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
     1042                { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); }
    10171043        ;
    10181044
     
    10291055//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    10301056//                      } else {
    1031                                 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
     1057                                $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) );
    10321058//                      } // if
    10331059                }
     
    10741100//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    10751101        '[' ',' tuple_expression_list ']'
    1076                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     1102                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    10771103        | '[' push assignment_expression pop ',' tuple_expression_list ']'
    1078                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }
     1104                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); }
    10791105        ;
    10801106
     
    10921118        assignment_expression
    10931119        | comma_expression ',' assignment_expression
    1094                 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     1120                { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    10951121        ;
    10961122
     
    11131139        | mutex_statement
    11141140        | waitfor_statement
     1141        | waituntil_statement
    11151142        | exception_statement
    11161143        | enable_disable_statement
     
    11181145        | asm_statement
    11191146        | DIRECTIVE
    1120                 { $$ = new StatementNode( build_directive( $1 ) ); }
     1147                { $$ = new StatementNode( build_directive( yylloc, $1 ) ); }
    11211148        ;
    11221149
     
    11241151                // labels cannot be identifiers 0 or 1
    11251152        identifier_or_type_name ':' attribute_list_opt statement
    1126                 { $$ = $4->add_label( $1, $3 ); }
     1153                { $$ = $4->add_label( yylloc, $1, $3 ); }
    11271154        | identifier_or_type_name ':' attribute_list_opt error // syntax error
    11281155                {
     
    11361163compound_statement:
    11371164        '{' '}'
    1138                 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     1165                { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); }
    11391166        | '{' push
    11401167          local_label_declaration_opt                                           // GCC, local labels appear at start of block
    11411168          statement_decl_list                                                           // C99, intermix declarations and statements
    11421169          pop '}'
    1143                 { $$ = new StatementNode( build_compound( $4 ) ); }
     1170                { $$ = new StatementNode( build_compound( yylloc, $4 ) ); }
    11441171        ;
    11451172
     
    11721199expression_statement:
    11731200        comma_expression_opt ';'
    1174                 { $$ = new StatementNode( build_expr( $1 ) ); }
    1175         | MUTEX '(' ')' comma_expression ';'
    1176                 { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); }
     1201                { $$ = new StatementNode( build_expr( yylloc, $1 ) ); }
    11771202        ;
    11781203
     
    11831208                { $$ = $2; }
    11841209        | SWITCH '(' comma_expression ')' case_clause
    1185                 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
     1210                { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); }
    11861211        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    11871212                {
    1188                         StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
     1213                        StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) );
    11891214                        // The semantics of the declaration list is changed to include associated initialization, which is performed
    11901215                        // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
     
    11921217                        // therefore, are removed from the grammar even though C allows it. The change also applies to choose
    11931218                        // statement.
    1194                         $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1219                        $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    11951220                }
    11961221        | SWITCH '(' comma_expression ')' '{' error '}'         // CFA, syntax error
    11971222                { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    11981223        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    1199                 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
     1224                { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); }
    12001225        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12011226                {
    1202                         StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );
    1203                         $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1227                        StatementNode *sw = new StatementNode( build_switch( yylloc, false, $3, $8 ) );
     1228                        $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    12041229                }
    12051230        | CHOOSE '(' comma_expression ')' '{' error '}'         // CFA, syntax error
     
    12101235        IF '(' conditional_declaration ')' statement            %prec THEN
    12111236                // explicitly deal with the shift/reduce conflict on if/else
    1212                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
     1237                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); }
    12131238        | IF '(' conditional_declaration ')' statement ELSE statement
    1214                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); }
     1239                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); }
    12151240        ;
    12161241
     
    12241249        | declaration comma_expression                                          // semi-colon separated
    12251250                { $$ = new CondCtl( $1, $2 ); }
    1226         ;
     1251        ;
    12271252
    12281253// CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case
     
    12321257        constant_expression                                                     { $$ = $1; }
    12331258        | constant_expression ELLIPSIS constant_expression      // GCC, subrange
    1234                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     1259                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    12351260        | subrange                                                                                      // CFA, subrange
    12361261        ;
    12371262
    12381263case_value_list:                                                                                // CFA
    1239         case_value                                                                      { $$ = new StatementNode( build_case( $1 ) ); }
     1264        case_value                                                                      { $$ = new ClauseNode( build_case( yylloc, $1 ) ); }
    12401265                // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5"
    1241         | case_value_list ',' case_value                        { $$ = (StatementNode *)($1->set_last( new StatementNode( build_case( $3 ) ) ) ); }
     1266        | case_value_list ',' case_value                        { $$ = $1->set_last( new ClauseNode( build_case( yylloc, $3 ) ) ); }
    12421267        ;
    12431268
     
    12481273        | CASE case_value_list error                                            // syntax error
    12491274                { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
    1250         | DEFAULT ':'                                                           { $$ = new StatementNode( build_default() ); }
     1275        | DEFAULT ':'                                                           { $$ = new ClauseNode( build_default( yylloc ) ); }
    12511276                // A semantic check is required to ensure only one default clause per switch/choose statement.
    12521277        | DEFAULT error                                                                         //  syntax error
     
    12561281case_label_list:                                                                                // CFA
    12571282        case_label
    1258         | case_label_list case_label                            { $$ = (StatementNode *)( $1->set_last( $2 )); }
     1283        | case_label_list case_label                            { $$ = $1->set_last( $2 ); }
    12591284        ;
    12601285
    12611286case_clause:                                                                                    // CFA
    1262         case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }
     1287        case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( yylloc, $2 ) ); }
    12631288        ;
    12641289
     
    12711296switch_clause_list:                                                                             // CFA
    12721297        case_label_list statement_list_nodecl
    1273                 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
     1298                { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); }
    12741299        | switch_clause_list case_label_list statement_list_nodecl
    1275                 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
     1300                { $$ = $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ); }
    12761301        ;
    12771302
    12781303iteration_statement:
    12791304        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1280                 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
     1305                { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); }
    12811306        | WHILE '(' ')' statement ELSE statement                        // CFA
    12821307                {
    1283                         $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
    1284                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1308                        $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) );
     1309                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    12851310                }
    12861311        | WHILE '(' conditional_declaration ')' statement       %prec THEN
    1287                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
     1312                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    12881313        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
    1289                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
     1314                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    12901315        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1291                 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
     1316                { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); }
    12921317        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    12931318                {
    1294                         $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
    1295                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1319                        $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) );
     1320                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    12961321                }
    12971322        | DO statement WHILE '(' comma_expression ')' ';'
    1298                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
     1323                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); }
    12991324        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
    1300                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
     1325                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ), $8 ) ); }
    13011326        | FOR '(' ')' statement                                                         %prec THEN // CFA => for ( ;; )
    1302                 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); }
     1327                { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); }
    13031328        | FOR '(' ')' statement ELSE statement                          // CFA
    13041329                {
    1305                         $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) );
    1306                         SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
     1330                        $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) );
     1331                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13071332                }
    13081333        | FOR '(' for_control_expression_list ')' statement     %prec THEN
    1309                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
     1334                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    13101335        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
    1311                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
     1336                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    13121337        ;
    13131338
     
    13231348                        if ( $1->condition ) {
    13241349                                if ( $3->condition ) {
    1325                                         $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
     1350                                        $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr ) );
    13261351                                } // if
    13271352                        } else $1->condition = $3->condition;
    13281353                        if ( $1->change ) {
    13291354                                if ( $3->change ) {
    1330                                         $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
     1355                                        $1->change->expr.reset( new ast::CommaExpr( yylloc, $1->change->expr.release(), $3->change->expr.release() ) );
    13311356                                } // if
    13321357                        } else $1->change = $3->change;
     
    13371362for_control_expression:
    13381363        ';' comma_expression_opt ';' comma_expression_opt
    1339                 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
     1364                { $$ = new ForCtrl( nullptr, $2, $4 ); }
    13401365        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    1341                 { $$ = new ForCtrl( $1, $3, $5 ); }
     1366                {
     1367                        StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr;
     1368                        $$ = new ForCtrl( init, $3, $5 );
     1369                }
    13421370        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    1343                 { $$ = new ForCtrl( $1, $2, $4 ); }
     1371                { $$ = new ForCtrl( new StatementNode( $1 ), $2, $4 ); }
    13441372
    13451373        | '@' ';' comma_expression                                                      // CFA, empty loop-index
    1346                 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }
     1374                { $$ = new ForCtrl( nullptr, $3, nullptr ); }
    13471375        | '@' ';' comma_expression ';' comma_expression         // CFA, empty loop-index
    1348                 { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }
     1376                { $$ = new ForCtrl( nullptr, $3, $5 ); }
    13491377
    13501378        | comma_expression                                                                      // CFA, anonymous loop-index
    1351                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
     1379                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
    13521380        | downupdowneq comma_expression                                         // CFA, anonymous loop-index
    1353                 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
     1381                { $$ = forCtrl( yylloc, $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
    13541382
    13551383        | comma_expression updowneq comma_expression            // CFA, anonymous loop-index
    1356                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
     1384                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
    13571385        | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
    13581386                {
    13591387                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1360                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
     1388                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
    13611389                }
    13621390        | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
     
    13661394                }
    13671395        | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    1368                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
     1396                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
    13691397        | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    13701398                {
    13711399                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1372                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
     1400                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
    13731401                }
    13741402        | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
     
    13891417
    13901418        | comma_expression ';' comma_expression                         // CFA
    1391                 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1419                { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    13921420        | comma_expression ';' downupdowneq comma_expression // CFA
    1393                 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
     1421                { $$ = forCtrl( yylloc, $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
    13941422
    13951423        | comma_expression ';' comma_expression updowneq comma_expression // CFA
    1396                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
     1424                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
    13971425        | comma_expression ';' '@' updowneq comma_expression // CFA
    13981426                {
    13991427                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1400                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1428                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    14011429                }
    14021430        | comma_expression ';' comma_expression updowneq '@' // CFA
     
    14041432                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14051433                        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 );
     1434                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    14071435                }
    14081436        | comma_expression ';' '@' updowneq '@'                         // CFA, error
     
    14101438
    14111439        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    1412                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
     1440                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    14131441        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
    14141442                {
    14151443                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1416                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
     1444                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 );
    14171445                }
    14181446        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
     
    14201448                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14211449                        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 );
     1450                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, $7 );
    14231451                }
    14241452        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    1425                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
     1453                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    14261454        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
    14271455                {
    14281456                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1429                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
     1457                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr );
    14301458                }
    14311459        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
     
    14331461                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14341462                        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 );
     1463                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, nullptr );
    14361464                }
    14371465        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
     
    14391467
    14401468        | declaration comma_expression                                          // CFA
    1441                 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1469                { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    14421470        | declaration downupdowneq comma_expression                     // CFA
    1443                 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
     1471                { $$ = forCtrl( yylloc, $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
    14441472
    14451473        | declaration comma_expression updowneq comma_expression // CFA
    1446                 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
     1474                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
    14471475        | declaration '@' updowneq comma_expression                     // CFA
    14481476                {
    14491477                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1450                         else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
     1478                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE );
    14511479                }
    14521480        | declaration comma_expression updowneq '@'                     // CFA
     
    14541482                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14551483                        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 );
     1484                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, NEW_ONE );
    14571485                }
    14581486
    14591487        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1460                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
     1488                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
    14611489        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    14621490                {
    14631491                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1464                         else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
     1492                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 );
    14651493                }
    14661494        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
     
    14681496                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14691497                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1470                         else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
     1498                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, $6 );
    14711499                }
    14721500        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1473                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
     1501                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
    14741502        | declaration '@' updowneq comma_expression '~' '@' // CFA
    14751503                {
    14761504                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1477                         else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
     1505                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr );
    14781506                }
    14791507        | declaration comma_expression updowneq '@' '~' '@'     // CFA
     
    14811509                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14821510                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1483                         else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
     1511                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr );
    14841512                }
    14851513        | declaration '@' updowneq '@' '~' '@'                          // CFA, error
     
    14961524                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    14971525                }
    1498         ;
     1526        ;
    14991527
    15001528downupdowneq:
     
    15051533        | ErangeDownEq
    15061534                { $$ = OperKinds::GEThan; }
    1507         ;
     1535        ;
    15081536
    15091537updown:
     
    15121540        | ErangeDown
    15131541                { $$ = OperKinds::GThan; }
    1514         ;
     1542        ;
    15151543
    15161544updowneq:
     
    15201548        | ErangeDownEq
    15211549                { $$ = OperKinds::GEThan; }
    1522         ;
     1550        ;
    15231551
    15241552jump_statement:
    15251553        GOTO identifier_or_type_name ';'
    1526                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); }
     1554                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }
    15271555        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    15281556                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    15311559                // A semantic check is required to ensure fallthru appears only in the body of a choose statement.
    15321560        | fall_through_name ';'                                                         // CFA
    1533                 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }
     1561                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }
    15341562        | fall_through_name identifier_or_type_name ';'         // CFA
    1535                 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); }
     1563                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }
    15361564        | fall_through_name DEFAULT ';'                                         // CFA
    1537                 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }
     1565                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }
    15381566        | CONTINUE ';'
    15391567                // 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 ) ); }
     1568                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }
    15411569        | CONTINUE identifier_or_type_name ';'                          // CFA, multi-level continue
    15421570                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15431571                // the target of the transfer appears only at the start of an iteration statement.
    1544                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); }
     1572                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }
    15451573        | BREAK ';'
    15461574                // 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 ) ); }
     1575                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }
    15481576        | BREAK identifier_or_type_name ';'                                     // CFA, multi-level exit
    15491577                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15501578                // the target of the transfer appears only at the start of an iteration statement.
    1551                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); }
     1579                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }
    15521580        | RETURN comma_expression_opt ';'
    1553                 { $$ = new StatementNode( build_return( $2 ) ); }
     1581                { $$ = new StatementNode( build_return( yylloc, $2 ) ); }
    15541582        | RETURN '{' initializer_list_opt comma_opt '}' ';'
    15551583                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    15561584        | SUSPEND ';'
    1557                 { $$ = new StatementNode( build_suspend( nullptr ) ); }
     1585                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); }
    15581586        | SUSPEND compound_statement
    1559                 { $$ = new StatementNode( build_suspend( $2 ) ); }
     1587                { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); }
    15601588        | SUSPEND COROUTINE ';'
    1561                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); }
     1589                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }
    15621590        | SUSPEND COROUTINE compound_statement
    1563                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); }
     1591                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }
    15641592        | SUSPEND GENERATOR ';'
    1565                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); }
     1593                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }
    15661594        | SUSPEND GENERATOR compound_statement
    1567                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); }
     1595                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }
    15681596        | THROW assignment_expression_opt ';'                           // handles rethrow
    1569                 { $$ = new StatementNode( build_throw( $2 ) ); }
     1597                { $$ = new StatementNode( build_throw( yylloc, $2 ) ); }
    15701598        | THROWRESUME assignment_expression_opt ';'                     // handles reresume
    1571                 { $$ = new StatementNode( build_resume( $2 ) ); }
     1599                { $$ = new StatementNode( build_resume( yylloc, $2 ) ); }
    15721600        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    15731601                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
     
    15811609with_statement:
    15821610        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".
     1611                { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); }
     1612        ;
     1613
     1614// If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so possibly change syntax to "with mutex".
    15871615mutex_statement:
    1588         MUTEX '(' argument_expression_list ')' statement
    1589                 { $$ = new StatementNode( build_mutex( $3, $5 ) ); }
     1616        MUTEX '(' argument_expression_list_opt ')' statement
     1617                {
     1618                        if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; }
     1619                        $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) );
     1620                }
    15901621        ;
    15911622
     
    15981629                { $$ = nullptr; }
    15991630        | 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 )); }
    16091631        ;
    16101632
     
    16171639
    16181640timeout:
    1619         TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
    1620         ;
    1621 
    1622 waitfor_clause:
     1641        TIMEOUT '(' comma_expression ')'                        { $$ = $3; }
     1642        ;
     1643
     1644wor:
     1645        OROR
     1646        | WOR
     1647
     1648waitfor:
     1649        WAITFOR '(' cast_expression ')'
     1650                { $$ = $3; }
     1651        | WAITFOR '(' cast_expression_list ':' argument_expression_list_opt ')'
     1652                { $$ = (ExpressionNode *)($3->set_last( $5 )); }
     1653        ;
     1654
     1655wor_waitfor_clause:
    16231656        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 ); }
     1657                // Called first: create header for WaitForStmt.
     1658                { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); }
     1659        | wor_waitfor_clause wor when_clause_opt waitfor statement
     1660                { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
     1661        | wor_waitfor_clause wor when_clause_opt ELSE statement
     1662                { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); }
     1663        | wor_waitfor_clause wor when_clause_opt timeout statement      %prec THEN
     1664                { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    16311665        // "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
     1666        | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
    16331667                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    1634         | when_clause_opt timeout statement WOR when_clause ELSE statement
    1635                 { $$ = build_waitfor_timeout( $2, maybe_build_compound( $3 ), $1, maybe_build_compound( $7 ), $5 ); }
     1668        | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
     1669                { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); }
    16361670        ;
    16371671
    16381672waitfor_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 ) ); }
     1673        wor_waitfor_clause                                                                      %prec THEN
     1674                { $$ = new StatementNode( $1 ); }
     1675        ;
     1676
     1677wand:
     1678        ANDAND
     1679        | WAND
     1680        ;
     1681
     1682waituntil:
     1683        WAITUNTIL '(' comma_expression ')'
     1684                { $$ = $3; }
     1685        ;
     1686
     1687waituntil_clause:
     1688        when_clause_opt waituntil statement
     1689                { $$ = build_waituntil_clause( yylloc, $1, $2, maybe_build_compound( yylloc, $3 ) ); }
     1690        | '(' wor_waituntil_clause ')'
     1691                { $$ = $2; }
     1692        ;
     1693
     1694wand_waituntil_clause:
     1695        waituntil_clause                                                                        %prec THEN
     1696                { $$ = $1; }
     1697        | waituntil_clause wand wand_waituntil_clause
     1698                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::AND, $1, $3 ); }
     1699        ;
     1700
     1701wor_waituntil_clause:
     1702        wand_waituntil_clause
     1703                { $$ = $1; }
     1704        | wor_waituntil_clause wor wand_waituntil_clause
     1705                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR, $1, $3 ); }
     1706        | wor_waituntil_clause wor when_clause_opt ELSE statement
     1707                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
     1708        | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
     1709                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); }
     1710        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
     1711        | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
     1712                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
     1713        | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
     1714                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1,
     1715                new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR,
     1716                    build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ),
     1717                    build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); }
     1718        ;
     1719
     1720waituntil_statement:
     1721        wor_waituntil_clause                                                            %prec THEN
     1722                // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
     1723                {
     1724            $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) );
     1725            // $$ = new StatementNode( build_compound( yylloc, nullptr ) );
     1726        }
    16431727        ;
    16441728
    16451729exception_statement:
    1646         TRY compound_statement handler_clause                                   %prec THEN
    1647                 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); }
     1730        TRY compound_statement handler_clause                                   %prec THEN
     1731                { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
    16481732        | TRY compound_statement finally_clause
    1649                 { $$ = new StatementNode( build_try( $2, 0, $3 ) ); }
     1733                { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
    16501734        | TRY compound_statement handler_clause finally_clause
    1651                 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
     1735                { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
    16521736        ;
    16531737
    16541738handler_clause:
    16551739        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1656                 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
     1740                { $$ = new ClauseNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
    16571741        | 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 ) ) ); }
     1742                { $$ = $1->set_last( new ClauseNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
    16591743        ;
    16601744
     
    16661750
    16671751handler_key:
    1668         CATCH                                                                           { $$ = CatchStmt::Terminate; }
    1669         | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
    1670         | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
    1671         | FIXUP                                                                         { $$ = CatchStmt::Resume; }
     1752        CATCH                                                                           { $$ = ast::Terminate; }
     1753        | RECOVER                                                                       { $$ = ast::Terminate; }
     1754        | CATCHRESUME                                                           { $$ = ast::Resume; }
     1755        | FIXUP                                                                         { $$ = ast::Resume; }
    16721756        ;
    16731757
    16741758finally_clause:
    1675         FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
     1759        FINALLY compound_statement                                      { $$ = new ClauseNode( build_finally( yylloc, $2 ) ); }
    16761760        ;
    16771761
     
    16991783asm_statement:
    17001784        ASM asm_volatile_opt '(' string_literal ')' ';'
    1701                 { $$ = new StatementNode( build_asm( $2, $4, 0 ) ); }
     1785                { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
    17021786        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1703                 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
     1787                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
    17041788        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1705                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
     1789                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
    17061790        | 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 ) ); }
     1791                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
    17081792        | 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 ) ); }
     1793                { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
    17101794        ;
    17111795
     
    17311815asm_operand:                                                                                    // GCC
    17321816        string_literal '(' constant_expression ')'
    1733                 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild<Expression>( $3 ) ) ); }
     1817                { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    17341818        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1735                 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild<Expression>( $6 ) ) ); }
     1819                {
     1820                        $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) );
     1821                        delete $2.str;
     1822                }
    17361823        ;
    17371824
     
    17401827                { $$ = nullptr; }                                                               // use default argument
    17411828        | string_literal
    1742                 { $$ = new ExpressionNode( $1 ); }
     1829                { $$ = $1; }
    17431830        | asm_clobbers_list_opt ',' string_literal
    1744                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); }
     1831                { $$ = (ExpressionNode *)( $1->set_last( $3 ) ); }
    17451832        ;
    17461833
     
    17481835        identifier
    17491836                {
    1750                         $$ = new LabelNode(); $$->labels.push_back( *$1 );
     1837                        $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
    17511838                        delete $1;                                                                      // allocated by lexer
    17521839                }
    17531840        | label_list ',' identifier
    17541841                {
    1755                         $$ = $1; $1->labels.push_back( *$3 );
     1842                        $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
    17561843                        delete $3;                                                                      // allocated by lexer
    17571844                }
     
    18041891                {
    18051892                        // printf( "C_DECLARATION1 %p %s\n", $$, $$->name ? $$->name->c_str() : "(nil)" );
    1806                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     1893                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    18071894                        //   printf( "\tattr %s\n", attr->name.c_str() );
    18081895                        // } // for
     
    18141901static_assert:
    18151902        STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
    1816                 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
     1903                { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 ) ); }
    18171904        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1818                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
     1905                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
    18191906
    18201907// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    18801967//      '[' ']' identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' // S/R conflict
    18811968//              {
    1882 //                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, 0, true );
     1969//                      $$ = DeclarationNode::newFunction( $3, DeclarationNode::newTuple( 0 ), $6, nullptr, true );
    18831970//              }
    18841971//      '[' ']' identifier '(' push cfa_parameter_ellipsis_list_opt pop ')'
    18851972//              {
    18861973//                      typedefTable.setNextIdentifier( *$5 );
    1887 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1974//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
    18881975//              }
    18891976//      | '[' ']' TYPEDEFname '(' push cfa_parameter_ellipsis_list_opt pop ')'
    18901977//              {
    18911978//                      typedefTable.setNextIdentifier( *$5 );
    1892 //                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, 0, true );
     1979//                      $$ = DeclarationNode::newFunction( $5, DeclarationNode::newTuple( 0 ), $8, nullptr, true );
    18931980//              }
    18941981//      | '[' ']' typegen_name
     
    19021989        cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_ellipsis_list_opt pop ')' attribute_list_opt
    19031990                // 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 ); }
     1991                { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
    19051992        | 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 ); }
     1993                { $$ = DeclarationNode::newFunction( $2, $1, $5, nullptr )->addQualifiers( $8 ); }
    19071994        ;
    19081995
     
    19402027                {
    19412028                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
    1942                         $$ = $3->addType( $2 )->addTypedef();
     2029                        if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) {
     2030                                SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr;
     2031                        } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
    19432032                }
    19442033        | typedef_declaration pop ',' push declarator
     
    19482037                }
    19492038        | 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                 }
     2039                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19542040        | type_specifier TYPEDEF declarator
    1955                 {
    1956                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "7" );
    1957                         $$ = $3->addType( $1 )->addTypedef();
    1958                 }
     2041                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19592042        | type_specifier TYPEDEF type_qualifier_list declarator
    1960                 {
    1961                         typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "8" );
    1962                         $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 );
    1963                 }
     2043                { SemanticError( yylloc, "Type qualifiers/specifiers before TYPEDEF is deprecated, move after TYPEDEF." ); $$ = nullptr; }
    19642044        ;
    19652045
     
    19682048        TYPEDEF identifier '=' assignment_expression
    19692049                {
    1970                         SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     2050                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    19712051                }
    19722052        | typedef_expression pop ',' push identifier '=' assignment_expression
    19732053                {
    1974                         SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     2054                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    19752055                }
    19762056        ;
     
    19822062        | typedef_expression                                                            // deprecated GCC, naming expression type
    19832063        | sue_declaration_specifier
     2064                {
     2065                        assert( $1->type );
     2066                        if ( $1->type->qualifiers.any() ) {                     // CV qualifiers ?
     2067                                SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr;
     2068                        }
     2069                        // enums are never empty declarations because there must have at least one enumeration.
     2070                        if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ?
     2071                                SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr;
     2072                        }
     2073                }
    19842074        ;
    19852075
     
    19872077                // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static
    19882078                // storage-class
    1989         declarator asm_name_opt initializer_opt
     2079        variable_declarator asm_name_opt initializer_opt
    19902080                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
     2081        | variable_type_redeclarator asm_name_opt initializer_opt
     2082                { $$ = $1->addAsmName( $2 )->addInitializer( $3 ); }
     2083
     2084        | general_function_declarator asm_name_opt
     2085                { $$ = $1->addAsmName( $2 )->addInitializer( nullptr ); }
     2086        | general_function_declarator asm_name_opt '=' VOID
     2087                { $$ = $1->addAsmName( $2 )->addInitializer( new InitializerNode( true ) ); }
     2088
    19912089        | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt
    19922090                { $$ = $1->appendList( $4->addQualifiers( $3 )->addAsmName( $5 )->addInitializer( $6 ) ); }
    19932091        ;
    19942092
     2093general_function_declarator:
     2094        function_type_redeclarator
     2095        | function_declarator
     2096        ;
     2097
    19952098declaration_specifier:                                                                  // type specifier + storage class
    19962099        basic_declaration_specifier
     2100        | type_declaration_specifier
    19972101        | sue_declaration_specifier
    1998         | type_declaration_specifier
     2102        | sue_declaration_specifier invalid_types
     2103                {
     2104                        SemanticError( yylloc, ::toString( "Missing ';' after end of ",
     2105                                $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),
     2106                                " declaration" ) );
     2107                        $$ = nullptr;
     2108                }
     2109        ;
     2110
     2111invalid_types:
     2112        aggregate_key
     2113        | basic_type_name
     2114        | indirect_type
    19992115        ;
    20002116
     
    20132129        basic_type_specifier
    20142130        | 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                 }
    20212131        | type_type_specifier
    20222132        ;
     
    20652175                { $$ = DeclarationNode::newTypeQualifier( Type::Atomic ); }
    20662176        | forall
     2177                { $$ = DeclarationNode::newForall( $1 ); }
    20672178        ;
    20682179
    20692180forall:
    20702181        FORALL '(' type_parameter_list ')'                                      // CFA
    2071                 { $$ = DeclarationNode::newForall( $3 ); }
     2182                { $$ = $3; }
    20722183        ;
    20732184
     
    22262337                { $$ = DeclarationNode::newTypeof( $3 ); }
    22272338        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2228                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
     2339                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
    22292340        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    22302341                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    22392350                {
    22402351                        // printf( "sue_declaration_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2241                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2352                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    22422353                        //   printf( "\tattr %s\n", attr->name.c_str() );
    22432354                        // } // for
     
    22552366                {
    22562367                        // printf( "sue_type_specifier %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2257                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2368                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    22582369                        //   printf( "\tattr %s\n", attr->name.c_str() );
    22592370                        // } // for
     
    23332444                {
    23342445                        // printf( "elaborated_type %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2335                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2446                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    23362447                        //   printf( "\tattr %s\n", attr->name.c_str() );
    23372448                        // } // for
     
    23572468          '{' field_declaration_list_opt '}' type_parameters_opt
    23582469                {
    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
    23642470                        $$ = 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
    23692471                }
    23702472        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     
    23752477          '{' field_declaration_list_opt '}' type_parameters_opt
    23762478                {
    2377                         // printf( "AGG3\n" );
    23782479                        DeclarationNode::newFromTypedef( $3 );
    23792480                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    23862487          '{' field_declaration_list_opt '}' type_parameters_opt
    23872488                {
    2388                         // printf( "AGG4\n" );
    23892489                        DeclarationNode::newFromTypeGen( $3, nullptr );
    23902490                        $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     
    24132513                        // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
    24142514                        // 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;
     2515                        if ( $3->type->kind == TypeData::SymbolicInst && ! $3->type->symbolic.isTypedef ) {
     2516                                $$ = $3->addQualifiers( $2 );
     2517                        } else {
     2518                                $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 );
     2519                                $3->type->symbolic.name = nullptr;                      // copied to $$
     2520                                $3->type->symbolic.actuals = nullptr;
     2521                                delete $3;
     2522                        }
    24192523                }
    24202524        ;
     
    24272531aggregate_data:
    24282532        STRUCT vtable_opt
    2429                 { $$ = AggregateDecl::Struct; }
     2533                { $$ = ast::AggregateDecl::Struct; }
    24302534        | UNION
    2431                 { $$ = AggregateDecl::Union; }
     2535                { $$ = ast::AggregateDecl::Union; }
    24322536        | EXCEPTION                                                                                     // CFA
    2433                 { $$ = AggregateDecl::Exception; }
    2434           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2537                { $$ = ast::AggregateDecl::Exception; }
     2538          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
    24352539        ;
    24362540
    24372541aggregate_control:                                                                              // CFA
    24382542        MONITOR
    2439                 { $$ = AggregateDecl::Monitor; }
     2543                { $$ = ast::AggregateDecl::Monitor; }
    24402544        | MUTEX STRUCT
    2441                 { $$ = AggregateDecl::Monitor; }
     2545                { $$ = ast::AggregateDecl::Monitor; }
    24422546        | GENERATOR
    2443                 { $$ = AggregateDecl::Generator; }
     2547                { $$ = ast::AggregateDecl::Generator; }
    24442548        | MUTEX GENERATOR
    2445                 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2549                {
     2550                        SemanticError( yylloc, "monitor generator is currently unimplemented." );
     2551                        $$ = ast::AggregateDecl::NoAggregate;
     2552                }
    24462553        | COROUTINE
    2447                 { $$ = AggregateDecl::Coroutine; }
     2554                { $$ = ast::AggregateDecl::Coroutine; }
    24482555        | MUTEX COROUTINE
    2449                 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2556                {
     2557                        SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
     2558                        $$ = ast::AggregateDecl::NoAggregate;
     2559                }
    24502560        | THREAD
    2451                 { $$ = AggregateDecl::Thread; }
     2561                { $$ = ast::AggregateDecl::Thread; }
    24522562        | MUTEX THREAD
    2453                 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2563                {
     2564                        SemanticError( yylloc, "monitor thread is currently unimplemented." );
     2565                        $$ = ast::AggregateDecl::NoAggregate;
     2566                }
    24542567        ;
    24552568
     
    24672580                        $$ = fieldDecl( $1, $2 );
    24682581                        // printf( "type_specifier2 %p %s\n", $$, $$->type->aggregate.name ? $$->type->aggregate.name->c_str() : "(nil)" );
    2469                         // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
     2582                        // for ( Attribute * attr: reverseIterate( $$->attributes ) ) {
    24702583                        //   printf( "\tattr %s\n", attr->name.c_str() );
    24712584                        // } // for
     
    24732586        | EXTENSION type_specifier field_declaring_list_opt ';' // GCC
    24742587                { $$ = fieldDecl( $2, $3 ); distExt( $$ ); }
     2588        | STATIC type_specifier field_declaring_list_opt ';' // CFA
     2589                { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }
    24752590        | INLINE type_specifier field_abstract_list_opt ';'     // CFA
    24762591                {
     
    24832598                }
    24842599        | INLINE aggregate_control ';'                                          // CFA
    2485                 { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
     2600                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    24862601        | typedef_declaration ';'                                                       // CFA
    24872602        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
     
    25092624                { $$ = $1->addBitfield( $2 ); }
    25102625        | variable_type_redeclarator bit_subrange_size_opt
     2626                // A semantic check is required to ensure bit_subrange only appears on integral types.
     2627                { $$ = $1->addBitfield( $2 ); }
     2628        | function_type_redeclarator bit_subrange_size_opt
    25112629                // A semantic check is required to ensure bit_subrange only appears on integral types.
    25122630                { $$ = $1->addBitfield( $2 ); }
     
    25632681                { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
    25642682        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2565                 {
    2566                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 )
     2683                {
     2684                        if ( $3->storageClasses.val != 0 || $3->type->qualifiers.any() )
    25672685                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    25682686
     
    25752693        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    25762694                {
    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." ); }
     2695                        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." ); }
    25782696                        typedefTable.makeTypedef( *$6 );
    25792697                }
     
    26092727enum_type_nobody:                                                                               // enum - {...}
    26102728        ENUM attribute_list_opt identifier
    2611                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
     2729                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }
    26122730        | ENUM attribute_list_opt type_name
    2613                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
     2731                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }
    26142732        ;
    26152733
     
    27512869type_no_function:                                                                               // sizeof, alignof, cast (constructor)
    27522870        cfa_abstract_declarator_tuple                                           // CFA
    2753         | type_specifier
     2871        | type_specifier                                                                        // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
    27542872        | type_specifier abstract_declarator
    27552873                { $$ = $2->addType( $1 ); }
     
    27962914        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    27972915        | identifier_at ':'                                                                     // GCC, field name
    2798                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     2916                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    27992917        ;
    28002918
     
    28082926designator:
    28092927        '.' identifier_at                                                                       // C99, field name
    2810                 { $$ = new ExpressionNode( build_varref( $2 ) ); }
     2928                { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
    28112929        | '[' push assignment_expression pop ']'                        // C99, single array element
    28122930                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    28152933                { $$ = $3; }
    28162934        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2817                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $3 ), maybeMoveBuild<Expression>( $5 ) ) ); }
     2935                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
    28182936        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    28192937                { $$ = $4; }
     
    28552973                {
    28562974                        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 ..." ); }
     2975                        if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
     2976                        if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     2977                        if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
    28602978                }
    28612979          type_initializer_opt assertion_list_opt
     
    28682986                {
    28692987                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2870                         $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
     2988                        $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
    28712989                }
    28722990        // | type_specifier identifier_parameter_declarator
    28732991        | assertion_list
    2874                 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2992                { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    28752993        ;
    28762994
    28772995new_type_class:                                                                                 // CFA
    28782996        // empty
    2879                 { $$ = TypeDecl::Otype; }
     2997                { $$ = ast::TypeDecl::Otype; }
    28802998        | '&'
    2881                 { $$ = TypeDecl::Dtype; }
     2999                { $$ = ast::TypeDecl::Dtype; }
    28823000        | '*'
    2883                 { $$ = TypeDecl::DStype; }                                              // dtype + sized
     3001                { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
    28843002        // | '(' '*' ')'
    2885         //      { $$ = TypeDecl::Ftype; }
     3003        //      { $$ = ast::TypeDecl::Ftype; }
    28863004        | ELLIPSIS
    2887                 { $$ = TypeDecl::Ttype; }
     3005                { $$ = ast::TypeDecl::Ttype; }
    28883006        ;
    28893007
    28903008type_class:                                                                                             // CFA
    28913009        OTYPE
    2892                 { $$ = TypeDecl::Otype; }
     3010                { $$ = ast::TypeDecl::Otype; }
    28933011        | DTYPE
    2894                 { $$ = TypeDecl::Dtype; }
     3012                { $$ = ast::TypeDecl::Dtype; }
    28953013        | FTYPE
    2896                 { $$ = TypeDecl::Ftype; }
     3014                { $$ = ast::TypeDecl::Ftype; }
    28973015        | TTYPE
    2898                 { $$ = TypeDecl::Ttype; }
     3016                { $$ = ast::TypeDecl::Ttype; }
    28993017        ;
    29003018
     
    29223040type_list:                                                                                              // CFA
    29233041        type
    2924                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3042                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    29253043        | assignment_expression
    29263044        | type_list ',' type
    2927                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3045                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    29283046        | type_list ',' assignment_expression
    29293047                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    29503068                {
    29513069                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    2952                         $$ = DeclarationNode::newTypeDecl( $1, 0 );
     3070                        $$ = DeclarationNode::newTypeDecl( $1, nullptr );
    29533071                }
    29543072        | identifier_or_type_name '(' type_parameter_list ')'
     
    29613079trait_specifier:                                                                                // CFA
    29623080        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    2963                 { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
     3081                {
     3082                        SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
     3083                        $$ = DeclarationNode::newTrait( $2, $4, nullptr );
     3084                }
     3085        | forall TRAIT identifier_or_type_name '{' '}'          // alternate
     3086                { $$ = DeclarationNode::newTrait( $3, $1, nullptr ); }
    29643087        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    2965                 { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
     3088                {
     3089                        SemanticWarning( yylloc, Warning::DeprecTraitSyntax );
     3090                        $$ = DeclarationNode::newTrait( $2, $4, $8 );
     3091                }
     3092        | forall TRAIT identifier_or_type_name '{' push trait_declaration_list pop '}' // alternate
     3093                { $$ = DeclarationNode::newTrait( $3, $1, $6 ); }
    29663094        ;
    29673095
     
    30223150external_definition:
    30233151        DIRECTIVE
    3024                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
     3152                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
    30253153        | declaration
     3154                {
     3155                        // Variable declarations of anonymous types requires creating a unique type-name across multiple translation
     3156                        // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is
     3157                        // disallowed at the moment.
     3158                        if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
     3159                                if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
     3160                                        SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
     3161                                } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union
     3162                                        SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr;
     3163                                }
     3164                        }
     3165                }
    30263166        | IDENTIFIER IDENTIFIER
    30273167                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
     
    30433183                }
    30443184        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3045                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
     3185                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
    30463186        | EXTERN STRINGliteral
    30473187                {
    30483188                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3049                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3189                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    30503190                }
    30513191          up external_definition down
     
    30583198                {
    30593199                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3060                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3200                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    30613201                }
    30623202          '{' up external_definition_list_opt down '}'
     
    30693209        | type_qualifier_list
    30703210                {
    3071                         if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3211                        if ( $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    30723212                        if ( $1->type->forall ) forall = true;          // remember generic type
    30733213                }
     
    30753215                {
    30763216                        distQual( $5, $1 );
    3077                         forall = false;
     3217                        forall = false;
    30783218                        $$ = $5;
    30793219                }
    30803220        | declaration_qualifier_list
    30813221                {
    3082                         if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     3222                        if ( $1->type && $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
    30833223                        if ( $1->type && $1->type->forall ) forall = true; // remember generic type
    30843224                }
     
    30863226                {
    30873227                        distQual( $5, $1 );
    3088                         forall = false;
     3228                        forall = false;
    30893229                        $$ = $5;
    30903230                }
    30913231        | declaration_qualifier_list type_qualifier_list
    30923232                {
    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." ); }
     3233                        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." ); }
    30943234                        if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type
    30953235                }
     
    30973237                {
    30983238                        distQual( $6, $1->addQualifiers( $2 ) );
    3099                         forall = false;
     3239                        forall = false;
    31003240                        $$ = $6;
    31013241                }
     
    31413281                        $$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
    31423282                }
    3143         | declaration_specifier variable_type_redeclarator with_clause_opt compound_statement
     3283        | declaration_specifier function_type_redeclarator with_clause_opt compound_statement
    31443284                {
    31453285                        rebindForall( $1, $2 );
     
    31773317        | variable_type_redeclarator
    31783318        | function_declarator
     3319        | function_type_redeclarator
    31793320        ;
    31803321
    31813322subrange:
    31823323        constant_expression '~' constant_expression                     // CFA, integer subrange
    3183                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild<Expression>( $1 ), maybeMoveBuild<Expression>( $3 ) ) ); }
     3324                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    31843325        ;
    31853326
     
    31903331                {
    31913332                        DeclarationNode * name = new DeclarationNode();
    3192                         name->asmName = $3;
     3333                        name->asmName = maybeMoveBuild( $3 );
    31933334                        $$ = name->addQualifiers( $5 );
    31943335                }
     
    32873428variable_ptr:
    32883429        ptrref_operator variable_declarator
    3289                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3430                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    32903431        | ptrref_operator type_qualifier_list variable_declarator
    32913432                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    33033444        | '(' attribute_list variable_ptr ')' array_dimension
    33043445                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3305         | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
     3446        | '(' variable_array ')' multi_array_dimension          // redundant parenthesis
    33063447                { $$ = $2->addArray( $4 ); }
    33073448        | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis
     
    33513492function_ptr:
    33523493        ptrref_operator function_declarator
    3353                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3494                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    33543495        | ptrref_operator type_qualifier_list function_declarator
    33553496                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34033544KR_function_ptr:
    34043545        ptrref_operator KR_function_declarator
    3405                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3546                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    34063547        | ptrref_operator type_qualifier_list KR_function_declarator
    34073548                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    34273568        ;
    34283569
    3429 // This pattern parses a declaration for a variable or function prototype that redefines a type name, e.g.:
     3570// This pattern parses a declaration for a variable that redefines a type name, e.g.:
    34303571//
    34313572//              typedef int foo;
     
    34333574//                 int foo; // redefine typedef name in new scope
    34343575//              }
    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.
    34383576
    34393577paren_type:
     
    34503588        paren_type attribute_list_opt
    34513589                { $$ = $1->addQualifiers( $2 ); }
    3452         | type_ptr
    3453         | type_array attribute_list_opt
     3590        | variable_type_ptr
     3591        | variable_type_array attribute_list_opt
    34543592                { $$ = $1->addQualifiers( $2 ); }
    3455         | type_function attribute_list_opt
     3593        | variable_type_function attribute_list_opt
    34563594                { $$ = $1->addQualifiers( $2 ); }
    34573595        ;
    34583596
    3459 type_ptr:
     3597variable_type_ptr:
    34603598        ptrref_operator variable_type_redeclarator
    3461                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3599                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    34623600        | ptrref_operator type_qualifier_list variable_type_redeclarator
    34633601                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    3464         | '(' type_ptr ')' attribute_list_opt                           // redundant parenthesis
     3602        | '(' variable_type_ptr ')' attribute_list_opt          // redundant parenthesis
    34653603                { $$ = $2->addQualifiers( $4 ); }
    3466         | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis
     3604        | '(' attribute_list variable_type_ptr ')' attribute_list_opt // redundant parenthesis
    34673605                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
    34683606        ;
    34693607
    3470 type_array:
     3608variable_type_array:
    34713609        paren_type array_dimension
    34723610                { $$ = $1->addArray( $2 ); }
    3473         | '(' type_ptr ')' array_dimension
     3611        | '(' variable_type_ptr ')' array_dimension
    34743612                { $$ = $2->addArray( $4 ); }
    3475         | '(' attribute_list type_ptr ')' array_dimension
     3613        | '(' attribute_list variable_type_ptr ')' array_dimension
    34763614                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3477         | '(' type_array ')' multi_array_dimension                      // redundant parenthesis
     3615        | '(' variable_type_array ')' multi_array_dimension     // redundant parenthesis
    34783616                { $$ = $2->addArray( $4 ); }
    3479         | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis
     3617        | '(' attribute_list variable_type_array ')' multi_array_dimension // redundant parenthesis
    34803618                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
    3481         | '(' type_array ')'                                                            // redundant parenthesis
     3619        | '(' variable_type_array ')'                                           // redundant parenthesis
    34823620                { $$ = $2; }
    3483         | '(' attribute_list type_array ')'                                     // redundant parenthesis
     3621        | '(' attribute_list variable_type_array ')'            // redundant parenthesis
    34843622                { $$ = $3->addQualifiers( $2 ); }
    34853623        ;
    34863624
    3487 type_function:
     3625variable_type_function:
     3626        '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3627                { $$ = $2->addParamList( $6 ); }
     3628        | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3629                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
     3630        | '(' variable_type_function ')'                                        // redundant parenthesis
     3631                { $$ = $2; }
     3632        | '(' attribute_list variable_type_function ')'         // redundant parenthesis
     3633                { $$ = $3->addQualifiers( $2 ); }
     3634        ;
     3635
     3636// This pattern parses a declaration for a function prototype that redefines a type name.  It precludes declaring an
     3637// array of functions versus a pointer to an array of functions, and returning arrays and functions versus pointers to
     3638// arrays and functions.
     3639
     3640function_type_redeclarator:
     3641        function_type_no_ptr attribute_list_opt
     3642                { $$ = $1->addQualifiers( $2 ); }
     3643        | function_type_ptr
     3644        | function_type_array attribute_list_opt
     3645                { $$ = $1->addQualifiers( $2 ); }
     3646        ;
     3647
     3648function_type_no_ptr:
    34883649        paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    34893650                { $$ = $1->addParamList( $4 ); }
    3490         | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3651        | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    34913652                { $$ = $2->addParamList( $6 ); }
    3492         | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
     3653        | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    34933654                { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
    3494         | '(' type_function ')'                                                         // redundant parenthesis
     3655        | '(' function_type_no_ptr ')'                                          // redundant parenthesis
    34953656                { $$ = $2; }
    3496         | '(' attribute_list type_function ')'                          // redundant parenthesis
     3657        | '(' attribute_list function_type_no_ptr ')'           // redundant parenthesis
     3658                { $$ = $3->addQualifiers( $2 ); }
     3659        ;
     3660
     3661function_type_ptr:
     3662        ptrref_operator function_type_redeclarator
     3663                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3664        | ptrref_operator type_qualifier_list function_type_redeclarator
     3665                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     3666        | '(' function_type_ptr ')' attribute_list_opt
     3667                { $$ = $2->addQualifiers( $4 ); }
     3668        | '(' attribute_list function_type_ptr ')' attribute_list_opt
     3669                { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); }
     3670        ;
     3671
     3672function_type_array:
     3673        '(' function_type_ptr ')' array_dimension
     3674                { $$ = $2->addArray( $4 ); }
     3675        | '(' attribute_list function_type_ptr ')' array_dimension
     3676                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
     3677        | '(' function_type_array ')' multi_array_dimension     // redundant parenthesis
     3678                { $$ = $2->addArray( $4 ); }
     3679        | '(' attribute_list function_type_array ')' multi_array_dimension // redundant parenthesis
     3680                { $$ = $3->addQualifiers( $2 )->addArray( $5 ); }
     3681        | '(' function_type_array ')'                                           // redundant parenthesis
     3682                { $$ = $2; }
     3683        | '(' attribute_list function_type_array ')'            // redundant parenthesis
    34973684                { $$ = $3->addQualifiers( $2 ); }
    34983685        ;
     
    35173704identifier_parameter_ptr:
    35183705        ptrref_operator identifier_parameter_declarator
    3519                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3706                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    35203707        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    35213708                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    35743761type_parameter_ptr:
    35753762        ptrref_operator type_parameter_redeclarator
    3576                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3763                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    35773764        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    35783765                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36173804abstract_ptr:
    36183805        ptrref_operator
    3619                 { $$ = DeclarationNode::newPointer( 0, $1 ); }
     3806                { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
    36203807        | ptrref_operator type_qualifier_list
    36213808                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    36223809        | ptrref_operator abstract_declarator
    3623                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     3810                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    36243811        | ptrref_operator type_qualifier_list abstract_declarator
    36253812                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36503837                // Only the first dimension can be empty.
    36513838        '[' ']'
    3652                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
     3839                { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
    36533840        | '[' ']' multi_array_dimension
    3654                 { $$ = DeclarationNode::newArray( 0, 0, false )->addArray( $3 ); }
     3841                { $$ = DeclarationNode::newArray( nullptr, nullptr, false )->addArray( $3 ); }
    36553842                // Cannot use constant_expression because of tuples => semantic check
    36563843        | '[' push assignment_expression pop ',' comma_expression ']' // CFA
    3657                 { $$ = DeclarationNode::newArray( $3, 0, false )->addArray( DeclarationNode::newArray( $6, 0, false ) ); }
     3844                { $$ = DeclarationNode::newArray( $3, nullptr, false )->addArray( DeclarationNode::newArray( $6, nullptr, false ) ); }
    36583845                // { SemanticError( yylloc, "New array dimension is currently unimplemented." ); $$ = nullptr; }
    36593846        | '[' push array_type_list pop ']'                                      // CFA
     
    36643851array_type_list:
    36653852        basic_type_name
    3666                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3853                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    36673854        | type_name
    3668                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3855                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    36693856        | assignment_expression upupeq assignment_expression
    36703857        | 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 ) ) ) )); }
     3858                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     3859        | array_type_list ',' type_name
     3860                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    36743861        | array_type_list ',' assignment_expression upupeq assignment_expression
    36753862        ;
     
    36803867        | ErangeUpEq
    36813868                { $$ = OperKinds::LEThan; }
    3682         ;
     3869        ;
    36833870
    36843871multi_array_dimension:
    36853872        '[' push assignment_expression pop ']'
    3686                 { $$ = DeclarationNode::newArray( $3, 0, false ); }
     3873                { $$ = DeclarationNode::newArray( $3, nullptr, false ); }
    36873874        | '[' push '*' pop ']'                                                          // C99
    36883875                { $$ = DeclarationNode::newVarArray( 0 ); }
    36893876        | multi_array_dimension '[' push assignment_expression pop ']'
    3690                 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
     3877                { $$ = $1->addArray( DeclarationNode::newArray( $4, nullptr, false ) ); }
    36913878        | multi_array_dimension '[' push '*' pop ']'            // C99
    36923879                { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
     
    37853972array_parameter_1st_dimension:
    37863973        '[' ']'
    3787                 { $$ = DeclarationNode::newArray( 0, 0, false ); }
     3974                { $$ = DeclarationNode::newArray( nullptr, nullptr, false ); }
    37883975                // multi_array_dimension handles the '[' '*' ']' case
    37893976        | '[' push type_qualifier_list '*' pop ']'                      // remaining C99
    37903977                { $$ = DeclarationNode::newVarArray( $3 ); }
    37913978        | '[' push type_qualifier_list pop ']'
    3792                 { $$ = DeclarationNode::newArray( 0, $3, false ); }
     3979                { $$ = DeclarationNode::newArray( nullptr, $3, false ); }
    37933980                // multi_array_dimension handles the '[' assignment_expression ']' case
    37943981        | '[' push type_qualifier_list assignment_expression pop ']'
     
    38194006variable_abstract_ptr:
    38204007        ptrref_operator
    3821                 { $$ = DeclarationNode::newPointer( 0, $1 ); }
     4008                { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
    38224009        | ptrref_operator type_qualifier_list
    38234010                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    38244011        | ptrref_operator variable_abstract_declarator
    3825                 { $$ = $2->addPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4012                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38264013        | ptrref_operator type_qualifier_list variable_abstract_declarator
    38274014                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38654052                // No SUE declaration in parameter list.
    38664053        ptrref_operator type_specifier_nobody
    3867                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4054                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38684055        | type_qualifier_list ptrref_operator type_specifier_nobody
    38694056                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    38704057        | ptrref_operator cfa_abstract_function
    3871                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4058                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38724059        | type_qualifier_list ptrref_operator cfa_abstract_function
    38734060                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    38744061        | ptrref_operator cfa_identifier_parameter_declarator_tuple
    3875                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4062                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    38764063        | type_qualifier_list ptrref_operator cfa_identifier_parameter_declarator_tuple
    38774064                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
     
    38824069                // shift/reduce conflict with new-style empty (void) function return type.
    38834070        '[' ']' type_specifier_nobody
    3884                 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4071                { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38854072        | cfa_array_parameter_1st_dimension type_specifier_nobody
    38864073                { $$ = $2->addNewArray( $1 ); }
    38874074        | '[' ']' multi_array_dimension type_specifier_nobody
    3888                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4075                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38894076        | cfa_array_parameter_1st_dimension multi_array_dimension type_specifier_nobody
    38904077                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    38934080
    38944081        | '[' ']' cfa_identifier_parameter_ptr
    3895                 { $$ = $3->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4082                { $$ = $3->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    38964083        | cfa_array_parameter_1st_dimension cfa_identifier_parameter_ptr
    38974084                { $$ = $2->addNewArray( $1 ); }
    38984085        | '[' ']' multi_array_dimension cfa_identifier_parameter_ptr
    3899                 { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); }
     4086                { $$ = $4->addNewArray( $3 )->addNewArray( DeclarationNode::newArray( nullptr, nullptr, false ) ); }
    39004087        | cfa_array_parameter_1st_dimension multi_array_dimension cfa_identifier_parameter_ptr
    39014088                { $$ = $3->addNewArray( $2 )->addNewArray( $1 ); }
     
    39534140cfa_abstract_ptr:                                                                               // CFA
    39544141        ptrref_operator type_specifier
    3955                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4142                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39564143        | type_qualifier_list ptrref_operator type_specifier
    39574144                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    39584145        | ptrref_operator cfa_abstract_function
    3959                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4146                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39604147        | type_qualifier_list ptrref_operator cfa_abstract_function
    39614148                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
    39624149        | ptrref_operator cfa_abstract_declarator_tuple
    3963                 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0, $1 ) ); }
     4150                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
    39644151        | type_qualifier_list ptrref_operator cfa_abstract_declarator_tuple
    39654152                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
  • src/Parser/parserutility.cc

    r34b4268 r24d6572  
    1010// Created On       : Sat May 16 15:30:39 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jul 18 10:12:00 2017
    13 // Update Count     : 8
     12// Last Modified On : Wed Mar  1 10:42:00 2023
     13// Update Count     : 9
    1414//
    1515
     
    1919#include <string>                // for string
    2020
    21 #include "SynTree/Constant.h"    // for Constant
    22 #include "SynTree/Expression.h"  // for UntypedExpr, CastExpr, ConstantExpr
    23 #include "SynTree/Type.h"        // for BasicType, ZeroType, BasicType::Kind...
     21#include "AST/Expr.hpp"          // for UntypedExpr, CastExpr, ConstantExpr
     22#include "AST/Type.hpp"          // for BasicType, ZeroType, BasicType::Kind...
    2423
    2524// rewrite
     
    2827//    if ( (int)(x != 0) ) ...
    2928
    30 Expression *notZeroExpr( Expression *orig ) {
    31         if( !orig ) return nullptr;
    32         UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) );
    33         comparison->get_args().push_back( orig );
    34         comparison->get_args().push_back( new ConstantExpr( Constant( new ZeroType( noQualifiers ), "0", (unsigned long long int)0 ) ) );
    35         return new CastExpr( comparison, new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     29ast::Expr * notZeroExpr( ast::Expr * orig ) {
     30        return ( !orig ) ? nullptr : new ast::CastExpr( orig->location,
     31                ast::UntypedExpr::createCall( orig->location,
     32                        "?!=?",
     33                        {
     34                                orig,
     35                                new ast::ConstantExpr( orig->location,
     36                                        new ast::ZeroType(),
     37                                        "0",
     38                                        std::optional<unsigned long long>( 0 )
     39                                ),
     40                        }
     41                ),
     42                new ast::BasicType( ast::BasicType::SignedInt )
     43        );
    3644}
    3745
  • src/Parser/parserutility.h

    r34b4268 r24d6572  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // parserutility.h --
     7// parserutility.h -- Collected utilities for the parser.
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:31:46 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:32:58 2017
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 14:03:00 2023
     13// Update Count     : 7
    1414//
    1515
    1616#pragma once
    1717
    18 class Expression;
     18#include "AST/Copy.hpp"            // for shallowCopy
     19namespace ast {
     20        class Expr;
     21}
    1922
    20 Expression *notZeroExpr( Expression *orig );
     23ast::Expr * notZeroExpr( ast::Expr *orig );
     24
     25template< typename T >
     26static inline auto maybeBuild( T * orig ) -> decltype(orig->build()) {
     27        return (orig) ? orig->build() : nullptr;
     28}
     29
     30template< typename T >
     31static inline auto maybeMoveBuild( T * orig ) -> decltype(orig->build()) {
     32        auto ret = maybeBuild<T>(orig);
     33        delete orig;
     34        return ret;
     35}
     36
     37template<typename node_t>
     38node_t * maybeCopy( node_t const * node ) {
     39        return node ? ast::shallowCopy( node ) : nullptr;
     40}
    2141
    2242// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.