Changeset 3f840e3


Ignore:
Timestamp:
May 22, 2019, 1:00:36 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
9d23c2d, ed3935da
Parents:
461046f (diff), ed5e798 (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/iostream.cfa

    r461046f r3f840e3  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 19 10:48:27 2019
    13 // Update Count     : 654
     12// Last Modified On : Tue May 21 13:01:26 2019
     13// Update Count     : 674
    1414//
    1515
     
    154154        } // ?|?
    155155
    156         static void checkDecPt( ostype & os, const char * buf, int len ) {
    157                 for ( int i = 0;; i += 1 ) {
    158                         if ( i == len ) { fmt( os, "." ); break; }
    159                         if ( buf[i] == '.' ) break;
    160                 } // for
    161         } // checkDecPt
     156        #define PrintWithDP( os, format, val, ... ) \
     157                { \
     158                        enum { size = 48 }; \
     159                        char buf[size]; \
     160                        int len = snprintf( buf, size, format, ##__VA_ARGS__, val ); \
     161                        fmt( os, "%s", buf ); \
     162                        if ( isfinite( val ) ) {                                        /* if number, always print decimal point */ \
     163                                for ( int i = 0;; i += 1 ) { \
     164                                        if ( i == len ) { fmt( os, "." ); break; } \
     165                                        if ( buf[i] == '.' ) break; \
     166                                } /* for */ \
     167                        } /* if */ \
     168                }
    162169
    163170        ostype & ?|?( ostype & os, float f ) {
    164171                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    165                 char buf[48];
    166                 int len = snprintf( buf, 48, "%g", f );
    167                 fmt( os, "%s", buf );
    168                 if ( isfinite( f ) ) checkDecPt( os, buf, len ); // always print decimal point
     172                PrintWithDP( os, "%g", f );
    169173                return os;
    170174        } // ?|?
     
    175179        ostype & ?|?( ostype & os, double d ) {
    176180                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    177                 char buf[48];
    178                 int len = snprintf( buf, 48, "%.*lg", DBL_DIG, d );
    179                 fmt( os, "%s", buf );
    180                 if ( isfinite( d ) ) checkDecPt( os, buf, len ); // always print decimal point
     181                PrintWithDP( os, "%.*lg", d, DBL_DIG );
    181182                return os;
    182183        } // ?|?
     
    187188        ostype & ?|?( ostype & os, long double ld ) {
    188189                if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
    189                 char buf[48];
    190                 int len = snprintf( buf, 48, "%.*Lg", LDBL_DIG, ld );
    191                 fmt( os, "%s", buf );
    192                 if ( isfinite( ld ) ) checkDecPt( os, buf, len ); // always print decimal point
     190                PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
    193191                return os;
    194192        } // ?|?
     
    201199//              os | crealf( fc ) | nonl;
    202200                float f = crealf( fc );
    203                 char buf[48];
    204                 int len = snprintf( buf, 48, "%g", f );
    205                 fmt( os, "%s", buf );
    206                 if ( isfinite( f ) ) checkDecPt( os, buf, len ); // always print decimal point
     201                PrintWithDP( os, "%g", f );
    207202                f = cimagf( fc );
    208                 len = snprintf( buf, 48, "%+g", f );
    209                 fmt( os, "%s", buf );
    210                 if ( isfinite( f ) ) checkDecPt( os, buf, len ); // always print decimal point
     203                PrintWithDP( os, "%+g", f );
    211204                fmt( os, "i" );
    212205                return os;
     
    220213//              os | creal( dc ) | nonl;
    221214                double d = creal( dc );
    222                 char buf[48];
    223                 int len = snprintf( buf, 48, "%.*lg", DBL_DIG, d );
    224                 fmt( os, "%s", buf );
    225                 if ( isfinite( d ) ) checkDecPt( os, buf, len ); // always print decimal point
     215                PrintWithDP( os, "%.*lg", d, DBL_DIG );
    226216                d = cimag( dc );
    227                 len = snprintf( buf, 48, "%+.*lg", DBL_DIG, d );
    228                 fmt( os, "%s", buf );
    229                 if ( isfinite( d ) ) checkDecPt( os, buf, len ); // always print decimal point
     217                PrintWithDP( os, "%+.*lg", d, DBL_DIG );
    230218                fmt( os, "i" );
    231219                return os;
     
    239227//              os | creall( ldc ) || nonl;
    240228                long double ld = creall( ldc );
    241                 char buf[48];
    242                 int len = snprintf( buf, 48, "%.*Lg", LDBL_DIG, ld );
    243                 fmt( os, "%s", buf );
    244                 if ( isfinite( ld ) ) checkDecPt( os, buf, len ); // always print decimal point
     229                PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
    245230                ld = cimagl( ldc );
    246                 len = snprintf( buf, 48, "%+.*Lg", LDBL_DIG, ld );
    247                 fmt( os, "%s", buf );
    248                 if ( isfinite( ld ) ) checkDecPt( os, buf, len ); // always print decimal point
     231                PrintWithDP( os, "%+.*Lg", ld, LDBL_DIG );
    249232                fmt( os, "i" );
    250233                return os;
  • src/AST/Convert.cpp

    r461046f r3f840e3  
    1616#include "Convert.hpp"
    1717
     18#include <unordered_map>
     19
    1820#include "AST/Attribute.hpp"
    1921#include "AST/Decl.hpp"
     
    4244class ConverterNewToOld : public ast::Visitor {
    4345        BaseSyntaxNode * node = nullptr;
     46        using Cache = std::unordered_map< const ast::Node *, BaseSyntaxNode * >;
     47        Cache cache;
    4448
    4549        template<typename T>
     
    4751                ConverterNewToOld & visitor;
    4852
    49                 template<typename U>
    50                 T * accept1( const ast::ptr<U> & ptr ) {
     53                template<typename U, enum ast::Node::ref_type R>
     54                T * accept1( const ast::ptr_base<U, R> & ptr ) {
     55                        if ( ! ptr ) return nullptr;
    5156                        ptr->accept( visitor );
    5257                        T * ret = strict_dynamic_cast< T * >( visitor.node );
     
    8590                }
    8691                return ret;
     92        }
     93
     94        /// get new qualifiers from old type
     95        Type::Qualifiers cv( const ast::Type * ty ) { return { ty->qualifiers.val }; }
     96
     97        /// returns true and sets `node` if in cache
     98        bool inCache( const ast::Node * node ) {
     99                auto it = cache.find( node );
     100                if ( it == cache.end() ) return false;
     101                this->node = it->second;
     102                return true;
    87103        }
    88104
     
    112128                decl->isDeleted = node->isDeleted;
    113129                // fs comes from constructor
     130                cache.emplace( node, decl );
    114131                return nullptr;
    115132        }
    116133
    117134        const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
     135                if ( inCache( node ) ) return nullptr;
    118136                auto decl = new ObjectDecl(
    119137                        node->name,
     
    130148
    131149        const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
     150                if ( inCache( node ) ) return nullptr;
    132151                auto decl = new FunctionDecl(
    133152                        node->name,
     
    153172
    154173        const ast::Decl * visit( const ast::TypeDecl * node ) override final {
    155                 TypeDecl::Kind kind;
    156                 switch (node->kind) {
    157                 case ast::TypeVar::Dtype:
    158                         kind = TypeDecl::Dtype;
    159                         break;
    160                 case ast::TypeVar::Ftype:
    161                         kind = TypeDecl::Ftype;
    162                         break;
    163                 case ast::TypeVar::Ttype:
    164                         kind = TypeDecl::Ttype;
    165                         break;
    166                 default:
    167                         assertf(false, "Invalid ast::TypeVar::Kind: %d\n", node->kind);
    168                 };
     174                if ( inCache( node ) ) return nullptr;
    169175                auto decl = new TypeDecl(
    170176                        node->name,
    171177                        Type::StorageClasses( node->storage.val ),
    172178                        get<Type>().accept1( node->base ),
    173                         kind,
     179                        (TypeDecl::Kind)(unsigned)node->kind,
    174180                        node->sized,
    175181                        get<Type>().accept1( node->init )
    176182                );
     183                cache.emplace( node, decl );
    177184                return namedTypePostamble( decl, node );
    178185        }
     
    194201                decl->body = node->body;
    195202                // attributes come from constructor
    196                 // TODO: Need caching for: decl->parent = node->parent;
     203                decl->parent = get<AggregateDecl>().accept1( node->parent );
     204                cache.emplace( node, decl );
    197205                return nullptr;
    198206        }
    199207
    200208        const ast::Decl * visit( const ast::StructDecl * node ) override final {
     209                if ( inCache( node ) ) return nullptr;
    201210                auto decl = new StructDecl(
    202211                        node->name,
     
    209218
    210219        const ast::Decl * visit( const ast::UnionDecl * node ) override final {
     220                if ( inCache( node ) ) return nullptr;
    211221                auto decl = new UnionDecl(
    212222                        node->name,
     
    218228
    219229        const ast::Decl * visit( const ast::EnumDecl * node ) override final {
     230                if ( inCache( node ) ) return nullptr;
    220231                auto decl = new EnumDecl(
    221232                        node->name,
     
    227238
    228239        const ast::Decl * visit( const ast::TraitDecl * node ) override final {
     240                if ( inCache( node ) ) return nullptr;
    229241                auto decl = new TraitDecl(
    230242                        node->name,
     
    559571
    560572        const ast::Expr * visit( const ast::AddressExpr * node ) override final {
    561                 (void)node;
     573                auto expr = visitBaseExpr( node,
     574                        new AddressExpr(
     575                                get<Expression>().accept1(node->arg)
     576                        )
     577                );
     578                this->node = expr;
    562579                return nullptr;
    563580        }
    564581
    565582        const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
    566                 (void)node;
     583                auto expr = visitBaseExpr( node,
     584                        new LabelAddressExpr(
     585                                makeLabel(nullptr, node->arg)
     586                        )
     587                );
     588                this->node = expr;
    567589                return nullptr;
    568590        }
    569591
    570592        const ast::Expr * visit( const ast::CastExpr * node ) override final {
    571                 (void)node;
     593                auto expr = visitBaseExpr( node,
     594                        new CastExpr(
     595                                get<Expression>().accept1(node->arg),
     596                                (node->isGenerated == ast::GeneratedCast)
     597                        )
     598                );
     599                this->node = expr;
    572600                return nullptr;
    573601        }
    574602
    575603        const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
    576                 (void)node;
     604                KeywordCastExpr::Target castTarget = KeywordCastExpr::NUMBER_OF_TARGETS;
     605                switch (node->target) {
     606                        case ast::KeywordCastExpr::Coroutine:
     607                                castTarget = KeywordCastExpr::Coroutine;
     608                                break;
     609                        case ast::KeywordCastExpr::Thread:
     610                                castTarget = KeywordCastExpr::Thread;
     611                                break;
     612                        case ast::KeywordCastExpr::Monitor:
     613                                castTarget = KeywordCastExpr::Monitor;
     614                                break;
     615                        default:
     616                                break;
     617                }
     618                assert ( castTarget < KeywordCastExpr::NUMBER_OF_TARGETS );
     619                auto expr = visitBaseExpr( node,
     620                        new KeywordCastExpr(
     621                                get<Expression>().accept1(node->arg),
     622                                castTarget
     623                        )
     624                );
     625                this->node = expr;
    577626                return nullptr;
    578627        }
    579628
    580629        const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
    581                 (void)node;
     630                auto expr = visitBaseExpr( node,
     631                        new VirtualCastExpr(
     632                                get<Expression>().accept1(node->arg),
     633                                nullptr // cast's "to" type is expr's result type; converted in visitBaseExpr
     634                        )
     635                );
     636                this->node = expr;
    582637                return nullptr;
    583638        }
    584639
    585640        const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
    586                 (void)node;
     641                auto expr = visitBaseExpr( node,
     642                        new UntypedMemberExpr(
     643                                get<Expression>().accept1(node->member),
     644                                get<Expression>().accept1(node->aggregate)
     645                        )
     646                );
     647                this->node = expr;
    587648                return nullptr;
    588649        }
    589650
    590651        const ast::Expr * visit( const ast::MemberExpr * node ) override final {
    591                 (void)node;
     652                auto expr = visitBaseExpr( node,
     653                        new MemberExpr(
     654                                inCache(node->member) ?
     655                                        dynamic_cast<DeclarationWithType *>(this->node) :
     656                                        get<DeclarationWithType>().accept1(node->member),
     657                                get<Expression>().accept1(node->aggregate)
     658                        )
     659                );
     660                this->node = expr;
    592661                return nullptr;
    593662        }
    594663
    595664        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
    596                 (void)node;
    597                 return nullptr;
     665                auto expr = visitBaseExpr( node,
     666                        new VariableExpr(
     667                                inCache(node->var) ?
     668                                        dynamic_cast<DeclarationWithType *>(this->node) :
     669                                        get<DeclarationWithType>().accept1(node->var)
     670                        )
     671                );
     672                this->node = expr;
     673                return nullptr;
     674        }
     675
     676        bool isIntlikeConstantType(const ast::Type *t) {
     677                if ( const ast::BasicType * basicType = dynamic_cast< const ast::BasicType * >( t ) ) {
     678                        if ( basicType->isInteger() ) {
     679                                return true;
     680                        }
     681                } else if ( dynamic_cast< const ast::OneType * >( t ) ) {
     682                        return true;
     683                } else if ( dynamic_cast< const ast::ZeroType * >( t ) ) {
     684                        return true;
     685                } else if ( dynamic_cast< const ast::PointerType * >( t ) ) {
     686                        // null pointer constants, with zero int-values
     687                        return true;
     688                }
     689                return false;
     690        }
     691
     692        bool isFloatlikeConstantType(const ast::Type *t) {
     693                if ( const ast::BasicType * bty = dynamic_cast< const ast::BasicType * >( t ) ) {
     694                        if ( ! bty->isInteger() ) {
     695                                return true;
     696                        }
     697                }
     698                return false;
     699        }
     700
     701        bool isStringlikeConstantType(const ast::Type *t) {
     702                if ( const ast::ArrayType * aty = dynamic_cast< const ast::ArrayType * >( t ) ) {
     703                        if ( const ast::BasicType * bty = aty->base.as<ast::BasicType>() ) {
     704                           if ( bty->kind == ast::BasicType::Kind::Char ) {
     705                                   return true;
     706                           }
     707                        }
     708                }
     709                return false;
    598710        }
    599711
    600712        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
    601                 (void)node;
     713                ConstantExpr *rslt = nullptr;
     714                if (isIntlikeConstantType(node->result)) {
     715                        rslt = new ConstantExpr(Constant(
     716                                get<Type>().accept1(node->result),
     717                                node->rep,
     718                                (unsigned long long) node->intValue()
     719                        ));
     720                } else if (isFloatlikeConstantType(node->result)) {
     721                        rslt = new ConstantExpr(Constant(
     722                                get<Type>().accept1(node->result),
     723                                node->rep,
     724                                (double) node->floatValue()
     725                        ));
     726                } else if (isStringlikeConstantType(node->result)) {
     727                        rslt = new ConstantExpr(Constant::from_string(
     728                                node->rep
     729                        ));
     730                }
     731                assert(rslt);
     732                auto expr = visitBaseExpr( node, rslt );
     733                this->node = expr;
    602734                return nullptr;
    603735        }
    604736
    605737        const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
    606                 (void)node;
     738                assert (node->expr || node->type);
     739                assert (! (node->expr && node->type));
     740                SizeofExpr *rslt;
     741                if (node->expr) {
     742                        rslt = new SizeofExpr(
     743                                get<Expression>().accept1(node->expr)
     744                        );
     745                        assert (!rslt->isType);
     746                }
     747                if (node->type) {
     748                        rslt = new SizeofExpr(
     749                                get<Type>().accept1(node->type)
     750                        );
     751                        assert (rslt->isType);
     752                }
     753                auto expr = visitBaseExpr( node, rslt );
     754                this->node = expr;
    607755                return nullptr;
    608756        }
    609757
    610758        const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
    611                 (void)node;
     759                assert (node->expr || node->type);
     760                assert (! (node->expr && node->type));
     761                AlignofExpr *rslt;
     762                if (node->expr) {
     763                        rslt = new AlignofExpr(
     764                                get<Expression>().accept1(node->expr)
     765                        );
     766                        assert (!rslt->isType);
     767                }
     768                if (node->type) {
     769                        rslt = new AlignofExpr(
     770                                get<Type>().accept1(node->type)
     771                        );
     772                        assert (rslt->isType);
     773                }
     774                auto expr = visitBaseExpr( node, rslt );
     775                this->node = expr;
    612776                return nullptr;
    613777        }
    614778
    615779        const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
    616                 (void)node;
     780                auto expr = visitBaseExpr( node,
     781                        new UntypedOffsetofExpr(
     782                                get<Type>().accept1(node->type),
     783                                node->member
     784                        )
     785                );
     786                this->node = expr;
    617787                return nullptr;
    618788        }
    619789
    620790        const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
    621                 (void)node;
     791                auto expr = visitBaseExpr( node,
     792                        new OffsetofExpr(
     793                                get<Type>().accept1(node->type),
     794                                inCache(node->member) ?
     795                                        dynamic_cast<DeclarationWithType *>(this->node) :
     796                                        get<DeclarationWithType>().accept1(node->member)
     797                        )
     798                );
     799                this->node = expr;
    622800                return nullptr;
    623801        }
    624802
    625803        const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
    626                 (void)node;
     804                auto expr = visitBaseExpr( node,
     805                        new OffsetPackExpr(
     806                                get<StructInstType>().accept1(node->type)
     807                        )
     808                );
     809                this->node = expr;
    627810                return nullptr;
    628811        }
    629812
    630813        const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
    631                 (void)node;
     814                assert (node->isAnd == ast::LogicalFlag::AndExpr ||
     815                                node->isAnd == ast::LogicalFlag::OrExpr );
     816                auto expr = visitBaseExpr( node,
     817                        new LogicalExpr(
     818                                get<Expression>().accept1(node->arg1),
     819                                get<Expression>().accept1(node->arg2),
     820                                (node->isAnd == ast::LogicalFlag::AndExpr)
     821                        )
     822                );
     823                this->node = expr;
    632824                return nullptr;
    633825        }
    634826
    635827        const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
    636                 (void)node;
     828                auto expr = visitBaseExpr( node,
     829                        new ConditionalExpr(
     830                                get<Expression>().accept1(node->arg1),
     831                                get<Expression>().accept1(node->arg2),
     832                                get<Expression>().accept1(node->arg3)
     833                        )
     834                );
     835                this->node = expr;
    637836                return nullptr;
    638837        }
    639838
    640839        const ast::Expr * visit( const ast::CommaExpr * node ) override final {
    641                 (void)node;
     840                auto expr = visitBaseExpr( node,
     841                        new CommaExpr(
     842                                get<Expression>().accept1(node->arg1),
     843                                get<Expression>().accept1(node->arg2)
     844                        )
     845                );
     846                this->node = expr;
    642847                return nullptr;
    643848        }
     
    729934
    730935        const ast::Type * visit( const ast::VoidType * node ) override final {
    731                 (void)node;
     936                this->node = new VoidType{ cv( node ) };
    732937                return nullptr;
    733938        }
    734939
    735940        const ast::Type * visit( const ast::BasicType * node ) override final {
    736                 (void)node;
     941                this->node = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind };
    737942                return nullptr;
    738943        }
    739944
    740945        const ast::Type * visit( const ast::PointerType * node ) override final {
    741                 (void)node;
     946                this->node = new PointerType{
     947                        cv( node ),
     948                        get<Type>().accept1( node->base ),
     949                        get<Expression>().accept1( node->dimension ),
     950                        (bool)node->isVarLen,
     951                        (bool)node->isStatic
     952                };
    742953                return nullptr;
    743954        }
    744955
    745956        const ast::Type * visit( const ast::ArrayType * node ) override final {
    746                 (void)node;
     957                this->node = new ArrayType{
     958                        cv( node ),
     959                        get<Type>().accept1( node->base ),
     960                        get<Expression>().accept1( node->dimension ),
     961                        (bool)node->isVarLen,
     962                        (bool)node->isStatic
     963                };
    747964                return nullptr;
    748965        }
    749966
    750967        const ast::Type * visit( const ast::ReferenceType * node ) override final {
    751                 (void)node;
     968                this->node = new ReferenceType{
     969                        cv( node ),
     970                        get<Type>().accept1( node->base )
     971                };
    752972                return nullptr;
    753973        }
    754974
    755975        const ast::Type * visit( const ast::QualifiedType * node ) override final {
    756                 (void)node;
     976                this->node = new QualifiedType{
     977                        cv( node ),
     978                        get<Type>().accept1( node->parent ),
     979                        get<Type>().accept1( node->child )
     980                };
    757981                return nullptr;
    758982        }
    759983
    760984        const ast::Type * visit( const ast::FunctionType * node ) override final {
    761                 (void)node;
    762                 return nullptr;
     985                auto ty = new FunctionType {
     986                        cv( node ),
     987                        (bool)node->isVarArgs
     988                };
     989                ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
     990                ty->parameters = get<DeclarationWithType>().acceptL( node->params );
     991                ty->forall = get<TypeDecl>().acceptL( node->forall );
     992                this->node = ty;
     993                return nullptr;
     994        }
     995
     996        void postvisit( const ast::ReferenceToType * old, ReferenceToType * ty ) {
     997                ty->forall = get<TypeDecl>().acceptL( old->forall );
     998                ty->parameters = get<Expression>().acceptL( old->params );
     999                ty->hoistType = old->hoistType;
    7631000        }
    7641001
    7651002        const ast::Type * visit( const ast::StructInstType * node ) override final {
    766                 (void)node;
     1003                StructInstType * ty;
     1004                if ( node->base ) {
     1005                        ty = new StructInstType{
     1006                                cv( node ),
     1007                                get<StructDecl>().accept1( node->base ),
     1008                                get<Attribute>().acceptL( node->attributes )
     1009                        };
     1010                } else {
     1011                        ty = new StructInstType{
     1012                                cv( node ),
     1013                                node->name,
     1014                                get<Attribute>().acceptL( node->attributes )
     1015                        };
     1016                }
     1017                postvisit( node, ty );
     1018                this->node = ty;
    7671019                return nullptr;
    7681020        }
    7691021
    7701022        const ast::Type * visit( const ast::UnionInstType * node ) override final {
    771                 (void)node;
     1023                UnionInstType * ty;
     1024                if ( node->base ) {
     1025                        ty = new UnionInstType{
     1026                                cv( node ),
     1027                                get<UnionDecl>().accept1( node->base ),
     1028                                get<Attribute>().acceptL( node->attributes )
     1029                        };
     1030                } else {
     1031                        ty = new UnionInstType{
     1032                                cv( node ),
     1033                                node->name,
     1034                                get<Attribute>().acceptL( node->attributes )
     1035                        };
     1036                }
     1037                postvisit( node, ty );
     1038                this->node = ty;
    7721039                return nullptr;
    7731040        }
    7741041
    7751042        const ast::Type * visit( const ast::EnumInstType * node ) override final {
    776                 (void)node;
     1043                EnumInstType * ty;
     1044                if ( node->base ) {
     1045                        ty = new EnumInstType{
     1046                                cv( node ),
     1047                                get<EnumDecl>().accept1( node->base ),
     1048                                get<Attribute>().acceptL( node->attributes )
     1049                        };
     1050                } else {
     1051                        ty = new EnumInstType{
     1052                                cv( node ),
     1053                                node->name,
     1054                                get<Attribute>().acceptL( node->attributes )
     1055                        };
     1056                }
     1057                postvisit( node, ty );
     1058                this->node = ty;
    7771059                return nullptr;
    7781060        }
    7791061
    7801062        const ast::Type * visit( const ast::TraitInstType * node ) override final {
    781                 (void)node;
     1063                TraitInstType * ty;
     1064                if ( node->base ) {
     1065                        ty = new TraitInstType{
     1066                                cv( node ),
     1067                                get<TraitDecl>().accept1( node->base ),
     1068                                get<Attribute>().acceptL( node->attributes )
     1069                        };
     1070                } else {
     1071                        ty = new TraitInstType{
     1072                                cv( node ),
     1073                                node->name,
     1074                                get<Attribute>().acceptL( node->attributes )
     1075                        };
     1076                }
     1077                postvisit( node, ty );
     1078                this->node = ty;
    7821079                return nullptr;
    7831080        }
    7841081
    7851082        const ast::Type * visit( const ast::TypeInstType * node ) override final {
    786                 (void)node;
     1083                TypeInstType * ty;
     1084                if ( node->base ) {
     1085                        ty = new TypeInstType{
     1086                                cv( node ),
     1087                                node->name,
     1088                                get<TypeDecl>().accept1( node->base ),
     1089                                get<Attribute>().acceptL( node->attributes )
     1090                        };
     1091                } else {
     1092                        ty = new TypeInstType{
     1093                                cv( node ),
     1094                                node->name,
     1095                                node->kind == ast::TypeVar::Ftype,
     1096                                get<Attribute>().acceptL( node->attributes )
     1097                        };
     1098                }
     1099                postvisit( node, ty );
     1100                this->node = ty;
    7871101                return nullptr;
    7881102        }
    7891103
    7901104        const ast::Type * visit( const ast::TupleType * node ) override final {
    791                 (void)node;
     1105                this->node = new TupleType{
     1106                        cv( node ),
     1107                        get<Type>().acceptL( node->types )
     1108                        // members generated by TupleType c'tor
     1109                };
    7921110                return nullptr;
    7931111        }
    7941112
    7951113        const ast::Type * visit( const ast::TypeofType * node ) override final {
    796                 (void)node;
     1114                this->node = new TypeofType{
     1115                        cv( node ),
     1116                        get<Expression>().accept1( node->expr ),
     1117                        (bool)node->kind
     1118                };
    7971119                return nullptr;
    7981120        }
    7991121
    8001122        const ast::Type * visit( const ast::VarArgsType * node ) override final {
    801                 (void)node;
     1123                this->node = new VarArgsType{ cv( node ) };
    8021124                return nullptr;
    8031125        }
    8041126
    8051127        const ast::Type * visit( const ast::ZeroType * node ) override final {
    806                 (void)node;
     1128                this->node = new ZeroType{ cv( node ) };
    8071129                return nullptr;
    8081130        }
    8091131
    8101132        const ast::Type * visit( const ast::OneType * node ) override final {
    811                 (void)node;
    812                 return nullptr;
    813         }
    814 
    815         const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
    816                 (void)node;
     1133                this->node = new OneType{ cv( node ) };
     1134                return nullptr;
     1135        }
     1136
     1137        const ast::Type * visit( const ast::GlobalScopeType * ) override final {
     1138                this->node = new GlobalScopeType{};
    8171139                return nullptr;
    8181140        }
     
    8671189        }
    8681190private:
     1191        /// conversion output
    8691192        ast::Node * node;
     1193        /// cache of nodes that might be referenced by readonly<> for de-duplication
     1194        std::unordered_map< BaseSyntaxNode *, ast::Node * > cache;
    8701195
    8711196        // Local Utilities:
     
    8731198        template<typename NewT, typename OldT>
    8741199        NewT * getAccept1( OldT old ) {
     1200                if ( ! old ) return nullptr;
    8751201                old->accept(*this);
    8761202                return strict_dynamic_cast< NewT * >( node );
     
    9131239#       define GET_LABELS_V(labels) \
    9141240                to<std::vector>::from( make_labels( std::move( labels ) ) )
     1241       
     1242        static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
     1243
     1244        /// returns true and sets `node` if in cache
     1245        bool inCache( BaseSyntaxNode * old ) {
     1246                auto it = cache.find( old );
     1247                if ( it == cache.end() ) return false;
     1248                node = it->second;
     1249                return true;
     1250        }
    9151251
    9161252        // Now all the visit functions:
    9171253
    9181254        virtual void visit( ObjectDecl * old ) override final {
     1255                if ( inCache( old ) ) return;
    9191256                auto decl = new ast::ObjectDecl(
    9201257                        old->location,
     
    9331270                decl->uniqueId   = old->uniqueId;
    9341271                decl->extension  = old->extension;
     1272                cache.emplace( old, decl );
    9351273
    9361274                this->node = decl;
    9371275        }
    9381276
    939         virtual void visit( FunctionDecl * ) override final {
    940 
     1277        virtual void visit( FunctionDecl * old ) override final {
     1278                if ( inCache( old ) ) return;
     1279                // TODO
     1280                auto decl = (ast::FunctionDecl *)nullptr;
     1281                cache.emplace( old, decl );
    9411282        }
    9421283
    9431284        virtual void visit( StructDecl * old ) override final {
     1285                if ( inCache( old ) ) return;
    9441286                auto decl = new ast::StructDecl(
    9451287                        old->location,
     
    9561298                decl->uniqueId   = old->uniqueId;
    9571299                decl->storage    = { old->storageClasses.val };
     1300                cache.emplace( old, decl );
    9581301
    9591302                this->node = decl;
     
    9611304
    9621305        virtual void visit( UnionDecl * old ) override final {
     1306                if ( inCache( old ) ) return;
    9631307                auto decl = new ast::UnionDecl(
    9641308                        old->location,
     
    9741318                decl->uniqueId   = old->uniqueId;
    9751319                decl->storage    = { old->storageClasses.val };
     1320                cache.emplace( old, decl );
    9761321
    9771322                this->node = decl;
     
    9791324
    9801325        virtual void visit( EnumDecl * old ) override final {
     1326                if ( inCache( old ) ) return;
    9811327                auto decl = new ast::UnionDecl(
    9821328                        old->location,
     
    9921338                decl->uniqueId   = old->uniqueId;
    9931339                decl->storage    = { old->storageClasses.val };
     1340                cache.emplace( old, decl );
    9941341
    9951342                this->node = decl;
     
    9971344
    9981345        virtual void visit( TraitDecl * old ) override final {
     1346                if ( inCache( old ) ) return;
    9991347                auto decl = new ast::UnionDecl(
    10001348                        old->location,
     
    10101358                decl->uniqueId   = old->uniqueId;
    10111359                decl->storage    = { old->storageClasses.val };
     1360                cache.emplace( old, decl );
    10121361
    10131362                this->node = decl;
    10141363        }
    10151364
    1016         virtual void visit( TypeDecl * ) override final {
    1017 
     1365        virtual void visit( TypeDecl * old ) override final {
     1366                if ( inCache( old ) ) return;
     1367                // TODO
     1368                auto decl = (ast::TypeDecl *)nullptr;
     1369                cache.emplace( old, decl );
    10181370        }
    10191371
     
    13881740                        new ast::CastExpr(
    13891741                                old->location,
    1390                                 nullptr, // cast's "to" type is expr's result type; converted in visitBaseExpr
     1742                                GET_ACCEPT_1(arg, Expr),
    13911743                                old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
    13921744                        )
     
    13941746        }
    13951747
    1396         virtual void visit( KeywordCastExpr * ) override final {
    1397 
    1398         }
    1399 
    1400         virtual void visit( VirtualCastExpr * ) override final {
    1401 
    1402         }
    1403 
    1404         virtual void visit( AddressExpr * ) override final {
    1405 
    1406         }
    1407 
    1408         virtual void visit( LabelAddressExpr * ) override final {
    1409 
    1410         }
    1411 
    1412         virtual void visit( UntypedMemberExpr * ) override final {
    1413 
    1414         }
    1415 
    1416         virtual void visit( MemberExpr * ) override final {
    1417 
    1418         }
    1419 
    1420         virtual void visit( VariableExpr * ) override final {
    1421 
    1422         }
    1423 
    1424         virtual void visit( ConstantExpr * ) override final {
    1425 
    1426         }
    1427 
    1428         virtual void visit( SizeofExpr * ) override final {
    1429 
    1430         }
    1431 
    1432         virtual void visit( AlignofExpr * ) override final {
    1433 
    1434         }
    1435 
    1436         virtual void visit( UntypedOffsetofExpr * ) override final {
    1437 
    1438         }
    1439 
    1440         virtual void visit( OffsetofExpr * ) override final {
    1441 
    1442         }
    1443 
    1444         virtual void visit( OffsetPackExpr * ) override final {
    1445 
    1446         }
    1447 
    1448         virtual void visit( LogicalExpr * ) override final {
    1449 
    1450         }
    1451 
    1452         virtual void visit( ConditionalExpr * ) override final {
    1453 
    1454         }
    1455 
    1456         virtual void visit( CommaExpr * ) override final {
    1457 
     1748        virtual void visit( KeywordCastExpr * old) override final {
     1749                ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
     1750                switch (old->target) {
     1751                        case KeywordCastExpr::Coroutine:
     1752                                castTarget = ast::KeywordCastExpr::Coroutine;
     1753                                break;
     1754                        case KeywordCastExpr::Thread:
     1755                                castTarget = ast::KeywordCastExpr::Thread;
     1756                                break;
     1757                        case KeywordCastExpr::Monitor:
     1758                                castTarget = ast::KeywordCastExpr::Monitor;
     1759                                break;
     1760                        default:
     1761                                break;
     1762                }
     1763                assert ( castTarget < ast::KeywordCastExpr::NUMBER_OF_TARGETS );
     1764                this->node = visitBaseExpr( old,
     1765                        new ast::KeywordCastExpr(
     1766                                old->location,
     1767                                GET_ACCEPT_1(arg, Expr),
     1768                                castTarget
     1769                        )
     1770                );
     1771        }
     1772
     1773        virtual void visit( VirtualCastExpr * old ) override final {
     1774                this->node = visitBaseExpr( old,
     1775                        new ast::VirtualCastExpr(
     1776                                old->location,
     1777                                GET_ACCEPT_1(arg, Expr),
     1778                                nullptr // cast's "to" type is expr's result type; converted in visitBaseExpr
     1779                        )
     1780                );
     1781        }
     1782
     1783        virtual void visit( AddressExpr * old ) override final {
     1784                this->node = visitBaseExpr( old,
     1785                        new ast::AddressExpr(
     1786                                old->location,
     1787                                GET_ACCEPT_1(arg, Expr)
     1788                        )
     1789                );
     1790        }
     1791
     1792        virtual void visit( LabelAddressExpr * old ) override final {
     1793                this->node = visitBaseExpr( old,
     1794                        new ast::LabelAddressExpr(
     1795                                old->location,
     1796                                make_label(&old->arg)
     1797                        )
     1798                );
     1799        }
     1800
     1801        virtual void visit( UntypedMemberExpr * old ) override final {
     1802                this->node = visitBaseExpr( old,
     1803                        new ast::UntypedMemberExpr(
     1804                                old->location,
     1805                                GET_ACCEPT_1(member, Expr),
     1806                                GET_ACCEPT_1(aggregate, Expr)
     1807                        )
     1808                );
     1809        }
     1810
     1811        virtual void visit( MemberExpr * old ) override final {
     1812                this->node = visitBaseExpr( old,
     1813                        new ast::MemberExpr(
     1814                                old->location,
     1815                                inCache(old->member) ?
     1816                                        dynamic_cast<ast::DeclWithType *>(this->node) :
     1817                                        GET_ACCEPT_1(member, DeclWithType),
     1818                                GET_ACCEPT_1(aggregate, Expr)
     1819                        )
     1820                );
     1821        }
     1822
     1823        virtual void visit( VariableExpr * old ) override final {
     1824                this->node = visitBaseExpr( old,
     1825                        new ast::VariableExpr(
     1826                                old->location,
     1827                                inCache(old->var) ?
     1828                                        dynamic_cast<ast::DeclWithType *>(this->node) :
     1829                                        GET_ACCEPT_1(var, DeclWithType)
     1830                        )
     1831                );
     1832        }
     1833
     1834        bool isIntlikeConstantType(const Type *t) {
     1835                if ( const BasicType * basicType = dynamic_cast< const BasicType * >( t ) ) {
     1836                        if ( basicType->isInteger() ) {
     1837                                return true;
     1838                        }
     1839                } else if ( dynamic_cast< const OneType * >( t ) ) {
     1840                        return true;
     1841                } else if ( dynamic_cast< const ZeroType * >( t ) ) {
     1842                        return true;
     1843                } else if ( dynamic_cast< const PointerType * >( t ) ) {
     1844                        // null pointer constants, with zero int-values
     1845                        return true;
     1846                }
     1847                return false;
     1848        }
     1849
     1850        int isFloatlikeConstantType(const Type *t) {
     1851                if ( const BasicType * bty = dynamic_cast< const BasicType * >( t ) ) {
     1852                        if ( ! bty->isInteger() ) {
     1853                                return true;
     1854                        }
     1855                }
     1856                return false;
     1857        }
     1858
     1859        int isStringlikeConstantType(const Type *t) {
     1860                if ( const ArrayType * aty = dynamic_cast< const ArrayType * >( t ) ) {
     1861                        if ( const BasicType * bty = dynamic_cast< const BasicType * >( aty->base ) ) {
     1862                           if ( bty->kind == BasicType::Kind::Char ) {
     1863                                   return true;
     1864                           }
     1865                        }
     1866                }
     1867                return false;
     1868        }
     1869
     1870        virtual void visit( ConstantExpr * old ) override final {
     1871                ast::ConstantExpr *rslt = nullptr;
     1872                if (isIntlikeConstantType(old->result)) {
     1873                        rslt = new ast::ConstantExpr(
     1874                                old->location,
     1875                                GET_ACCEPT_1(result, Type),
     1876                                old->constant.get_value(),
     1877                                (unsigned long long) old->intValue()
     1878                        );
     1879                } else if (isFloatlikeConstantType(old->result)) {
     1880                        rslt = new ast::ConstantExpr(
     1881                                old->location,
     1882                                GET_ACCEPT_1(result, Type),
     1883                                old->constant.get_value(),
     1884                                (double) old->constant.get_dval()
     1885                        );
     1886                } else if (isStringlikeConstantType(old->result)) {
     1887                        rslt = ast::ConstantExpr::from_string(
     1888                                old->location,
     1889                                old->constant.get_value()
     1890                        );
     1891                }
     1892                assert(rslt);
     1893                this->node = visitBaseExpr( old, rslt );
     1894        }
     1895
     1896        virtual void visit( SizeofExpr * old ) override final {
     1897                assert (old->expr || old->type);
     1898                assert (! (old->expr && old->type));
     1899                ast::SizeofExpr *rslt;
     1900                if (old->expr) {
     1901                        assert(!old->isType);
     1902                        rslt = new ast::SizeofExpr(
     1903                                old->location,
     1904                                GET_ACCEPT_1(expr, Expr)
     1905                        );
     1906                }
     1907                if (old->type) {
     1908                        assert(old->isType);
     1909                        rslt = new ast::SizeofExpr(
     1910                                old->location,
     1911                                GET_ACCEPT_1(type, Type)
     1912                        );
     1913                }
     1914                this->node = visitBaseExpr( old, rslt );
     1915        }
     1916
     1917        virtual void visit( AlignofExpr * old ) override final {
     1918                assert (old->expr || old->type);
     1919                assert (! (old->expr && old->type));
     1920                ast::AlignofExpr *rslt;
     1921                if (old->expr) {
     1922                        assert(!old->isType);
     1923                        rslt = new ast::AlignofExpr(
     1924                                old->location,
     1925                                GET_ACCEPT_1(expr, Expr)
     1926                        );
     1927                }
     1928                if (old->type) {
     1929                        assert(old->isType);
     1930                        rslt = new ast::AlignofExpr(
     1931                                old->location,
     1932                                GET_ACCEPT_1(type, Type)
     1933                        );
     1934                }
     1935                this->node = visitBaseExpr( old, rslt );
     1936        }
     1937
     1938        virtual void visit( UntypedOffsetofExpr * old ) override final {
     1939                this->node = visitBaseExpr( old,
     1940                        new ast::UntypedOffsetofExpr(
     1941                                old->location,
     1942                                GET_ACCEPT_1(type, Type),
     1943                                old->member
     1944                        )
     1945                );
     1946        }
     1947
     1948        virtual void visit( OffsetofExpr * old ) override final {
     1949                this->node = visitBaseExpr( old,
     1950                        new ast::OffsetofExpr(
     1951                                old->location,
     1952                                GET_ACCEPT_1(type, Type),
     1953                                inCache(old->member) ?
     1954                                        dynamic_cast<ast::DeclWithType *>(this->node) :
     1955                                        GET_ACCEPT_1(member, DeclWithType)
     1956                        )
     1957                );
     1958        }
     1959
     1960        virtual void visit( OffsetPackExpr * old ) override final {
     1961                this->node = visitBaseExpr( old,
     1962                        new ast::OffsetPackExpr(
     1963                                old->location,
     1964                                GET_ACCEPT_1(type, StructInstType)
     1965                        )
     1966                );
     1967        }
     1968
     1969        virtual void visit( LogicalExpr * old ) override final {
     1970                this->node = visitBaseExpr( old,
     1971                        new ast::LogicalExpr(
     1972                                old->location,
     1973                                GET_ACCEPT_1(arg1, Expr),
     1974                                GET_ACCEPT_1(arg2, Expr),
     1975                                old->get_isAnd() ?
     1976                                        ast::LogicalFlag::AndExpr :
     1977                                        ast::LogicalFlag::OrExpr
     1978                        )
     1979                );
     1980        }
     1981
     1982        virtual void visit( ConditionalExpr * old ) override final {
     1983                this->node = visitBaseExpr( old,
     1984                        new ast::ConditionalExpr(
     1985                                old->location,
     1986                                GET_ACCEPT_1(arg1, Expr),
     1987                                GET_ACCEPT_1(arg2, Expr),
     1988                                GET_ACCEPT_1(arg3, Expr)
     1989                        )
     1990                );
     1991        }
     1992
     1993        virtual void visit( CommaExpr * old ) override final {
     1994                this->node = visitBaseExpr( old,
     1995                        new ast::CommaExpr(
     1996                                old->location,
     1997                                GET_ACCEPT_1(arg1, Expr),
     1998                                GET_ACCEPT_1(arg2, Expr)
     1999                        )
     2000                );
    14582001        }
    14592002
     
    15262069        }
    15272070
    1528         virtual void visit( VoidType * ) override final {
    1529 
    1530         }
    1531 
    1532         virtual void visit( BasicType * ) override final {
    1533 
    1534         }
    1535 
    1536         virtual void visit( PointerType * ) override final {
    1537 
    1538         }
    1539 
    1540         virtual void visit( ArrayType * ) override final {
    1541 
    1542         }
    1543 
    1544         virtual void visit( ReferenceType * ) override final {
    1545 
    1546         }
    1547 
    1548         virtual void visit( QualifiedType * ) override final {
    1549 
    1550         }
    1551 
    1552         virtual void visit( FunctionType * ) override final {
    1553 
    1554         }
    1555 
    1556         virtual void visit( StructInstType * ) override final {
    1557 
    1558         }
    1559 
    1560         virtual void visit( UnionInstType * ) override final {
    1561 
    1562         }
    1563 
    1564         virtual void visit( EnumInstType * ) override final {
    1565 
    1566         }
    1567 
    1568         virtual void visit( TraitInstType * ) override final {
    1569 
    1570         }
    1571 
    1572         virtual void visit( TypeInstType * ) override final {
    1573 
    1574         }
    1575 
    1576         virtual void visit( TupleType * ) override final {
    1577 
    1578         }
    1579 
    1580         virtual void visit( TypeofType * ) override final {
    1581 
     2071        virtual void visit( VoidType * old ) override final {
     2072                this->node = new ast::VoidType{ cv( old ) };
     2073        }
     2074
     2075        virtual void visit( BasicType * old ) override final {
     2076                this->node = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
     2077        }
     2078
     2079        virtual void visit( PointerType * old ) override final {
     2080                this->node = new ast::PointerType{
     2081                        GET_ACCEPT_1( base, Type ),
     2082                        GET_ACCEPT_1( dimension, Expr ),
     2083                        (ast::LengthFlag)old->isVarLen,
     2084                        (ast::DimensionFlag)old->isStatic,
     2085                        cv( old )
     2086                };
     2087        }
     2088
     2089        virtual void visit( ArrayType * old ) override final {
     2090                this->node = new ast::ArrayType{
     2091                        GET_ACCEPT_1( base, Type ),
     2092                        GET_ACCEPT_1( dimension, Expr ),
     2093                        (ast::LengthFlag)old->isVarLen,
     2094                        (ast::DimensionFlag)old->isStatic,
     2095                        cv( old )
     2096                };
     2097        }
     2098
     2099        virtual void visit( ReferenceType * old ) override final {
     2100                this->node = new ast::ReferenceType{
     2101                        GET_ACCEPT_1( base, Type ),
     2102                        cv( old )
     2103                };
     2104        }
     2105
     2106        virtual void visit( QualifiedType * old ) override final {
     2107                this->node = new ast::QualifiedType{
     2108                        GET_ACCEPT_1( parent, Type ),
     2109                        GET_ACCEPT_1( child, Type ),
     2110                        cv( old )
     2111                };
     2112        }
     2113
     2114        virtual void visit( FunctionType * old ) override final {
     2115                auto ty = new ast::FunctionType {
     2116                        (ast::ArgumentFlag)old->isVarArgs,
     2117                        cv( old )
     2118                };
     2119                ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
     2120                ty->params = GET_ACCEPT_V( parameters, DeclWithType );
     2121                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
     2122                this->node = ty;
     2123        }
     2124
     2125        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
     2126                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
     2127                ty->params = GET_ACCEPT_V( parameters, Expr );
     2128                ty->hoistType = old->hoistType;
     2129        }
     2130
     2131        virtual void visit( StructInstType * old ) override final {
     2132                ast::StructInstType * ty;
     2133                if ( old->baseStruct ) {
     2134                        ty = new ast::StructInstType{
     2135                                GET_ACCEPT_1( baseStruct, StructDecl ),
     2136                                cv( old ),
     2137                                GET_ACCEPT_V( attributes, Attribute )
     2138                        };
     2139                } else {
     2140                        ty = new ast::StructInstType{
     2141                                old->name,
     2142                                cv( old ),
     2143                                GET_ACCEPT_V( attributes, Attribute )
     2144                        };
     2145                }
     2146                postvisit( old, ty );
     2147                this->node = ty;
     2148        }
     2149
     2150        virtual void visit( UnionInstType * old ) override final {
     2151                ast::UnionInstType * ty;
     2152                if ( old->baseUnion ) {
     2153                        ty = new ast::UnionInstType{
     2154                                GET_ACCEPT_1( baseUnion, UnionDecl ),
     2155                                cv( old ),
     2156                                GET_ACCEPT_V( attributes, Attribute )
     2157                        };
     2158                } else {
     2159                        ty = new ast::UnionInstType{
     2160                                old->name,
     2161                                cv( old ),
     2162                                GET_ACCEPT_V( attributes, Attribute )
     2163                        };
     2164                }
     2165                postvisit( old, ty );
     2166                this->node = ty;
     2167        }
     2168
     2169        virtual void visit( EnumInstType * old ) override final {
     2170                ast::EnumInstType * ty;
     2171                if ( old->baseEnum ) {
     2172                        ty = new ast::EnumInstType{
     2173                                GET_ACCEPT_1( baseEnum, EnumDecl ),
     2174                                cv( old ),
     2175                                GET_ACCEPT_V( attributes, Attribute )
     2176                        };
     2177                } else {
     2178                        ty = new ast::EnumInstType{
     2179                                old->name,
     2180                                cv( old ),
     2181                                GET_ACCEPT_V( attributes, Attribute )
     2182                        };
     2183                }
     2184                postvisit( old, ty );
     2185                this->node = ty;
     2186        }
     2187
     2188        virtual void visit( TraitInstType * old ) override final {
     2189                ast::TraitInstType * ty;
     2190                if ( old->baseTrait ) {
     2191                        ty = new ast::TraitInstType{
     2192                                GET_ACCEPT_1( baseTrait, TraitDecl ),
     2193                                cv( old ),
     2194                                GET_ACCEPT_V( attributes, Attribute )
     2195                        };
     2196                } else {
     2197                        ty = new ast::TraitInstType{
     2198                                old->name,
     2199                                cv( old ),
     2200                                GET_ACCEPT_V( attributes, Attribute )
     2201                        };
     2202                }
     2203                postvisit( old, ty );
     2204                this->node = ty;
     2205        }
     2206
     2207        virtual void visit( TypeInstType * old ) override final {
     2208                ast::TypeInstType * ty;
     2209                if ( old->baseType ) {
     2210                        ty = new ast::TypeInstType{
     2211                                old->name,
     2212                                GET_ACCEPT_1( baseType, TypeDecl ),
     2213                                cv( old ),
     2214                                GET_ACCEPT_V( attributes, Attribute )
     2215                        };
     2216                } else {
     2217                        ty = new ast::TypeInstType{
     2218                                old->name,
     2219                                old->isFtype ? ast::TypeVar::Ftype : ast::TypeVar::Dtype,
     2220                                cv( old ),
     2221                                GET_ACCEPT_V( attributes, Attribute )
     2222                        };
     2223                }
     2224                postvisit( old, ty );
     2225                this->node = ty;
     2226        }
     2227
     2228        virtual void visit( TupleType * old ) override final {
     2229                this->node = new ast::TupleType{
     2230                        GET_ACCEPT_V( types, Type ),
     2231                        // members generated by TupleType c'tor
     2232                        cv( old )
     2233                };
     2234        }
     2235
     2236        virtual void visit( TypeofType * old ) override final {
     2237                this->node = new ast::TypeofType{
     2238                        GET_ACCEPT_1( expr, Expr ),
     2239                        (ast::TypeofType::Kind)old->is_basetypeof,
     2240                        cv( old )
     2241                };
    15822242        }
    15832243
    15842244        virtual void visit( AttrType * ) override final {
    1585 
    1586         }
    1587 
    1588         virtual void visit( VarArgsType * ) override final {
    1589 
    1590         }
    1591 
    1592         virtual void visit( ZeroType * ) override final {
    1593 
    1594         }
    1595 
    1596         virtual void visit( OneType * ) override final {
    1597 
     2245                assertf( false, "AttrType deprecated in new AST." );
     2246        }
     2247
     2248        virtual void visit( VarArgsType * old ) override final {
     2249                this->node = new ast::VarArgsType{ cv( old ) };
     2250        }
     2251
     2252        virtual void visit( ZeroType * old ) override final {
     2253                this->node = new ast::ZeroType{ cv( old ) };
     2254        }
     2255
     2256        virtual void visit( OneType * old ) override final {
     2257                this->node = new ast::OneType{ cv( old ) };
    15982258        }
    15992259
    16002260        virtual void visit( GlobalScopeType * ) override final {
    1601 
     2261                this->node = new ast::GlobalScopeType{};
    16022262        }
    16032263
  • src/AST/Type.cpp

    r461046f r3f840e3  
    141141bool EnumInstType::isComplete() const { return base ? base->body : false; }
    142142
     143// --- TraitInstType
     144
     145TraitInstType::TraitInstType( const TraitDecl * b, CV::Qualifiers q,
     146        std::vector<ptr<Attribute>>&& as )
     147: ReferenceToType( b->name, q, std::move(as) ), base( b ) {}
     148
    143149// --- TypeInstType
    144150
  • src/AST/Type.hpp

    r461046f r3f840e3  
    514514class GlobalScopeType final : public Type {
    515515public:
    516         GlobalScopeType( CV::Qualifiers q = {} ) : Type( q ) {}
     516        GlobalScopeType() : Type() {}
    517517
    518518        const Type * accept( Visitor & v ) const override { return v.visit( this ); }
Note: See TracChangeset for help on using the changeset viewer.