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

Merge branch 'master' into ast-experimental

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/TypeData.cc

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