Changeset bb7422a


Ignore:
Timestamp:
Apr 4, 2023, 2:25:52 PM (2 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, ast-experimental, master
Children:
beeff61e, e02e13f
Parents:
4541b09
Message:

Translated parser to the new ast. This incuded a small fix in the resolver so larger expressions can be used in with statements and some updated tests. errors/declaration just is a formatting update. attributes now actually preserves more attributes (unknown if all versions work).

Files:
18 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified src/AST/SymbolTable.cpp

    r4541b09 rbb7422a  
    7070        if ( baseExpr ) {
    7171                if (baseExpr->env) {
    72                         Expr * base = shallowCopy(baseExpr);
     72                        Expr * base = deepCopy(baseExpr);
    7373                        const TypeSubstitution * subs = baseExpr->env;
    7474                        base->env = nullptr;
  • TabularUnified src/Parser/DeclarationNode.cc

    r4541b09 rbb7422a  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Mar 14 11:56:00 2023
    13 // Update Count     : 1406
     12// Last Modified On : Tue Apr  4 10:28:00 2023
     13// Update Count     : 1392
    1414//
    1515
     
    2121#include <string>                  // for string, operator+, allocator, char...
    2222
     23#include "AST/Attribute.hpp"       // for Attribute
     24#include "AST/Copy.hpp"            // for shallowCopy
     25#include "AST/Decl.hpp"            // for Decl
     26#include "AST/Expr.hpp"            // for Expr
     27#include "AST/Print.hpp"           // for print
     28#include "AST/Stmt.hpp"            // for AsmStmt, DirectiveStmt
     29#include "AST/StorageClasses.hpp"  // for Storage::Class
     30#include "AST/Type.hpp"            // for Type
     31#include "Common/CodeLocation.h"   // for CodeLocation
     32#include "Common/Iterate.hpp"      // for reverseIterate
    2333#include "Common/SemanticError.h"  // for SemanticError
    2434#include "Common/UniqueName.h"     // for UniqueName
    25 #include "Common/utility.h"        // for maybeClone, maybeBuild, CodeLocation
     35#include "Common/utility.h"        // for maybeClone
    2636#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::...
    3337#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
    3438#include "TypedefTable.h"          // for TypedefTable
     
    6165UniqueName DeclarationNode::anonymous( "__anonymous" );
    6266
    63 extern LinkageSpec::Spec linkage;                                               // defined in parser.yy
     67extern ast::Linkage::Spec linkage;                                              // defined in parser.yy
    6468
    6569DeclarationNode::DeclarationNode() :
     
    6771
    6872//      variable.name = nullptr;
    69         variable.tyClass = TypeDecl::NUMBER_OF_KINDS;
     73        variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;
    7074        variable.assertions = nullptr;
    7175        variable.initializer = nullptr;
     
    105109        newnode->hasEllipsis = hasEllipsis;
    106110        newnode->linkage = linkage;
    107         newnode->asmName = maybeClone( asmName );
    108         cloneAll( attributes, newnode->attributes );
     111        newnode->asmName = maybeCopy( asmName );
     112        newnode->attributes = attributes;
    109113        newnode->initializer = maybeClone( initializer );
    110114        newnode->extension = extension;
     
    118122
    119123        newnode->assert.condition = maybeClone( assert.condition );
    120         newnode->assert.message = maybeClone( assert.message );
     124        newnode->assert.message = maybeCopy( assert.message );
    121125        return newnode;
    122126} // DeclarationNode::clone
     
    128132        } // if
    129133
    130         if ( linkage != LinkageSpec::Cforall ) {
    131                 os << LinkageSpec::name( linkage ) << " ";
    132         } // if
    133 
    134         storageClasses.print( os );
    135         funcSpecs.print( os );
     134        if ( linkage != ast::Linkage::Cforall ) {
     135                os << ast::Linkage::name( linkage ) << " ";
     136        } // if
     137
     138        ast::print( os, storageClasses );
     139        ast::print( os, funcSpecs );
    136140
    137141        if ( type ) {
     
    154158        if ( ! attributes.empty() ) {
    155159                os << string( indent + 2, ' ' ) << "with attributes " << endl;
    156                 for ( Attribute * attr: reverseIterate( attributes ) ) {
     160                for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) {
    157161                        os << string( indent + 4, ' ' ) << attr->name.c_str() << endl;
    158162                } // for
     
    169173}
    170174
    171 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {
     175DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {
    172176        DeclarationNode * newnode = new DeclarationNode;
    173177        newnode->storageClasses = sc;
     
    175179} // DeclarationNode::newStorageClass
    176180
    177 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {
     181DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {
    178182        DeclarationNode * newnode = new DeclarationNode;
    179183        newnode->funcSpecs = fs;
     
    181185} // DeclarationNode::newFuncSpecifier
    182186
    183 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {
     187DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {
    184188        DeclarationNode * newnode = new DeclarationNode;
    185189        newnode->type = new TypeData();
     
    241245}
    242246
    243 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
     247DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    244248        DeclarationNode * newnode = new DeclarationNode;
    245249        newnode->type = new TypeData( TypeData::Aggregate );
     
    271275} // DeclarationNode::newEnum
    272276
    273 
    274 
    275277DeclarationNode * DeclarationNode::newName( const string * name ) {
    276278        DeclarationNode * newnode = new DeclarationNode;
     
    324326} // DeclarationNode::newFromTypeGen
    325327
    326 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {
     328DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {
    327329        DeclarationNode * newnode = newName( name );
    328330        newnode->type = nullptr;
     
    336338        newnode->type = new TypeData( TypeData::Aggregate );
    337339        newnode->type->aggregate.name = name;
    338         newnode->type->aggregate.kind = AggregateDecl::Trait;
     340        newnode->type->aggregate.kind = ast::AggregateDecl::Trait;
    339341        newnode->type->aggregate.params = params;
    340342        newnode->type->aggregate.fields = asserts;
     
    346348        newnode->type = new TypeData( TypeData::AggregateInst );
    347349        newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
    348         newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;
     350        newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;
    349351        newnode->type->aggInst.aggregate->aggregate.name = name;
    350352        newnode->type->aggInst.params = params;
     
    381383        newnode->type->array.dimension = size;
    382384        newnode->type->array.isStatic = isStatic;
    383         if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ConstantExpr * >() ) {
     385        if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) {
    384386                newnode->type->array.isVarLen = false;
    385387        } else {
     
    451453        DeclarationNode * newnode = new DeclarationNode;
    452454        newnode->type = nullptr;
    453         std::list< Expression * > exprs;
     455        std::vector<ast::ptr<ast::Expr>> exprs;
    454456        buildList( expr, exprs );
    455         newnode->attributes.push_back( new Attribute( *name, exprs ) );
     457        newnode->attributes.push_back(
     458                new ast::Attribute( *name, std::move( exprs ) ) );
    456459        delete name;
    457460        return newnode;
     
    470473}
    471474
    472 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) {
     475DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) {
    473476        DeclarationNode * newnode = new DeclarationNode;
    474477        newnode->assert.condition = condition;
     
    477480}
    478481
    479 
    480 void appendError( string & dst, const string & src ) {
     482static void appendError( string & dst, const string & src ) {
    481483        if ( src.empty() ) return;
    482484        if ( dst.empty() ) { dst = src; return; }
     
    485487
    486488void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
    487         const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
    488 
    489         if ( (qsrc & qdst).any() ) {                                            // duplicates ?
    490                 for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates
    491                         if ( qsrc[i] && qdst[i] ) {
    492                                 appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] );
    493                         } // if
    494                 } // for
     489        const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
     490        const ast::CV::Qualifiers duplicates = qsrc & qdst;
     491
     492        if ( duplicates.any() ) {
     493                std::stringstream str;
     494                str << "duplicate ";
     495                ast::print( str, duplicates );
     496                str << "qualifier(s)";
     497                appendError( error, str.str() );
    495498        } // for
    496499} // DeclarationNode::checkQualifiers
    497500
    498501void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
    499         if ( (funcSpecs & src->funcSpecs).any() ) {                     // duplicates ?
    500                 for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates
    501                         if ( funcSpecs[i] && src->funcSpecs[i] ) {
    502                                 appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] );
    503                         } // if
    504                 } // for
    505         } // if
    506 
    507         if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ?
    508                 if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ?
    509                         for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates
    510                                 if ( storageClasses[i] && src->storageClasses[i] ) {
    511                                         appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] );
    512                                 } // if
    513                         } // for
    514                         // src is the new item being added and has a single bit
    515                 } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ?
    516                         appendError( error, string( "conflicting " )
    517                                 + Type::StorageClassesNames[storageClasses.ffs()]
    518                                 + " & " + Type::StorageClassesNames[src->storageClasses.ffs()] );
    519                         src->storageClasses.reset();                            // FIX to preserve invariant of one basic storage specifier
    520                 } // if
     502        ast::Function::Specs fsDups = funcSpecs & src->funcSpecs;
     503        if ( fsDups.any() ) {
     504                std::stringstream str;
     505                str << "duplicate ";
     506                ast::print( str, fsDups );
     507                str << "function specifier(s)";
     508                appendError( error, str.str() );
     509        } // if
     510
     511        // Skip if everything is unset.
     512        if ( storageClasses.any() && src->storageClasses.any() ) {
     513                ast::Storage::Classes dups = storageClasses & src->storageClasses;
     514                // Check for duplicates.
     515                if ( dups.any() ) {
     516                        std::stringstream str;
     517                        str << "duplicate ";
     518                        ast::print( str, dups );
     519                        str << "storage class(es)";
     520                        appendError( error, str.str() );
     521                // Check for conflicts.
     522                } else if ( !src->storageClasses.is_threadlocal_any() ) {
     523                        std::stringstream str;
     524                        str << "conflicting ";
     525                        ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) );
     526                        str << "& ";
     527                        ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) );
     528                        str << "storage classes";
     529                        appendError( error, str.str() );
     530                        // FIX to preserve invariant of one basic storage specifier
     531                        src->storageClasses.reset();
     532                }
    521533        } // if
    522534
     
    528540        storageClasses |= q->storageClasses;
    529541
    530         for ( Attribute * attr: reverseIterate( q->attributes ) ) {
    531                 attributes.push_front( attr->clone() );
    532         } // for
     542        std::vector<ast::ptr<ast::Attribute>> tmp;
     543        tmp.reserve( q->attributes.size() );
     544        for ( auto const & attr : q->attributes ) {
     545                tmp.emplace_back( ast::shallowCopy( attr.get() ) );
     546        }
     547        spliceBegin( attributes, tmp );
     548
    533549        return this;
    534550} // DeclarationNode::copySpecifiers
     
    716732
    717733DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
    718         if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
     734        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
    719735                if ( variable.assertions ) {
    720736                        variable.assertions->appendList( assertions );
     
    798814DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) {
    799815        if ( a ) {
    800                 for ( Attribute *attr: reverseIterate( a->attributes ) ) {
    801                         attributes.push_front( attr );
    802                 } // for
     816                spliceBegin( attributes, a->attributes );
    803817                a->attributes.clear();
    804818        } // if
     
    921935
    922936DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
    923         assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
     937        assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
    924938        variable.initializer = init;
    925939        return this;
     
    985999}
    9861000
    987 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {
     1001void buildList( const DeclarationNode * firstNode,
     1002                std::vector<ast::ptr<ast::Decl>> & outputList ) {
    9881003        SemanticErrorException errors;
    989         std::back_insert_iterator< std::list< Declaration * > > out( outputList );
     1004        std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
    9901005
    9911006        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    9921007                try {
    9931008                        bool extracted = false, anon = false;
    994                         AggregateDecl * unionDecl = nullptr;
     1009                        ast::AggregateDecl * unionDecl = nullptr;
    9951010
    9961011                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
     
    10291044                                } // if
    10301045
    1031                                 Declaration * decl = extr->build();
     1046                                ast::Decl * decl = extr->build();
    10321047                                if ( decl ) {
    10331048                                        // Remember the declaration if it is a union aggregate ?
    1034                                         unionDecl = dynamic_cast<UnionDecl *>( decl );
     1049                                        unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
    10351050
    10361051                                        decl->location = cur->location;
     
    10511066                        } // if
    10521067
    1053                         Declaration * decl = cur->build();
     1068                        ast::Decl * decl = cur->build();
    10541069                        if ( decl ) {
    1055                                 if ( TypedefDecl * typedefDecl = dynamic_cast<TypedefDecl *>( decl ) ) {
     1070                                if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) {
    10561071                                        if ( unionDecl ) {                                      // is the typedef alias a union aggregate ?
    10571072                                                // This code handles a special issue with the attribute transparent_union.
     
    10651080
    10661081                                                // If typedef is an alias for a union, then its alias type was hoisted above and remembered.
    1067                                                 if ( UnionInstType * unionInstType = dynamic_cast<UnionInstType *>( typedefDecl->base ) ) {
     1082                                                if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) {
     1083                                                        auto instType = ast::mutate( unionInstType );
    10681084                                                        // Remove all transparent_union attributes from typedef and move to alias union.
    1069                                                         list<Attribute *>::iterator attr;
    1070                                                         for ( attr = unionInstType->attributes.begin(); attr != unionInstType->attributes.end(); ) { // forward order
     1085                                                        for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) { // forward order
     1086                                                                assert( *attr );
    10711087                                                                if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {
    1072                                                                         list<Attribute *>::iterator cur = attr; // remember current node
    1073                                                                         attr++;                         // advance iterator
    1074                                                                         unionDecl->attributes.emplace_back( *cur ); // move current
    1075                                                                         unionInstType->attributes.erase( cur ); // remove current
     1088                                                                        unionDecl->attributes.emplace_back( attr->release() );
     1089                                                                        attr = instType->attributes.erase( attr );
    10761090                                                                } else {
    1077                                                                         attr++;                         // advance iterator
     1091                                                                        attr++;
    10781092                                                                } // if
    10791093                                                        } // for
     1094                                                        typedefDecl->base = instType;
    10801095                                                } // if
    10811096                                        } // if
     
    10901105                                if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) {
    10911106                                        if ( decl->name == "" ) {
    1092                                                 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) {
    1093                                                         if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) {
     1107                                                if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
     1108                                                        if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) {
    10941109                                                                if ( aggr->name.find("anonymous") == std::string::npos ) {
    10951110                                                                        if ( ! cur->get_inLine() ) {
     
    11171132
    11181133// currently only builds assertions, function parameters, and return values
    1119 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) {
     1134void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
    11201135        SemanticErrorException errors;
    1121         std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList );
     1136        std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
    11221137
    11231138        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    11241139                try {
    1125                         Declaration * decl = cur->build();
     1140                        ast::Decl * decl = cur->build();
    11261141                        assert( decl );
    1127                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     1142                        if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
    11281143                                dwt->location = cur->location;
    11291144                                *out++ = dwt;
    1130                         } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
     1145                        } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {
    11311146                                // e.g., int foo(struct S) {}
    1132                                 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name );
    1133                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1134                                 obj->location = cur->location;
     1147                                auto inst = new ast::StructInstType( agg->name );
     1148                                auto obj = new ast::ObjectDecl( cur->location, "", inst );
     1149                                obj->linkage = linkage;
    11351150                                *out++ = obj;
    11361151                                delete agg;
    1137                         } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
     1152                        } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {
    11381153                                // e.g., int foo(union U) {}
    1139                                 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name );
    1140                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1141                                 obj->location = cur->location;
     1154                                auto inst = new ast::UnionInstType( agg->name );
     1155                                auto obj = new ast::ObjectDecl( cur->location,
     1156                                        "", inst, nullptr, ast::Storage::Classes(),
     1157                                        linkage );
    11421158                                *out++ = obj;
    1143                         } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
     1159                        } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {
    11441160                                // e.g., int foo(enum E) {}
    1145                                 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name );
    1146                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1147                                 obj->location = cur->location;
     1161                                auto inst = new ast::EnumInstType( agg->name );
     1162                                auto obj = new ast::ObjectDecl( cur->location,
     1163                                        "",
     1164                                        inst,
     1165                                        nullptr,
     1166                                        ast::Storage::Classes(),
     1167                                        linkage
     1168                                );
    11481169                                *out++ = obj;
    11491170                        } // if
     
    11581179} // buildList
    11591180
    1160 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) {
     1181void buildTypeList( const DeclarationNode * firstNode,
     1182                std::vector<ast::ptr<ast::Type>> & outputList ) {
    11611183        SemanticErrorException errors;
    1162         std::back_insert_iterator< std::list< Type * > > out( outputList );
     1184        std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
    11631185        const DeclarationNode * cur = firstNode;
    11641186
     
    11771199} // buildTypeList
    11781200
    1179 Declaration * DeclarationNode::build() const {
     1201ast::Decl * DeclarationNode::build() const {
    11801202        if ( ! error.empty() ) SemanticError( this, error + " in declaration of " );
    11811203
    11821204        if ( asmStmt ) {
    1183                 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) );
     1205                auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() );
     1206                return new ast::AsmDecl( stmt->location, stmt );
    11841207        } // if
    11851208        if ( directiveStmt ) {
    1186                 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) );
    1187         } // if
    1188 
    1189         if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
     1209                auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() );
     1210                return new ast::DirectiveDecl( stmt->location, stmt );
     1211        } // if
     1212
     1213        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
    11901214                // otype is internally converted to dtype + otype parameters
    1191                 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension };
    1192                 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
     1215                static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension };
     1216                static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
    11931217                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
    1194                 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 );
    1195                 buildList( variable.assertions, ret->get_assertions() );
     1218                ast::TypeDecl * ret = new ast::TypeDecl( location,
     1219                        *name,
     1220                        ast::Storage::Classes(),
     1221                        (ast::Type *)nullptr,
     1222                        kindMap[ variable.tyClass ],
     1223                        variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype,
     1224                        variable.initializer ? variable.initializer->buildType() : nullptr
     1225                );
     1226                buildList( variable.assertions, ret->assertions );
    11961227                return ret;
    11971228        } // if
     
    12151246                } // if
    12161247                bool isDelete = initializer && initializer->get_isDelete();
    1217                 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild(initializer), attributes )->set_extension( extension );
     1248                ast::Decl * decl = buildDecl(
     1249                        type,
     1250                        name ? *name : string( "" ),
     1251                        storageClasses,
     1252                        maybeBuild( bitfieldWidth ),
     1253                        funcSpecs,
     1254                        linkage,
     1255                        asmName,
     1256                        isDelete ? nullptr : maybeBuild( initializer ),
     1257                        copy( attributes )
     1258                )->set_extension( extension );
    12181259                if ( isDelete ) {
    1219                         DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );
     1260                        auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );
    12201261                        dwt->isDeleted = true;
    12211262                }
     
    12241265
    12251266        if ( assert.condition ) {
    1226                 return new StaticAssertDecl( maybeBuild( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) );
     1267                auto cond = maybeBuild( assert.condition );
     1268                auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) );
     1269                return new ast::StaticAssertDecl( location, cond, msg );
    12271270        }
    12281271
     
    12351278        } // if
    12361279        if ( enumInLine ) {
    1237                 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr );
     1280                return new ast::InlineMemberDecl( location,
     1281                        *name, (ast::Type*)nullptr, storageClasses, linkage );
    12381282        } // if
    12391283        assertf( name, "ObjectDecl must a have name\n" );
    1240         return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild( bitfieldWidth ), nullptr, maybeBuild( initializer ) ))->set_asmName( asmName )->set_extension( extension );
    1241 }
    1242 
    1243 Type * DeclarationNode::buildType() const {
     1284        auto ret = new ast::ObjectDecl( location,
     1285                *name,
     1286                (ast::Type*)nullptr,
     1287                maybeBuild( initializer ),
     1288                storageClasses,
     1289                linkage,
     1290                maybeBuild( bitfieldWidth )
     1291        );
     1292        ret->asmName = asmName;
     1293        ret->extension = extension;
     1294        return ret;
     1295}
     1296
     1297ast::Type * DeclarationNode::buildType() const {
    12441298        assert( type );
    12451299
     
    12471301        case TypeData::Enum:
    12481302        case TypeData::Aggregate: {
    1249                 ReferenceToType * ret = buildComAggInst( type, attributes, linkage );
    1250                 buildList( type->aggregate.actuals, ret->get_parameters() );
     1303                ast::BaseInstType * ret =
     1304                        buildComAggInst( type, copy( attributes ), linkage );
     1305                buildList( type->aggregate.actuals, ret->params );
    12511306                return ret;
    12521307        }
    12531308        case TypeData::Symbolic: {
    1254                 TypeInstType * ret = new TypeInstType( buildQualifiers( type ), *type->symbolic.name, false, attributes );
    1255                 buildList( type->symbolic.actuals, ret->get_parameters() );
     1309                ast::TypeInstType * ret = new ast::TypeInstType(
     1310                        *type->symbolic.name,
     1311                        // This is just a default, the true value is not known yet.
     1312                        ast::TypeDecl::Dtype,
     1313                        buildQualifiers( type ),
     1314                        copy( attributes ) );
     1315                buildList( type->symbolic.actuals, ret->params );
    12561316                return ret;
    12571317        }
    12581318        default:
    1259                 Type * simpletypes = typebuild( type );
    1260                 simpletypes->get_attributes() = attributes;             // copy because member is const
     1319                ast::Type * simpletypes = typebuild( type );
     1320                // copy because member is const
     1321                simpletypes->attributes = attributes;
    12611322                return simpletypes;
    12621323        } // switch
  • TabularUnified src/Parser/ExpressionNode.cc

    r4541b09 rbb7422a  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Mar 14 12:00:00 2023
    13 // Update Count     : 1082
     12// Last Modified On : Tue Apr  4 11:07:00 2023
     13// Update Count     : 1083
    1414//
    1515
     
    2121#include <string>                  // for string, operator+, operator==
    2222
     23#include "AST/Expr.hpp"            // for NameExpr
     24#include "AST/Type.hpp"            // for BaseType, SueInstType
    2325#include "Common/SemanticError.h"  // for SemanticError
    2426#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild, CodeLo...
    2527#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
    3128#include "parserutility.h"         // for notZeroExpr
    32 
    33 class Initializer;
    3429
    3530using namespace std;
     
    4843// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
    4944// type.
    50 
    51 extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
    5245
    5346// static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
     
    127120} // scanbin
    128121
    129 Expression * build_constantInteger( string & str ) {
    130         static const BasicType::Kind kind[2][6] = {
     122ast::Expr * build_constantInteger(
     123                const CodeLocation & location, string & str ) {
     124        static const ast::BasicType::Kind kind[2][6] = {
    131125                // 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, },
     126                { ast::BasicType::ShortSignedInt, ast::BasicType::SignedChar, ast::BasicType::SignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ ast::BasicType::LongLongSignedInt, },
     127                { ast::BasicType::ShortUnsignedInt, ast::BasicType::UnsignedChar, ast::BasicType::UnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ ast::BasicType::LongLongUnsignedInt, },
    134128        };
    135129
     
    141135        string str2( "0x0" );
    142136        unsigned long long int v, v2 = 0;                                       // converted integral value
    143         Expression * ret, * ret2;
     137        ast::Expr * ret, * ret2;
    144138
    145139        int type = -1;                                                                          // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     
    149143        // special constants
    150144        if ( str == "0" ) {
    151                 ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ) );
     145                ret = new ast::ConstantExpr( location, new ast::ZeroType(), str, 0 );
    152146                goto CLEANUP;
    153147        } // if
    154148        if ( str == "1" ) {
    155                 ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ) );
     149                ret = new ast::ConstantExpr( location, new ast::OneType(), str, 1 );
    156150                goto CLEANUP;
    157151        } // if
     
    304298
    305299        // Constant type is correct for overload resolving.
    306         ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) );
     300        ret = new ast::ConstantExpr( location,
     301                new ast::BasicType( kind[Unsigned][type] ), str, v );
    307302        if ( Unsigned && type < 2 ) {                                           // hh or h, less than int ?
    308303                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
    309                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
     304                ret = new ast::CastExpr( location,
     305                        ret,
     306                        new ast::BasicType( kind[Unsigned][type] ),
     307                        ast::ExplicitCast );
    310308        } else if ( ltype != -1 ) {                                                     // explicit length ?
    311309                if ( ltype == 6 ) {                                                             // int128, (int128)constant
    312 //                      ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    313                         ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) );
    314                         ret = build_compoundLiteral(
    315                                 DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ),
    316                                 new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) );
     310                        ret2 = new ast::ConstantExpr( location,
     311                                new ast::BasicType( ast::BasicType::LongLongSignedInt ),
     312                                str2,
     313                                v2 );
     314                        ret = build_compoundLiteral( location,
     315                                DeclarationNode::newBasicType(
     316                                        DeclarationNode::Int128
     317                                )->addType(
     318                                        DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ),
     319                                new InitializerNode(
     320                                        (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true )
     321                        );
    317322                } else {                                                                                // explicit length, (length_type)constant
    318                         ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false );
     323                        ret = new ast::CastExpr( location,
     324                                ret,
     325                                new ast::TypeInstType( lnthsInt[Unsigned][ltype], ast::TypeDecl::Dtype ),
     326                                ast::ExplicitCast );
    319327                        if ( ltype == 5 ) {                                                     // pointer, intptr( (uintptr_t)constant )
    320                                 ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) );
     328                                ret = build_func( location,
     329                                        new ExpressionNode(
     330                                                build_varref( location, new string( "intptr" ) ) ),
     331                                        new ExpressionNode( ret ) );
    321332                        } // if
    322333                } // if
     
    362373
    363374
    364 Expression * build_constantFloat( string & str ) {
    365         static const BasicType::Kind kind[2][12] = {
    366                 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x },
    367                 { 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 },
     375ast::Expr * build_constantFloat(
     376                const CodeLocation & location, string & str ) {
     377        static const ast::BasicType::Kind kind[2][12] = {
     378                { 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 },
     379                { 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 },
    368380        };
    369381
     
    402414
    403415        assert( 0 <= type && type < 12 );
    404         Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) );
    405         if ( explnth ) {                                                                        // explicit length ?
    406                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false );
     416        ast::Expr * ret = new ast::ConstantExpr( location,
     417                new ast::BasicType( kind[complx][type] ),
     418                str,
     419                v );
     420        // explicit length ?
     421        if ( explnth ) {
     422                ret = new ast::CastExpr( location,
     423                        ret,
     424                        new ast::BasicType( kind[complx][type] ),
     425                        ast::ExplicitCast );
    407426        } // if
    408427
     
    419438} // sepString
    420439
    421 Expression * build_constantChar( string & str ) {
     440ast::Expr * build_constantChar( const CodeLocation & location, string & str ) {
    422441        string units;                                                                           // units
    423442        sepString( str, units, '\'' );                                          // separate constant from units
    424443
    425         Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
     444        ast::Expr * ret = new ast::ConstantExpr( location,
     445                new ast::BasicType( ast::BasicType::Char ),
     446                str,
     447                (unsigned long long int)(unsigned char)str[1] );
    426448        if ( units.length() != 0 ) {
    427                 ret = new UntypedExpr( new NameExpr( units ), { ret } );
     449                ret = new ast::UntypedExpr( location,
     450                        new ast::NameExpr( location, units ),
     451                        { ret } );
    428452        } // if
    429453
     
    432456} // build_constantChar
    433457
    434 Expression * build_constantStr( string & str ) {
     458ast::Expr * build_constantStr(
     459                const CodeLocation & location,
     460                string & str ) {
    435461        assert( str.length() > 0 );
    436462        string units;                                                                           // units
    437463        sepString( str, units, '"' );                                           // separate constant from units
    438464
    439         Type * strtype;
     465        ast::Type * strtype;
    440466        switch ( str[0] ) {                                                                     // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1
    441467        case 'u':
    442468                if ( str[1] == '8' ) goto Default;                              // utf-8 characters => array of char
    443469                // lookup type of associated typedef
    444                 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false );
     470                strtype = new ast::TypeInstType( "char16_t", ast::TypeDecl::Dtype );
    445471                break;
    446472        case 'U':
    447                 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false );
     473                strtype = new ast::TypeInstType( "char32_t", ast::TypeDecl::Dtype );
    448474                break;
    449475        case 'L':
    450                 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false );
     476                strtype = new ast::TypeInstType( "wchar_t", ast::TypeDecl::Dtype );
    451477                break;
    452478        Default:                                                                                        // char default string type
    453479        default:
    454                 strtype = new BasicType( Type::Qualifiers( ), BasicType::Char );
     480                strtype = new ast::BasicType( ast::BasicType::Char );
    455481        } // switch
    456         ArrayType * at = new ArrayType( noQualifiers, strtype,
    457                                                                         new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
    458                                                                         false, false );
    459         Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) );
     482        ast::ArrayType * at = new ast::ArrayType(
     483                strtype,
     484                // Length is adjusted: +1 for '\0' and -2 for '"'
     485                ast::ConstantExpr::from_ulong( location, str.size() + 1 - 2 ),
     486                ast::FixedLen,
     487                ast::DynamicDim );
     488        ast::Expr * ret = new ast::ConstantExpr( location, at, str, std::nullopt );
    460489        if ( units.length() != 0 ) {
    461                 ret = new UntypedExpr( new NameExpr( units ), { ret } );
     490                ret = new ast::UntypedExpr( location,
     491                        new ast::NameExpr( location, units ),
     492                        { ret } );
    462493        } // if
    463494
     
    466497} // build_constantStr
    467498
    468 Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
     499ast::Expr * build_field_name_FLOATING_FRACTIONconstant(
     500                const CodeLocation & location, const string & str ) {
    469501        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) SemanticError( yylloc, "invalid tuple index " + str );
    470         Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
     502        ast::Expr * ret = build_constantInteger( location,
     503                *new string( str.substr(1) ) );
    471504        delete &str;
    472505        return ret;
    473506} // build_field_name_FLOATING_FRACTIONconstant
    474507
    475 Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
     508ast::Expr * build_field_name_FLOATING_DECIMALconstant(
     509                const CodeLocation & location, const string & str ) {
    476510        if ( str[str.size() - 1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str );
    477         Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
     511        ast::Expr * ret = build_constantInteger(
     512                location, *new string( str.substr( 0, str.size()-1 ) ) );
    478513        delete &str;
    479514        return ret;
    480515} // build_field_name_FLOATING_DECIMALconstant
    481516
    482 Expression * build_field_name_FLOATINGconstant( const string & str ) {
     517ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation & location,
     518                const string & str ) {
    483519        // str is of the form A.B -> separate at the . and return member expression
    484520        int a, b;
     
    486522        stringstream ss( str );
    487523        ss >> a >> dot >> b;
    488         UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
     524        auto ret = new ast::UntypedMemberExpr( location,
     525                ast::ConstantExpr::from_int( location, b ),
     526                ast::ConstantExpr::from_int( location, a )
     527        );
    489528        delete &str;
    490529        return ret;
    491530} // build_field_name_FLOATINGconstant
    492531
    493 Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) {
    494         if ( fracts ) {
    495                 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) {
    496                         memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) );
    497                         return memberExpr;
    498                 } else {
    499                         return new UntypedMemberExpr( fracts, fieldName );
    500                 } // if
    501         } // if
    502         return fieldName;
     532ast::Expr * make_field_name_fraction_constants( const CodeLocation & location,
     533                ast::Expr * fieldName,
     534                ast::Expr * fracts ) {
     535        if ( nullptr == fracts ) {
     536                return fieldName;
     537        } else if ( auto memberExpr = dynamic_cast<ast::UntypedMemberExpr *>( fracts ) ) {
     538                memberExpr->member = make_field_name_fraction_constants( location,
     539                        fieldName,
     540                        ast::mutate( memberExpr->aggregate.get() ) );
     541                return memberExpr;
     542        } else {
     543                return new ast::UntypedMemberExpr( location, fracts, fieldName );
     544        } // if
    503545} // make_field_name_fraction_constants
    504546
    505 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) {
    506         return make_field_name_fraction_constants( fieldName, maybeMoveBuild( fracts ) );
     547ast::Expr * build_field_name_fraction_constants( const CodeLocation & location,
     548                ast::Expr * fieldName,
     549                ExpressionNode * fracts ) {
     550        return make_field_name_fraction_constants( location, fieldName, maybeMoveBuild( fracts ) );
    507551} // build_field_name_fraction_constants
    508552
    509 NameExpr * build_varref( const string * name ) {
    510         NameExpr * expr = new NameExpr( *name );
     553ast::NameExpr * build_varref( const CodeLocation & location,
     554                const string * name ) {
     555        ast::NameExpr * expr = new ast::NameExpr( location, *name );
    511556        delete name;
    512557        return expr;
    513558} // build_varref
    514559
    515 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) {
    516         Declaration * newDecl = maybeBuild(decl_node);
    517         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) {
    518                 const Type * t = newDeclWithType->get_type();
    519                 if ( t ) {
    520                         if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) {
    521                                 newDecl= new EnumDecl( typeInst->name );
     560ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location,
     561                const DeclarationNode * decl_node,
     562                const ast::NameExpr * name ) {
     563        ast::Decl * newDecl = maybeBuild( decl_node );
     564        if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) {
     565                if ( const ast::Type * t = newDeclWithType->get_type() ) {
     566                        if ( auto typeInst = dynamic_cast<const ast::TypeInstType *>( t ) ) {
     567                                newDecl = new ast::EnumDecl( location, typeInst->name );
    522568                        }
    523569                }
    524570        }
    525         return new QualifiedNameExpr( newDecl, name->name );
     571        return new ast::QualifiedNameExpr( location, newDecl, name->name );
    526572}
    527573
    528 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) {
    529         EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node );
    530         return new QualifiedNameExpr( newDecl, name->name );
     574ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location,
     575                const ast::EnumDecl * decl,
     576                const ast::NameExpr * name ) {
     577        return new ast::QualifiedNameExpr( location, decl, name->name );
    531578}
    532579
    533 DimensionExpr * build_dimensionref( const string * name ) {
    534         DimensionExpr * expr = new DimensionExpr( *name );
     580ast::DimensionExpr * build_dimensionref( const CodeLocation & location,
     581                const string * name ) {
     582        ast::DimensionExpr * expr = new ast::DimensionExpr( location, *name );
    535583        delete name;
    536584        return expr;
     
    548596}; // OperName
    549597
    550 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
    551         Type * targetType = maybeMoveBuildType( decl_node );
    552         if ( dynamic_cast< VoidType * >( targetType ) ) {
     598ast::Expr * build_cast( const CodeLocation & location,
     599                DeclarationNode * decl_node,
     600                ExpressionNode * expr_node ) {
     601        ast::Type * targetType = maybeMoveBuildType( decl_node );
     602        if ( dynamic_cast<ast::VoidType *>( targetType ) ) {
    553603                delete targetType;
    554                 return new CastExpr( maybeMoveBuild( expr_node ), false );
     604                return new ast::CastExpr( location,
     605                        maybeMoveBuild( expr_node ),
     606                        ast::ExplicitCast );
    555607        } else {
    556                 return new CastExpr( maybeMoveBuild( expr_node ), targetType, false );
     608                return new ast::CastExpr( location,
     609                        maybeMoveBuild( expr_node ),
     610                        targetType,
     611                        ast::ExplicitCast );
    557612        } // if
    558613} // build_cast
    559614
    560 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) {
    561         return new KeywordCastExpr( maybeMoveBuild( expr_node ), target );
     615ast::Expr * build_keyword_cast( const CodeLocation & location,
     616                ast::AggregateDecl::Aggregate target,
     617                ExpressionNode * expr_node ) {
     618        return new ast::KeywordCastExpr( location,
     619                maybeMoveBuild( expr_node ),
     620                target
     621        );
    562622}
    563623
    564 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
    565         return new VirtualCastExpr( maybeMoveBuild( expr_node ), maybeMoveBuildType( decl_node ) );
     624ast::Expr * build_virtual_cast( const CodeLocation & location,
     625                DeclarationNode * decl_node,
     626                ExpressionNode * expr_node ) {
     627        return new ast::VirtualCastExpr( location,
     628                maybeMoveBuild( expr_node ),
     629                maybeMoveBuildType( decl_node )
     630        );
    566631} // build_virtual_cast
    567632
    568 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) {
    569         return new UntypedMemberExpr( member, maybeMoveBuild( expr_node ) );
     633ast::Expr * build_fieldSel( const CodeLocation & location,
     634                ExpressionNode * expr_node,
     635                ast::Expr * member ) {
     636        return new ast::UntypedMemberExpr( location,
     637                member,
     638                maybeMoveBuild( expr_node )
     639        );
    570640} // build_fieldSel
    571641
    572 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) {
    573         UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
     642ast::Expr * build_pfieldSel( const CodeLocation & location,
     643                ExpressionNode * expr_node,
     644                ast::Expr * member ) {
     645        auto deref = new ast::UntypedExpr( location,
     646                new ast::NameExpr( location, "*?" )
     647        );
    574648        deref->location = expr_node->location;
    575         deref->get_args().push_back( maybeMoveBuild( expr_node ) );
    576         UntypedMemberExpr * ret = new UntypedMemberExpr( member, deref );
     649        deref->args.push_back( maybeMoveBuild( expr_node ) );
     650        auto ret = new ast::UntypedMemberExpr( location, member, deref );
    577651        return ret;
    578652} // build_pfieldSel
    579653
    580 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) {
    581         Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() );
     654ast::Expr * build_offsetOf( const CodeLocation & location,
     655                DeclarationNode * decl_node,
     656                ast::NameExpr * member ) {
     657        ast::Expr * ret = new ast::UntypedOffsetofExpr( location,
     658                maybeMoveBuildType( decl_node ),
     659                member->name
     660        );
     661        ret->result = new ast::BasicType( ast::BasicType::LongUnsignedInt );
    582662        delete member;
    583663        return ret;
    584664} // build_offsetOf
    585665
    586 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ) {
    587         return new LogicalExpr( notZeroExpr( maybeMoveBuild( expr_node1 ) ), notZeroExpr( maybeMoveBuild( expr_node2 ) ), kind );
     666ast::Expr * build_and_or( const CodeLocation & location,
     667                ExpressionNode * expr_node1,
     668                ExpressionNode * expr_node2,
     669                ast::LogicalFlag flag ) {
     670        return new ast::LogicalExpr( location,
     671                notZeroExpr( maybeMoveBuild( expr_node1 ) ),
     672                notZeroExpr( maybeMoveBuild( expr_node2 ) ),
     673                flag
     674        );
    588675} // build_and_or
    589676
    590 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) {
    591         list< Expression * > args;
     677ast::Expr * build_unary_val( const CodeLocation & location,
     678                OperKinds op,
     679                ExpressionNode * expr_node ) {
     680        std::vector<ast::ptr<ast::Expr>> args;
    592681        args.push_back( maybeMoveBuild( expr_node ) );
    593         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     682        return new ast::UntypedExpr( location,
     683                new ast::NameExpr( location, OperName[ (int)op ] ),
     684                std::move( args )
     685        );
    594686} // build_unary_val
    595687
    596 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    597         list< Expression * > args;
     688ast::Expr * build_binary_val( const CodeLocation & location,
     689                OperKinds op,
     690                ExpressionNode * expr_node1,
     691                ExpressionNode * expr_node2 ) {
     692        std::vector<ast::ptr<ast::Expr>> args;
    598693        args.push_back( maybeMoveBuild( expr_node1 ) );
    599694        args.push_back( maybeMoveBuild( expr_node2 ) );
    600         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     695        return new ast::UntypedExpr( location,
     696                new ast::NameExpr( location, OperName[ (int)op ] ),
     697                std::move( args )
     698        );
    601699} // build_binary_val
    602700
    603 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    604         list< Expression * > args;
    605         args.push_back( maybeMoveBuild( expr_node1 ) );
    606         args.push_back( maybeMoveBuild( expr_node2 ) );
    607         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     701ast::Expr * build_binary_ptr( const CodeLocation & location,
     702                OperKinds op,
     703                ExpressionNode * expr_node1,
     704                ExpressionNode * expr_node2 ) {
     705        return build_binary_val( location, op, expr_node1, expr_node2 );
    608706} // build_binary_ptr
    609707
    610 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ) {
    611         return new ConditionalExpr( notZeroExpr( maybeMoveBuild( expr_node1 ) ), maybeMoveBuild( expr_node2 ), maybeMoveBuild( expr_node3 ) );
     708ast::Expr * build_cond( const CodeLocation & location,
     709                ExpressionNode * expr_node1,
     710                ExpressionNode * expr_node2,
     711                ExpressionNode * expr_node3 ) {
     712        return new ast::ConditionalExpr( location,
     713                notZeroExpr( maybeMoveBuild( expr_node1 ) ),
     714                maybeMoveBuild( expr_node2 ),
     715                maybeMoveBuild( expr_node3 )
     716        );
    612717} // build_cond
    613718
    614 Expression * build_tuple( ExpressionNode * expr_node ) {
    615         list< Expression * > exprs;
     719ast::Expr * build_tuple( const CodeLocation & location,
     720                ExpressionNode * expr_node ) {
     721        std::vector<ast::ptr<ast::Expr>> exprs;
    616722        buildMoveList( expr_node, exprs );
    617         return new UntypedTupleExpr( exprs );;
     723        return new ast::UntypedTupleExpr( location, std::move( exprs ) );
    618724} // build_tuple
    619725
    620 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
    621         list< Expression * > args;
     726ast::Expr * build_func( const CodeLocation & location,
     727                ExpressionNode * function,
     728                ExpressionNode * expr_node ) {
     729        std::vector<ast::ptr<ast::Expr>> args;
    622730        buildMoveList( expr_node, args );
    623         return new UntypedExpr( maybeMoveBuild( function ), args );
     731        return new ast::UntypedExpr( location,
     732                maybeMoveBuild( function ),
     733                std::move( args )
     734        );
    624735} // build_func
    625736
    626 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ) {
    627         Declaration * newDecl = maybeBuild( decl_node ); // compound literal type
    628         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
    629                 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild( kids ) );
     737ast::Expr * build_compoundLiteral( const CodeLocation & location,
     738                DeclarationNode * decl_node,
     739                InitializerNode * kids ) {
     740        // compound literal type
     741        ast::Decl * newDecl = maybeBuild( decl_node );
     742        // non-sue compound-literal type
     743        if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) {
     744                return new ast::CompoundLiteralExpr( location,
     745                        newDeclWithType->get_type(),
     746                        maybeMoveBuild( kids ) );
    630747        // these types do not have associated type information
    631         } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
    632                 if ( newDeclStructDecl->has_body() ) {
    633                         return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild( kids ) );
     748        } else if ( auto newDeclStructDecl = dynamic_cast<ast::StructDecl *>( newDecl ) ) {
     749                if ( newDeclStructDecl->body ) {
     750                        return new ast::CompoundLiteralExpr( location,
     751                                new ast::StructInstType( newDeclStructDecl ),
     752                                maybeMoveBuild( kids ) );
    634753                } else {
    635                         return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild( kids ) );
    636                 } // if
    637         } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
    638                 if ( newDeclUnionDecl->has_body() ) {
    639                         return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild( kids ) );
     754                        return new ast::CompoundLiteralExpr( location,
     755                                new ast::StructInstType( newDeclStructDecl->name ),
     756                                maybeMoveBuild( kids ) );
     757                } // if
     758        } else if ( auto newDeclUnionDecl = dynamic_cast<ast::UnionDecl *>( newDecl )  ) {
     759                if ( newDeclUnionDecl->body ) {
     760                        return new ast::CompoundLiteralExpr( location,
     761                                new ast::UnionInstType( newDeclUnionDecl ),
     762                                maybeMoveBuild( kids ) );
    640763                } else {
    641                         return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild( kids ) );
    642                 } // if
    643         } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
    644                 if ( newDeclEnumDecl->has_body() ) {
    645                         return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild( kids ) );
     764                        return new ast::CompoundLiteralExpr( location,
     765                                new ast::UnionInstType( newDeclUnionDecl->name ),
     766                                maybeMoveBuild( kids ) );
     767                } // if
     768        } else if ( auto newDeclEnumDecl = dynamic_cast<ast::EnumDecl *>( newDecl )  ) {
     769                if ( newDeclEnumDecl->body ) {
     770                        return new ast::CompoundLiteralExpr( location,
     771                                new ast::EnumInstType( newDeclEnumDecl ),
     772                                maybeMoveBuild( kids ) );
    646773                } else {
    647                         return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild( kids ) );
     774                        return new ast::CompoundLiteralExpr( location,
     775                                new ast::EnumInstType( newDeclEnumDecl->name ),
     776                                maybeMoveBuild( kids ) );
    648777                } // if
    649778        } else {
  • TabularUnified src/Parser/InitializerNode.cc

    r4541b09 rbb7422a  
    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//
    1515
     
    2020using namespace std;
    2121
     22#include "AST/Expr.hpp"            // for Expr
     23#include "AST/Init.hpp"            // for Designator, Init, ListInit, Sing...
    2224#include "Common/SemanticError.h"  // for SemanticError
    2325#include "Common/utility.h"        // for maybeBuild
    2426#include "ParseNode.h"             // for InitializerNode, ExpressionNode
    25 #include "SynTree/Expression.h"    // for Expression
    26 #include "SynTree/Initializer.h"   // for Initializer, ListInit, SingleInit
     27
     28static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) {
     29        return maybeConstructed ? ast::MaybeConstruct : ast::NoConstruct;
     30}
    2731
    2832InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des )
     
    3337        if ( kids )
    3438                set_last( nullptr );
    35 } // InitializerNode::InitializerNode
     39} // InitializerNode::InitializerNode
    3640
    3741InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des )
     
    8589} // InitializerNode::printOneLine
    8690
    87 Initializer * InitializerNode::build() const {
     91ast::Init * InitializerNode::build() const {
    8892        assertf( ! isDelete, "Should not build delete stmt InitializerNode" );
    8993        if ( aggregate ) {
    9094                // steal designators from children
    91                 std::list< Designation * > designlist;
     95                std::vector<ast::ptr<ast::Designation>> designlist;
    9296                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 ) );
     97                for ( ; child != nullptr ; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
     98                        std::deque<ast::ptr<ast::Expr>> desList;
     99                        buildList( child->designator, desList );
     100                        designlist.push_back(
     101                                new ast::Designation( location, std::move( desList ) ) );
    97102                } // 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( get_expression() ), maybeConstructed );
    105                 } // if
     103                std::vector<ast::ptr<ast::Init>> initlist;
     104                buildList( next_init(), initlist );
     105                return new ast::ListInit( location,
     106                        std::move( initlist ),
     107                        std::move( designlist ),
     108                        toConstructFlag( maybeConstructed )
     109                );
     110        } else if ( get_expression() ) {
     111                assertf( get_expression()->expr, "The expression of initializer must have value" );
     112                return new ast::SingleInit( location,
     113                        maybeBuild( get_expression() ),
     114                        toConstructFlag( maybeConstructed )
     115                );
    106116        } // if
    107117        return nullptr;
  • TabularUnified src/Parser/ParseNode.h

    r4541b09 rbb7422a  
    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 Mar 29 08:40:27 2023
    13 // Update Count     : 948
     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
    2932#include "Common/utility.h"        // for maybeClone
    30 #include "Parser/parserutility.h"  // for maybeBuild
    31 #include "SynTree/LinkageSpec.h"   // for Spec
    32 #include "SynTree/Declaration.h"   // for Aggregate
    33 #include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
    34 #include "SynTree/Label.h"         // for Label
    35 #include "SynTree/Statement.h"     // for Statement, BranchStmt, BranchStmt:...
    36 #include "SynTree/Type.h"          // for Type, Type::FuncSpecifiers, Type::...
     33#include "Parser/parserutility.h"  // for maybeBuild, maybeCopy
    3734
    3835class Attribute;
     
    108105        void printOneLine( std::ostream & ) const;
    109106
    110         virtual Initializer * build() const;
     107        virtual ast::Init * build() const;
    111108  private:
    112109        ExpressionNode * expr;
     
    122119class ExpressionNode final : public ParseNode {
    123120  public:
    124         ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
     121        ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {}
    125122        virtual ~ExpressionNode() {}
    126         virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
     123        virtual ExpressionNode * clone() const override {
     124                if ( nullptr == expr ) return nullptr;
     125                return static_cast<ExpressionNode*>(
     126                        (new ExpressionNode( ast::shallowCopy( expr.get() ) ))->set_next( maybeCopy( get_next() ) ));
     127        }
    127128
    128129        bool get_extension() const { return extension; }
     
    137138        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
    138139
    139         Expression * build() const {
    140                 Expression * node = const_cast<ExpressionNode *>(this)->expr.release();
     140        ast::Expr * build() const {
     141                ast::Expr * node = const_cast<ExpressionNode *>(this)->expr.release();
    141142                node->set_extension( this->get_extension() );
    142143                node->location = this->location;
     
    144145        }
    145146
    146         std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
     147        // Public because of lifetime implications (what lifetime implications?)
     148        std::unique_ptr<ast::Expr> expr;
    147149  private:
    148150        bool extension = false;
     
    164166
    165167struct LabelNode {
    166         std::list< Label > labels;
     168        std::vector<ast::Label> labels;
    167169};
    168170
    169 Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
    170 Expression * build_constantFloat( std::string & str );
    171 Expression * build_constantChar( std::string & str );
    172 Expression * build_constantStr( std::string & str );
    173 Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
    174 Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
    175 Expression * build_field_name_FLOATINGconstant( const std::string & str );
    176 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
    177 
    178 NameExpr * build_varref( const std::string * name );
    179 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
    180 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
    181 DimensionExpr * build_dimensionref( const std::string * name );
    182 
    183 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
    184 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
    185 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
    186 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
    187 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
    188 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
    189 Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    190 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
    191 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
    192 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    193 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    194 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
    195 Expression * build_tuple( ExpressionNode * expr_node = nullptr );
    196 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
    197 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
     171// These 4 routines modify the string:
     172ast::Expr * build_constantInteger( const CodeLocation &, std::string & );
     173ast::Expr * build_constantFloat( const CodeLocation &, std::string & );
     174ast::Expr * build_constantChar( const CodeLocation &, std::string & );
     175ast::Expr * build_constantStr( const CodeLocation &, std::string & );
     176ast::Expr * build_field_name_FLOATING_FRACTIONconstant( const CodeLocation &, const std::string & str );
     177ast::Expr * build_field_name_FLOATING_DECIMALconstant( const CodeLocation &, const std::string & str );
     178ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation &, const std::string & str );
     179ast::Expr * build_field_name_fraction_constants( const CodeLocation &, ast::Expr * fieldName, ExpressionNode * fracts );
     180
     181ast::NameExpr * build_varref( const CodeLocation &, const std::string * name );
     182ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const DeclarationNode * decl_node, const ast::NameExpr * name );
     183ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const ast::EnumDecl * decl, const ast::NameExpr * name );
     184ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name );
     185
     186ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
     187ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node );
     188ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
     189ast::Expr * build_fieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );
     190ast::Expr * build_pfieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );
     191ast::Expr * build_offsetOf( const CodeLocation &, DeclarationNode * decl_node, ast::NameExpr * member );
     192ast::Expr * build_and( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
     193ast::Expr * build_and_or( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ast::LogicalFlag flag );
     194ast::Expr * build_unary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node );
     195ast::Expr * build_binary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
     196ast::Expr * build_binary_ptr( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
     197ast::Expr * build_cond( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
     198ast::Expr * build_tuple( const CodeLocation &, ExpressionNode * expr_node = nullptr );
     199ast::Expr * build_func( const CodeLocation &, ExpressionNode * function, ExpressionNode * expr_node );
     200ast::Expr * build_compoundLiteral( const CodeLocation &, DeclarationNode * decl_node, InitializerNode * kids );
    198201
    199202//##############################################################################
     
    219222        static const char * builtinTypeNames[];
    220223
    221         static DeclarationNode * newStorageClass( Type::StorageClasses );
    222         static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
    223         static DeclarationNode * newTypeQualifier( Type::Qualifiers );
     224        static DeclarationNode * newStorageClass( ast::Storage::Classes );
     225        static DeclarationNode * newFuncSpecifier( ast::Function::Specs );
     226        static DeclarationNode * newTypeQualifier( ast::CV::Qualifiers );
    224227        static DeclarationNode * newBasicType( BasicType );
    225228        static DeclarationNode * newComplexType( ComplexType );
     
    232235        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
    233236        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    234         static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
     237        static DeclarationNode * newAggregate( ast::AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
    235238        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
    236239        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
     
    239242        static DeclarationNode * newName( const std::string * );
    240243        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
    241         static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
     244        static DeclarationNode * newTypeParam( ast::TypeDecl::Kind, const std::string * );
    242245        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
    243246        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
     
    253256        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
    254257        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
    255         static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
     258        static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message );
    256259
    257260        DeclarationNode();
     
    294297        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
    295298
    296         Declaration * build() const;
    297         Type * buildType() const;
    298 
    299         LinkageSpec::Spec get_linkage() const { return linkage; }
     299        ast::Decl * build() const;
     300        ast::Type * buildType() const;
     301
     302        ast::Linkage::Spec get_linkage() const { return linkage; }
    300303        DeclarationNode * extractAggregate() const;
    301304        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
     
    312315        struct Variable_t {
    313316//              const std::string * name;
    314                 TypeDecl::Kind tyClass;
     317                ast::TypeDecl::Kind tyClass;
    315318                DeclarationNode * assertions;
    316319                DeclarationNode * initializer;
     
    320323        struct StaticAssert_t {
    321324                ExpressionNode * condition;
    322                 Expression * message;
     325                ast::Expr * message;
    323326        };
    324327        StaticAssert_t assert;
     
    330333        bool inLine = false;
    331334        bool enumInLine = false;
    332         Type::FuncSpecifiers funcSpecs;
    333         Type::StorageClasses storageClasses;
     335        ast::Function::Specs funcSpecs;
     336        ast::Storage::Classes storageClasses;
    334337
    335338        ExpressionNode * bitfieldWidth = nullptr;
    336339        std::unique_ptr<ExpressionNode> enumeratorValue;
    337340        bool hasEllipsis = false;
    338         LinkageSpec::Spec linkage;
    339         Expression * asmName = nullptr;
    340         std::list< Attribute * > attributes;
     341        ast::Linkage::Spec linkage;
     342        ast::Expr * asmName = nullptr;
     343        std::vector<ast::ptr<ast::Attribute>> attributes;
    341344        InitializerNode * initializer = nullptr;
    342345        bool extension = false;
     
    348351}; // DeclarationNode
    349352
    350 Type * buildType( TypeData * type );
    351 
    352 static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
    353         Type * ret = orig ? orig->buildType() : nullptr;
     353ast::Type * buildType( TypeData * type );
     354
     355static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) {
     356        ast::Type * ret = orig ? orig->buildType() : nullptr;
    354357        delete orig;
    355358        return ret;
     
    359362
    360363struct StatementNode final : public ParseNode {
    361         StatementNode() { stmt = nullptr; }
    362         StatementNode( Statement * stmt ) : stmt( stmt ) {}
     364        StatementNode() :
     365                stmt( nullptr ), clause( nullptr ) {}
     366        StatementNode( ast::Stmt * stmt ) :
     367                stmt( stmt ), clause( nullptr ) {}
     368        StatementNode( ast::StmtClause * clause ) :
     369                stmt( nullptr ), clause( clause ) {}
    363370        StatementNode( DeclarationNode * decl );
    364371        virtual ~StatementNode() {}
    365372
    366373        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
    367         Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
    368 
    369         virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
    370                 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
     374        ast::Stmt * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
     375
     376        virtual StatementNode * add_label(
     377                        const CodeLocation & location,
     378                        const std::string * name,
     379                        DeclarationNode * attr = nullptr ) {
     380                stmt->labels.emplace_back( location,
     381                        *name,
     382                        attr ? std::move( attr->attributes )
     383                                : std::vector<ast::ptr<ast::Attribute>>{} );
    371384                delete attr;
    372385                delete name;
     
    380393        }
    381394
    382         std::unique_ptr<Statement> stmt;
     395        std::unique_ptr<ast::Stmt> stmt;
     396        std::unique_ptr<ast::StmtClause> clause;
    383397}; // StatementNode
    384398
    385 Statement * build_expr( ExpressionNode * ctl );
     399ast::Stmt * build_expr( CodeLocation const &, ExpressionNode * ctl );
    386400
    387401struct CondCtl {
     
    402416};
    403417
    404 Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
    405 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
    406 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
    407 Statement * build_case( ExpressionNode * ctl );
    408 Statement * build_default();
    409 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    410 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    411 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    412 Statement * build_branch( BranchStmt::Type kind );
    413 Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
    414 Statement * build_computedgoto( ExpressionNode * ctl );
    415 Statement * build_return( ExpressionNode * ctl );
    416 Statement * build_throw( ExpressionNode * ctl );
    417 Statement * build_resume( ExpressionNode * ctl );
    418 Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
    419 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
    420 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
    421 Statement * build_finally( StatementNode * stmt );
    422 Statement * build_compound( StatementNode * first );
    423 StatementNode * maybe_build_compound( StatementNode * first );
    424 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
    425 Statement * build_directive( std::string * directive );
    426 SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
    427 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
    428 WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );
    429 WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
    430 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
    431 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
    432 
    433 //##############################################################################
    434 
    435 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
    436 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
     418ast::Stmt * build_if( const CodeLocation &, CondCtl * ctl, StatementNode * then, StatementNode * else_ );
     419ast::Stmt * build_switch( const CodeLocation &, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
     420ast::CaseClause * build_case( ExpressionNode * ctl );
     421ast::CaseClause * build_default( const CodeLocation & );
     422ast::Stmt * build_while( const CodeLocation &, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
     423ast::Stmt * build_do_while( const CodeLocation &, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
     424ast::Stmt * build_for( const CodeLocation &, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
     425ast::Stmt * build_branch( const CodeLocation &, ast::BranchStmt::Kind kind );
     426ast::Stmt * build_branch( const CodeLocation &, std::string * identifier, ast::BranchStmt::Kind kind );
     427ast::Stmt * build_computedgoto( ExpressionNode * ctl );
     428ast::Stmt * build_return( const CodeLocation &, ExpressionNode * ctl );
     429ast::Stmt * build_throw( const CodeLocation &, ExpressionNode * ctl );
     430ast::Stmt * build_resume( const CodeLocation &, ExpressionNode * ctl );
     431ast::Stmt * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
     432ast::Stmt * build_try( const CodeLocation &, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
     433ast::CatchClause * build_catch( const CodeLocation &, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
     434ast::FinallyClause * build_finally( const CodeLocation &, StatementNode * stmt );
     435ast::Stmt * build_compound( const CodeLocation &, StatementNode * first );
     436StatementNode * maybe_build_compound( const CodeLocation &, StatementNode * first );
     437ast::Stmt * build_asm( const CodeLocation &, bool voltile, ast::Expr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
     438ast::Stmt * build_directive( const CodeLocation &, std::string * directive );
     439ast::SuspendStmt * build_suspend( const CodeLocation &, StatementNode *, ast::SuspendStmt::Type );
     440ast::WaitForStmt * build_waitfor( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
     441ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );
     442ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
     443ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
     444ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
     445
     446//##############################################################################
     447
     448template<typename AstType, typename NodeType,
     449        template<typename, typename...> class Container, typename... Args>
     450void buildList( const NodeType * firstNode,
     451                Container<ast::ptr<AstType>, Args...> & output ) {
    437452        SemanticErrorException errors;
    438         std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
     453        std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output );
    439454        const NodeType * cur = firstNode;
    440455
    441456        while ( cur ) {
    442457                try {
    443                         SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild( cur ) );
    444                         if ( result ) {
    445                                 result->location = cur->location;
    446                                 * out++ = result;
     458                        if ( auto result = dynamic_cast<AstType *>( maybeBuild( cur ) ) ) {
     459                                *out++ = result;
    447460                        } else {
     461                                assertf(false, __PRETTY_FUNCTION__ );
    448462                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
    449463                        } // if
     
    451465                        errors.append( e );
    452466                } // try
    453                 const ParseNode * temp = (cur->get_next());
    454                 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
    455                 if ( ! cur && temp ) {                                                  // non-homogeneous nodes ?
     467                const ParseNode * temp = cur->get_next();
     468                // Should not return nullptr, then it is non-homogeneous:
     469                cur = dynamic_cast<const NodeType *>( temp );
     470                if ( !cur && temp ) {
    456471                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
    457472                } // if
     
    463478
    464479// in DeclarationNode.cc
    465 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
    466 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
    467 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
    468 
    469 template< typename SynTreeType, typename NodeType >
    470 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
    471         buildList( firstNode, outputList );
     480void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList );
     481void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList );
     482void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList );
     483
     484template<typename AstType, typename NodeType,
     485        template<typename, typename...> class Container, typename... Args>
     486void buildMoveList( const NodeType * firstNode,
     487                Container<ast::ptr<AstType>, Args...> & output ) {
     488        buildList<AstType, NodeType, Container, Args...>( firstNode, output );
    472489        delete firstNode;
    473490}
  • TabularUnified src/Parser/ParserTypes.h

    r4541b09 rbb7422a  
    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
  • TabularUnified src/Parser/RunParser.cpp

    r4541b09 rbb7422a  
    1010// Created On       : Mon Dec 19 11:00:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Feb 16 10:08:00 2023
    13 // Update Count     : 2
     12// Last Modified On : Mon Mar  6  9:42:00 2023
     13// Update Count     : 3
    1414//
    1515
     
    4646
    4747ast::TranslationUnit buildUnit(void) {
    48         std::list<Declaration *> translationUnit;
    49         buildList( parseTree, translationUnit );
    50 
     48        std::vector<ast::ptr<ast::Decl>> decls;
     49        buildList( parseTree, decls );
    5150        delete parseTree;
    5251        parseTree = nullptr;
    5352
    54         // When the parse/buildList code is translated to the new ast, these
    55         // fill passes (and the one after 'Hoist Type Decls') should be redundent
    56         // because the code locations should already be filled.
    57         CodeTools::fillLocations( translationUnit );
    58         ast::TranslationUnit transUnit = convert( std::move( translationUnit ) );
    59         forceFillCodeLocations( transUnit );
     53        ast::TranslationUnit transUnit;
     54        for ( auto decl : decls ) {
     55                transUnit.decls.emplace_back( std::move( decl ) );
     56        }
    6057        return transUnit;
    6158}
  • TabularUnified src/Parser/StatementNode.cc

    r4541b09 rbb7422a  
    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 Mar 29 08:51:23 2023
    14 // Update Count     : 454
     12// Last Modified By : Andrew Beach
     13// Last Modified On : Tue Apr  4 11:40:00 2023
     14// Update Count     : 427
    1515//
    1616
    1717#include <cassert>                 // for assert, strict_dynamic_cast, assertf
    18 #include <list>                    // for list
    1918#include <memory>                  // for unique_ptr
    2019#include <string>                  // for string
    2120
     21#include "AST/Label.hpp"           // for Label
     22#include "AST/Stmt.hpp"            // for Stmt, AsmStmt, BranchStmt, CaseCla...
    2223#include "Common/SemanticError.h"  // for SemanticError
    2324#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild
    2425#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
    2926#include "parserutility.h"         // for notZeroExpr
    3027
     
    3229
    3330using namespace std;
    34 
    3531
    3632StatementNode::StatementNode( DeclarationNode * decl ) {
     
    3834        DeclarationNode * agg = decl->extractAggregate();
    3935        if ( agg ) {
    40                 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild( decl ) ) );
     36                StatementNode * nextStmt = new StatementNode(
     37                        new ast::DeclStmt( decl->location, maybeBuild( decl ) ) );
    4138                set_next( nextStmt );
    4239                if ( decl->get_next() ) {
     
    5148                agg = decl;
    5249        } // if
    53         stmt.reset( new DeclStmt( maybeMoveBuild( agg ) ) );
     50        // Local copy to avoid accessing the pointer after it is moved from.
     51        CodeLocation declLocation = agg->location;
     52        stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) );
    5453} // StatementNode::StatementNode
    5554
     
    5958        for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {
    6059                StatementNode * node = strict_dynamic_cast< StatementNode * >(curr);
    61                 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) );
     60                assert( nullptr == node->stmt.get() );
     61                assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) );
    6262                prev = curr;
    6363        } // for
    6464        // convert from StatementNode list to Statement list
    6565        StatementNode * node = dynamic_cast< StatementNode * >(prev);
    66         list< Statement * > stmts;
     66        std::vector<ast::ptr<ast::Stmt>> stmts;
    6767        buildMoveList( stmt, stmts );
    6868        // 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 );
     69        auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() );
     70        for ( auto const & newStmt : stmts ) {
     71                caseStmt->stmts.emplace_back( newStmt );
     72        }
     73        stmts.clear();
    7174        return this;
    7275} // StatementNode::append_last_case
    7376
    74 Statement * build_expr( ExpressionNode * ctl ) {
    75         Expression * e = maybeMoveBuild( ctl );
    76 
    77         if ( e ) return new ExprStmt( e );
    78         else return new NullStmt();
     77ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) {
     78        if ( ast::Expr * e = maybeMoveBuild( ctl ) ) {
     79                return new ast::ExprStmt( location, e );
     80        } else {
     81                return new ast::NullStmt( location );
     82        }
    7983} // build_expr
    8084
    81 Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) {
    82         if ( ctl->init != 0 ) {
    83                 buildMoveList( ctl->init, init );
    84         } // if
    85 
    86         Expression * cond = nullptr;
     85static ast::Expr * build_if_control( CondCtl * ctl,
     86                std::vector<ast::ptr<ast::Stmt>> & inits ) {
     87        assert( inits.empty() );
     88        if ( nullptr != ctl->init ) {
     89                buildMoveList( ctl->init, inits );
     90        } // if
     91
     92        ast::Expr * cond = nullptr;
    8793        if ( ctl->condition ) {
    8894                // compare the provided condition against 0
    8995                cond = notZeroExpr( maybeMoveBuild( ctl->condition ) );
    9096        } else {
    91                 for ( Statement * stmt : init ) {
     97                for ( ast::ptr<ast::Stmt> & stmt : inits ) {
    9298                        // 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;
     99                        //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt );
     100                        auto declStmt = stmt.strict_as<ast::DeclStmt>();
     101                        //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl );
     102                        auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();
     103                        ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) );
     104                        cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze;
    97105                }
    98106        }
     
    101109} // build_if_control
    102110
    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 );
     111ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
     112        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     113        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
     114
     115        std::vector<ast::ptr<ast::Stmt>> aststmt;
     116        buildMoveList( then, aststmt );
    110117        assert( aststmt.size() == 1 );
    111         astthen = aststmt.front();
    112 
     118        ast::Stmt const * astthen = aststmt.front().release();
     119
     120        ast::Stmt const * astelse = nullptr;
    113121        if ( else_ ) {
    114                 list< Statement * > aststmt;
    115                 buildMoveList< Statement, StatementNode >( else_, aststmt );
     122                std::vector<ast::ptr<ast::Stmt>> aststmt;
     123                buildMoveList( else_, aststmt );
    116124                assert( aststmt.size() == 1 );
    117                 astelse = aststmt.front();
    118         } // if
    119 
    120         return new IfStmt( astcond, astthen, astelse, astinit );
     125                astelse = aststmt.front().release();
     126        } // if
     127
     128        return new ast::IfStmt( location, astcond, astthen, astelse,
     129                std::move( astinit )
     130        );
    121131} // build_if
    122132
    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 ) );
     133// Temporary work around. Split StmtClause off from StatementNode.
     134template<typename clause_t>
     135static void buildMoveClauseList( StatementNode * firstNode,
     136                std::vector<ast::ptr<clause_t>> & output ) {
     137        SemanticErrorException errors;
     138        std::back_insert_iterator<std::vector<ast::ptr<clause_t>>>
     139                out( output );
     140        StatementNode * cur = firstNode;
     141
     142        while ( cur ) {
     143                try {
     144                        auto clause = cur->clause.release();
     145                        if ( auto result = dynamic_cast<clause_t *>( clause ) ) {
     146                                *out++ = result;
     147                        } else {
     148                                assertf(false, __PRETTY_FUNCTION__ );
     149                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
     150                        } // if
     151                } catch( SemanticErrorException & e ) {
     152                        errors.append( e );
     153                } // try
     154                ParseNode * temp = cur->get_next();
     155                // Should not return nullptr, then it is non-homogeneous:
     156                cur = dynamic_cast<StatementNode *>( temp );
     157                if ( !cur && temp ) {
     158                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
     159                } // if
     160        } // while
     161        if ( ! errors.isEmpty() ) {
     162                throw errors;
     163        } // if
     164        // Usually in the wrapper.
     165        delete firstNode;
     166}
     167
     168ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
     169        std::vector<ast::ptr<ast::CaseClause>> aststmt;
     170        buildMoveClauseList( stmt, aststmt );
     171        // If it is not a switch it is a choose statement.
     172        if ( ! isSwitch ) {
     173                for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) {
     174                        // Code after "case" is the end of case list.
     175                        if ( !stmt->stmts.empty() ) {
     176                                auto mutStmt = ast::mutate( stmt.get() );
     177                                // I believe the stmts are actually always one block.
     178                                auto stmts = mutStmt->stmts.front().get_and_mutate();
     179                                auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts );
     180                                block->kids.push_back( new ast::BranchStmt( block->location,
     181                                        ast::BranchStmt::Break,
     182                                        ast::Label( block->location ) ) );
     183                                stmt = mutStmt;
    132184                        } // if
    133185                } // for
    134186        } // if
    135187        // aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements
    136         return new SwitchStmt( maybeMoveBuild( ctl ), aststmt );
     188        return new ast::SwitchStmt( location,
     189                maybeMoveBuild( ctl ), std::move( aststmt ) );
    137190} // build_switch
    138191
    139 Statement * build_case( ExpressionNode * ctl ) {
    140         return new CaseStmt( maybeMoveBuild( ctl ), {} ); // stmt starts empty and then added to
     192ast::CaseClause * build_case( ExpressionNode * ctl ) {
     193        // stmt starts empty and then added to
     194        auto expr = maybeMoveBuild( ctl );
     195        return new ast::CaseClause( expr->location, expr, {} );
    141196} // build_case
    142197
    143 Statement * build_default() {
    144         return new CaseStmt( nullptr, {}, true );                       // stmt starts empty and then added to
     198ast::CaseClause * build_default( const CodeLocation & location ) {
     199        // stmt starts empty and then added to
     200        return new ast::CaseClause( location, nullptr, {} );
    145201} // build_default
    146202
    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 );
     203ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
     204        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     205        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
     206
     207        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     208        buildMoveList( stmt, aststmt );
    153209        assert( aststmt.size() == 1 );
    154210
    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 );
     211        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     212        buildMoveList( else_, astelse );
     213        assert( astelse.size() <= 1 );
     214
     215        return new ast::WhileDoStmt( location,
     216                astcond,
     217                aststmt.front(),
     218                astelse.empty() ? nullptr : astelse.front().release(),
     219                std::move( astinit ),
     220                false
     221        );
    159222} // build_while
    160223
    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 );
     224ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
     225        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     226        buildMoveList( stmt, aststmt );
    164227        assert( aststmt.size() == 1 );                                          // compound created if empty
    165228
    166         list< Statement * > astelse;                                            // else clause, maybe empty
    167         buildMoveList< Statement, StatementNode >( else_, astelse );
     229        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     230        buildMoveList( else_, astelse );
     231        assert( astelse.size() <= 1 );
    168232
    169233        // do-while cannot have declarations in the contitional, so init is always empty
    170         return new WhileDoStmt( notZeroExpr( maybeMoveBuild( ctl ) ), aststmt.front(), astelse.front(), {}, true );
     234        return new ast::WhileDoStmt( location,
     235                notZeroExpr( maybeMoveBuild( ctl ) ),
     236                aststmt.front(),
     237                astelse.empty() ? nullptr : astelse.front().release(),
     238                {},
     239                true
     240        );
    171241} // build_do_while
    172242
    173 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
    174         list< Statement * > astinit;                                            // maybe empty
     243ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
     244        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
    175245        buildMoveList( forctl->init, astinit );
    176246
    177         Expression * astcond = nullptr;                                         // maybe empty
     247        ast::Expr * astcond = nullptr;                                          // maybe empty
    178248        astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) );
    179249
    180         Expression * astincr = nullptr;                                         // maybe empty
     250        ast::Expr * astincr = nullptr;                                          // maybe empty
    181251        astincr = maybeMoveBuild( forctl->change );
    182252        delete forctl;
    183253
    184         list< Statement * > aststmt;                                            // loop body, compound created if empty
    185         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     254        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     255        buildMoveList( stmt, aststmt );
    186256        assert( aststmt.size() == 1 );
    187257
    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() );
     258        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     259        buildMoveList( else_, astelse );
     260        assert( astelse.size() <= 1 );
     261
     262        return new ast::ForStmt( location,
     263                std::move( astinit ),
     264                astcond,
     265                astincr,
     266                aststmt.front(),
     267                astelse.empty() ? nullptr : astelse.front().release()
     268        );
    192269} // build_for
    193270
    194 Statement * build_branch( BranchStmt::Type kind ) {
    195         Statement * ret = new BranchStmt( "", kind );
     271ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) {
     272        return new ast::BranchStmt( location,
     273                kind,
     274                ast::Label( location )
     275        );
     276} // build_branch
     277
     278ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) {
     279        ast::Stmt * ret = new ast::BranchStmt( location,
     280                kind,
     281                ast::Label( location, *identifier )
     282        );
     283        delete identifier;                                                                      // allocated by lexer
    196284        return ret;
    197285} // build_branch
    198286
    199 Statement * build_branch( string * identifier, BranchStmt::Type kind ) {
    200         Statement * ret = new BranchStmt( * identifier, kind );
    201         delete identifier;                                                                      // allocated by lexer
    202         return ret;
    203 } // build_branch
    204 
    205 Statement * build_computedgoto( ExpressionNode * ctl ) {
    206         return new BranchStmt( maybeMoveBuild( ctl ), BranchStmt::Goto );
     287ast::Stmt * build_computedgoto( ExpressionNode * ctl ) {
     288        ast::Expr * expr = maybeMoveBuild( ctl );
     289        return new ast::BranchStmt( expr->location, expr );
    207290} // build_computedgoto
    208291
    209 Statement * build_return( ExpressionNode * ctl ) {
    210         list< Expression * > exps;
     292ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) {
     293        std::vector<ast::ptr<ast::Expr>> exps;
    211294        buildMoveList( ctl, exps );
    212         return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr );
     295        return new ast::ReturnStmt( location,
     296                exps.size() > 0 ? exps.back().release() : nullptr
     297        );
    213298} // build_return
    214299
    215 Statement * build_throw( ExpressionNode * ctl ) {
    216         list< Expression * > exps;
     300static ast::Stmt * build_throw_stmt(
     301                const CodeLocation & location,
     302                ExpressionNode * ctl,
     303                ast::ExceptionKind kind ) {
     304        std::vector<ast::ptr<ast::Expr>> exps;
    217305        buildMoveList( ctl, exps );
    218306        assertf( exps.size() < 2, "CFA internal error: leaking memory" );
    219         return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
     307        return new ast::ThrowStmt( location,
     308                kind,
     309                !exps.empty() ? exps.back().release() : nullptr,
     310                (ast::Expr *)nullptr
     311        );
     312}
     313
     314ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) {
     315        return build_throw_stmt( loc, ctl, ast::Terminate );
    220316} // build_throw
    221317
    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 );
     318ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) {
     319        return build_throw_stmt( loc, ctl, ast::Resume );
    227320} // build_resume
    228321
    229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
     322ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
    230323        (void)ctl;
    231324        (void)target;
     
    233326} // build_resume_at
    234327
    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( try_ ) );
    239         FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >( maybeMoveBuild( finally_ ) );
    240         return new TryStmt( tryBlock, aststmt, finallyBlock );
     328ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
     329        std::vector<ast::ptr<ast::CatchClause>> aststmt;
     330        buildMoveClauseList( catch_, aststmt );
     331        ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) );
     332        ast::FinallyClause * finallyBlock = nullptr;
     333        if ( finally_ ) {
     334                finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() );
     335        }
     336        return new ast::TryStmt( location,
     337                tryBlock,
     338                std::move( aststmt ),
     339                finallyBlock
     340        );
    241341} // build_try
    242342
    243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
    244         list< Statement * > aststmt;
    245         buildMoveList< Statement, StatementNode >( body, aststmt );
     343ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
     344        std::vector<ast::ptr<ast::Stmt>> aststmt;
     345        buildMoveList( body, aststmt );
    246346        assert( aststmt.size() == 1 );
    247         return new CatchStmt( kind, maybeMoveBuild( decl ), maybeMoveBuild( cond ), aststmt.front() );
     347        return new ast::CatchClause( location,
     348                kind,
     349                maybeMoveBuild( decl ),
     350                maybeMoveBuild( cond ),
     351                aststmt.front().release()
     352        );
    248353} // build_catch
    249354
    250 Statement * build_finally( StatementNode * stmt ) {
    251         list< Statement * > aststmt;
    252         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     355ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) {
     356        std::vector<ast::ptr<ast::Stmt>> aststmt;
     357        buildMoveList( stmt, aststmt );
    253358        assert( aststmt.size() == 1 );
    254         return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) );
     359        return new ast::FinallyClause( location,
     360                aststmt.front().strict_as<ast::CompoundStmt>()
     361        );
    255362} // build_finally
    256363
    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 );
     364ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Type type ) {
     365        std::vector<ast::ptr<ast::Stmt>> stmts;
     366        buildMoveList( then, stmts );
     367        ast::CompoundStmt const * then2 = nullptr;
    264368        if(!stmts.empty()) {
    265369                assert( stmts.size() == 1 );
    266                 node->then = dynamic_cast< CompoundStmt * >( stmts.front() );
     370                then2 = stmts.front().strict_as<ast::CompoundStmt>();
    267371        }
    268 
     372        auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None );
     373        node->type = type;
    269374        return node;
    270375} // build_suspend
    271376
    272 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
    273         WaitForStmt::Target target;
    274         target.function = maybeBuild( targetExpr );
     377ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
     378        auto clause = new ast::WaitForClause( location );
     379        clause->target_func = maybeBuild( targetExpr );
     380        clause->stmt = maybeMoveBuild( stmt );
     381        clause->cond = notZeroExpr( maybeMoveBuild( when ) );
    275382
    276383        ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
    277384        targetExpr->set_next( nullptr );
    278         buildMoveList< Expression >( next, target.arguments );
     385        buildMoveList( next, clause->target_args );
    279386
    280387        delete targetExpr;
    281388
    282         existing->clauses.insert( existing->clauses.begin(), WaitForStmt::Clause{
    283                 std::move( target ),
    284                 maybeMoveBuild( stmt ),
    285                 notZeroExpr( maybeMoveBuild( when ) )
    286         });
     389        existing->clauses.insert( existing->clauses.begin(), clause );
    287390
    288391        return existing;
    289392} // build_waitfor
    290393
    291 WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
    292         existing->orelse.statement  = maybeMoveBuild( stmt );
    293         existing->orelse.condition  = notZeroExpr( maybeMoveBuild( when ) );
    294 
     394ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
     395        existing->else_stmt = maybeMoveBuild( stmt );
     396        existing->else_cond = notZeroExpr( maybeMoveBuild( when ) );
     397
     398        (void)location;
    295399        return existing;
    296400} // build_waitfor_else
    297401
    298 WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
    299         existing->timeout.time      = maybeMoveBuild( timeout );
    300         existing->timeout.statement = maybeMoveBuild( stmt );
    301         existing->timeout.condition = notZeroExpr( maybeMoveBuild( when ) );
    302 
     402ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
     403        existing->timeout_time = maybeMoveBuild( timeout );
     404        existing->timeout_stmt = maybeMoveBuild( stmt );
     405        existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) );
     406
     407        (void)location;
    303408        return existing;
    304409} // build_waitfor_timeout
    305410
    306 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
    307         list< Expression * > e;
     411ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
     412        std::vector<ast::ptr<ast::Expr>> e;
    308413        buildMoveList( exprs, e );
    309         Statement * s = maybeMoveBuild( stmt );
    310         return new DeclStmt( new WithStmt( e, s ) );
     414        ast::Stmt * s = maybeMoveBuild( stmt );
     415        return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) );
    311416} // build_with
    312417
    313 Statement * build_compound( StatementNode * first ) {
    314         CompoundStmt * cs = new CompoundStmt();
    315         buildMoveList( first, cs->get_kids() );
     418ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) {
     419        auto cs = new ast::CompoundStmt( location );
     420        buildMoveList( first, cs->kids );
    316421        return cs;
    317422} // build_compound
     
    321426// statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a
    322427// conical form for code generation.
    323 StatementNode * maybe_build_compound( StatementNode * first ) {
     428StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) {
    324429        // Optimization: if the control-structure statement is a compound statement, do not wrap it.
    325430        // e.g., if (...) {...} do not wrap the existing compound statement.
    326         if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
    327                 CompoundStmt * cs = new CompoundStmt();
    328                 buildMoveList( first, cs->get_kids() );
    329                 return new StatementNode( cs );
     431        if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
     432                return new StatementNode( build_compound( location, first ) );
    330433        } // if
    331434        return first;
     
    333436
    334437// Question
    335 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
    336         list< Expression * > out, in;
    337         list< ConstantExpr * > clob;
     438ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
     439        std::vector<ast::ptr<ast::Expr>> out, in;
     440        std::vector<ast::ptr<ast::ConstantExpr>> clob;
    338441
    339442        buildMoveList( output, out );
    340443        buildMoveList( input, in );
    341444        buildMoveList( clobber, clob );
    342         return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );
     445        return new ast::AsmStmt( location,
     446                voltile,
     447                instruction,
     448                std::move( out ),
     449                std::move( in ),
     450                std::move( clob ),
     451                gotolabels ? gotolabels->labels : std::vector<ast::Label>()
     452        );
    343453} // build_asm
    344454
    345 Statement * build_directive( string * directive ) {
    346         return new DirectiveStmt( *directive );
     455ast::Stmt * build_directive( const CodeLocation & location, string * directive ) {
     456        auto stmt = new ast::DirectiveStmt( location, *directive );
     457        delete directive;
     458        return stmt;
    347459} // build_directive
    348460
    349 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt ) {
    350         list< Expression * > expList;
     461ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
     462        std::vector<ast::ptr<ast::Expr>> expList;
    351463        buildMoveList( exprs, expList );
    352         Statement * body = maybeMoveBuild( stmt );
    353         return new MutexStmt( body, expList );
     464        ast::Stmt * body = maybeMoveBuild( stmt );
     465        return new ast::MutexStmt( location, body, std::move( expList ) );
    354466} // build_mutex
    355467
  • TabularUnified src/Parser/TypeData.cc

    r4541b09 rbb7422a  
    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 : Sun Feb 19 11:00:46 2023
    13 // Update Count     : 679
     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...
     25#include "Common/utility.h"        // for splice, spliceBegin
     26#include "Parser/parserutility.h"  // for maybeCopy, maybeBuild, maybeMoveB...
    2127#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"
    2828
    2929class Attribute;
     
    6060                break;
    6161        case Aggregate:
    62                 aggregate.kind = AggregateDecl::NoAggregate;
     62                aggregate.kind = ast::AggregateDecl::NoAggregate;
    6363                aggregate.name = nullptr;
    6464                aggregate.params = nullptr;
     
    8989                typeexpr = nullptr;
    9090                break;
     91        case Vtable:
    9192        case Builtin:
    92         case Vtable:
    9393                // No unique data to initialize.
    9494                break;
     
    111111        case EnumConstant:
    112112        case GlobalScope:
     113        case Basic:
    113114                // No unique data to deconstruct.
    114                 break;
    115         case Basic:
    116115                break;
    117116        case Array:
     
    250249
    251250void TypeData::print( ostream &os, int indent ) const {
    252         for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) {
    253                 if ( qualifiers[i] ) os << Type::QualifiersNames[ i ] << ' ';
    254         } // for
     251        ast::print( os, qualifiers );
    255252
    256253        if ( forall ) {
     
    325322                break;
    326323        case Aggregate:
    327                 os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
     324                os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
    328325                if ( aggregate.params ) {
    329326                        os << string( indent + 2, ' ' ) << "with type parameters" << endl;
     
    472469
    473470
    474 template< typename ForallList >
    475 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
    476         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        }
    477483        auto n = firstNode;
    478         for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) {
    479                 TypeDecl * td = static_cast<TypeDecl *>(*i);
    480                 if ( n->variable.tyClass == TypeDecl::Otype ) {
    481                         // add assertion parameters to `type' tyvars in reverse order
    482                         // add dtor:  void ^?{}(T *)
    483                         FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
    484                         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 ) );
    485                         td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) );
    486 
    487                         // add copy ctor:  void ?{}(T *, T)
    488                         FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
    489                         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 ) );
    490                         copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    491                         td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) );
    492 
    493                         // add default ctor:  void ?{}(T *)
    494                         FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
    495                         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 ) );
    496                         td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) );
    497 
    498                         // add assignment operator:  T * ?=?(T *, T)
    499                         FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
    500                         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 ) );
    501                         assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    502                         assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    503                         td->get_assertions().push_front( new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Cforall, assignType, nullptr ) );
    504                 } // 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 );
    505769        } // for
    506770} // buildForall
    507771
    508772
    509 Type * typebuild( const TypeData * td ) {
     773ast::Type * typebuild( const TypeData * td ) {
    510774        assert( td );
    511775        switch ( td->kind ) {
    512776        case TypeData::Unknown:
    513777                // fill in implicit int
    514                 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
     778                return new ast::BasicType(
     779                        ast::BasicType::SignedInt,
     780                        buildQualifiers( td )
     781                );
    515782        case TypeData::Basic:
    516783                return buildBasicType( td );
     
    522789                return buildReference( td );
    523790        case TypeData::Function:
    524                 return buildFunction( td );
     791                return buildFunctionType( td );
    525792        case TypeData::AggregateInst:
    526793                return buildAggInst( td );
    527794        case TypeData::EnumConstant:
    528                 return new EnumInstType( buildQualifiers( td ), "" );
     795                return new ast::EnumInstType( "", buildQualifiers( td ) );
    529796        case TypeData::SymbolicInst:
    530797                return buildSymbolicInst( td );
     
    539806                switch ( td->builtintype ) {
    540807                case DeclarationNode::Zero:
    541                         return new ZeroType( noQualifiers );
     808                        return new ast::ZeroType();
    542809                case DeclarationNode::One:
    543                         return new OneType( noQualifiers );
     810                        return new ast::OneType();
    544811                default:
    545                         return new VarArgsType( buildQualifiers( td ) );
     812                        return new ast::VarArgsType( buildQualifiers( td ) );
    546813                } // switch
    547814        case TypeData::GlobalScope:
    548                 return new GlobalScopeType();
     815                return new ast::GlobalScopeType();
    549816        case TypeData::Qualified:
    550                 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
     817                return new ast::QualifiedType(
     818                        typebuild( td->qualified.parent ),
     819                        typebuild( td->qualified.child ),
     820                        buildQualifiers( td )
     821                );
    551822        case TypeData::Symbolic:
    552823        case TypeData::Enum:
     
    587858
    588859
    589 Type::Qualifiers buildQualifiers( const TypeData * td ) {
     860ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {
    590861        return td->qualifiers;
    591862} // buildQualifiers
     
    596867} // genTSError
    597868
    598 Type * buildBasicType( const TypeData * td ) {
    599         BasicType::Kind ret;
     869ast::Type * buildBasicType( const TypeData * td ) {
     870        ast::BasicType::Kind ret;
    600871
    601872        switch ( td->basictype ) {
     
    607878                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
    608879                } // if
    609                 return new VoidType( buildQualifiers( td ) );
     880                return new ast::VoidType( buildQualifiers( td ) );
    610881                break;
    611882
     
    618889                } // if
    619890
    620                 ret = BasicType::Bool;
     891                ret = ast::BasicType::Bool;
    621892                break;
    622893
     
    625896                // character types. The implementation shall define char to have the same range, representation, and behavior as
    626897                // either signed char or unsigned char.
    627                 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 };
    628899
    629900                if ( td->length != DeclarationNode::NoLength ) {
     
    635906
    636907        case DeclarationNode::Int:
    637                 static BasicType::Kind inttype[2][4] = {
    638                         { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt },
    639                         { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt },
     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 },
    640911                };
    641912
     
    648919
    649920        case DeclarationNode::Int128:
    650                 ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
     921                ret = td->signedness == DeclarationNode::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128;
    651922                if ( td->length != DeclarationNode::NoLength ) {
    652923                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
     
    666937        case DeclarationNode::uFloat128:
    667938        case DeclarationNode::uFloat128x:
    668                 static BasicType::Kind floattype[2][12] = {
    669                         { 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, },
    670                         { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::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, },
    671942                };
    672943
     
    709980        } // switch
    710981
    711         BasicType * bt = new BasicType( buildQualifiers( td ), ret );
    712         buildForall( td->forall, bt->get_forall() );
     982        ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
    713983        return bt;
    714984} // buildBasicType
    715985
    716986
    717 PointerType * buildPointer( const TypeData * td ) {
    718         PointerType * pt;
     987ast::PointerType * buildPointer( const TypeData * td ) {
     988        ast::PointerType * pt;
    719989        if ( td->base ) {
    720                 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
     990                pt = new ast::PointerType(
     991                        typebuild( td->base ),
     992                        buildQualifiers( td )
     993                );
    721994        } else {
    722                 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                );
    723999        } // if
    724         buildForall( td->forall, pt->get_forall() );
    7251000        return pt;
    7261001} // buildPointer
    7271002
    7281003
    729 ArrayType * buildArray( const TypeData * td ) {
    730         ArrayType * at;
     1004ast::ArrayType * buildArray( const TypeData * td ) {
     1005        ast::ArrayType * at;
    7311006        if ( td->base ) {
    732                 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild( td->array.dimension ),
    733                                                         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                );
    7341014        } else {
    735                 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
    736                                                         maybeBuild( 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                );
    7371022        } // if
    738         buildForall( td->forall, at->get_forall() );
    7391023        return at;
    7401024} // buildArray
    7411025
    7421026
    743 ReferenceType * buildReference( const TypeData * td ) {
    744         ReferenceType * rt;
     1027ast::ReferenceType * buildReference( const TypeData * td ) {
     1028        ast::ReferenceType * rt;
    7451029        if ( td->base ) {
    746                 rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) );
     1030                rt = new ast::ReferenceType(
     1031                        typebuild( td->base ),
     1032                        buildQualifiers( td )
     1033                );
    7471034        } else {
    748                 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                );
    7491039        } // if
    750         buildForall( td->forall, rt->get_forall() );
    7511040        return rt;
    7521041} // buildReference
    7531042
    7541043
    755 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 ) {
    7561045        assert( td->kind == TypeData::Aggregate );
    757         AggregateDecl * at;
     1046        ast::AggregateDecl * at;
    7581047        switch ( td->aggregate.kind ) {
    759         case AggregateDecl::Struct:
    760         case AggregateDecl::Coroutine:
    761         case AggregateDecl::Exception:
    762         case AggregateDecl::Generator:
    763         case AggregateDecl::Monitor:
    764         case AggregateDecl::Thread:
    765                 at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage );
    766                 buildForall( td->aggregate.params, at->get_parameters() );
    767                 break;
    768         case AggregateDecl::Union:
    769                 at = new UnionDecl( *td->aggregate.name, attributes, linkage );
    770                 buildForall( td->aggregate.params, at->get_parameters() );
    771                 break;
    772         case AggregateDecl::Trait:
    773                 at = new TraitDecl( *td->aggregate.name, attributes, linkage );
    774                 buildList( td->aggregate.params, at->get_parameters() );
     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 );
    7751077                break;
    7761078        default:
     
    7781080        } // switch
    7791081
    780         buildList( td->aggregate.fields, at->get_members() );
     1082        buildList( td->aggregate.fields, at->members );
    7811083        at->set_body( td->aggregate.body );
    7821084
     
    7851087
    7861088
    787 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 ) {
    7881093        switch ( type->kind ) {
    7891094        case TypeData::Enum:
    7901095                if ( type->enumeration.body ) {
    791                         EnumDecl * typedecl = buildEnum( type, attributes, linkage );
    792                         return new EnumInstType( buildQualifiers( type ), typedecl );
     1096                        ast::EnumDecl * typedecl =
     1097                                buildEnum( type, std::move( attributes ), linkage );
     1098                        return new ast::EnumInstType(
     1099                                typedecl,
     1100                                buildQualifiers( type )
     1101                        );
    7931102                } else {
    794                         return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
    795                 } // if
     1103                        return new ast::EnumInstType(
     1104                                *type->enumeration.name,
     1105                                buildQualifiers( type )
     1106                        );
     1107                } // if
     1108                break;
    7961109        case TypeData::Aggregate:
    7971110                if ( type->aggregate.body ) {
    798                         AggregateDecl * typedecl = buildAggregate( type, attributes, linkage );
     1111                        ast::AggregateDecl * typedecl =
     1112                                buildAggregate( type, std::move( attributes ), linkage );
    7991113                        switch ( type->aggregate.kind ) {
    800                         case AggregateDecl::Struct:
    801                         case AggregateDecl::Coroutine:
    802                         case AggregateDecl::Monitor:
    803                         case AggregateDecl::Thread:
    804                                 return new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
    805                         case AggregateDecl::Union:
    806                                 return new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
    807                         case AggregateDecl::Trait:
     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:
    8081128                                assert( false );
    809                                 //return new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
    8101129                                break;
    8111130                        default:
     
    8141133                } else {
    8151134                        switch ( type->aggregate.kind ) {
    816                         case AggregateDecl::Struct:
    817                         case AggregateDecl::Coroutine:
    818                         case AggregateDecl::Monitor:
    819                         case AggregateDecl::Thread:
    820                                 return new StructInstType( buildQualifiers( type ), *type->aggregate.name );
    821                         case AggregateDecl::Union:
    822                                 return new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
    823                         case AggregateDecl::Trait:
    824                                 return new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
     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                                );
    8251153                        default:
    8261154                                assert( false );
    8271155                        } // switch
    828                 } // if
    829                 return nullptr;
     1156                        break;
     1157                } // if
     1158                break;
    8301159        default:
    8311160                assert( false );
    8321161        } // switch
     1162        assert( false );
    8331163} // buildAggInst
    8341164
    8351165
    836 ReferenceToType * buildAggInst( const TypeData * td ) {
     1166ast::BaseInstType * buildAggInst( const TypeData * td ) {
    8371167        assert( td->kind == TypeData::AggregateInst );
    8381168
    839         // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() );
    840         ReferenceToType * ret = nullptr;
     1169        ast::BaseInstType * ret = nullptr;
    8411170        TypeData * type = td->aggInst.aggregate;
    8421171        switch ( type->kind ) {
    8431172        case TypeData::Enum:
    844                 return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
     1173                return new ast::EnumInstType(
     1174                        *type->enumeration.name,
     1175                        buildQualifiers( type )
     1176                );
    8451177        case TypeData::Aggregate:
    8461178                switch ( type->aggregate.kind ) {
    847                 case AggregateDecl::Struct:
    848                 case AggregateDecl::Coroutine:
    849                 case AggregateDecl::Monitor:
    850                 case AggregateDecl::Thread:
    851                         ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
     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                        );
    8521187                        break;
    853                 case AggregateDecl::Union:
    854                         ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
     1188                case ast::AggregateDecl::Union:
     1189                        ret = new ast::UnionInstType(
     1190                                *type->aggregate.name,
     1191                                buildQualifiers( type )
     1192                        );
    8551193                        break;
    856                 case AggregateDecl::Trait:
    857                         ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
     1194                case ast::AggregateDecl::Trait:
     1195                        ret = new ast::TraitInstType(
     1196                                *type->aggregate.name,
     1197                                buildQualifiers( type )
     1198                        );
    8581199                        break;
    8591200                default:
     
    8651206        } // switch
    8661207
    867         ret->set_hoistType( td->aggInst.hoistType );
    868         buildList( td->aggInst.params, ret->get_parameters() );
    869         buildForall( td->forall, ret->get_forall() );
     1208        ret->hoistType = td->aggInst.hoistType;
     1209        buildList( td->aggInst.params, ret->params );
    8701210        return ret;
    8711211} // buildAggInst
    8721212
    8731213
    874 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 ) {
    8751220        assert( td->kind == TypeData::Symbolic );
    876         NamedTypeDecl * ret;
     1221        ast::NamedTypeDecl * ret;
    8771222        assert( td->base );
    8781223        if ( td->symbolic.isTypedef ) {
    879                 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                );
    8801231        } else {
    881                 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                );
    8821240        } // if
    883         buildList( td->symbolic.assertions, ret->get_assertions() );
    884         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 );
    8851243        return ret;
    8861244} // buildSymbolic
    8871245
    8881246
    889 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 ) {
    8901251        assert( td->kind == TypeData::Enum );
    891         Type * baseType = td->base ? typebuild(td->base) : nullptr;
    892         EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType );
    893         buildList( td->enumeration.constants, ret->get_members() );
    894         list< Declaration * >::iterator members = ret->get_members().begin();
    895         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;
    8961264        for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
    8971265                if ( cur->enumInLine ) {
     
    9001268                        SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
    9011269                } else if ( cur->has_enumeratorValue() ) {
    902                         ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
    903                         member->set_init( new SingleInit( maybeMoveBuild( 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                        );
    9041277                } else if ( !cur->initializer ) {
    905                         if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) {
     1278                        if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) {
    9061279                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
    9071280                        }
     
    9101283                // if
    9111284        } // for
    912         ret->set_body( td->enumeration.body );
     1285        ret->body = td->enumeration.body;
    9131286        return ret;
    9141287} // buildEnum
    9151288
    9161289
    917 TypeInstType * buildSymbolicInst( const TypeData * td ) {
     1290ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
    9181291        assert( td->kind == TypeData::SymbolicInst );
    919         TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false );
    920         buildList( td->symbolic.actuals, ret->get_parameters() );
    921         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 );
    9221298        return ret;
    9231299} // buildSymbolicInst
    9241300
    9251301
    926 TupleType * buildTuple( const TypeData * td ) {
     1302ast::TupleType * buildTuple( const TypeData * td ) {
    9271303        assert( td->kind == TypeData::Tuple );
    928         std::list< Type * > types;
     1304        std::vector<ast::ptr<ast::Type>> types;
    9291305        buildTypeList( td->tuple, types );
    930         TupleType * ret = new TupleType( buildQualifiers( td ), types );
    931         buildForall( td->forall, ret->get_forall() );
     1306        ast::TupleType * ret = new ast::TupleType(
     1307                std::move( types ),
     1308                buildQualifiers( td )
     1309        );
    9321310        return ret;
    9331311} // buildTuple
    9341312
    9351313
    936 TypeofType * buildTypeof( const TypeData * td ) {
     1314ast::TypeofType * buildTypeof( const TypeData * td ) {
    9371315        assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
    9381316        assert( td->typeexpr );
    939         // assert( td->typeexpr->expr );
    940         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        );
    9411323} // buildTypeof
    9421324
    9431325
    944 VTableType * buildVtable( const TypeData * td ) {
     1326ast::VTableType * buildVtable( const TypeData * td ) {
    9451327        assert( td->base );
    946         return new VTableType{ buildQualifiers( td ), typebuild( td->base ) };
     1328        return new ast::VTableType(
     1329                typebuild( td->base ),
     1330                buildQualifiers( td )
     1331        );
    9471332} // buildVtable
    9481333
    9491334
    950 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
     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 ) {
    9511419        if ( td->kind == TypeData::Function ) {
    9521420                if ( td->function.idList ) {                                    // KR function ?
     
    9541422                } // if
    9551423
    956                 FunctionDecl * decl;
    957                 Statement * stmt = maybeBuild( td->function.body );
    958                 CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt );
    959                 decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec );
    960                 buildList( td->function.withExprs, decl->withExprs );
    961                 return decl->set_asmName( asmName );
     1424                return buildFunctionDecl(
     1425                        td, name, scs, funcSpec, linkage,
     1426                        asmName, std::move( attributes ) );
    9621427        } else if ( td->kind == TypeData::Aggregate ) {
    963                 return buildAggregate( td, attributes, linkage );
     1428                return buildAggregate( td, std::move( attributes ), linkage );
    9641429        } else if ( td->kind == TypeData::Enum ) {
    965                 return buildEnum( td, attributes, linkage );
     1430                return buildEnum( td, std::move( attributes ), linkage );
    9661431        } else if ( td->kind == TypeData::Symbolic ) {
    967                 return buildSymbolic( td, attributes, name, scs, linkage );
     1432                return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
    9681433        } else {
    969                 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;
    9701445        } // if
    9711446        return nullptr;
     
    9731448
    9741449
    975 FunctionType * buildFunction( const TypeData * td ) {
     1450ast::FunctionType * buildFunctionType( const TypeData * td ) {
    9761451        assert( td->kind == TypeData::Function );
    977         FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis );
    978         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 );
    9791458        buildForall( td->forall, ft->forall );
    9801459        if ( td->base ) {
    9811460                switch ( td->base->kind ) {
    9821461                case TypeData::Tuple:
    983                         buildList( td->base->tuple, ft->returnVals );
     1462                        buildTypeList( td->base->tuple, ft->returns );
    9841463                        break;
    9851464                default:
    986                         ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType * >( buildDecl( td->base, "", Type::StorageClasses(), nullptr, Type::FuncSpecifiers(), LinkageSpec::Cforall, nullptr ) ) );
     1465                        ft->returns.push_back( typebuild( td->base ) );
     1466                        break;
    9871467                } // switch
    9881468        } else {
    989                 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 ) );
    9901471        } // if
    9911472        return ft;
    992 } // buildFunction
     1473} // buildFunctionType
    9931474
    9941475
     
    10211502                                param->type = decl->type;                               // set copy declaration type to parameter type
    10221503                                decl->type = nullptr;                                   // reset declaration type
    1023                                 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 );
    10241506                        } // if
    10251507                } // for
  • TabularUnified src/Parser/TypeData.h

    r4541b09 rbb7422a  
    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 : Fri Feb 24 14:25:02 2023
    13 // Update Count     : 205
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Mar  1 10:44:00 2023
     13// Update Count     : 206
    1414//
    1515
     
    2020#include <string>                                                                               // for string
    2121
     22#include "AST/Type.hpp"                                                                 // for Type
    2223#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
    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;
     
    4139        };
    4240
    43         struct AggInst_t {                                                                      // handles SUE
     41        struct AggInst_t {
    4442                TypeData * aggregate = nullptr;
    4543                ExpressionNode * params = nullptr;
     
    9391        DeclarationNode::BuiltinType builtintype = DeclarationNode::NoBuiltinType;
    9492
    95         Type::Qualifiers qualifiers;
     93        ast::CV::Qualifiers qualifiers;
    9694        DeclarationNode * forall = nullptr;
    9795
     
    114112};
    115113
    116 Type * typebuild( const TypeData * );
     114ast::Type * typebuild( const TypeData * );
    117115TypeData * typeextractAggregate( const TypeData * td, bool toplevel = true );
    118 Type::Qualifiers buildQualifiers( const TypeData * td );
    119 Type * buildBasicType( const TypeData * );
    120 PointerType * buildPointer( const TypeData * );
    121 ArrayType * buildArray( const TypeData * );
    122 ReferenceType * buildReference( const TypeData * );
    123 AggregateDecl * buildAggregate( const TypeData *, std::list< Attribute * > );
    124 ReferenceToType * buildComAggInst( const TypeData *, std::list< Attribute * > attributes, LinkageSpec::Spec linkage );
    125 ReferenceToType * buildAggInst( const TypeData * );
    126 TypeDecl * buildVariable( const TypeData * );
    127 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * >, LinkageSpec::Spec );
    128 TypeInstType * buildSymbolicInst( const TypeData * );
    129 TupleType * buildTuple( const TypeData * );
    130 TypeofType * buildTypeof( const TypeData * );
    131 VTableType * buildVtable( const TypeData * );
    132 Declaration * buildDecl(
    133         const TypeData *, const std::string &, Type::StorageClasses, Expression *,
    134         Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName,
    135         Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
    136 FunctionType * buildFunction( const TypeData * );
    137 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 * );
    138136void buildKRFunction( const TypeData::Function_t & function );
    139137
  • TabularUnified src/Parser/lex.ll

    r4541b09 rbb7422a  
    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__
  • TabularUnified src/Parser/parser.yy

    r4541b09 rbb7422a  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 30 21:28:25 2023
    13 // Update Count     : 6328
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 14:02:00 2023
     13// Update Count     : 6329
    1414//
    1515
     
    6464
    6565extern DeclarationNode * parseTree;
    66 extern LinkageSpec::Spec linkage;
     66extern ast::Linkage::Spec linkage;
    6767extern TypedefTable typedefTable;
    6868
    69 stack<LinkageSpec::Spec> linkageStack;
     69stack<ast::Linkage::Spec> linkageStack;
    7070
    7171bool appendStr( string & to, string & from ) {
     
    200200} // fieldDecl
    201201
    202 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
    203 #define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
     202#define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) )
     203#define NEW_ONE  new ExpressionNode( build_constantInteger( yylloc, *new string( "1" ) ) )
    204204#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    205205#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     
    208208
    209209static ForCtrl * makeForCtrl(
     210                const CodeLocation & location,
    210211                DeclarationNode * init,
    211212                enum OperKinds compop,
     
    213214                ExpressionNode * inc ) {
    214215        // Wrap both comp/inc if they are non-null.
    215         if ( comp ) comp = new ExpressionNode( build_binary_val(
     216        if ( comp ) comp = new ExpressionNode( build_binary_val( location,
    216217                compop,
    217                 new ExpressionNode( build_varref( new string( *init->name ) ) ),
     218                new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
    218219                comp ) );
    219         if ( inc ) inc = new ExpressionNode( build_binary_val(
     220        if ( inc ) inc = new ExpressionNode( build_binary_val( location,
    220221                // choose += or -= for upto/downto
    221222                compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn,
    222                 new ExpressionNode( build_varref( new string( *init->name ) ) ),
     223                new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
    223224                inc ) );
    224225        // The StatementNode call frees init->name, it must happen later.
     
    226227}
    227228
    228 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     229ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    229230        if ( index->initializer ) {
    230231                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    234235        } // if
    235236        DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) );
    236         return makeForCtrl( initDecl, compop, comp, inc );
     237        return makeForCtrl( location, initDecl, compop, comp, inc );
    237238} // forCtrl
    238239
    239 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    240         ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
    241         if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
    242                 type = new ExpressionNode( new CastExpr( maybeMoveBuild( type ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
     240ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     241        ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());
     242        if ( constant && (constant->rep == "0" || constant->rep == "1") ) {
     243                type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) );
    243244        } // if
    244245        DeclarationNode * initDecl = distAttr(
     
    246247                DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) )
    247248        );
    248         return makeForCtrl( initDecl, compop, comp, inc );
     249        return makeForCtrl( location, initDecl, compop, comp, inc );
    249250} // forCtrl
    250251
    251 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    252         if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {
    253                 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
    254         } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {
    255                 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) {
    256                         return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     252ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     253        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {
     254                return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
     255        } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {
     256                if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
     257                        return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
    257258                } else {
    258259                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     
    299300        ExpressionNode * en;
    300301        DeclarationNode * decl;
    301         AggregateDecl::Aggregate aggKey;
    302         TypeDecl::Kind tclass;
     302        ast::AggregateDecl::Aggregate aggKey;
     303        ast::TypeDecl::Kind tclass;
    303304        StatementNode * sn;
    304         WaitForStmt * wfs;
    305         Expression * constant;
     305        ast::WaitForStmt * wfs;
     306        ast::Expr * constant;
    306307        CondCtl * ifctl;
    307308        ForCtrl * fctl;
     
    313314        bool flag;
    314315        EnumHiding hide;
    315         CatchStmt::Kind catch_kind;
    316         GenericExpr * genexpr;
     316        ast::ExceptionKind catch_kind;
     317        ast::GenericExpr * genexpr;
    317318}
    318319
    319 //************************* TERMINAL TOKENS ********************************
     320// ************************ TERMINAL TOKENS ********************************
    320321
    321322// keywords
     
    611612constant:
    612613                // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
    613         INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }
    614         | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    615         | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    616         | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    617         | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( *$1 ) ); }
     614        INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( yylloc, *$1 ) ); }
     615        | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     616        | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     617        | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     618        | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( yylloc, *$1 ) ); }
    618619        ;
    619620
     
    641642
    642643string_literal:
    643         string_literal_list                                                     { $$ = build_constantStr( *$1 ); }
     644        string_literal_list                                                     { $$ = build_constantStr( yylloc, *$1 ); }
    644645        ;
    645646
     
    658659primary_expression:
    659660        IDENTIFIER                                                                                      // typedef name cannot be used as a variable name
    660                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     661                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    661662        | quasi_keyword
    662                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     663                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    663664        | TYPEDIMname                                                                           // CFA, generic length argument
    664665                // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); }
    665666                // { $$ = new ExpressionNode( build_varref( $1 ) ); }
    666                 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }
     667                { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); }
    667668        | tuple
    668669        | '(' comma_expression ')'
    669670                { $$ = $2; }
    670671        | '(' compound_statement ')'                                            // GCC, lambda expression
    671                 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild( $2 ) ) ) ); }
     672                { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); }
    672673        | type_name '.' identifier                                                      // CFA, nested type
    673                 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
     674                { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    674675        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    675676                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    703704                {
    704705                        // steal the association node from the singleton and delete the wrapper
    705                         $1->associations.splice($1->associations.end(), $3->associations);
     706                        assert( 1 == $3->associations.size() );
     707                        $1->associations.push_back( $3->associations.front() );
    706708                        delete $3;
    707709                        $$ = $1;
     
    713715                {
    714716                        // create a GenericExpr wrapper with one association pair
    715                         $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild( $3 ) } } );
     717                        $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );
    716718                }
    717719        | DEFAULT ':' assignment_expression
    718                 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild( $3 ) } } ); }
     720                { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }
    719721        ;
    720722
     
    725727                // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
    726728                // Current: Commas in subscripts make tuples.
    727                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
     729                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
    728730        | postfix_expression '[' assignment_expression ']'
    729731                // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
     
    731733                // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
    732734                // equivalent to the old x[i,j].
    733                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     735                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    734736        | constant '[' assignment_expression ']'                        // 3[a], 'a'[a], 3.5[a]
    735                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     737                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    736738        | string_literal '[' assignment_expression ']'          // "abc"[3], 3["abc"]
    737                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
     739                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
    738740        | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call
    739741                {
    740742                        Token fn;
    741743                        fn.str = new std::string( "?{}" );                      // location undefined - use location of '{'?
    742                         $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
     744                        $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
    743745                }
    744746        | postfix_expression '(' argument_expression_list_opt ')'
    745                 { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
     747                { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); }
    746748        | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')'
    747749                // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; }
    748                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ),
     750                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, new string( "__builtin_va_arg") ) ),
    749751                                                                                           (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); }
    750752        | postfix_expression '`' identifier                                     // CFA, postfix call
    751                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     753                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    752754        | constant '`' identifier                                                       // CFA, postfix call
    753                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     755                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    754756        | string_literal '`' identifier                                         // CFA, postfix call
    755                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
     757                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
    756758        | postfix_expression '.' identifier
    757                 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
     759                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    758760        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
    759                 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); }
     761                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    760762        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    761                 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
     763                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ) ) ); }
    762764        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    763                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     765                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    764766        | postfix_expression '.' aggregate_control
    765                 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
     767                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); }
    766768        | postfix_expression ARROW identifier
    767                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
     769                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    768770        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    769                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
     771                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    770772        | postfix_expression ARROW '[' field_name_list ']'      // CFA, tuple field selector
    771                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     773                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    772774        | postfix_expression ICR
    773                 { $$ = new ExpressionNode( build_unary_val( OperKinds::IncrPost, $1 ) ); }
     775                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); }
    774776        | postfix_expression DECR
    775                 { $$ = new ExpressionNode( build_unary_val( OperKinds::DecrPost, $1 ) ); }
     777                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); }
    776778        | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
    777                 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
     779                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); }
    778780        | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
    779                 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
     781                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
    780782        | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call
    781783                {
    782784                        Token fn;
    783785                        fn.str = new string( "^?{}" );                          // location undefined
    784                         $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
     786                        $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
    785787                }
    786788        ;
     
    813815        field_name
    814816        | FLOATING_DECIMALconstant field
    815                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild( $2 ) ) ); }
     817                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); }
    816818        | FLOATING_DECIMALconstant '[' field_name_list ']'
    817                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
     819                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc, $3 ) ) ); }
    818820        | field_name '.' field
    819                 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild( $3 ) ) ); }
     821                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    820822        | field_name '.' '[' field_name_list ']'
    821                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     823                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    822824        | field_name ARROW field
    823                 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild( $3 ) ) ); }
     825                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    824826        | field_name ARROW '[' field_name_list ']'
    825                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     827                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    826828        ;
    827829
    828830field_name:
    829831        INTEGERconstant fraction_constants_opt
    830                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }
     832                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc, *$1 ), $2 ) ); }
    831833        | FLOATINGconstant fraction_constants_opt
    832                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
     834                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc, *$1 ), $2 ) ); }
    833835        | identifier_at fraction_constants_opt                          // CFA, allow anonymous fields
    834836                {
    835                         $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
     837                        $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc, $1 ), $2 ) );
    836838                }
    837839        ;
     
    842844        | fraction_constants_opt FLOATING_FRACTIONconstant
    843845                {
    844                         Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
    845                         $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant );
     846                        ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 );
     847                        $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1, constant ) ) : new ExpressionNode( constant );
    846848                }
    847849        ;
     
    862864                {
    863865                        switch ( $1 ) {
    864                           case OperKinds::AddressOf:
    865                                 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild( $2 ) ) );
     866                        case OperKinds::AddressOf:
     867                                $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );
    866868                                break;
    867                           case OperKinds::PointTo:
    868                                 $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
     869                        case OperKinds::PointTo:
     870                                $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) );
    869871                                break;
    870                           case OperKinds::And:
    871                                 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild( $2 ) ) ) );
     872                        case OperKinds::And:
     873                                $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );
    872874                                break;
    873                           default:
     875                        default:
    874876                                assert( false );
    875877                        }
    876878                }
    877879        | unary_operator cast_expression
    878                 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }
     880                { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); }
    879881        | ICR unary_expression
    880                 { $$ = new ExpressionNode( build_unary_val( OperKinds::Incr, $2 ) ); }
     882                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); }
    881883        | DECR unary_expression
    882                 { $$ = new ExpressionNode( build_unary_val( OperKinds::Decr, $2 ) ); }
     884                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); }
    883885        | SIZEOF unary_expression
    884                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild( $2 ) ) ); }
     886                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    885887        | SIZEOF '(' type_no_function ')'
    886                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); }
     888                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    887889        | ALIGNOF unary_expression                                                      // GCC, variable alignment
    888                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild( $2 ) ) ); }
     890                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    889891        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    890                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
     892                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    891893        | OFFSETOF '(' type_no_function ',' identifier ')'
    892                 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
     894                { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); }
    893895        | TYPEID '(' type_no_function ')'
    894896                {
     
    915917        unary_expression
    916918        | '(' type_no_function ')' cast_expression
    917                 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     919                { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    918920        | '(' aggregate_control '&' ')' cast_expression         // CFA
    919                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     921                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    920922        | '(' aggregate_control '*' ')' cast_expression         // CFA
    921                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     923                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    922924        | '(' VIRTUAL ')' cast_expression                                       // CFA
    923                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     925                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    924926        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    925                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
     927                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
    926928        | '(' RETURN type_no_function ')' cast_expression       // CFA
    927929                { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
     
    931933                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    932934//      | '(' type_no_function ')' tuple
    933 //              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     935//              { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    934936        ;
    935937
     
    949951        cast_expression
    950952        | exponential_expression '\\' cast_expression
    951                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }
     953                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); }
    952954        ;
    953955
     
    955957        exponential_expression
    956958        | multiplicative_expression '*' exponential_expression
    957                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }
     959                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); }
    958960        | multiplicative_expression '/' exponential_expression
    959                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }
     961                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); }
    960962        | multiplicative_expression '%' exponential_expression
    961                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }
     963                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); }
    962964        ;
    963965
     
    965967        multiplicative_expression
    966968        | additive_expression '+' multiplicative_expression
    967                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }
     969                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); }
    968970        | additive_expression '-' multiplicative_expression
    969                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }
     971                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); }
    970972        ;
    971973
     
    973975        additive_expression
    974976        | shift_expression LS additive_expression
    975                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }
     977                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); }
    976978        | shift_expression RS additive_expression
    977                 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }
     979                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); }
    978980        ;
    979981
     
    981983        shift_expression
    982984        | relational_expression '<' shift_expression
    983                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }
     985                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); }
    984986        | relational_expression '>' shift_expression
    985                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }
     987                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); }
    986988        | relational_expression LE shift_expression
    987                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }
     989                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); }
    988990        | relational_expression GE shift_expression
    989                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }
     991                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); }
    990992        ;
    991993
     
    993995        relational_expression
    994996        | equality_expression EQ relational_expression
    995                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }
     997                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); }
    996998        | equality_expression NE relational_expression
    997                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }
     999                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); }
    9981000        ;
    9991001
     
    10011003        equality_expression
    10021004        | AND_expression '&' equality_expression
    1003                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }
     1005                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); }
    10041006        ;
    10051007
     
    10071009        AND_expression
    10081010        | exclusive_OR_expression '^' AND_expression
    1009                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }
     1011                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); }
    10101012        ;
    10111013
     
    10131015        exclusive_OR_expression
    10141016        | inclusive_OR_expression '|' exclusive_OR_expression
    1015                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }
     1017                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); }
    10161018        ;
    10171019
     
    10191021        inclusive_OR_expression
    10201022        | logical_AND_expression ANDAND inclusive_OR_expression
    1021                 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); }
     1023                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); }
    10221024        ;
    10231025
     
    10251027        logical_AND_expression
    10261028        | logical_OR_expression OROR logical_AND_expression
    1027                 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); }
     1029                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); }
    10281030        ;
    10291031
     
    10311033        logical_OR_expression
    10321034        | logical_OR_expression '?' comma_expression ':' conditional_expression
    1033                 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
     1035                { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); }
    10341036                // FIX ME: computes $1 twice
    10351037        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    1036                 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
     1038                { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); }
    10371039        ;
    10381040
     
    10491051//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    10501052//                      } else {
    1051                                 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
     1053                                $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) );
    10521054//                      } // if
    10531055                }
     
    10941096//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    10951097        '[' ',' tuple_expression_list ']'
    1096                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     1098                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    10971099        | '[' push assignment_expression pop ',' tuple_expression_list ']'
    1098                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }
     1100                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); }
    10991101        ;
    11001102
     
    11121114        assignment_expression
    11131115        | comma_expression ',' assignment_expression
    1114                 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1116                { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    11151117        ;
    11161118
     
    11391141        | asm_statement
    11401142        | DIRECTIVE
    1141                 { $$ = new StatementNode( build_directive( $1 ) ); }
     1143                { $$ = new StatementNode( build_directive( yylloc, $1 ) ); }
    11421144        ;
    11431145
     
    11451147                // labels cannot be identifiers 0 or 1
    11461148        identifier_or_type_name ':' attribute_list_opt statement
    1147                 { $$ = $4->add_label( $1, $3 ); }
     1149                { $$ = $4->add_label( yylloc, $1, $3 ); }
    11481150        | identifier_or_type_name ':' attribute_list_opt error // syntax error
    11491151                {
     
    11571159compound_statement:
    11581160        '{' '}'
    1159                 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     1161                { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); }
    11601162        | '{' push
    11611163          local_label_declaration_opt                                           // GCC, local labels appear at start of block
    11621164          statement_decl_list                                                           // C99, intermix declarations and statements
    11631165          pop '}'
    1164                 { $$ = new StatementNode( build_compound( $4 ) ); }
     1166                { $$ = new StatementNode( build_compound( yylloc, $4 ) ); }
    11651167        ;
    11661168
     
    11931195expression_statement:
    11941196        comma_expression_opt ';'
    1195                 { $$ = new StatementNode( build_expr( $1 ) ); }
     1197                { $$ = new StatementNode( build_expr( yylloc, $1 ) ); }
    11961198        ;
    11971199
     
    12021204                { $$ = $2; }
    12031205        | SWITCH '(' comma_expression ')' case_clause
    1204                 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
     1206                { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); }
    12051207        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12061208                {
    1207                         StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
     1209                        StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) );
    12081210                        // The semantics of the declaration list is changed to include associated initialization, which is performed
    12091211                        // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
     
    12111213                        // therefore, are removed from the grammar even though C allows it. The change also applies to choose
    12121214                        // statement.
    1213                         $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1215                        $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    12141216                }
    12151217        | SWITCH '(' comma_expression ')' '{' error '}'         // CFA, syntax error
    12161218                { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    12171219        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    1218                 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
     1220                { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); }
    12191221        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12201222                {
    1221                         StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );
    1222                         $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1223                        StatementNode *sw = new StatementNode( build_switch( yylloc, false, $3, $8 ) );
     1224                        $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    12231225                }
    12241226        | CHOOSE '(' comma_expression ')' '{' error '}'         // CFA, syntax error
     
    12291231        IF '(' conditional_declaration ')' statement            %prec THEN
    12301232                // explicitly deal with the shift/reduce conflict on if/else
    1231                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
     1233                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); }
    12321234        | IF '(' conditional_declaration ')' statement ELSE statement
    1233                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); }
     1235                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); }
    12341236        ;
    12351237
     
    12511253        constant_expression                                                     { $$ = $1; }
    12521254        | constant_expression ELLIPSIS constant_expression      // GCC, subrange
    1253                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1255                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    12541256        | subrange                                                                                      // CFA, subrange
    12551257        ;
     
    12671269        | CASE case_value_list error                                            // syntax error
    12681270                { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
    1269         | DEFAULT ':'                                                           { $$ = new StatementNode( build_default() ); }
     1271        | DEFAULT ':'                                                           { $$ = new StatementNode( build_default( yylloc ) ); }
    12701272                // A semantic check is required to ensure only one default clause per switch/choose statement.
    12711273        | DEFAULT error                                                                         //  syntax error
     
    12791281
    12801282case_clause:                                                                                    // CFA
    1281         case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }
     1283        case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( yylloc, $2 ) ); }
    12821284        ;
    12831285
     
    12901292switch_clause_list:                                                                             // CFA
    12911293        case_label_list statement_list_nodecl
    1292                 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
     1294                { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); }
    12931295        | switch_clause_list case_label_list statement_list_nodecl
    1294                 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
     1296                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ) ); }
    12951297        ;
    12961298
    12971299iteration_statement:
    12981300        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1299                 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
     1301                { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); }
    13001302        | WHILE '(' ')' statement ELSE statement                        // CFA
    13011303                {
    1302                         $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
     1304                        $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) );
    13031305                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13041306                }
    13051307        | WHILE '(' conditional_declaration ')' statement       %prec THEN
    1306                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
     1308                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    13071309        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
    1308                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
     1310                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    13091311        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1310                 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
     1312                { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); }
    13111313        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    13121314                {
    1313                         $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
     1315                        $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) );
    13141316                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13151317                }
    13161318        | DO statement WHILE '(' comma_expression ')' ';'
    1317                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
     1319                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); }
    13181320        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
    1319                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
     1321                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ), $8 ) ); }
    13201322        | FOR '(' ')' statement                                                         %prec THEN // CFA => for ( ;; )
    1321                 { $$ = new StatementNode( build_for( new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( $4 ) ) ); }
     1323                { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); }
    13221324        | FOR '(' ')' statement ELSE statement                          // CFA
    13231325                {
    1324                         $$ = new StatementNode( build_for( new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( $4 ) ) );
     1326                        $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) );
    13251327                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13261328                }
    13271329        | FOR '(' for_control_expression_list ')' statement     %prec THEN
    1328                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
     1330                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    13291331        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
    1330                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
     1332                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    13311333        ;
    13321334
     
    13421344                        if ( $1->condition ) {
    13431345                                if ( $3->condition ) {
    1344                                         $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
     1346                                        $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr ) );
    13451347                                } // if
    13461348                        } else $1->condition = $3->condition;
    13471349                        if ( $1->change ) {
    13481350                                if ( $3->change ) {
    1349                                         $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
     1351                                        $1->change->expr.reset( new ast::CommaExpr( yylloc, $1->change->expr.release(), $3->change->expr.release() ) );
    13501352                                } // if
    13511353                        } else $1->change = $3->change;
     
    13591361        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    13601362                {
    1361                         StatementNode * init = $1 ? new StatementNode( new ExprStmt( maybeMoveBuild( $1 ) ) ) : nullptr;
     1363                        StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr;
    13621364                        $$ = new ForCtrl( init, $3, $5 );
    13631365                }
     
    13711373
    13721374        | comma_expression                                                                      // CFA, anonymous loop-index
    1373                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
     1375                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
    13741376        | downupdowneq comma_expression                                         // CFA, anonymous loop-index
    1375                 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
     1377                { $$ = forCtrl( yylloc, $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
    13761378
    13771379        | comma_expression updowneq comma_expression            // CFA, anonymous loop-index
    1378                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
     1380                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
    13791381        | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
    13801382                {
    13811383                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1382                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
     1384                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
    13831385                }
    13841386        | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
     
    13881390                }
    13891391        | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    1390                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
     1392                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
    13911393        | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    13921394                {
    13931395                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1394                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
     1396                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
    13951397                }
    13961398        | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
     
    14111413
    14121414        | comma_expression ';' comma_expression                         // CFA
    1413                 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1415                { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    14141416        | comma_expression ';' downupdowneq comma_expression // CFA
    1415                 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
     1417                { $$ = forCtrl( yylloc, $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
    14161418
    14171419        | comma_expression ';' comma_expression updowneq comma_expression // CFA
    1418                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
     1420                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
    14191421        | comma_expression ';' '@' updowneq comma_expression // CFA
    14201422                {
    14211423                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1422                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1424                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    14231425                }
    14241426        | comma_expression ';' comma_expression updowneq '@' // CFA
     
    14261428                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14271429                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1428                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
     1430                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    14291431                }
    14301432        | comma_expression ';' '@' updowneq '@'                         // CFA, error
     
    14321434
    14331435        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    1434                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
     1436                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    14351437        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
    14361438                {
    14371439                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1438                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
     1440                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 );
    14391441                }
    14401442        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
     
    14421444                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14431445                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1444                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
     1446                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, $7 );
    14451447                }
    14461448        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    1447                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
     1449                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    14481450        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
    14491451                {
    14501452                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1451                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
     1453                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr );
    14521454                }
    14531455        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
     
    14551457                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14561458                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1457                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
     1459                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, nullptr );
    14581460                }
    14591461        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
     
    14611463
    14621464        | declaration comma_expression                                          // CFA
    1463                 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1465                { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    14641466        | declaration downupdowneq comma_expression                     // CFA
    1465                 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
     1467                { $$ = forCtrl( yylloc, $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
    14661468
    14671469        | declaration comma_expression updowneq comma_expression // CFA
    1468                 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
     1470                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
    14691471        | declaration '@' updowneq comma_expression                     // CFA
    14701472                {
    14711473                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1472                         else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
     1474                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE );
    14731475                }
    14741476        | declaration comma_expression updowneq '@'                     // CFA
     
    14761478                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14771479                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1478                         else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
     1480                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, NEW_ONE );
    14791481                }
    14801482
    14811483        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1482                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
     1484                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
    14831485        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    14841486                {
    14851487                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1486                         else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
     1488                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 );
    14871489                }
    14881490        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
     
    14901492                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14911493                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1492                         else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
     1494                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, $6 );
    14931495                }
    14941496        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1495                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
     1497                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
    14961498        | declaration '@' updowneq comma_expression '~' '@' // CFA
    14971499                {
    14981500                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1499                         else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
     1501                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr );
    15001502                }
    15011503        | declaration comma_expression updowneq '@' '~' '@'     // CFA
     
    15031505                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    15041506                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1505                         else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
     1507                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr );
    15061508                }
    15071509        | declaration '@' updowneq '@' '~' '@'                          // CFA, error
     
    15461548jump_statement:
    15471549        GOTO identifier_or_type_name ';'
    1548                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); }
     1550                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }
    15491551        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    15501552                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    15531555                // A semantic check is required to ensure fallthru appears only in the body of a choose statement.
    15541556        | fall_through_name ';'                                                         // CFA
    1555                 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }
     1557                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }
    15561558        | fall_through_name identifier_or_type_name ';'         // CFA
    1557                 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); }
     1559                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }
    15581560        | fall_through_name DEFAULT ';'                                         // CFA
    1559                 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }
     1561                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }
    15601562        | CONTINUE ';'
    15611563                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1562                 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); }
     1564                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }
    15631565        | CONTINUE identifier_or_type_name ';'                          // CFA, multi-level continue
    15641566                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15651567                // the target of the transfer appears only at the start of an iteration statement.
    1566                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); }
     1568                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }
    15671569        | BREAK ';'
    15681570                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1569                 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); }
     1571                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }
    15701572        | BREAK identifier_or_type_name ';'                                     // CFA, multi-level exit
    15711573                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15721574                // the target of the transfer appears only at the start of an iteration statement.
    1573                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); }
     1575                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }
    15741576        | RETURN comma_expression_opt ';'
    1575                 { $$ = new StatementNode( build_return( $2 ) ); }
     1577                { $$ = new StatementNode( build_return( yylloc, $2 ) ); }
    15761578        | RETURN '{' initializer_list_opt comma_opt '}' ';'
    15771579                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    15781580        | SUSPEND ';'
    1579                 { $$ = new StatementNode( build_suspend( nullptr ) ); }
     1581                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); }
    15801582        | SUSPEND compound_statement
    1581                 { $$ = new StatementNode( build_suspend( $2 ) ); }
     1583                { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); }
    15821584        | SUSPEND COROUTINE ';'
    1583                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); }
     1585                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }
    15841586        | SUSPEND COROUTINE compound_statement
    1585                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); }
     1587                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }
    15861588        | SUSPEND GENERATOR ';'
    1587                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); }
     1589                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }
    15881590        | SUSPEND GENERATOR compound_statement
    1589                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); }
     1591                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }
    15901592        | THROW assignment_expression_opt ';'                           // handles rethrow
    1591                 { $$ = new StatementNode( build_throw( $2 ) ); }
     1593                { $$ = new StatementNode( build_throw( yylloc, $2 ) ); }
    15921594        | THROWRESUME assignment_expression_opt ';'                     // handles reresume
    1593                 { $$ = new StatementNode( build_resume( $2 ) ); }
     1595                { $$ = new StatementNode( build_resume( yylloc, $2 ) ); }
    15941596        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    15951597                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
     
    16031605with_statement:
    16041606        WITH '(' tuple_expression_list ')' statement
    1605                 { $$ = new StatementNode( build_with( $3, $5 ) ); }
     1607                { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); }
    16061608        ;
    16071609
     
    16111613                {
    16121614                        if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; }
    1613                         $$ = new StatementNode( build_mutex( $3, $5 ) );
     1615                        $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) );
    16141616                }
    16151617        ;
     
    16501652        when_clause_opt waitfor statement                                       %prec THEN
    16511653                // Called first: create header for WaitForStmt.
    1652                 { $$ = build_waitfor( new WaitForStmt(), $1, $2, maybe_build_compound( $3 ) ); }
     1654                { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); }
    16531655        | wor_waitfor_clause wor when_clause_opt waitfor statement
    1654                 { $$ = build_waitfor( $1, $3, $4, maybe_build_compound( $5 ) ); }
     1656                { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    16551657        | wor_waitfor_clause wor when_clause_opt ELSE statement
    1656                 { $$ = build_waitfor_else( $1, $3, maybe_build_compound( $5 ) ); }
     1658                { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); }
    16571659        | wor_waitfor_clause wor when_clause_opt timeout statement      %prec THEN
    1658                 { $$ = build_waitfor_timeout( $1, $3, $4, maybe_build_compound( $5 ) ); }
     1660                { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    16591661        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    16601662        | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
    16611663                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    16621664        | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1663                 { $$ = build_waitfor_else( build_waitfor_timeout( $1, $3, $4, maybe_build_compound( $5 ) ), $7, maybe_build_compound( $9 ) ); }
     1665                { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); }
     1666        ;
    16641667
    16651668waitfor_statement:
     
    17111714        wor_waituntil_clause                                                            %prec THEN
    17121715                // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
    1713                 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     1716                { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); }
    17141717        ;
    17151718
    17161719exception_statement:
    1717         TRY compound_statement handler_clause                           %prec THEN
    1718                 { $$ = new StatementNode( build_try( $2, $3, nullptr ) ); }
     1720        TRY compound_statement handler_clause                                   %prec THEN
     1721                { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
    17191722        | TRY compound_statement finally_clause
    1720                 { $$ = new StatementNode( build_try( $2, nullptr, $3 ) ); }
     1723                { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
    17211724        | TRY compound_statement handler_clause finally_clause
    1722                 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
     1725                { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
    17231726        ;
    17241727
    17251728handler_clause:
    17261729        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1727                 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
     1730                { $$ = new StatementNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
    17281731        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1729                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }
     1732                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
    17301733        ;
    17311734
     
    17371740
    17381741handler_key:
    1739         CATCH                                                                           { $$ = CatchStmt::Terminate; }
    1740         | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
    1741         | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
    1742         | FIXUP                                                                         { $$ = CatchStmt::Resume; }
     1742        CATCH                                                                           { $$ = ast::Terminate; }
     1743        | RECOVER                                                                       { $$ = ast::Terminate; }
     1744        | CATCHRESUME                                                           { $$ = ast::Resume; }
     1745        | FIXUP                                                                         { $$ = ast::Resume; }
    17431746        ;
    17441747
    17451748finally_clause:
    1746         FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
     1749        FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( yylloc, $2 ) ); }
    17471750        ;
    17481751
     
    17701773asm_statement:
    17711774        ASM asm_volatile_opt '(' string_literal ')' ';'
    1772                 { $$ = new StatementNode( build_asm( $2, $4, nullptr ) ); }
     1775                { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
    17731776        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1774                 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
     1777                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
    17751778        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1776                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
     1779                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
    17771780        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';'
    1778                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); }
     1781                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
    17791782        | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';'
    1780                 { $$ = new StatementNode( build_asm( $2, $5, nullptr, $8, $10, $12 ) ); }
     1783                { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
    17811784        ;
    17821785
     
    18021805asm_operand:                                                                                    // GCC
    18031806        string_literal '(' constant_expression ')'
    1804                 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild( $3 ) ) ); }
     1807                { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); }
    18051808        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1806                 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild( $6 ) ) ); }
     1809                {
     1810                        $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, $4, maybeMoveBuild( $6 ) ) );
     1811                        delete $2.str;
     1812                }
    18071813        ;
    18081814
     
    18191825        identifier
    18201826                {
    1821                         $$ = new LabelNode(); $$->labels.push_back( *$1 );
     1827                        $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
    18221828                        delete $1;                                                                      // allocated by lexer
    18231829                }
    18241830        | label_list ',' identifier
    18251831                {
    1826                         $$ = $1; $1->labels.push_back( *$3 );
     1832                        $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
    18271833                        delete $3;                                                                      // allocated by lexer
    18281834                }
     
    18871893                { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
    18881894        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1889                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
     1895                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
    18901896
    18911897// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    20872093                {
    20882094                        SemanticError( yylloc, ::toString( "Missing ';' after end of ",
    2089                                 $1->type->enumeration.name ? "enum" : AggregateDecl::aggrString( $1->type->aggregate.kind ),
     2095                                $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),
    20902096                                " declaration" ) );
    20912097                        $$ = nullptr;
     
    23212327                { $$ = DeclarationNode::newTypeof( $3 ); }
    23222328        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2323                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
     2329                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
    23242330        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    23252331                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    25152521aggregate_data:
    25162522        STRUCT vtable_opt
    2517                 { $$ = AggregateDecl::Struct; }
     2523                { $$ = ast::AggregateDecl::Struct; }
    25182524        | UNION
    2519                 { $$ = AggregateDecl::Union; }
     2525                { $$ = ast::AggregateDecl::Union; }
    25202526        | EXCEPTION                                                                                     // CFA
    2521                 { $$ = AggregateDecl::Exception; }
    2522           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2527                { $$ = ast::AggregateDecl::Exception; }
     2528          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
    25232529        ;
    25242530
    25252531aggregate_control:                                                                              // CFA
    25262532        MONITOR
    2527                 { $$ = AggregateDecl::Monitor; }
     2533                { $$ = ast::AggregateDecl::Monitor; }
    25282534        | MUTEX STRUCT
    2529                 { $$ = AggregateDecl::Monitor; }
     2535                { $$ = ast::AggregateDecl::Monitor; }
    25302536        | GENERATOR
    2531                 { $$ = AggregateDecl::Generator; }
     2537                { $$ = ast::AggregateDecl::Generator; }
    25322538        | MUTEX GENERATOR
    2533                 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2539                {
     2540                        SemanticError( yylloc, "monitor generator is currently unimplemented." );
     2541                        $$ = ast::AggregateDecl::NoAggregate;
     2542                }
    25342543        | COROUTINE
    2535                 { $$ = AggregateDecl::Coroutine; }
     2544                { $$ = ast::AggregateDecl::Coroutine; }
    25362545        | MUTEX COROUTINE
    2537                 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2546                {
     2547                        SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
     2548                        $$ = ast::AggregateDecl::NoAggregate;
     2549                }
    25382550        | THREAD
    2539                 { $$ = AggregateDecl::Thread; }
     2551                { $$ = ast::AggregateDecl::Thread; }
    25402552        | MUTEX THREAD
    2541                 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2553                {
     2554                        SemanticError( yylloc, "monitor thread is currently unimplemented." );
     2555                        $$ = ast::AggregateDecl::NoAggregate;
     2556                }
    25422557        ;
    25432558
     
    28892904        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    28902905        | identifier_at ':'                                                                     // GCC, field name
    2891                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     2906                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    28922907        ;
    28932908
     
    29012916designator:
    29022917        '.' identifier_at                                                                       // C99, field name
    2903                 { $$ = new ExpressionNode( build_varref( $2 ) ); }
     2918                { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
    29042919        | '[' push assignment_expression pop ']'                        // C99, single array element
    29052920                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    29082923                { $$ = $3; }
    29092924        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2910                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
     2925                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
    29112926        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    29122927                { $$ = $4; }
     
    29482963                {
    29492964                        typedefTable.addToScope( *$2, TYPEDEFname, "9" );
    2950                         if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
    2951                         if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
    2952                         if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
     2965                        if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
     2966                        if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     2967                        if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
    29532968                }
    29542969          type_initializer_opt assertion_list_opt
     
    29612976                {
    29622977                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2963                         $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
     2978                        $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
    29642979                }
    29652980        // | type_specifier identifier_parameter_declarator
    29662981        | assertion_list
    2967                 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2982                { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    29682983        ;
    29692984
    29702985new_type_class:                                                                                 // CFA
    29712986        // empty
    2972                 { $$ = TypeDecl::Otype; }
     2987                { $$ = ast::TypeDecl::Otype; }
    29732988        | '&'
    2974                 { $$ = TypeDecl::Dtype; }
     2989                { $$ = ast::TypeDecl::Dtype; }
    29752990        | '*'
    2976                 { $$ = TypeDecl::DStype; }                                              // dtype + sized
     2991                { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
    29772992        // | '(' '*' ')'
    2978         //      { $$ = TypeDecl::Ftype; }
     2993        //      { $$ = ast::TypeDecl::Ftype; }
    29792994        | ELLIPSIS
    2980                 { $$ = TypeDecl::Ttype; }
     2995                { $$ = ast::TypeDecl::Ttype; }
    29812996        ;
    29822997
    29832998type_class:                                                                                             // CFA
    29842999        OTYPE
    2985                 { $$ = TypeDecl::Otype; }
     3000                { $$ = ast::TypeDecl::Otype; }
    29863001        | DTYPE
    2987                 { $$ = TypeDecl::Dtype; }
     3002                { $$ = ast::TypeDecl::Dtype; }
    29883003        | FTYPE
    2989                 { $$ = TypeDecl::Ftype; }
     3004                { $$ = ast::TypeDecl::Ftype; }
    29903005        | TTYPE
    2991                 { $$ = TypeDecl::Ttype; }
     3006                { $$ = ast::TypeDecl::Ttype; }
    29923007        ;
    29933008
     
    30153030type_list:                                                                                              // CFA
    30163031        type
    3017                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3032                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    30183033        | assignment_expression
    30193034        | type_list ',' type
    3020                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3035                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    30213036        | type_list ',' assignment_expression
    30223037                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    31253140external_definition:
    31263141        DIRECTIVE
    3127                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
     3142                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
    31283143        | declaration
    31293144                {
     
    31313146                        // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is
    31323147                        // disallowed at the moment.
    3133                         if ( $1->linkage == LinkageSpec::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
     3148                        if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
    31343149                                if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
    31353150                                        SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
     
    31583173                }
    31593174        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3160                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, nullptr ) ) ); }
     3175                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
    31613176        | EXTERN STRINGliteral
    31623177                {
    31633178                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3164                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3179                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    31653180                }
    31663181          up external_definition down
     
    31733188                {
    31743189                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3175                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3190                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    31763191                }
    31773192          '{' up external_definition_list_opt down '}'
     
    32973312subrange:
    32983313        constant_expression '~' constant_expression                     // CFA, integer subrange
    3299                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     3314                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    33003315        ;
    33013316
     
    38263841array_type_list:
    38273842        basic_type_name
    3828                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3843                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    38293844        | type_name
    3830                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3845                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    38313846        | assignment_expression upupeq assignment_expression
    38323847        | array_type_list ',' basic_type_name
    3833                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    3834         | array_type_list ',' type_name 
    3835                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3848                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     3849        | array_type_list ',' type_name
     3850                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    38363851        | array_type_list ',' assignment_expression upupeq assignment_expression
    38373852        ;
  • TabularUnified src/Parser/parserutility.cc

    r4541b09 rbb7422a  
    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
  • TabularUnified src/Parser/parserutility.h

    r4541b09 rbb7422a  
    1010// Created On       : Sat May 16 15:31:46 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Mar  9 12:16:00 2023
    13 // Update Count     : 6
     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 );
    2124
    2225template< typename T >
     
    3235}
    3336
     37template<typename node_t>
     38node_t * maybeCopy( node_t const * node ) {
     39        return node ? ast::shallowCopy( node ) : nullptr;
     40}
     41
    3442// Local Variables: //
    3543// tab-width: 4 //
  • TabularUnified tests/.expect/attributes.arm64.txt

    r4541b09 rbb7422a  
    13511351signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0));
    13521352signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)());
    1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));
     1353signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0));
    13541354struct Vad {
    13551355    __attribute__ ((unused)) signed int :4;
  • TabularUnified tests/.expect/attributes.x64.txt

    r4541b09 rbb7422a  
    13511351signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0));
    13521352signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)());
    1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));
     1353signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0));
    13541354struct Vad {
    13551355    __attribute__ ((unused)) signed int :4;
  • TabularUnified tests/.expect/attributes.x86.txt

    r4541b09 rbb7422a  
    13511351signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0));
    13521352signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)());
    1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));
     1353signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0));
    13541354struct Vad {
    13551355    __attribute__ ((unused)) signed int :4;
  • TabularUnified tests/errors/.expect/declaration.txt

    r4541b09 rbb7422a  
    1 errors/declaration.cfa:16:1 error: duplicate static in declaration of x1: static const volatile short int
     1errors/declaration.cfa:16:1 error: duplicate static storage class(es) in declaration of x1: static const volatile short int
    22
    3 errors/declaration.cfa:17:1 error: conflicting extern & static in declaration of x2: extern const volatile short int
     3errors/declaration.cfa:17:1 error: conflicting extern & static storage classes in declaration of x2: extern const volatile short int
    44
    5 errors/declaration.cfa:18:1 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int
     5errors/declaration.cfa:18:1 error: conflicting extern & auto storage classes, conflicting extern & static storage classes, conflicting extern & static storage classes, duplicate extern storage class(es) in declaration of x3: extern const volatile short int
    66
    7 errors/declaration.cfa:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
     7errors/declaration.cfa:19:1 error: duplicate static storage class(es) in declaration of x4: static const volatile instance of const volatile struct __anonymous0
    88  with members
    99    i: int
     
    1111
    1212
    13 errors/declaration.cfa:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
     13errors/declaration.cfa:20:1 error: duplicate const qualifier(s), duplicate static storage class(es), duplicate volatile qualifier(s) in declaration of x5: static const volatile instance of const volatile struct __anonymous1
    1414  with members
    1515    i: int
     
    1717
    1818
    19 errors/declaration.cfa:22:1 error: duplicate static in declaration of x6: static const volatile Int
     19errors/declaration.cfa:22:1 error: duplicate static storage class(es) in declaration of x6: static const volatile Int
    2020
    21 errors/declaration.cfa:24:1 error: duplicate const in declaration of f01: static inline function
     21errors/declaration.cfa:24:1 error: duplicate const qualifier(s) in declaration of f01: static inline function
    2222  with no parameters
    2323  returning const volatile int
    2424
    2525
    26 errors/declaration.cfa:25:1 error: duplicate volatile in declaration of f02: static inline function
     26errors/declaration.cfa:25:1 error: duplicate volatile qualifier(s) in declaration of f02: static inline function
    2727  with no parameters
    2828  returning const volatile int
    2929
    3030
    31 errors/declaration.cfa:26:1 error: duplicate const in declaration of f03: static inline function
     31errors/declaration.cfa:26:1 error: duplicate const qualifier(s) in declaration of f03: static inline function
    3232  with no parameters
    3333  returning const volatile int
    3434
    3535
    36 errors/declaration.cfa:27:1 error: duplicate volatile in declaration of f04: static inline function
     36errors/declaration.cfa:27:1 error: duplicate volatile qualifier(s) in declaration of f04: static inline function
    3737  with no parameters
    3838  returning const volatile int
    3939
    4040
    41 errors/declaration.cfa:28:1 error: duplicate const in declaration of f05: static inline function
     41errors/declaration.cfa:28:1 error: duplicate const qualifier(s) in declaration of f05: static inline function
    4242  with no parameters
    4343  returning const volatile int
    4444
    4545
    46 errors/declaration.cfa:29:1 error: duplicate volatile in declaration of f06: static inline function
     46errors/declaration.cfa:29:1 error: duplicate volatile qualifier(s) in declaration of f06: static inline function
    4747  with no parameters
    4848  returning const volatile int
    4949
    5050
    51 errors/declaration.cfa:30:1 error: duplicate const in declaration of f07: static inline function
     51errors/declaration.cfa:30:1 error: duplicate const qualifier(s) in declaration of f07: static inline function
    5252  with no parameters
    5353  returning const volatile int
    5454
    5555
    56 errors/declaration.cfa:31:1 error: duplicate const, duplicate volatile in declaration of f08: static inline function
     56errors/declaration.cfa:31:1 error: duplicate const volatile qualifier(s) in declaration of f08: static inline function
    5757  with no parameters
    5858  returning const volatile int
    5959
    6060
    61 errors/declaration.cfa:33:1 error: duplicate const, duplicate volatile in declaration of f09: static inline function
     61errors/declaration.cfa:33:1 error: duplicate const volatile qualifier(s) in declaration of f09: static inline function
    6262  with no parameters
    6363  returning const volatile int
    6464
    6565
    66 errors/declaration.cfa:34:1 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function
     66errors/declaration.cfa:34:1 error: duplicate const qualifier(s), duplicate _Atomic qualifier(s), duplicate _Atomic qualifier(s), duplicate const restrict volatile qualifier(s) in declaration of f09: static inline function
    6767  with no parameters
    6868  returning const restrict volatile _Atomic int
Note: See TracChangeset for help on using the changeset viewer.