source: src/AST/Convert.cpp @ 6a1dfda

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 6a1dfda was 6896548, checked in by Michael Brooks <mlbrooks@…>, 5 years ago

Fixed convert-convert issues with strings, when conversion happens after resolve. Three specific issues fixed.

  1. String literals were not roundtripping new-old-new with the original type at the constant level, whereas the resolver changes the expression-level type from array to pointer.
  2. String literals were roundtripping with noise on a "--print astexpr" diff, with the char-array's index type coming up signed int (expecting unsigned long long int).
  3. Function calls that pass a foo[] variable as argument to a foo* formal were crashing on copy-constructor generation because convert-convert was changing the arg-expression type from foo* (set by the resolver, as expecteed) back to foo[], taken from the variable (switched to foo* taken from convert-src expression).
  • Property mode set to 100644
File size: 73.1 KB
RevLine 
[6d51bd7]1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[74dbbf6]7// Convert.cpp -- Convert between the new and old syntax trees.
[6d51bd7]8//
9// Author           : Thierry Delisle
10// Created On       : Thu May 09 15::37::05 2019
[6f8e87d]11// Last Modified By : Andrew Beach
[a62749f]12// Last Modified On : Man Jun 10 11:51:00 2019
13// Update Count     : 11
[6d51bd7]14//
15
16#include "Convert.hpp"
17
[60aaa51d]18#include <deque>
[d148778]19#include <unordered_map>
20
[6d51bd7]21#include "AST/Attribute.hpp"
22#include "AST/Decl.hpp"
23#include "AST/Expr.hpp"
24#include "AST/Init.hpp"
25#include "AST/Stmt.hpp"
[172d9342]26#include "AST/TypeSubstitution.hpp"
[6d51bd7]27
[157a816]28#include "SymTab/Autogen.h"
[6d51bd7]29#include "SynTree/Attribute.h"
30#include "SynTree/Declaration.h"
[172d9342]31#include "SynTree/TypeSubstitution.h"
[6d51bd7]32
[0aedb01]33#include "Validate/FindSpecialDecls.h"
34
[6d51bd7]35//================================================================================================
36// Utilities
37template<template <class...> class C>
38struct to {
39        template<typename T>
40        static auto from( T && v ) -> C< typename T::value_type > {
41                C< typename T::value_type > l;
42                std::move(std::begin(v), std::end(v), std::back_inserter(l));
43                return l;
44        }
45};
46
[157a816]47//================================================================================================
48namespace {
49
[043a5b6]50// This is to preserve the FindSpecialDecls hack. It does not (and perhaps should not)
[157a816]51// allow us to use the same stratagy in the new ast.
[2a54479]52ast::Type * sizeType = nullptr;
[157a816]53ast::FunctionDecl * dereferenceOperator = nullptr;
[043a5b6]54ast::StructDecl   * dtorStruct = nullptr;
55ast::FunctionDecl * dtorStructDestroy = nullptr;
[157a816]56
57}
58
[6d51bd7]59//================================================================================================
[74dbbf6]60class ConverterNewToOld : public ast::Visitor {
[675d816]61        BaseSyntaxNode * node = nullptr;
[b869ec5]62        using Cache = std::unordered_map< const ast::Node *, BaseSyntaxNode * >;
63        Cache cache;
[675d816]64
[74dbbf6]65        template<typename T>
[675d816]66        struct Getter {
67                ConverterNewToOld & visitor;
68
[514a791]69                template<typename U, enum ast::Node::ref_type R>
70                T * accept1( const ast::ptr_base<U, R> & ptr ) {
[d148778]71                        if ( ! ptr ) return nullptr;
[675d816]72                        ptr->accept( visitor );
73                        T * ret = strict_dynamic_cast< T * >( visitor.node );
74                        visitor.node = nullptr;
75                        return ret;
76                }
77
78                template<typename U>
79                std::list< T * > acceptL( const U & container ) {
80                        std::list< T * > ret;
[d76c588]81                        for ( auto ptr : container ) {
[675d816]82                                ret.emplace_back( accept1( ptr ) );
83                        }
84                        return ret;
85                }
86        };
87
88    template<typename T>
89    Getter<T> get() {
90        return Getter<T>{ *this };
91    }
92
93        Label makeLabel(Statement * labelled, const ast::Label& label) {
[a62749f]94                // This probably will leak memory, but only until we get rid of the old tree.
95                if ( nullptr == labelled && label.location.isSet() ) {
96                        labelled = new NullStmt();
97                        labelled->location = label.location;
98                }
[675d816]99                return Label(
100                        label.name,
101                        labelled,
102                        get<Attribute>().acceptL(label.attributes)
103                );
104        }
105
106        template<template <class...> class C>
107        std::list<Label> makeLabelL(Statement * labelled, const C<ast::Label>& labels) {
108                std::list<Label> ret;
109                for (auto label : labels) {
110                        ret.push_back( makeLabel(labelled, label) );
111                }
[74dbbf6]112                return ret;
113        }
114
[d148778]115        /// get new qualifiers from old type
116        Type::Qualifiers cv( const ast::Type * ty ) { return { ty->qualifiers.val }; }
117
[b869ec5]118        /// returns true and sets `node` if in cache
119        bool inCache( const ast::Node * node ) {
120                auto it = cache.find( node );
121                if ( it == cache.end() ) return false;
122                this->node = it->second;
123                return true;
[d148778]124        }
125
[675d816]126public:
127        Declaration * decl( const ast::Decl * declNode ) {
128                return get<Declaration>().accept1( ast::ptr<ast::Decl>( declNode ) );
129        }
[74dbbf6]130
[675d816]131private:
[112fe04]132        void declPostamble( Declaration * decl, const ast::Decl * node ) {
133                decl->location = node->location;
134                // name comes from constructor
135                // linkage comes from constructor
136                decl->extension = node->extension;
137                decl->uniqueId = node->uniqueId;
138                // storageClasses comes from constructor
139                this->node = decl;
140        }
141
142        const ast::DeclWithType * declWithTypePostamble (
143                        DeclarationWithType * decl, const ast::DeclWithType * node ) {
[f685679]144                cache.emplace( node, decl );
[112fe04]145                decl->mangleName = node->mangleName;
146                decl->scopeLevel = node->scopeLevel;
147                decl->asmName = get<Expression>().accept1( node->asmName );
148                // attributes comes from constructor
149                decl->isDeleted = node->isDeleted;
150                // fs comes from constructor
[f685679]151                declPostamble( decl, node );
[74dbbf6]152                return nullptr;
153        }
154
[112fe04]155        const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
[546e712]156                auto&& bfwd = get<Expression>().accept1( node->bitfieldWidth );
157                auto&& type = get<Type>().accept1( node->type );
158                auto&& init = get<Initializer>().accept1( node->init );
159                auto&& attr = get<Attribute>().acceptL( node->attributes );
160                if ( inCache( node ) ) {
161                        return nullptr;
162                }
[112fe04]163                auto decl = new ObjectDecl(
164                        node->name,
165                        Type::StorageClasses( node->storage.val ),
166                        LinkageSpec::Spec( node->linkage.val ),
[546e712]167                        bfwd,
168                        type,
169                        init,
170                        attr,
[112fe04]171                        Type::FuncSpecifiers( node->funcSpec.val )
172                );
173                return declWithTypePostamble( decl, node );
174        }
175
[74dbbf6]176        const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
[b869ec5]177                if ( inCache( node ) ) return nullptr;
[112fe04]178                auto decl = new FunctionDecl(
179                        node->name,
180                        Type::StorageClasses( node->storage.val ),
181                        LinkageSpec::Spec( node->linkage.val ),
182                        get<FunctionType>().accept1( node->type ),
[d88f8b3b]183                        {},
[112fe04]184                        get<Attribute>().acceptL( node->attributes ),
185                        Type::FuncSpecifiers( node->funcSpec.val )
186                );
[d88f8b3b]187                cache.emplace( node, decl );
188                decl->statements = get<CompoundStmt>().accept1( node->stmts );
[112fe04]189                decl->withExprs = get<Expression>().acceptL( node->withExprs );
[157a816]190                if ( dereferenceOperator == node ) {
[0aedb01]191                        Validate::dereferenceOperator = decl;
[157a816]192                }
[043a5b6]193                if ( dtorStructDestroy == node ) {
194                        Validate::dtorStructDestroy = decl;
195                }
[112fe04]196                return declWithTypePostamble( decl, node );
[74dbbf6]197        }
198
[112fe04]199        const ast::Decl * namedTypePostamble( NamedTypeDecl * decl, const ast::NamedTypeDecl * node ) {
200                // base comes from constructor
201                decl->parameters = get<TypeDecl>().acceptL( node->params );
202                decl->assertions = get<DeclarationWithType>().acceptL( node->assertions );
[f685679]203                declPostamble( decl, node );
[74dbbf6]204                return nullptr;
205        }
206
[112fe04]207        const ast::Decl * visit( const ast::TypeDecl * node ) override final {
[b869ec5]208                if ( inCache( node ) ) return nullptr;
[112fe04]209                auto decl = new TypeDecl(
210                        node->name,
211                        Type::StorageClasses( node->storage.val ),
212                        get<Type>().accept1( node->base ),
[b869ec5]213                        (TypeDecl::Kind)(unsigned)node->kind,
[112fe04]214                        node->sized,
215                        get<Type>().accept1( node->init )
216                );
[b869ec5]217                cache.emplace( node, decl );
[112fe04]218                return namedTypePostamble( decl, node );
[74dbbf6]219        }
220
[112fe04]221        const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
222                auto decl = new TypedefDecl(
223                        node->name,
224                        node->location,
225                        Type::StorageClasses( node->storage.val ),
226            get<Type>().accept1( node->base ),
227                        LinkageSpec::Spec( node->linkage.val )
228                );
229                return namedTypePostamble( decl, node );
[74dbbf6]230        }
231
[112fe04]232        const ast::Decl * aggregatePostamble( AggregateDecl * decl, const ast::AggregateDecl * node ) {
[f685679]233                cache.emplace( node, decl );
[112fe04]234                decl->members = get<Declaration>().acceptL( node->members );
235                decl->parameters = get<TypeDecl>().acceptL( node->params );
236                decl->body = node->body;
237                // attributes come from constructor
[b869ec5]238                decl->parent = get<AggregateDecl>().accept1( node->parent );
[f685679]239                declPostamble( decl, node );
[74dbbf6]240                return nullptr;
241        }
242
[112fe04]243        const ast::Decl * visit( const ast::StructDecl * node ) override final {
[b869ec5]244                if ( inCache( node ) ) return nullptr;
[112fe04]245                auto decl = new StructDecl(
246                        node->name,
247                        node->kind,
248                        get<Attribute>().acceptL( node->attributes ),
249                        LinkageSpec::Spec( node->linkage.val )
250                );
[043a5b6]251
252                if ( dtorStruct == node ) {
253                        Validate::dtorStruct = decl;
254                }
255
[112fe04]256                return aggregatePostamble( decl, node );
[74dbbf6]257        }
258
[112fe04]259        const ast::Decl * visit( const ast::UnionDecl * node ) override final {
[b869ec5]260                if ( inCache( node ) ) return nullptr;
[112fe04]261                auto decl = new UnionDecl(
262                        node->name,
263                        get<Attribute>().acceptL( node->attributes ),
264                        LinkageSpec::Spec( node->linkage.val )
265                );
266                return aggregatePostamble( decl, node );
267        }
268
269        const ast::Decl * visit( const ast::EnumDecl * node ) override final {
[b869ec5]270                if ( inCache( node ) ) return nullptr;
[112fe04]271                auto decl = new EnumDecl(
272                        node->name,
273                        get<Attribute>().acceptL( node->attributes ),
274                        LinkageSpec::Spec( node->linkage.val )
275                );
276                return aggregatePostamble( decl, node );
277        }
278
279        const ast::Decl * visit( const ast::TraitDecl * node ) override final {
[b869ec5]280                if ( inCache( node ) ) return nullptr;
[112fe04]281                auto decl = new TraitDecl(
282                        node->name,
283                        {},
284                        LinkageSpec::Spec( node->linkage.val )
285                );
286                return aggregatePostamble( decl, node );
[74dbbf6]287        }
288
289        const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
[112fe04]290                auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) );
291                declPostamble( decl, node );
[74dbbf6]292                return nullptr;
293        }
294
295        const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
[112fe04]296                auto decl = new StaticAssertDecl(
297                        get<Expression>().accept1( node->cond ),
298                        get<ConstantExpr>().accept1( node->msg )
299                );
300                declPostamble( decl, node );
[74dbbf6]301                return nullptr;
302        }
303
[112fe04]304        const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) {
[f685679]305                cache.emplace( node, stmt );
[675d816]306                stmt->location = node->location;
307                stmt->labels = makeLabelL( stmt, node->labels );
308                this->node = stmt;
[74dbbf6]309                return nullptr;
310        }
311
[112fe04]312        const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
[4073b16]313                if ( inCache( node ) ) return nullptr;
[112fe04]314                auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) );
315                stmtPostamble( stmt, node );
316                return nullptr;
317        }
318
[74dbbf6]319        const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
[4073b16]320                if ( inCache( node ) ) return nullptr;
[f685679]321                auto stmt = new ExprStmt( nullptr );
322                cache.emplace( node, stmt );
323                stmt->expr = get<Expression>().accept1( node->expr );
[112fe04]324                return stmtPostamble( stmt, node );
[74dbbf6]325        }
326
327        const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
[4073b16]328                if ( inCache( node ) ) return nullptr;
[675d816]329                auto stmt = new AsmStmt(
330                        node->isVolatile,
331                        get<Expression>().accept1( node->instruction ),
332                        get<Expression>().acceptL( node->output ),
333                        get<Expression>().acceptL( node->input ),
334                        get<ConstantExpr>().acceptL( node->clobber ),
335                        makeLabelL( nullptr, node->gotoLabels ) // What are these labelling?
336                );
[112fe04]337                return stmtPostamble( stmt, node );
[74dbbf6]338        }
339
340        const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
[4073b16]341                if ( inCache( node ) ) return nullptr;
[675d816]342                auto stmt = new DirectiveStmt( node->directive );
[112fe04]343                return stmtPostamble( stmt, node );
[74dbbf6]344        }
345
346        const ast::Stmt * visit( const ast::IfStmt * node ) override final {
[4073b16]347                if ( inCache( node ) ) return nullptr;
[675d816]348                auto stmt = new IfStmt(
349                        get<Expression>().accept1( node->cond ),
350                        get<Statement>().accept1( node->thenPart ),
351                        get<Statement>().accept1( node->elsePart ),
352                        get<Statement>().acceptL( node->inits )
353                );
[112fe04]354                return stmtPostamble( stmt, node );
[74dbbf6]355        }
356
[675d816]357        const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
[4073b16]358                if ( inCache( node ) ) return nullptr;
[675d816]359                auto stmt = new SwitchStmt(
360                        get<Expression>().accept1( node->cond ),
361                        get<Statement>().acceptL( node->stmts )
362                );
[112fe04]363                return stmtPostamble( stmt, node );
[74dbbf6]364        }
365
[675d816]366        const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
[4073b16]367                if ( inCache( node ) ) return nullptr;
[675d816]368                auto stmt = new CaseStmt(
369                        get<Expression>().accept1( node->cond ),
370                        get<Statement>().acceptL( node->stmts ),
371                        node->isDefault()
372                );
[112fe04]373                return stmtPostamble( stmt, node );
[74dbbf6]374        }
375
[675d816]376        const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
[4073b16]377                if ( inCache( node ) ) return nullptr;
[675d816]378                auto inits = get<Statement>().acceptL( node->inits );
379                auto stmt = new WhileStmt(
380                        get<Expression>().accept1( node->cond ),
381                        get<Statement>().accept1( node->body ),
382                        inits,
383                        node->isDoWhile
384                );
[112fe04]385                return stmtPostamble( stmt, node );
[74dbbf6]386        }
387
[675d816]388        const ast::Stmt * visit( const ast::ForStmt * node ) override final {
[4073b16]389                if ( inCache( node ) ) return nullptr;
[675d816]390                auto stmt = new ForStmt(
391                        get<Statement>().acceptL( node->inits ),
392                        get<Expression>().accept1( node->cond ),
393                        get<Expression>().accept1( node->inc ),
394                        get<Statement>().accept1( node->body )
395                );
[112fe04]396                return stmtPostamble( stmt, node );
[74dbbf6]397        }
398
399        const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
[4073b16]400                if ( inCache( node ) ) return nullptr;
[675d816]401                BranchStmt * stmt;
402                if (node->computedTarget) {
403                        stmt = new BranchStmt( get<Expression>().accept1( node->computedTarget ),
404                                BranchStmt::Goto );
405                } else {
406                        BranchStmt::Type type;
407                        switch (node->kind) {
408                        #define CASE(n) \
409                        case ast::BranchStmt::n: \
410                                type = BranchStmt::n; \
411                                break
412                        CASE(Goto);
413                        CASE(Break);
414                        CASE(Continue);
415                        CASE(FallThrough);
416                        CASE(FallThroughDefault);
417                        #undef CASE
418                        default:
419                                assertf(false, "Invalid ast::BranchStmt::Kind: %d\n", node->kind);
420                        }
421
422                        // The labels here are also weird.
423                        stmt = new BranchStmt( makeLabel( nullptr, node->originalTarget ), type );
424                        stmt->target = makeLabel( stmt, node->target );
425                }
[112fe04]426                return stmtPostamble( stmt, node );
[74dbbf6]427        }
428
429        const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
[4073b16]430                if ( inCache( node ) ) return nullptr;
[675d816]431                auto stmt = new ReturnStmt( get<Expression>().accept1( node->expr ) );
[112fe04]432                return stmtPostamble( stmt, node );
[74dbbf6]433        }
434
435        const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
[4073b16]436                if ( inCache( node ) ) return nullptr;
[675d816]437                ThrowStmt::Kind kind;
438                switch (node->kind) {
[6f4b7f2]439                case ast::ExceptionKind::Terminate:
[675d816]440                        kind = ThrowStmt::Terminate;
441                        break;
[6f4b7f2]442                case ast::ExceptionKind::Resume:
[675d816]443                        kind = ThrowStmt::Resume;
444                        break;
445                default:
446                        assertf(false, "Invalid ast::ThrowStmt::Kind: %d\n", node->kind);
447                }
448                auto stmt = new ThrowStmt(
449                        kind,
450                        get<Expression>().accept1( node->expr ),
451                        get<Expression>().accept1( node->target )
452                );
[112fe04]453                return stmtPostamble( stmt, node );
[74dbbf6]454        }
455
456        const ast::Stmt * visit( const ast::TryStmt * node ) override final {
[4073b16]457                if ( inCache( node ) ) return nullptr;
[675d816]458                auto handlers = get<CatchStmt>().acceptL( node->handlers );
459                auto stmt = new TryStmt(
460                        get<CompoundStmt>().accept1( node->body ),
461                        handlers,
462                        get<FinallyStmt>().accept1( node->finally )
463                );
[112fe04]464                return stmtPostamble( stmt, node );
[74dbbf6]465        }
466
467        const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
[4073b16]468                if ( inCache( node ) ) return nullptr;
[675d816]469                CatchStmt::Kind kind;
470                switch (node->kind) {
[6f4b7f2]471                case ast::ExceptionKind::Terminate:
[675d816]472                        kind = CatchStmt::Terminate;
473                        break;
[6f4b7f2]474                case ast::ExceptionKind::Resume:
[675d816]475                        kind = CatchStmt::Resume;
476                        break;
477                default:
478                        assertf(false, "Invalid ast::CatchStmt::Kind: %d\n", node->kind);
479                }
480                auto stmt = new CatchStmt(
481                        kind,
482                        get<Declaration>().accept1( node->decl ),
483                        get<Expression>().accept1( node->cond ),
484                        get<Statement>().accept1( node->body )
485                );
[112fe04]486                return stmtPostamble( stmt, node );
[74dbbf6]487        }
488
489        const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
[4073b16]490                if ( inCache( node ) ) return nullptr;
[675d816]491                auto stmt = new FinallyStmt( get<CompoundStmt>().accept1( node->body ) );
[112fe04]492                return stmtPostamble( stmt, node );
[74dbbf6]493        }
494
495        const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
[4073b16]496                if ( inCache( node ) ) return nullptr;
[675d816]497                auto stmt = new WaitForStmt;
498                stmt->clauses.reserve( node->clauses.size() );
499                for ( auto clause : node->clauses ) {
500                        stmt->clauses.push_back({{
[e0016a5]501                                        get<Expression>().accept1( clause.target.func ),
502                                        get<Expression>().acceptL( clause.target.args ),
[675d816]503                                },
504                                get<Statement>().accept1( clause.stmt ),
505                                get<Expression>().accept1( clause.cond ),
506                        });
507                }
508                stmt->timeout = {
509                        get<Expression>().accept1( node->timeout.time ),
510                        get<Statement>().accept1( node->timeout.stmt ),
511                        get<Expression>().accept1( node->timeout.cond ),
512                };
513                stmt->orelse = {
514                        get<Statement>().accept1( node->orElse.stmt ),
515                        get<Expression>().accept1( node->orElse.cond ),
516                };
[112fe04]517                return stmtPostamble( stmt, node );
[74dbbf6]518        }
519
520        const ast::Stmt * visit( const ast::WithStmt * node ) override final {
[4073b16]521                if ( inCache( node ) ) return nullptr;
[675d816]522                auto stmt = new WithStmt(
523                        get<Expression>().acceptL( node->exprs ),
524                        get<Statement>().accept1( node->stmt )
525                );
[112fe04]526                return stmtPostamble( stmt, node );
[74dbbf6]527        }
528
529        const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
[4073b16]530                if ( inCache( node ) ) return nullptr;
[675d816]531                auto stmt = new NullStmt();
[112fe04]532                stmtPostamble( stmt, node );
[74dbbf6]533                return nullptr;
534        }
535
536        const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
[4073b16]537                if ( inCache( node ) ) return nullptr;
[675d816]538                auto stmt = new DeclStmt( get<Declaration>().accept1( node->decl ) );
[112fe04]539                return stmtPostamble( stmt, node );
[74dbbf6]540        }
541
542        const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
[4073b16]543                if ( inCache( node ) ) return nullptr;
544                auto stmt = new ImplicitCtorDtorStmt{
545                        get<Statement>().accept1( node->callStmt )
546                };
547                return stmtPostamble( stmt, node );
[74dbbf6]548        }
549
[19e567dd]550        TypeSubstitution * convertTypeSubstitution(const ast::TypeSubstitution * src) {
551
[f685679]552                if (!src) return nullptr;
553
[19e567dd]554                TypeSubstitution *rslt = new TypeSubstitution();
555
556                for (decltype(src->begin()) src_i = src->begin(); src_i != src->end(); src_i++) {
557                        rslt->add( src_i->first,
558                                   get<Type>().accept1(src_i->second) );
559                }
560
561                for (decltype(src->beginVar()) src_i = src->beginVar(); src_i != src->endVar(); src_i++) {
562                        rslt->addVar( src_i->first,
563                                      get<Expression>().accept1(src_i->second) );
564                }
565
566                return rslt;
567        }
568
569        void convertInferUnion(std::map<UniqueId,ParamEntry> &tgtInferParams,
570                                                   std::vector<UniqueId>         &tgtResnSlots,
571                                                   const ast::Expr::InferUnion   &srcInferred ) {
572
573                assert( tgtInferParams.empty() );
574                assert( tgtResnSlots.empty() );
575
576                if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
[60aaa51d]577                        const ast::InferredParams &srcParams = srcInferred.inferParams();
[19e567dd]578                        for (auto srcParam : srcParams) {
579                                tgtInferParams[srcParam.first] = ParamEntry(
580                                        srcParam.second.decl,
[aaeacf4]581                                        get<Declaration>().accept1(srcParam.second.declptr),
[19e567dd]582                                        get<Type>().accept1(srcParam.second.actualType),
583                                        get<Type>().accept1(srcParam.second.formalType),
584                                        get<Expression>().accept1(srcParam.second.expr)
585                                );
586                        }
587                } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
[60aaa51d]588                        const ast::ResnSlots &srcSlots = srcInferred.resnSlots();
[19e567dd]589                        for (auto srcSlot : srcSlots) {
590                                tgtResnSlots.push_back(srcSlot);
591                        }
592                }
593        }
594
[20de6fb]595        Expression * visitBaseExpr_skipResultType(const ast::Expr * src, Expression * tgt) {
[19e567dd]596
[20de6fb]597                tgt->location  = src->location;
598                tgt->env       = convertTypeSubstitution(src->env);
[19e567dd]599                tgt->extension = src->extension;
600
[20de6fb]601                convertInferUnion(tgt->inferParams, tgt->resnSlots, src->inferred);
[19e567dd]602                return tgt;
603        }
604
[20de6fb]605        Expression * visitBaseExpr(const ast::Expr * src, Expression * tgt) {
606
607                tgt->result = get<Type>().accept1(src->result);
608                return visitBaseExpr_skipResultType(src, tgt);
609        }
610
[74dbbf6]611        const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
[19e567dd]612                auto expr = visitBaseExpr( node,
613                        new ApplicationExpr(
614                                get<Expression>().accept1(node->func),
615                                get<Expression>().acceptL(node->args)
616                        )
617                );
618                this->node = expr;
[74dbbf6]619                return nullptr;
620        }
621
622        const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
[19e567dd]623                auto expr = visitBaseExpr( node,
624                        new UntypedExpr(
625                                get<Expression>().accept1(node->func),
626                                get<Expression>().acceptL(node->args)
627                        )
628                );
629                this->node = expr;
[74dbbf6]630                return nullptr;
631        }
632
633        const ast::Expr * visit( const ast::NameExpr * node ) override final {
[19e567dd]634                auto expr = visitBaseExpr( node,
635                        new NameExpr(
636                                node->name
637                        )
638                );
639                this->node = expr;
[74dbbf6]640                return nullptr;
641        }
642
643        const ast::Expr * visit( const ast::AddressExpr * node ) override final {
[28c89f4]644                auto expr = visitBaseExpr( node,
645                        new AddressExpr(
646                                get<Expression>().accept1(node->arg)
647                        )
648                );
649                this->node = expr;
[74dbbf6]650                return nullptr;
651        }
652
653        const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
[28c89f4]654                auto expr = visitBaseExpr( node,
655                        new LabelAddressExpr(
656                                makeLabel(nullptr, node->arg)
657                        )
658                );
659                this->node = expr;
[74dbbf6]660                return nullptr;
661        }
662
663        const ast::Expr * visit( const ast::CastExpr * node ) override final {
[28c89f4]664                auto expr = visitBaseExpr( node,
665                        new CastExpr(
666                                get<Expression>().accept1(node->arg),
667                                (node->isGenerated == ast::GeneratedCast)
668                        )
669                );
670                this->node = expr;
[74dbbf6]671                return nullptr;
672        }
673
674        const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
[28c89f4]675                KeywordCastExpr::Target castTarget = KeywordCastExpr::NUMBER_OF_TARGETS;
676                switch (node->target) {
677                        case ast::KeywordCastExpr::Coroutine:
678                                castTarget = KeywordCastExpr::Coroutine;
679                                break;
680                        case ast::KeywordCastExpr::Thread:
681                                castTarget = KeywordCastExpr::Thread;
682                                break;
683                        case ast::KeywordCastExpr::Monitor:
684                                castTarget = KeywordCastExpr::Monitor;
685                                break;
686                        default:
687                                break;
688                }
689                assert ( castTarget < KeywordCastExpr::NUMBER_OF_TARGETS );
690                auto expr = visitBaseExpr( node,
691                        new KeywordCastExpr(
692                                get<Expression>().accept1(node->arg),
693                                castTarget
694                        )
695                );
696                this->node = expr;
[74dbbf6]697                return nullptr;
698        }
699
700        const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
[20de6fb]701                auto expr = visitBaseExpr_skipResultType( node,
[28c89f4]702                        new VirtualCastExpr(
703                                get<Expression>().accept1(node->arg),
[20de6fb]704                                get<Type>().accept1(node->result)
[28c89f4]705                        )
706                );
707                this->node = expr;
[74dbbf6]708                return nullptr;
709        }
710
711        const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
[28c89f4]712                auto expr = visitBaseExpr( node,
713                        new UntypedMemberExpr(
714                                get<Expression>().accept1(node->member),
715                                get<Expression>().accept1(node->aggregate)
716                        )
717                );
718                this->node = expr;
[74dbbf6]719                return nullptr;
720        }
721
722        const ast::Expr * visit( const ast::MemberExpr * node ) override final {
[28c89f4]723                auto expr = visitBaseExpr( node,
724                        new MemberExpr(
[2a54479]725                                get<DeclarationWithType>().accept1(node->member),
[28c89f4]726                                get<Expression>().accept1(node->aggregate)
727                        )
728                );
729                this->node = expr;
[74dbbf6]730                return nullptr;
731        }
732
733        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
[546e712]734                auto expr = new VariableExpr();
735                expr->var = get<DeclarationWithType>().accept1(node->var);
[6896548]736                visitBaseExpr( node, expr );
[28c89f4]737                this->node = expr;
[74dbbf6]738                return nullptr;
739        }
740
741        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
[28c89f4]742                ConstantExpr *rslt = nullptr;
[20a5977]743                switch ( node->kind ) {
744                case ast::ConstantExpr::Integer:
745                        rslt = new ConstantExpr{Constant{
746                                get<Type>().accept1( node->result ),
[28c89f4]747                                node->rep,
748                                (unsigned long long) node->intValue()
[20a5977]749                        }};
750                        break;
751                case ast::ConstantExpr::FloatingPoint:
752                        rslt = new ConstantExpr{Constant{
[28c89f4]753                                get<Type>().accept1(node->result),
754                                node->rep,
755                                (double) node->floatValue()
[20a5977]756                        }};
757                        break;
758                case ast::ConstantExpr::String:
[6896548]759                        // Old world:   two types: rslt->constant.type, rslt->result
760                        // New workd:   one type: node->result
761                        // Both worlds: the outer, expression-level type can change during resolution
762                        //              in case of string, that's char[k] before-resolve and char * after
763                        // Old world:   the inner Constant type stays what it was built with
764                        //              in case of string, that's char[k]
765                        // Both worlds: the "rep" field of a string constant is the string value it was initialized from, wrapped in quotes, but not otherwise escaped
766                        ast::ptr<ast::Type> charType = nullptr;
767                        if (const ast::ArrayType *arrRslt = node->result.as<ast::ArrayType>()) {
768                                charType = arrRslt->base;
769                        } else {
770                                const ast::PointerType *ptrRslt = node->result.as<ast::PointerType>();
771                                assert(ptrRslt);
772                                charType = ptrRslt->base;
773                        }
774                        rslt = new ConstantExpr(Constant::from_string(
775                                node->rep, get<Type>().accept1(charType)));          // rslt->result is char[k]
776                        rslt->set_result( get<Type>().accept1( node->result ) ); // rslt->result is [[ node->rsult ]]
[20a5977]777                        break;
[28c89f4]778                }
779                assert(rslt);
780                auto expr = visitBaseExpr( node, rslt );
781                this->node = expr;
[74dbbf6]782                return nullptr;
783        }
784
785        const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
[28c89f4]786                assert (node->expr || node->type);
787                assert (! (node->expr && node->type));
788                SizeofExpr *rslt;
789                if (node->expr) {
790                        rslt = new SizeofExpr(
791                                get<Expression>().accept1(node->expr)
792                        );
793                        assert (!rslt->isType);
794                }
[0b73f0c]795                else {
796                        assert(node->type);
[28c89f4]797                        rslt = new SizeofExpr(
798                                get<Type>().accept1(node->type)
799                        );
800                        assert (rslt->isType);
801                }
802                auto expr = visitBaseExpr( node, rslt );
803                this->node = expr;
[74dbbf6]804                return nullptr;
805        }
806
807        const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
[28c89f4]808                assert (node->expr || node->type);
809                assert (! (node->expr && node->type));
810                AlignofExpr *rslt;
811                if (node->expr) {
812                        rslt = new AlignofExpr(
813                                get<Expression>().accept1(node->expr)
814                        );
815                        assert (!rslt->isType);
816                }
[0b73f0c]817                else {
818                        assert(node->type);
[28c89f4]819                        rslt = new AlignofExpr(
820                                get<Type>().accept1(node->type)
821                        );
822                        assert (rslt->isType);
823                }
824                auto expr = visitBaseExpr( node, rslt );
825                this->node = expr;
[74dbbf6]826                return nullptr;
827        }
828
829        const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
[28c89f4]830                auto expr = visitBaseExpr( node,
831                        new UntypedOffsetofExpr(
832                                get<Type>().accept1(node->type),
833                                node->member
834                        )
835                );
836                this->node = expr;
[74dbbf6]837                return nullptr;
838        }
839
840        const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
[28c89f4]841                auto expr = visitBaseExpr( node,
842                        new OffsetofExpr(
843                                get<Type>().accept1(node->type),
[2a54479]844                                get<DeclarationWithType>().accept1(node->member)
[28c89f4]845                        )
846                );
847                this->node = expr;
[74dbbf6]848                return nullptr;
849        }
850
851        const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
[28c89f4]852                auto expr = visitBaseExpr( node,
853                        new OffsetPackExpr(
854                                get<StructInstType>().accept1(node->type)
855                        )
856                );
857                this->node = expr;
[74dbbf6]858                return nullptr;
859        }
860
861        const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
[28c89f4]862                assert (node->isAnd == ast::LogicalFlag::AndExpr ||
863                                node->isAnd == ast::LogicalFlag::OrExpr );
864                auto expr = visitBaseExpr( node,
865                        new LogicalExpr(
866                                get<Expression>().accept1(node->arg1),
867                                get<Expression>().accept1(node->arg2),
868                                (node->isAnd == ast::LogicalFlag::AndExpr)
869                        )
870                );
871                this->node = expr;
[74dbbf6]872                return nullptr;
873        }
874
875        const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
[28c89f4]876                auto expr = visitBaseExpr( node,
877                        new ConditionalExpr(
878                                get<Expression>().accept1(node->arg1),
879                                get<Expression>().accept1(node->arg2),
880                                get<Expression>().accept1(node->arg3)
881                        )
882                );
883                this->node = expr;
[74dbbf6]884                return nullptr;
885        }
886
887        const ast::Expr * visit( const ast::CommaExpr * node ) override final {
[28c89f4]888                auto expr = visitBaseExpr( node,
889                        new CommaExpr(
890                                get<Expression>().accept1(node->arg1),
891                                get<Expression>().accept1(node->arg2)
892                        )
893                );
894                this->node = expr;
[74dbbf6]895                return nullptr;
896        }
897
898        const ast::Expr * visit( const ast::TypeExpr * node ) override final {
[20de6fb]899                auto expr = visitBaseExpr( node,
900                        new TypeExpr(
901                                get<Type>().accept1(node->type)
902                        )
903                );
904                this->node = expr;
[74dbbf6]905                return nullptr;
906        }
907
908        const ast::Expr * visit( const ast::AsmExpr * node ) override final {
[20de6fb]909                auto expr = visitBaseExpr( node,
910                        new AsmExpr(
911                                get<Expression>().accept1(node->inout),
912                                get<Expression>().accept1(node->constraint),
913                                get<Expression>().accept1(node->operand)
914                        )
915                );
916                this->node = expr;
[74dbbf6]917                return nullptr;
918        }
919
920        const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
[20de6fb]921                auto rslt = new ImplicitCopyCtorExpr(
922                        get<ApplicationExpr>().accept1(node->callExpr)
923                );
924
925                auto expr = visitBaseExpr( node, rslt );
926                this->node = expr;
[74dbbf6]927                return nullptr;
928        }
929
930        const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
[20de6fb]931                auto expr = visitBaseExpr( node,
932                        new ConstructorExpr(
933                                get<Expression>().accept1(node->callExpr)
934                        )
935                );
936                this->node = expr;
[74dbbf6]937                return nullptr;
938        }
939
940        const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
[20de6fb]941                auto expr = visitBaseExpr_skipResultType( node,
942                        new CompoundLiteralExpr(
943                                get<Type>().accept1(node->result),
944                                get<Initializer>().accept1(node->init)
945                        )
946                );
947                this->node = expr;
[74dbbf6]948                return nullptr;
949        }
950
951        const ast::Expr * visit( const ast::RangeExpr * node ) override final {
[20de6fb]952                auto expr = visitBaseExpr( node,
953                        new RangeExpr(
954                                get<Expression>().accept1(node->low),
955                                get<Expression>().accept1(node->high)
956                        )
957                );
958                this->node = expr;
[74dbbf6]959                return nullptr;
960        }
961
962        const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
[20de6fb]963                auto expr = visitBaseExpr( node,
964                        new UntypedTupleExpr(
965                                get<Expression>().acceptL(node->exprs)
966                        )
967                );
968                this->node = expr;
[74dbbf6]969                return nullptr;
970        }
971
972        const ast::Expr * visit( const ast::TupleExpr * node ) override final {
[20de6fb]973                auto expr = visitBaseExpr( node,
974                        new UntypedTupleExpr(
975                                get<Expression>().acceptL(node->exprs)
976                        )
977                );
978                this->node = expr;
[74dbbf6]979                return nullptr;
980        }
981
982        const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
[20de6fb]983                auto expr = visitBaseExpr( node,
984                        new TupleIndexExpr(
985                                get<Expression>().accept1(node->tuple),
986                                node->index
987                        )
988                );
989                this->node = expr;
[74dbbf6]990                return nullptr;
991        }
992
993        const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
[20de6fb]994                auto expr = visitBaseExpr( node,
995                        new TupleAssignExpr(
996                                get<StmtExpr>().accept1(node->stmtExpr)
997                        )
998                );
999                this->node = expr;
[74dbbf6]1000                return nullptr;
1001        }
1002
1003        const ast::Expr * visit( const ast::StmtExpr * node ) override final {
[20de6fb]1004                auto rslt = new StmtExpr(
1005                        get<CompoundStmt>().accept1(node->stmts)
1006                );
1007
1008                rslt->returnDecls = get<ObjectDecl>().acceptL(node->returnDecls);
1009                rslt->dtors       = get<Expression>().acceptL(node->dtors);
1010
1011                auto expr = visitBaseExpr( node, rslt );
1012                this->node = expr;
[74dbbf6]1013                return nullptr;
1014        }
1015
1016        const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
[20de6fb]1017                auto rslt = new UniqueExpr(
1018                        get<Expression>().accept1(node->expr)
1019                );
1020
1021                rslt->object = get<ObjectDecl>  ().accept1(node->object);
1022                rslt->var    = get<VariableExpr>().accept1(node->var);
1023
1024                auto expr = visitBaseExpr( node, rslt );
1025                this->node = expr;
[74dbbf6]1026                return nullptr;
1027        }
1028
1029        const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
[20de6fb]1030                std::list<InitAlternative> initAlts;
1031                for (auto ia : node->initAlts) {
1032                        initAlts.push_back(InitAlternative(
1033                                get<Type>       ().accept1(ia.type),
1034                                get<Designation>().accept1(ia.designation)
1035                        ));
1036                }
1037                auto expr = visitBaseExpr( node,
1038                        new UntypedInitExpr(
1039                                get<Expression>().accept1(node->expr),
1040                                initAlts
1041                        )
1042                );
1043                this->node = expr;
[74dbbf6]1044                return nullptr;
1045        }
1046
1047        const ast::Expr * visit( const ast::InitExpr * node ) override final {
[20de6fb]1048                auto expr = visitBaseExpr( node,
1049                        new InitExpr(
1050                                get<Expression>().accept1(node->expr),
1051                                get<Designation>().accept1(node->designation)
1052                        )
1053                );
1054                this->node = expr;
[74dbbf6]1055                return nullptr;
1056        }
1057
1058        const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
[20de6fb]1059                auto expr = visitBaseExpr( node,
1060                        new DeletedExpr(
1061                                get<Expression>().accept1(node->expr),
1062                                inCache(node->deleteStmt) ?
1063                                        this->node :
1064                                        get<BaseSyntaxNode>().accept1(node->deleteStmt)
1065                        )
1066                );
1067                this->node = expr;
[74dbbf6]1068                return nullptr;
1069        }
1070
1071        const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
[20de6fb]1072                auto expr = visitBaseExpr( node,
1073                        new DefaultArgExpr(
1074                                get<Expression>().accept1(node->expr)
1075                        )
1076                );
1077                this->node = expr;
[74dbbf6]1078                return nullptr;
1079        }
1080
1081        const ast::Expr * visit( const ast::GenericExpr * node ) override final {
[20de6fb]1082                std::list<GenericExpr::Association> associations;
1083                for (auto association : node->associations) {
1084                        associations.push_back(GenericExpr::Association(
1085                                get<Type>      ().accept1(association.type),
1086                                get<Expression>().accept1(association.expr)
1087                        ));
1088                }
1089                auto expr = visitBaseExpr( node,
1090                        new GenericExpr(
1091                                get<Expression>().accept1(node->control),
1092                                associations
1093                        )
1094                );
1095                this->node = expr;
[74dbbf6]1096                return nullptr;
1097        }
1098
1099        const ast::Type * visit( const ast::VoidType * node ) override final {
[d148778]1100                this->node = new VoidType{ cv( node ) };
[74dbbf6]1101                return nullptr;
1102        }
1103
1104        const ast::Type * visit( const ast::BasicType * node ) override final {
[2a54479]1105                auto type = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind };
1106                // I believe this should always be a BasicType.
1107                if ( sizeType == node ) {
1108                        Validate::SizeType = type;
1109                }
1110                this->node = type;
[74dbbf6]1111                return nullptr;
1112        }
1113
1114        const ast::Type * visit( const ast::PointerType * node ) override final {
[d148778]1115                this->node = new PointerType{
1116                        cv( node ),
1117                        get<Type>().accept1( node->base ),
1118                        get<Expression>().accept1( node->dimension ),
[746ae82]1119                        (bool)node->isVarLen,
1120                        (bool)node->isStatic
[d148778]1121                };
[74dbbf6]1122                return nullptr;
1123        }
1124
1125        const ast::Type * visit( const ast::ArrayType * node ) override final {
[d148778]1126                this->node = new ArrayType{
1127                        cv( node ),
1128                        get<Type>().accept1( node->base ),
1129                        get<Expression>().accept1( node->dimension ),
[746ae82]1130                        (bool)node->isVarLen,
1131                        (bool)node->isStatic
[d148778]1132                };
[74dbbf6]1133                return nullptr;
1134        }
1135
1136        const ast::Type * visit( const ast::ReferenceType * node ) override final {
[d148778]1137                this->node = new ReferenceType{
1138                        cv( node ),
1139                        get<Type>().accept1( node->base )
1140                };
[74dbbf6]1141                return nullptr;
1142        }
1143
1144        const ast::Type * visit( const ast::QualifiedType * node ) override final {
[d148778]1145                this->node = new QualifiedType{
1146                        cv( node ),
1147                        get<Type>().accept1( node->parent ),
1148                        get<Type>().accept1( node->child )
1149                };
[74dbbf6]1150                return nullptr;
1151        }
1152
1153        const ast::Type * visit( const ast::FunctionType * node ) override final {
[746ae82]1154                auto ty = new FunctionType {
[0b57626]1155                        cv( node ),
[746ae82]1156                        (bool)node->isVarArgs
1157                };
[d148778]1158                ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
1159                ty->parameters = get<DeclarationWithType>().acceptL( node->params );
1160                ty->forall = get<TypeDecl>().acceptL( node->forall );
[514a791]1161                this->node = ty;
[74dbbf6]1162                return nullptr;
1163        }
1164
[b869ec5]1165        void postvisit( const ast::ReferenceToType * old, ReferenceToType * ty ) {
1166                ty->forall = get<TypeDecl>().acceptL( old->forall );
1167                ty->parameters = get<Expression>().acceptL( old->params );
1168                ty->hoistType = old->hoistType;
1169        }
1170
[74dbbf6]1171        const ast::Type * visit( const ast::StructInstType * node ) override final {
[b869ec5]1172                StructInstType * ty;
1173                if ( node->base ) {
1174                        ty = new StructInstType{
1175                                cv( node ),
1176                                get<StructDecl>().accept1( node->base ),
1177                                get<Attribute>().acceptL( node->attributes )
1178                        };
1179                } else {
1180                        ty = new StructInstType{
1181                                cv( node ),
1182                                node->name,
1183                                get<Attribute>().acceptL( node->attributes )
1184                        };
1185                }
1186                postvisit( node, ty );
1187                this->node = ty;
[74dbbf6]1188                return nullptr;
1189        }
1190
1191        const ast::Type * visit( const ast::UnionInstType * node ) override final {
[b869ec5]1192                UnionInstType * ty;
1193                if ( node->base ) {
1194                        ty = new UnionInstType{
1195                                cv( node ),
1196                                get<UnionDecl>().accept1( node->base ),
1197                                get<Attribute>().acceptL( node->attributes )
1198                        };
1199                } else {
1200                        ty = new UnionInstType{
1201                                cv( node ),
1202                                node->name,
1203                                get<Attribute>().acceptL( node->attributes )
1204                        };
1205                }
1206                postvisit( node, ty );
1207                this->node = ty;
[74dbbf6]1208                return nullptr;
1209        }
1210
1211        const ast::Type * visit( const ast::EnumInstType * node ) override final {
[b869ec5]1212                EnumInstType * ty;
1213                if ( node->base ) {
1214                        ty = new EnumInstType{
1215                                cv( node ),
1216                                get<EnumDecl>().accept1( node->base ),
1217                                get<Attribute>().acceptL( node->attributes )
1218                        };
1219                } else {
1220                        ty = new EnumInstType{
1221                                cv( node ),
1222                                node->name,
1223                                get<Attribute>().acceptL( node->attributes )
1224                        };
1225                }
1226                postvisit( node, ty );
1227                this->node = ty;
[74dbbf6]1228                return nullptr;
1229        }
1230
1231        const ast::Type * visit( const ast::TraitInstType * node ) override final {
[b869ec5]1232                TraitInstType * ty;
1233                if ( node->base ) {
1234                        ty = new TraitInstType{
1235                                cv( node ),
1236                                get<TraitDecl>().accept1( node->base ),
1237                                get<Attribute>().acceptL( node->attributes )
1238                        };
1239                } else {
1240                        ty = new TraitInstType{
1241                                cv( node ),
1242                                node->name,
1243                                get<Attribute>().acceptL( node->attributes )
1244                        };
1245                }
1246                postvisit( node, ty );
1247                this->node = ty;
[74dbbf6]1248                return nullptr;
1249        }
1250
1251        const ast::Type * visit( const ast::TypeInstType * node ) override final {
[b869ec5]1252                TypeInstType * ty;
1253                if ( node->base ) {
1254                        ty = new TypeInstType{
1255                                cv( node ),
1256                                node->name,
1257                                get<TypeDecl>().accept1( node->base ),
1258                                get<Attribute>().acceptL( node->attributes )
1259                        };
1260                } else {
1261                        ty = new TypeInstType{
1262                                cv( node ),
1263                                node->name,
1264                                node->kind == ast::TypeVar::Ftype,
1265                                get<Attribute>().acceptL( node->attributes )
1266                        };
1267                }
1268                postvisit( node, ty );
1269                this->node = ty;
[74dbbf6]1270                return nullptr;
1271        }
1272
1273        const ast::Type * visit( const ast::TupleType * node ) override final {
[746ae82]1274                this->node = new TupleType{
1275                        cv( node ),
1276                        get<Type>().acceptL( node->types )
1277                        // members generated by TupleType c'tor
1278                };
[74dbbf6]1279                return nullptr;
1280        }
1281
1282        const ast::Type * visit( const ast::TypeofType * node ) override final {
[746ae82]1283                this->node = new TypeofType{
1284                        cv( node ),
1285                        get<Expression>().accept1( node->expr ),
1286                        (bool)node->kind
1287                };
[74dbbf6]1288                return nullptr;
1289        }
1290
1291        const ast::Type * visit( const ast::VarArgsType * node ) override final {
[746ae82]1292                this->node = new VarArgsType{ cv( node ) };
[74dbbf6]1293                return nullptr;
1294        }
1295
1296        const ast::Type * visit( const ast::ZeroType * node ) override final {
[746ae82]1297                this->node = new ZeroType{ cv( node ) };
[74dbbf6]1298                return nullptr;
1299        }
1300
1301        const ast::Type * visit( const ast::OneType * node ) override final {
[746ae82]1302                this->node = new OneType{ cv( node ) };
[74dbbf6]1303                return nullptr;
1304        }
1305
[746ae82]1306        const ast::Type * visit( const ast::GlobalScopeType * ) override final {
1307                this->node = new GlobalScopeType{};
[74dbbf6]1308                return nullptr;
1309        }
1310
1311        const ast::Designation * visit( const ast::Designation * node ) override final {
[74ad8c0]1312                auto designation = new Designation( get<Expression>().acceptL( node->designators ) );
1313                designation->location = node->location;
1314                this->node = designation;
[74dbbf6]1315                return nullptr;
1316        }
1317
1318        const ast::Init * visit( const ast::SingleInit * node ) override final {
[74ad8c0]1319                auto init = new SingleInit(
1320                        get<Expression>().accept1( node->value ),
1321                        ast::MaybeConstruct == node->maybeConstructed
1322                );
1323                init->location = node->location;
1324                this->node = init;
[74dbbf6]1325                return nullptr;
1326        }
1327
1328        const ast::Init * visit( const ast::ListInit * node ) override final {
[74ad8c0]1329                auto init = new ListInit(
1330                        get<Initializer>().acceptL( node->initializers ),
1331                        get<Designation>().acceptL( node->designations ),
1332                        ast::MaybeConstruct == node->maybeConstructed
1333                );
1334                init->location = node->location;
1335                this->node = init;
[74dbbf6]1336                return nullptr;
1337        }
1338
1339        const ast::Init * visit( const ast::ConstructorInit * node ) override final {
[74ad8c0]1340                auto init = new ConstructorInit(
1341                        get<Statement>().accept1( node->ctor ),
1342                        get<Statement>().accept1( node->dtor ),
1343                        get<Initializer>().accept1( node->init )
1344                );
1345                init->location = node->location;
1346                this->node = init;
[74dbbf6]1347                return nullptr;
1348        }
1349
1350        const ast::Attribute * visit( const ast::Attribute * node ) override final {
[dd6d7c6]1351                auto attr = new Attribute(
1352                        node->name,
[489bacf]1353                        get<Expression>().acceptL(node->params)
[dd6d7c6]1354                );
1355                this->node = attr;
[74dbbf6]1356                return nullptr;
1357        }
1358
1359        const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
[dd6d7c6]1360                // Handled by convertTypeSubstitution helper instead.
1361                // TypeSubstitution is not a node in the old model, so the conversion result wouldn't fit in this->node.
1362                assert( 0 );
[0b57626]1363                (void)node;
[74dbbf6]1364                return nullptr;
1365        }
[6d51bd7]1366};
1367
[8abee136]1368std::list< Declaration * > convert( const std::list< ast::ptr< ast::Decl > > && translationUnit ) {
[74dbbf6]1369        ConverterNewToOld c;
1370        std::list< Declaration * > decls;
1371        for(auto d : translationUnit) {
[675d816]1372                decls.emplace_back( c.decl( d ) );
[74dbbf6]1373        }
1374        return decls;
[6d51bd7]1375}
1376
1377//================================================================================================
1378
1379class ConverterOldToNew : public Visitor {
1380public:
1381        ast::Decl * decl() {
1382                return strict_dynamic_cast< ast::Decl * >( node );
1383        }
[546e712]1384
1385        ConverterOldToNew() = default;
1386        ConverterOldToNew(const ConverterOldToNew &) = delete;
1387        ConverterOldToNew(ConverterOldToNew &&) = delete;
[6d51bd7]1388private:
[d148778]1389        /// conversion output
[546e712]1390        ast::Node * node = nullptr;
[d148778]1391        /// cache of nodes that might be referenced by readonly<> for de-duplication
[546e712]1392        std::unordered_map< BaseSyntaxNode *, ast::Node * > cache = {};
[6d51bd7]1393
[6f8e87d]1394        // Local Utilities:
1395
1396        template<typename NewT, typename OldT>
1397        NewT * getAccept1( OldT old ) {
[d148778]1398                if ( ! old ) return nullptr;
[6f8e87d]1399                old->accept(*this);
[2c04369]1400                ast::Node * ret = node;
1401                node = nullptr;
1402                return strict_dynamic_cast< NewT * >( ret );
[6f8e87d]1403        }
1404
1405#       define GET_ACCEPT_1(child, type) \
1406                getAccept1< ast::type, decltype( old->child ) >( old->child )
1407
1408        template<typename NewT, typename OldC>
[a62749f]1409        std::vector< ast::ptr<NewT> > getAcceptV( const OldC& old ) {
[6f8e87d]1410                std::vector< ast::ptr<NewT> > ret;
1411                ret.reserve( old.size() );
1412                for ( auto a : old ) {
1413                        a->accept( *this );
1414                        ret.emplace_back( strict_dynamic_cast< NewT * >(node) );
[2c04369]1415                        node = nullptr;
[6f8e87d]1416                }
1417                return ret;
1418        }
1419
1420#       define GET_ACCEPT_V(child, type) \
1421                getAcceptV< ast::type, decltype( old->child ) >( old->child )
[6355ba7]1422
[60aaa51d]1423        template<typename NewT, typename OldC>
[a62749f]1424        std::deque< ast::ptr<NewT> > getAcceptD( const OldC& old ) {
[60aaa51d]1425                std::deque< ast::ptr<NewT> > ret;
1426                for ( auto a : old ) {
1427                        a->accept( *this );
1428                        ret.emplace_back( strict_dynamic_cast< NewT * >(node) );
1429                        node = nullptr;
1430                }
1431                return ret;
1432        }
1433
1434#       define GET_ACCEPT_D(child, type) \
1435                getAcceptD< ast::type, decltype( old->child ) >( old->child )
[6f8e87d]1436
[a62749f]1437        ast::Label make_label(const Label* old) {
1438                CodeLocation const & location =
1439                    ( old->labelled ) ? old->labelled->location : CodeLocation();
[6f8e87d]1440                return ast::Label(
[a62749f]1441                        location,
[6f8e87d]1442                        old->name,
1443                        GET_ACCEPT_V(attributes, Attribute)
1444                );
1445        }
1446
[6d51bd7]1447        template<template <class...> class C>
1448        C<ast::Label> make_labels(C<Label> olds) {
1449                C<ast::Label> ret;
[6f8e87d]1450                for (auto oldn : olds) {
1451                        ret.push_back( make_label( &oldn ) );
[6d51bd7]1452                }
1453                return ret;
1454        }
1455
[6f8e87d]1456#       define GET_LABELS_V(labels) \
1457                to<std::vector>::from( make_labels( std::move( labels ) ) )
[0b57626]1458
[d148778]1459        static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
1460
[b869ec5]1461        /// returns true and sets `node` if in cache
1462        bool inCache( BaseSyntaxNode * old ) {
[d148778]1463                auto it = cache.find( old );
[b869ec5]1464                if ( it == cache.end() ) return false;
1465                node = it->second;
1466                return true;
[d148778]1467        }
[6f8e87d]1468
1469        // Now all the visit functions:
1470
[6d51bd7]1471        virtual void visit( ObjectDecl * old ) override final {
[546e712]1472                auto&& type = GET_ACCEPT_1(type, Type);
1473                auto&& init = GET_ACCEPT_1(init, Init);
1474                auto&& bfwd = GET_ACCEPT_1(bitfieldWidth, Expr);
1475                auto&& attr = GET_ACCEPT_V(attributes, Attribute);
1476                if ( inCache( old ) ) {
1477                        return;
1478                }
[6d51bd7]1479                auto decl = new ast::ObjectDecl(
1480                        old->location,
1481                        old->name,
[546e712]1482                        type,
1483                        init,
[6d51bd7]1484                        { old->get_storageClasses().val },
1485                        { old->linkage.val },
[546e712]1486                        bfwd,
1487                        std::move(attr),
[6d51bd7]1488                        { old->get_funcSpec().val }
1489                );
[546e712]1490                cache.emplace(old, decl);
1491                assert(cache.find( old ) != cache.end());
[6d51bd7]1492                decl->scopeLevel = old->scopeLevel;
1493                decl->mangleName = old->mangleName;
1494                decl->isDeleted  = old->isDeleted;
1495                decl->uniqueId   = old->uniqueId;
1496                decl->extension  = old->extension;
1497
1498                this->node = decl;
1499        }
1500
[b869ec5]1501        virtual void visit( FunctionDecl * old ) override final {
1502                if ( inCache( old ) ) return;
[9a0cd9c]1503                auto decl = new ast::FunctionDecl{
1504                        old->location,
1505                        old->name,
1506                        GET_ACCEPT_1(type, FunctionType),
[d88f8b3b]1507                        {},
[9a0cd9c]1508                        { old->storageClasses.val },
1509                        { old->linkage.val },
1510                        GET_ACCEPT_V(attributes, Attribute),
1511                        { old->get_funcSpec().val }
1512                };
[8abee136]1513                cache.emplace( old, decl );
[d76c588]1514                decl->withExprs = GET_ACCEPT_V(withExprs, Expr);
[d88f8b3b]1515                decl->stmts = GET_ACCEPT_1(statements, CompoundStmt);
[9a0cd9c]1516                decl->scopeLevel = old->scopeLevel;
1517                decl->mangleName = old->mangleName;
1518                decl->isDeleted  = old->isDeleted;
1519                decl->uniqueId   = old->uniqueId;
1520                decl->extension  = old->extension;
1521
1522                this->node = decl;
[157a816]1523
[0aedb01]1524                if ( Validate::dereferenceOperator == old ) {
[157a816]1525                        dereferenceOperator = decl;
1526                }
[043a5b6]1527
1528                if ( Validate::dtorStructDestroy == old ) {
1529                        dtorStructDestroy = decl;
1530                }
[6d51bd7]1531        }
1532
1533        virtual void visit( StructDecl * old ) override final {
[b869ec5]1534                if ( inCache( old ) ) return;
[6d51bd7]1535                auto decl = new ast::StructDecl(
1536                        old->location,
1537                        old->name,
1538                        old->kind,
[d66e7b7]1539                        GET_ACCEPT_V(attributes, Attribute),
[6d51bd7]1540                        { old->linkage.val }
1541                );
[8abee136]1542                cache.emplace( old, decl );
[d66e7b7]1543                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
[6d51bd7]1544                decl->body   = old->body;
[d66e7b7]1545                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1546                decl->members    = GET_ACCEPT_V(members, Decl);
[6d51bd7]1547                decl->extension  = old->extension;
1548                decl->uniqueId   = old->uniqueId;
1549                decl->storage    = { old->storageClasses.val };
1550
1551                this->node = decl;
[043a5b6]1552
1553                if ( Validate::dtorStruct == old ) {
1554                        dtorStruct = decl;
1555                }
[6d51bd7]1556        }
1557
1558        virtual void visit( UnionDecl * old ) override final {
[b869ec5]1559                if ( inCache( old ) ) return;
[6d51bd7]1560                auto decl = new ast::UnionDecl(
1561                        old->location,
1562                        old->name,
[d66e7b7]1563                        GET_ACCEPT_V(attributes, Attribute),
[6d51bd7]1564                        { old->linkage.val }
1565                );
[8abee136]1566                cache.emplace( old, decl );
[d66e7b7]1567                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
[6d51bd7]1568                decl->body   = old->body;
[d66e7b7]1569                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1570                decl->members    = GET_ACCEPT_V(members, Decl);
[6d51bd7]1571                decl->extension  = old->extension;
1572                decl->uniqueId   = old->uniqueId;
1573                decl->storage    = { old->storageClasses.val };
1574
1575                this->node = decl;
1576        }
1577
1578        virtual void visit( EnumDecl * old ) override final {
[b869ec5]1579                if ( inCache( old ) ) return;
[157a816]1580                auto decl = new ast::EnumDecl(
[6d51bd7]1581                        old->location,
1582                        old->name,
[d66e7b7]1583                        GET_ACCEPT_V(attributes, Attribute),
[6d51bd7]1584                        { old->linkage.val }
1585                );
[8abee136]1586                cache.emplace( old, decl );
[d66e7b7]1587                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
[6d51bd7]1588                decl->body   = old->body;
[d66e7b7]1589                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1590                decl->members    = GET_ACCEPT_V(members, Decl);
[6d51bd7]1591                decl->extension  = old->extension;
1592                decl->uniqueId   = old->uniqueId;
1593                decl->storage    = { old->storageClasses.val };
1594
1595                this->node = decl;
1596        }
1597
1598        virtual void visit( TraitDecl * old ) override final {
[b869ec5]1599                if ( inCache( old ) ) return;
[157a816]1600                auto decl = new ast::TraitDecl(
[6d51bd7]1601                        old->location,
1602                        old->name,
[d66e7b7]1603                        GET_ACCEPT_V(attributes, Attribute),
[6d51bd7]1604                        { old->linkage.val }
1605                );
[8abee136]1606                cache.emplace( old, decl );
[d66e7b7]1607                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
[6d51bd7]1608                decl->body   = old->body;
[d66e7b7]1609                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1610                decl->members    = GET_ACCEPT_V(members, Decl);
[6d51bd7]1611                decl->extension  = old->extension;
1612                decl->uniqueId   = old->uniqueId;
1613                decl->storage    = { old->storageClasses.val };
1614
1615                this->node = decl;
1616        }
1617
[b869ec5]1618        virtual void visit( TypeDecl * old ) override final {
[0b57626]1619                if ( inCache( old ) ) return;
[9a0cd9c]1620                auto decl = new ast::TypeDecl{
1621                        old->location,
1622                        old->name,
1623                        { old->storageClasses.val },
1624                        GET_ACCEPT_1(base, Type),
1625                        (ast::TypeVar::Kind)(unsigned)old->kind,
1626                        old->sized,
1627                        GET_ACCEPT_1(init, Type)
1628                };
[8abee136]1629                cache.emplace( old, decl );
[9a0cd9c]1630                decl->assertions = GET_ACCEPT_V(assertions, DeclWithType);
1631                decl->params     = GET_ACCEPT_V(parameters, TypeDecl);
1632                decl->extension  = old->extension;
1633                decl->uniqueId   = old->uniqueId;
1634
1635                this->node = decl;
[6d51bd7]1636        }
1637
1638        virtual void visit( TypedefDecl * old ) override final {
1639                auto decl = new ast::TypedefDecl(
1640                        old->location,
1641                        old->name,
1642                        { old->storageClasses.val },
[d66e7b7]1643                        GET_ACCEPT_1(base, Type),
[6d51bd7]1644                        { old->linkage.val }
1645                );
[d66e7b7]1646                decl->assertions = GET_ACCEPT_V(assertions, DeclWithType);
1647                decl->params     = GET_ACCEPT_V(parameters, TypeDecl);
[6d51bd7]1648                decl->extension  = old->extension;
1649                decl->uniqueId   = old->uniqueId;
1650                decl->storage    = { old->storageClasses.val };
1651
1652                this->node = decl;
1653        }
1654
[9a0cd9c]1655        virtual void visit( AsmDecl * old ) override final {
1656                auto decl = new ast::AsmDecl{
[0b57626]1657                        old->location,
[9a0cd9c]1658                        GET_ACCEPT_1(stmt, AsmStmt)
1659                };
1660                decl->extension  = old->extension;
1661                decl->uniqueId   = old->uniqueId;
1662                decl->storage    = { old->storageClasses.val };
[6d51bd7]1663
[9a0cd9c]1664                this->node = decl;
[6d51bd7]1665        }
1666
[9a0cd9c]1667        virtual void visit( StaticAssertDecl * old ) override final {
1668                auto decl = new ast::StaticAssertDecl{
1669                        old->location,
1670                        GET_ACCEPT_1(condition, Expr),
1671                        GET_ACCEPT_1(message, ConstantExpr)
1672                };
1673                decl->extension  = old->extension;
1674                decl->uniqueId   = old->uniqueId;
1675                decl->storage    = { old->storageClasses.val };
[6d51bd7]1676
[9a0cd9c]1677                this->node = decl;
[6d51bd7]1678        }
1679
1680        virtual void visit( CompoundStmt * old ) override final {
[4073b16]1681                if ( inCache( old ) ) return;
[6d51bd7]1682                auto stmt = new ast::CompoundStmt(
1683                        old->location,
[d66e7b7]1684                        to<std::list>::from( GET_ACCEPT_V(kids, Stmt) ),
1685                        GET_LABELS_V(old->labels)
[6d51bd7]1686                );
1687
1688                this->node = stmt;
[4073b16]1689                cache.emplace( old, this->node );
[6d51bd7]1690        }
1691
1692        virtual void visit( ExprStmt * old ) override final {
[4073b16]1693                if ( inCache( old ) ) return;
[6f8e87d]1694                this->node = new ast::ExprStmt(
[6d51bd7]1695                        old->location,
[6f8e87d]1696                        GET_ACCEPT_1(expr, Expr),
1697                        GET_LABELS_V(old->labels)
[6d51bd7]1698                );
[4073b16]1699                cache.emplace( old, this->node );
[6d51bd7]1700        }
1701
[6f8e87d]1702        virtual void visit( AsmStmt * old ) override final {
[4073b16]1703                if ( inCache( old ) ) return;
[6f8e87d]1704                this->node = new ast::AsmStmt(
1705                        old->location,
1706                        old->voltile,
1707                        GET_ACCEPT_1(instruction, Expr),
1708                        GET_ACCEPT_V(output, Expr),
1709                        GET_ACCEPT_V(input, Expr),
1710                        GET_ACCEPT_V(clobber, ConstantExpr),
1711                        GET_LABELS_V(old->gotolabels),
1712                        GET_LABELS_V(old->labels)
1713                );
[4073b16]1714                cache.emplace( old, this->node );
[6d51bd7]1715        }
1716
[6f8e87d]1717        virtual void visit( DirectiveStmt * old ) override final {
[4073b16]1718                if ( inCache( old ) ) return;
[6f8e87d]1719                this->node = new ast::DirectiveStmt(
1720                        old->location,
1721                        old->directive,
1722                        GET_LABELS_V(old->labels)
1723                );
[4073b16]1724                cache.emplace( old, this->node );
[6d51bd7]1725        }
1726
[6f8e87d]1727        virtual void visit( IfStmt * old ) override final {
[4073b16]1728                if ( inCache( old ) ) return;
[6f8e87d]1729                this->node = new ast::IfStmt(
1730                        old->location,
1731                        GET_ACCEPT_1(condition, Expr),
1732                        GET_ACCEPT_1(thenPart, Stmt),
1733                        GET_ACCEPT_1(elsePart, Stmt),
1734                        GET_ACCEPT_V(initialization, Stmt),
1735                        GET_LABELS_V(old->labels)
1736                );
[4073b16]1737                cache.emplace( old, this->node );
[6d51bd7]1738        }
1739
[6f8e87d]1740        virtual void visit( SwitchStmt * old ) override final {
[4073b16]1741                if ( inCache( old ) ) return;
[6f8e87d]1742                this->node = new ast::SwitchStmt(
1743                        old->location,
1744                        GET_ACCEPT_1(condition, Expr),
1745                        GET_ACCEPT_V(statements, Stmt),
1746                        GET_LABELS_V(old->labels)
1747                );
[4073b16]1748                cache.emplace( old, this->node );
[6d51bd7]1749        }
1750
[6f8e87d]1751        virtual void visit( CaseStmt * old ) override final {
[4073b16]1752                if ( inCache( old ) ) return;
[6f8e87d]1753                this->node = new ast::CaseStmt(
1754                        old->location,
1755                        GET_ACCEPT_1(condition, Expr),
1756                        GET_ACCEPT_V(stmts, Stmt),
1757                        GET_LABELS_V(old->labels)
1758                );
[4073b16]1759                cache.emplace( old, this->node );
[6d51bd7]1760        }
1761
[6f8e87d]1762        virtual void visit( WhileStmt * old ) override final {
[4073b16]1763                if ( inCache( old ) ) return;
[6f8e87d]1764                this->node = new ast::WhileStmt(
1765                        old->location,
1766                        GET_ACCEPT_1(condition, Expr),
1767                        GET_ACCEPT_1(body, Stmt),
1768                        GET_ACCEPT_V(initialization, Stmt),
1769                        old->isDoWhile,
1770                        GET_LABELS_V(old->labels)
1771                );
[4073b16]1772                cache.emplace( old, this->node );
[6d51bd7]1773        }
1774
[6f8e87d]1775        virtual void visit( ForStmt * old ) override final {
[4073b16]1776                if ( inCache( old ) ) return;
[6f8e87d]1777                this->node = new ast::ForStmt(
1778                        old->location,
1779                        GET_ACCEPT_V(initialization, Stmt),
1780                        GET_ACCEPT_1(condition, Expr),
1781                        GET_ACCEPT_1(increment, Expr),
1782                        GET_ACCEPT_1(body, Stmt),
1783                        GET_LABELS_V(old->labels)
1784                );
[4073b16]1785                cache.emplace( old, this->node );
[6d51bd7]1786        }
1787
[6f8e87d]1788        virtual void visit( BranchStmt * old ) override final {
[4073b16]1789                if ( inCache( old ) ) return;
[6f8e87d]1790                if (old->computedTarget) {
1791                        this->node = new ast::BranchStmt(
1792                                old->location,
1793                                GET_ACCEPT_1(computedTarget, Expr),
1794                                GET_LABELS_V(old->labels)
1795                        );
1796                } else {
1797                        ast::BranchStmt::Kind kind;
1798                        switch (old->type) {
1799                        #define CASE(n) \
1800                        case BranchStmt::n: \
1801                                kind = ast::BranchStmt::n; \
1802                                break
1803                        CASE(Goto);
1804                        CASE(Break);
1805                        CASE(Continue);
1806                        CASE(FallThrough);
1807                        CASE(FallThroughDefault);
1808                        #undef CASE
[d66e7b7]1809                        default:
1810                                assertf(false, "Invalid BranchStmt::Type %d\n", old->type);
[6f8e87d]1811                        }
1812
1813                        auto stmt = new ast::BranchStmt(
1814                                old->location,
1815                                kind,
[a62749f]1816                                make_label(&old->originalTarget),
[6f8e87d]1817                                GET_LABELS_V(old->labels)
1818                        );
1819                        stmt->target = make_label(&old->target);
1820                        this->node = stmt;
1821                }
[4073b16]1822                cache.emplace( old, this->node );
[6d51bd7]1823        }
1824
[6f8e87d]1825        virtual void visit( ReturnStmt * old ) override final {
[4073b16]1826                if ( inCache( old ) ) return;
[6f8e87d]1827                this->node = new ast::ReturnStmt(
1828                        old->location,
1829                        GET_ACCEPT_1(expr, Expr),
1830                        GET_LABELS_V(old->labels)
1831                );
[4073b16]1832                cache.emplace( old, this->node );
[6d51bd7]1833        }
1834
[6f8e87d]1835        virtual void visit( ThrowStmt * old ) override final {
[4073b16]1836                if ( inCache( old ) ) return;
[6f4b7f2]1837                ast::ExceptionKind kind;
[6f8e87d]1838                switch (old->kind) {
1839                case ThrowStmt::Terminate:
[6f4b7f2]1840                        kind = ast::ExceptionKind::Terminate;
[6f8e87d]1841                        break;
1842                case ThrowStmt::Resume:
[6f4b7f2]1843                        kind = ast::ExceptionKind::Resume;
[6f8e87d]1844                        break;
[d66e7b7]1845                default:
1846                        assertf(false, "Invalid ThrowStmt::Kind %d\n", old->kind);
[6f8e87d]1847                }
[6d51bd7]1848
[6f8e87d]1849                this->node = new ast::ThrowStmt(
1850                        old->location,
1851                        kind,
1852                        GET_ACCEPT_1(expr, Expr),
1853                        GET_ACCEPT_1(target, Expr),
1854                        GET_LABELS_V(old->labels)
1855                );
[4073b16]1856                cache.emplace( old, this->node );
[6d51bd7]1857        }
1858
[6f8e87d]1859        virtual void visit( TryStmt * old ) override final {
[4073b16]1860                if ( inCache( old ) ) return;
[6f8e87d]1861                this->node = new ast::TryStmt(
1862                        old->location,
1863                        GET_ACCEPT_1(block, CompoundStmt),
1864                        GET_ACCEPT_V(handlers, CatchStmt),
1865                        GET_ACCEPT_1(finallyBlock, FinallyStmt),
1866                        GET_LABELS_V(old->labels)
1867                );
[4073b16]1868                cache.emplace( old, this->node );
[6d51bd7]1869        }
1870
[6f8e87d]1871        virtual void visit( CatchStmt * old ) override final {
[4073b16]1872                if ( inCache( old ) ) return;
[6f4b7f2]1873                ast::ExceptionKind kind;
[6f8e87d]1874                switch (old->kind) {
1875                case CatchStmt::Terminate:
[6f4b7f2]1876                        kind = ast::ExceptionKind::Terminate;
[6f8e87d]1877                        break;
1878                case CatchStmt::Resume:
[6f4b7f2]1879                        kind = ast::ExceptionKind::Resume;
[6f8e87d]1880                        break;
[d66e7b7]1881                default:
1882                        assertf(false, "Invalid CatchStmt::Kind %d\n", old->kind);
[6f8e87d]1883                }
[6d51bd7]1884
[6f8e87d]1885                this->node = new ast::CatchStmt(
1886                        old->location,
1887                        kind,
1888                        GET_ACCEPT_1(decl, Decl),
1889                        GET_ACCEPT_1(cond, Expr),
1890                        GET_ACCEPT_1(body, Stmt),
1891                        GET_LABELS_V(old->labels)
1892                );
[4073b16]1893                cache.emplace( old, this->node );
[6d51bd7]1894        }
1895
[6f8e87d]1896        virtual void visit( FinallyStmt * old ) override final {
[4073b16]1897                if ( inCache( old ) ) return;
[6f8e87d]1898                this->node = new ast::FinallyStmt(
1899                        old->location,
1900                        GET_ACCEPT_1(block, CompoundStmt),
1901                        GET_LABELS_V(old->labels)
1902                );
[4073b16]1903                cache.emplace( old, this->node );
[6d51bd7]1904        }
1905
[6f8e87d]1906        virtual void visit( WaitForStmt * old ) override final {
[4073b16]1907                if ( inCache( old ) ) return;
[6f8e87d]1908                ast::WaitForStmt * stmt = new ast::WaitForStmt(
1909                        old->location,
1910                        GET_LABELS_V(old->labels)
1911                );
[6d51bd7]1912
[6f8e87d]1913                stmt->clauses.reserve( old->clauses.size() );
1914                for (size_t i = 0 ; i < old->clauses.size() ; ++i) {
1915                        stmt->clauses.push_back({
1916                                ast::WaitForStmt::Target{
1917                                        GET_ACCEPT_1(clauses[i].target.function, Expr),
1918                                        GET_ACCEPT_V(clauses[i].target.arguments, Expr)
1919                                },
1920                                GET_ACCEPT_1(clauses[i].statement, Stmt),
1921                                GET_ACCEPT_1(clauses[i].condition, Expr)
1922                        });
1923                }
1924                stmt->timeout = {
1925                        GET_ACCEPT_1(timeout.time, Expr),
1926                        GET_ACCEPT_1(timeout.statement, Stmt),
1927                        GET_ACCEPT_1(timeout.condition, Expr),
1928                };
1929                stmt->orElse = {
1930                        GET_ACCEPT_1(timeout.statement, Stmt),
1931                        GET_ACCEPT_1(timeout.condition, Expr),
1932                };
[6d51bd7]1933
[6f8e87d]1934                this->node = stmt;
[4073b16]1935                cache.emplace( old, this->node );
[6f8e87d]1936        }
[6d51bd7]1937
[6f8e87d]1938        virtual void visit( WithStmt * old ) override final {
[4073b16]1939                if ( inCache( old ) ) return;
[6f8e87d]1940                this->node = new ast::WithStmt(
1941                        old->location,
1942                        GET_ACCEPT_V(exprs, Expr),
1943                        GET_ACCEPT_1(stmt, Stmt),
1944                        GET_LABELS_V(old->labels)
1945                );
[4073b16]1946                cache.emplace( old, this->node );
[6d51bd7]1947        }
1948
1949        virtual void visit( NullStmt * old ) override final {
[4073b16]1950                if ( inCache( old ) ) return;
[6f8e87d]1951                this->node = new ast::NullStmt(
[6d51bd7]1952                        old->location,
[6f8e87d]1953                        GET_LABELS_V(old->labels)
[6d51bd7]1954                );
[4073b16]1955                cache.emplace( old, this->node );
[6d51bd7]1956        }
1957
[6f8e87d]1958        virtual void visit( DeclStmt * old ) override final {
[4073b16]1959                if ( inCache( old ) ) return;
[6f8e87d]1960                this->node = new ast::DeclStmt(
1961                        old->location,
1962                        GET_ACCEPT_1(decl, Decl),
1963                        GET_LABELS_V(old->labels)
1964                );
[4073b16]1965                cache.emplace( old, this->node );
[6d51bd7]1966        }
1967
[6f8e87d]1968        virtual void visit( ImplicitCtorDtorStmt * old ) override final {
[4073b16]1969                if ( inCache( old ) ) return;
[f685679]1970                auto stmt = new ast::ImplicitCtorDtorStmt(
[6f8e87d]1971                        old->location,
[f685679]1972                        nullptr,
[6f8e87d]1973                        GET_LABELS_V(old->labels)
1974                );
[2c04369]1975                cache.emplace( old, stmt );
[f685679]1976                stmt->callStmt = GET_ACCEPT_1(callStmt, Stmt);
[2c04369]1977                this->node = stmt;
[6d51bd7]1978        }
1979
[172d9342]1980        ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) {
1981
[8abee136]1982                if (!old) return nullptr;
1983
[172d9342]1984                ast::TypeSubstitution *rslt = new ast::TypeSubstitution();
1985
1986                for (decltype(old->begin()) old_i = old->begin(); old_i != old->end(); old_i++) {
1987                        rslt->add( old_i->first,
1988                                   getAccept1<ast::Type>(old_i->second) );
1989                }
[6d51bd7]1990
[172d9342]1991                for (decltype(old->beginVar()) old_i = old->beginVar(); old_i != old->endVar(); old_i++) {
1992                        rslt->addVar( old_i->first,
1993                                      getAccept1<ast::Expr>(old_i->second) );
1994                }
[19e567dd]1995
1996                return rslt;
[6d51bd7]1997        }
1998
[e0016a5]1999        void convertInferUnion(ast::Expr::InferUnion               &newInferred,
[19e567dd]2000                                                   const std::map<UniqueId,ParamEntry> &oldInferParams,
2001                                                   const std::vector<UniqueId>         &oldResnSlots) {
2002
2003                assert( oldInferParams.empty() || oldResnSlots.empty() );
2004                assert( newInferred.mode == ast::Expr::InferUnion::Empty );
2005
2006                if ( !oldInferParams.empty() ) {
2007                        ast::InferredParams &tgt = newInferred.inferParams();
2008                        for (auto old : oldInferParams) {
2009                                tgt[old.first] = ast::ParamEntry(
2010                                        old.second.decl,
[aaeacf4]2011                                        getAccept1<ast::Decl>(old.second.declptr),
[19e567dd]2012                                        getAccept1<ast::Type>(old.second.actualType),
2013                                        getAccept1<ast::Type>(old.second.formalType),
2014                                        getAccept1<ast::Expr>(old.second.expr)
2015                                );
2016                        }
2017                } else if ( !oldResnSlots.empty() ) {
2018                        ast::ResnSlots &tgt = newInferred.resnSlots();
2019                        for (auto old : oldResnSlots) {
2020                                tgt.push_back(old);
2021                        }
2022                }
[172d9342]2023        }
2024
[20de6fb]2025        ast::Expr * visitBaseExpr_SkipResultType(Expression * old, ast::Expr * nw) {
[6d51bd7]2026
[172d9342]2027                nw->env    = convertTypeSubstitution(old->env);
2028
2029                nw->extension = old->extension;
2030                convertInferUnion(nw->inferred, old->inferParams, old->resnSlots);
2031
2032                return nw;
2033        }
[6d51bd7]2034
[20de6fb]2035        ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
2036
2037                nw->result = GET_ACCEPT_1(result, Type);
2038                return visitBaseExpr_SkipResultType(old, nw);;
2039        }
2040
[19e567dd]2041        virtual void visit( ApplicationExpr * old ) override final {
2042                this->node = visitBaseExpr( old,
2043                        new ast::ApplicationExpr(
2044                                old->location,
2045                                GET_ACCEPT_1(function, Expr),
2046                                GET_ACCEPT_V(args, Expr)
2047                        )
2048                );
[6d51bd7]2049        }
2050
[19e567dd]2051        virtual void visit( UntypedExpr * old ) override final {
2052                this->node = visitBaseExpr( old,
2053                        new ast::UntypedExpr(
2054                                old->location,
2055                                GET_ACCEPT_1(function, Expr),
2056                                GET_ACCEPT_V(args, Expr)
2057                        )
2058                );
[172d9342]2059        }
[6d51bd7]2060
[172d9342]2061        virtual void visit( NameExpr * old ) override final {
2062                this->node = visitBaseExpr( old,
2063                        new ast::NameExpr(
2064                                old->location,
2065                                old->get_name()
2066                        )
2067                );
[6d51bd7]2068        }
2069
[19e567dd]2070        virtual void visit( CastExpr * old ) override final {
2071                this->node = visitBaseExpr( old,
2072                        new ast::CastExpr(
2073                                old->location,
[28c89f4]2074                                GET_ACCEPT_1(arg, Expr),
[19e567dd]2075                                old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
2076                        )
2077                );
[6d51bd7]2078        }
2079
[28c89f4]2080        virtual void visit( KeywordCastExpr * old) override final {
2081                ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
2082                switch (old->target) {
2083                        case KeywordCastExpr::Coroutine:
2084                                castTarget = ast::KeywordCastExpr::Coroutine;
2085                                break;
2086                        case KeywordCastExpr::Thread:
2087                                castTarget = ast::KeywordCastExpr::Thread;
2088                                break;
2089                        case KeywordCastExpr::Monitor:
2090                                castTarget = ast::KeywordCastExpr::Monitor;
2091                                break;
2092                        default:
2093                                break;
2094                }
2095                assert ( castTarget < ast::KeywordCastExpr::NUMBER_OF_TARGETS );
2096                this->node = visitBaseExpr( old,
2097                        new ast::KeywordCastExpr(
2098                                old->location,
2099                                GET_ACCEPT_1(arg, Expr),
2100                                castTarget
2101                        )
2102                );
[6d51bd7]2103        }
2104
[28c89f4]2105        virtual void visit( VirtualCastExpr * old ) override final {
[20de6fb]2106                this->node = visitBaseExpr_SkipResultType( old,
[28c89f4]2107                        new ast::VirtualCastExpr(
2108                                old->location,
2109                                GET_ACCEPT_1(arg, Expr),
[20de6fb]2110                                GET_ACCEPT_1(result, Type)
[28c89f4]2111                        )
2112                );
[6d51bd7]2113        }
2114
[28c89f4]2115        virtual void visit( AddressExpr * old ) override final {
2116                this->node = visitBaseExpr( old,
2117                        new ast::AddressExpr(
2118                                old->location,
2119                                GET_ACCEPT_1(arg, Expr)
2120                        )
2121                );
[6d51bd7]2122        }
2123
[28c89f4]2124        virtual void visit( LabelAddressExpr * old ) override final {
2125                this->node = visitBaseExpr( old,
2126                        new ast::LabelAddressExpr(
2127                                old->location,
2128                                make_label(&old->arg)
2129                        )
2130                );
[6d51bd7]2131        }
2132
[28c89f4]2133        virtual void visit( UntypedMemberExpr * old ) override final {
2134                this->node = visitBaseExpr( old,
2135                        new ast::UntypedMemberExpr(
2136                                old->location,
2137                                GET_ACCEPT_1(member, Expr),
2138                                GET_ACCEPT_1(aggregate, Expr)
2139                        )
2140                );
[6d51bd7]2141        }
2142
[28c89f4]2143        virtual void visit( MemberExpr * old ) override final {
2144                this->node = visitBaseExpr( old,
2145                        new ast::MemberExpr(
2146                                old->location,
[2a54479]2147                                GET_ACCEPT_1(member, DeclWithType),
[28c89f4]2148                                GET_ACCEPT_1(aggregate, Expr)
2149                        )
2150                );
[6d51bd7]2151        }
2152
[28c89f4]2153        virtual void visit( VariableExpr * old ) override final {
[546e712]2154                auto expr = new ast::VariableExpr(
2155                        old->location
2156                );
2157
2158                expr->var = GET_ACCEPT_1(var, DeclWithType);
[6896548]2159                visitBaseExpr( old, expr );
2160
[546e712]2161                this->node = expr;
[6d51bd7]2162        }
2163
[28c89f4]2164        bool isIntlikeConstantType(const Type *t) {
2165                if ( const BasicType * basicType = dynamic_cast< const BasicType * >( t ) ) {
2166                        if ( basicType->isInteger() ) {
2167                                return true;
2168                        }
2169                } else if ( dynamic_cast< const OneType * >( t ) ) {
2170                        return true;
2171                } else if ( dynamic_cast< const ZeroType * >( t ) ) {
2172                        return true;
2173                } else if ( dynamic_cast< const PointerType * >( t ) ) {
2174                        // null pointer constants, with zero int-values
2175                        return true;
2176                }
2177                return false;
[6d51bd7]2178        }
2179
[28c89f4]2180        int isFloatlikeConstantType(const Type *t) {
2181                if ( const BasicType * bty = dynamic_cast< const BasicType * >( t ) ) {
2182                        if ( ! bty->isInteger() ) {
2183                                return true;
2184                        }
2185                }
2186                return false;
[6d51bd7]2187        }
2188
[28c89f4]2189        int isStringlikeConstantType(const Type *t) {
[558d13b]2190                const Type *referentType = nullptr;
[28c89f4]2191                if ( const ArrayType * aty = dynamic_cast< const ArrayType * >( t ) ) {
[558d13b]2192                        referentType = aty->base;
2193                } else if ( const PointerType * pty = dynamic_cast< const PointerType * >( t ) ) {
2194                        referentType = pty->base;
2195                }
2196                if (referentType) {
2197                        if ( const BasicType * bty = dynamic_cast< const BasicType * >( referentType ) ) {
[28c89f4]2198                           if ( bty->kind == BasicType::Kind::Char ) {
2199                                   return true;
2200                           }
2201                        }
2202                }
2203                return false;
[6d51bd7]2204        }
2205
[28c89f4]2206        virtual void visit( ConstantExpr * old ) override final {
2207                ast::ConstantExpr *rslt = nullptr;
[558d13b]2208                if (isStringlikeConstantType(old->result)) {
[28c89f4]2209                        rslt = new ast::ConstantExpr(
2210                                old->location,
[6896548]2211                                GET_ACCEPT_1(result, Type), // preserve the expression-level type (old->result, not old->constant.type); see new-to-old
[28c89f4]2212                                old->constant.get_value(),
[558d13b]2213                                0,
2214                                ast::ConstantExpr::Kind::String
[28c89f4]2215                        );
[558d13b]2216                } else if (isIntlikeConstantType(old->result)) {
[28c89f4]2217                        rslt = new ast::ConstantExpr(
2218                                old->location,
[0b57626]2219                                GET_ACCEPT_1(result, Type),
2220                                old->constant.get_value(),
[558d13b]2221                                (unsigned long long) old->intValue(),
2222                                ast::ConstantExpr::Kind::Integer
[28c89f4]2223                        );
[558d13b]2224                } else if (isFloatlikeConstantType(old->result)) {
[8568319]2225                        rslt = new ast::ConstantExpr(
[28c89f4]2226                                old->location,
[8568319]2227                                GET_ACCEPT_1(result, Type),
2228                                old->constant.get_value(),
[558d13b]2229                                (double) old->constant.get_dval()
[28c89f4]2230                        );
2231                }
2232                assert(rslt);
2233                this->node = visitBaseExpr( old, rslt );
2234        }
2235
2236        virtual void visit( SizeofExpr * old ) override final {
2237                assert (old->expr || old->type);
2238                assert (! (old->expr && old->type));
2239                ast::SizeofExpr *rslt;
2240                if (old->expr) {
2241                        assert(!old->isType);
2242                        rslt = new ast::SizeofExpr(
[0b57626]2243                                old->location,
[28c89f4]2244                                GET_ACCEPT_1(expr, Expr)
2245                        );
2246                }
2247                if (old->type) {
2248                        assert(old->isType);
2249                        rslt = new ast::SizeofExpr(
[0b57626]2250                                old->location,
[28c89f4]2251                                GET_ACCEPT_1(type, Type)
2252                        );
2253                }
2254                this->node = visitBaseExpr( old, rslt );
2255        }
2256
2257        virtual void visit( AlignofExpr * old ) override final {
2258                assert (old->expr || old->type);
2259                assert (! (old->expr && old->type));
2260                ast::AlignofExpr *rslt;
2261                if (old->expr) {
2262                        assert(!old->isType);
2263                        rslt = new ast::AlignofExpr(
[0b57626]2264                                old->location,
[28c89f4]2265                                GET_ACCEPT_1(expr, Expr)
2266                        );
2267                }
2268                if (old->type) {
2269                        assert(old->isType);
2270                        rslt = new ast::AlignofExpr(
[0b57626]2271                                old->location,
[28c89f4]2272                                GET_ACCEPT_1(type, Type)
2273                        );
2274                }
2275                this->node = visitBaseExpr( old, rslt );
[6d51bd7]2276        }
2277
[28c89f4]2278        virtual void visit( UntypedOffsetofExpr * old ) override final {
2279                this->node = visitBaseExpr( old,
2280                        new ast::UntypedOffsetofExpr(
2281                                old->location,
2282                                GET_ACCEPT_1(type, Type),
2283                                old->member
2284                        )
2285                );
[6d51bd7]2286        }
2287
[28c89f4]2288        virtual void visit( OffsetofExpr * old ) override final {
2289                this->node = visitBaseExpr( old,
2290                        new ast::OffsetofExpr(
2291                                old->location,
2292                                GET_ACCEPT_1(type, Type),
[2a54479]2293                                GET_ACCEPT_1(member, DeclWithType)
[28c89f4]2294                        )
2295                );
[6d51bd7]2296        }
2297
[28c89f4]2298        virtual void visit( OffsetPackExpr * old ) override final {
2299                this->node = visitBaseExpr( old,
2300                        new ast::OffsetPackExpr(
2301                                old->location,
2302                                GET_ACCEPT_1(type, StructInstType)
2303                        )
2304                );
[6d51bd7]2305        }
2306
[28c89f4]2307        virtual void visit( LogicalExpr * old ) override final {
2308                this->node = visitBaseExpr( old,
2309                        new ast::LogicalExpr(
2310                                old->location,
2311                                GET_ACCEPT_1(arg1, Expr),
2312                                GET_ACCEPT_1(arg2, Expr),
[0b57626]2313                                old->get_isAnd() ?
[28c89f4]2314                                        ast::LogicalFlag::AndExpr :
2315                                        ast::LogicalFlag::OrExpr
2316                        )
2317                );
[6d51bd7]2318        }
2319
[28c89f4]2320        virtual void visit( ConditionalExpr * old ) override final {
2321                this->node = visitBaseExpr( old,
2322                        new ast::ConditionalExpr(
2323                                old->location,
2324                                GET_ACCEPT_1(arg1, Expr),
2325                                GET_ACCEPT_1(arg2, Expr),
2326                                GET_ACCEPT_1(arg3, Expr)
2327                        )
2328                );
2329        }
[6d51bd7]2330
[28c89f4]2331        virtual void visit( CommaExpr * old ) override final {
2332                this->node = visitBaseExpr( old,
2333                        new ast::CommaExpr(
2334                                old->location,
2335                                GET_ACCEPT_1(arg1, Expr),
2336                                GET_ACCEPT_1(arg2, Expr)
2337                        )
2338                );
[6d51bd7]2339        }
2340
[20de6fb]2341        virtual void visit( TypeExpr * old ) override final {
2342                this->node = visitBaseExpr( old,
2343                        new ast::TypeExpr(
2344                                old->location,
2345                                GET_ACCEPT_1(type, Type)
2346                        )
2347                );
[6d51bd7]2348        }
2349
[20de6fb]2350        virtual void visit( AsmExpr * old ) override final {
2351                this->node = visitBaseExpr( old,
2352                        new ast::AsmExpr(
2353                                old->location,
2354                                GET_ACCEPT_1(inout, Expr),
2355                                GET_ACCEPT_1(constraint, Expr),
2356                                GET_ACCEPT_1(operand, Expr)
2357                        )
2358                );
[6d51bd7]2359        }
2360
[20de6fb]2361        virtual void visit( ImplicitCopyCtorExpr * old ) override final {
2362                auto rslt = new ast::ImplicitCopyCtorExpr(
2363                        old->location,
2364                        GET_ACCEPT_1(callExpr, ApplicationExpr)
2365                );
[6d51bd7]2366
[20de6fb]2367                this->node = visitBaseExpr( old, rslt );
[6d51bd7]2368        }
2369
[20de6fb]2370        virtual void visit( ConstructorExpr * old ) override final {
2371                this->node = visitBaseExpr( old,
2372                        new ast::ConstructorExpr(
2373                                old->location,
2374                                GET_ACCEPT_1(callExpr, Expr)
2375                        )
2376                );
[6d51bd7]2377        }
2378
[20de6fb]2379        virtual void visit( CompoundLiteralExpr * old ) override final {
2380                this->node = visitBaseExpr_SkipResultType( old,
2381                        new ast::CompoundLiteralExpr(
2382                                old->location,
2383                                GET_ACCEPT_1(result, Type),
2384                                GET_ACCEPT_1(initializer, Init)
2385                        )
2386                );
[6d51bd7]2387        }
2388
[20de6fb]2389        virtual void visit( RangeExpr * old ) override final {
2390                this->node = visitBaseExpr( old,
2391                        new ast::RangeExpr(
2392                                old->location,
2393                                GET_ACCEPT_1(low, Expr),
2394                                GET_ACCEPT_1(high, Expr)
2395                        )
2396                );
[6d51bd7]2397        }
2398
[20de6fb]2399        virtual void visit( UntypedTupleExpr * old ) override final {
2400                this->node = visitBaseExpr( old,
2401                        new ast::UntypedTupleExpr(
2402                                old->location,
2403                                GET_ACCEPT_V(exprs, Expr)
2404                        )
2405                );
[6d51bd7]2406        }
2407
[20de6fb]2408        virtual void visit( TupleExpr * old ) override final {
2409                this->node = visitBaseExpr( old,
2410                        new ast::TupleExpr(
2411                                old->location,
2412                                GET_ACCEPT_V(exprs, Expr)
2413                        )
2414                );
[6d51bd7]2415        }
2416
[20de6fb]2417        virtual void visit( TupleIndexExpr * old ) override final {
2418                this->node = visitBaseExpr( old,
2419                        new ast::TupleIndexExpr(
2420                                old->location,
2421                                GET_ACCEPT_1(tuple, Expr),
2422                                old->index
2423                        )
2424                );
[6d51bd7]2425        }
2426
[20de6fb]2427        virtual void visit( TupleAssignExpr * old ) override final {
2428                this->node = visitBaseExpr_SkipResultType( old,
2429                        new ast::TupleAssignExpr(
2430                                old->location,
2431                                GET_ACCEPT_1(result, Type),
2432                                GET_ACCEPT_1(stmtExpr, StmtExpr)
2433                        )
2434                );
[6d51bd7]2435        }
2436
[20de6fb]2437        virtual void visit( StmtExpr * old ) override final {
2438                auto rslt = new ast::StmtExpr(
2439                        old->location,
2440                        GET_ACCEPT_1(statements, CompoundStmt)
2441                );
2442                rslt->returnDecls = GET_ACCEPT_V(returnDecls, ObjectDecl);
2443                rslt->dtors       = GET_ACCEPT_V(dtors      , Expr);
[6d51bd7]2444
[20de6fb]2445                this->node = visitBaseExpr_SkipResultType( old, rslt );
[6d51bd7]2446        }
2447
[20de6fb]2448        virtual void visit( UniqueExpr * old ) override final {
2449                auto rslt = new ast::UniqueExpr(
2450                        old->location,
2451                        GET_ACCEPT_1(expr, Expr)
2452                );
2453                rslt->object = GET_ACCEPT_1(object, ObjectDecl);
2454                rslt->var    = GET_ACCEPT_1(var   , VariableExpr);
[6d51bd7]2455
[20de6fb]2456                this->node = visitBaseExpr( old, rslt );
[6d51bd7]2457        }
2458
[20de6fb]2459        virtual void visit( UntypedInitExpr * old ) override final {
[60aaa51d]2460                std::deque<ast::InitAlternative> initAlts;
[20de6fb]2461                for (auto ia : old->initAlts) {
2462                        initAlts.push_back(ast::InitAlternative(
2463                                getAccept1< ast::Type, Type * >( ia.type ),
2464                                getAccept1< ast::Designation, Designation * >( ia.designation )
2465                        ));
2466                }
2467                this->node = visitBaseExpr( old,
2468                        new ast::UntypedInitExpr(
2469                                old->location,
2470                                GET_ACCEPT_1(expr, Expr),
2471                                std::move(initAlts)
2472                        )
2473                );
[6d51bd7]2474        }
2475
[20de6fb]2476        virtual void visit( InitExpr * old ) override final {
2477                this->node = visitBaseExpr( old,
2478                        new ast::InitExpr(
2479                                old->location,
2480                                GET_ACCEPT_1(expr, Expr),
2481                                GET_ACCEPT_1(designation, Designation)
2482                        )
2483                );
[6d51bd7]2484        }
2485
[20de6fb]2486        virtual void visit( DeletedExpr * old ) override final {
2487                this->node = visitBaseExpr( old,
2488                        new ast::DeletedExpr(
2489                                old->location,
2490                                GET_ACCEPT_1(expr, Expr),
2491                                inCache(old->deleteStmt) ?
2492                                        this->node :
2493                                        GET_ACCEPT_1(deleteStmt, Node)
2494                        )
2495                );
[6d51bd7]2496        }
2497
[20de6fb]2498        virtual void visit( DefaultArgExpr * old ) override final {
2499                this->node = visitBaseExpr( old,
2500                        new ast::DefaultArgExpr(
2501                                old->location,
2502                                GET_ACCEPT_1(expr, Expr)
2503                        )
2504                );
2505        }
[6d51bd7]2506
[20de6fb]2507        virtual void visit( GenericExpr * old ) override final {
2508                std::vector<ast::GenericExpr::Association> associations;
2509                for (auto association : old->associations) {
2510                        associations.push_back(ast::GenericExpr::Association(
2511                                getAccept1< ast::Type, Type * >( association.type ),
2512                                getAccept1< ast::Expr, Expression * >( association.expr )
2513                        ));
2514                }
2515                this->node = visitBaseExpr( old,
2516                        new ast::GenericExpr(
2517                                old->location,
2518                                GET_ACCEPT_1(control, Expr),
2519                                std::move(associations)
2520                        )
2521                );
[6d51bd7]2522        }
2523
[d148778]2524        virtual void visit( VoidType * old ) override final {
2525                this->node = new ast::VoidType{ cv( old ) };
[6d51bd7]2526        }
2527
[d148778]2528        virtual void visit( BasicType * old ) override final {
[2a54479]2529                auto type = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
2530                // I believe this should always be a BasicType.
2531                if ( Validate::SizeType == old ) {
2532                        sizeType = type;
2533                }
2534                this->node = type;
[6d51bd7]2535        }
2536
[d148778]2537        virtual void visit( PointerType * old ) override final {
2538                this->node = new ast::PointerType{
2539                        GET_ACCEPT_1( base, Type ),
2540                        GET_ACCEPT_1( dimension, Expr ),
2541                        (ast::LengthFlag)old->isVarLen,
2542                        (ast::DimensionFlag)old->isStatic,
2543                        cv( old )
2544                };
[6d51bd7]2545        }
2546
[d148778]2547        virtual void visit( ArrayType * old ) override final {
2548                this->node = new ast::ArrayType{
2549                        GET_ACCEPT_1( base, Type ),
2550                        GET_ACCEPT_1( dimension, Expr ),
2551                        (ast::LengthFlag)old->isVarLen,
2552                        (ast::DimensionFlag)old->isStatic,
2553                        cv( old )
2554                };
[6d51bd7]2555        }
2556
[d148778]2557        virtual void visit( ReferenceType * old ) override final {
2558                this->node = new ast::ReferenceType{
2559                        GET_ACCEPT_1( base, Type ),
2560                        cv( old )
2561                };
[6d51bd7]2562        }
2563
[d148778]2564        virtual void visit( QualifiedType * old ) override final {
2565                this->node = new ast::QualifiedType{
2566                        GET_ACCEPT_1( parent, Type ),
2567                        GET_ACCEPT_1( child, Type ),
2568                        cv( old )
2569                };
[6d51bd7]2570        }
2571
[d148778]2572        virtual void visit( FunctionType * old ) override final {
2573                auto ty = new ast::FunctionType {
2574                        (ast::ArgumentFlag)old->isVarArgs,
2575                        cv( old )
2576                };
2577                ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
2578                ty->params = GET_ACCEPT_V( parameters, DeclWithType );
2579                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
2580                this->node = ty;
[6d51bd7]2581        }
2582
[d148778]2583        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
2584                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
2585                ty->params = GET_ACCEPT_V( parameters, Expr );
2586                ty->hoistType = old->hoistType;
[6d51bd7]2587        }
2588
[d148778]2589        virtual void visit( StructInstType * old ) override final {
[b869ec5]2590                ast::StructInstType * ty;
2591                if ( old->baseStruct ) {
2592                        ty = new ast::StructInstType{
2593                                GET_ACCEPT_1( baseStruct, StructDecl ),
2594                                cv( old ),
2595                                GET_ACCEPT_V( attributes, Attribute )
2596                        };
2597                } else {
2598                        ty = new ast::StructInstType{
2599                                old->name,
2600                                cv( old ),
2601                                GET_ACCEPT_V( attributes, Attribute )
2602                        };
2603                }
[d148778]2604                postvisit( old, ty );
2605                this->node = ty;
[6d51bd7]2606        }
2607
[d148778]2608        virtual void visit( UnionInstType * old ) override final {
[b869ec5]2609                ast::UnionInstType * ty;
2610                if ( old->baseUnion ) {
2611                        ty = new ast::UnionInstType{
2612                                GET_ACCEPT_1( baseUnion, UnionDecl ),
2613                                cv( old ),
2614                                GET_ACCEPT_V( attributes, Attribute )
2615                        };
2616                } else {
2617                        ty = new ast::UnionInstType{
2618                                old->name,
2619                                cv( old ),
2620                                GET_ACCEPT_V( attributes, Attribute )
2621                        };
2622                }
[d148778]2623                postvisit( old, ty );
2624                this->node = ty;
[6d51bd7]2625        }
2626
[d148778]2627        virtual void visit( EnumInstType * old ) override final {
[b869ec5]2628                ast::EnumInstType * ty;
2629                if ( old->baseEnum ) {
2630                        ty = new ast::EnumInstType{
2631                                GET_ACCEPT_1( baseEnum, EnumDecl ),
2632                                cv( old ),
2633                                GET_ACCEPT_V( attributes, Attribute )
2634                        };
2635                } else {
2636                        ty = new ast::EnumInstType{
2637                                old->name,
2638                                cv( old ),
2639                                GET_ACCEPT_V( attributes, Attribute )
2640                        };
2641                }
[d148778]2642                postvisit( old, ty );
2643                this->node = ty;
[6d51bd7]2644        }
2645
[d148778]2646        virtual void visit( TraitInstType * old ) override final {
[b869ec5]2647                ast::TraitInstType * ty;
2648                if ( old->baseTrait ) {
2649                        ty = new ast::TraitInstType{
2650                                GET_ACCEPT_1( baseTrait, TraitDecl ),
2651                                cv( old ),
2652                                GET_ACCEPT_V( attributes, Attribute )
2653                        };
2654                } else {
2655                        ty = new ast::TraitInstType{
2656                                old->name,
2657                                cv( old ),
2658                                GET_ACCEPT_V( attributes, Attribute )
2659                        };
2660                }
[d148778]2661                postvisit( old, ty );
2662                this->node = ty;
2663        }
[6d51bd7]2664
[d148778]2665        virtual void visit( TypeInstType * old ) override final {
[514a791]2666                ast::TypeInstType * ty;
2667                if ( old->baseType ) {
2668                        ty = new ast::TypeInstType{
2669                                old->name,
[b869ec5]2670                                GET_ACCEPT_1( baseType, TypeDecl ),
[514a791]2671                                cv( old ),
2672                                GET_ACCEPT_V( attributes, Attribute )
2673                        };
2674                } else {
2675                        ty = new ast::TypeInstType{
2676                                old->name,
2677                                old->isFtype ? ast::TypeVar::Ftype : ast::TypeVar::Dtype,
2678                                cv( old ),
2679                                GET_ACCEPT_V( attributes, Attribute )
2680                        };
2681                }
[d148778]2682                postvisit( old, ty );
2683                this->node = ty;
[6d51bd7]2684        }
2685
[746ae82]2686        virtual void visit( TupleType * old ) override final {
2687                this->node = new ast::TupleType{
2688                        GET_ACCEPT_V( types, Type ),
2689                        // members generated by TupleType c'tor
2690                        cv( old )
2691                };
[6d51bd7]2692        }
2693
[746ae82]2694        virtual void visit( TypeofType * old ) override final {
2695                this->node = new ast::TypeofType{
2696                        GET_ACCEPT_1( expr, Expr ),
2697                        (ast::TypeofType::Kind)old->is_basetypeof,
2698                        cv( old )
2699                };
[6d51bd7]2700        }
2701
2702        virtual void visit( AttrType * ) override final {
[746ae82]2703                assertf( false, "AttrType deprecated in new AST." );
[6d51bd7]2704        }
2705
[746ae82]2706        virtual void visit( VarArgsType * old ) override final {
2707                this->node = new ast::VarArgsType{ cv( old ) };
[6d51bd7]2708        }
2709
[746ae82]2710        virtual void visit( ZeroType * old ) override final {
2711                this->node = new ast::ZeroType{ cv( old ) };
[6d51bd7]2712        }
2713
[746ae82]2714        virtual void visit( OneType * old ) override final {
2715                this->node = new ast::OneType{ cv( old ) };
[6d51bd7]2716        }
2717
2718        virtual void visit( GlobalScopeType * ) override final {
[746ae82]2719                this->node = new ast::GlobalScopeType{};
[6d51bd7]2720        }
2721
[74ad8c0]2722        virtual void visit( Designation * old ) override final {
2723                this->node = new ast::Designation(
2724                        old->location,
[60aaa51d]2725                        GET_ACCEPT_D(designators, Expr)
[74ad8c0]2726                );
[6d51bd7]2727        }
2728
[74ad8c0]2729        virtual void visit( SingleInit * old ) override final {
2730                this->node = new ast::SingleInit(
2731                        old->location,
2732                        GET_ACCEPT_1(value, Expr),
2733                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
2734                );
[6d51bd7]2735        }
2736
[74ad8c0]2737        virtual void visit( ListInit * old ) override final {
2738                this->node = new ast::ListInit(
2739                        old->location,
2740                        GET_ACCEPT_V(initializers, Init),
2741                        GET_ACCEPT_V(designations, Designation),
2742                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
2743                );
[6d51bd7]2744        }
2745
[74ad8c0]2746        virtual void visit( ConstructorInit * old ) override final {
2747                this->node = new ast::ConstructorInit(
2748                        old->location,
2749                        GET_ACCEPT_1(ctor, Stmt),
2750                        GET_ACCEPT_1(dtor, Stmt),
2751                        GET_ACCEPT_1(init, Init)
2752                );
[6d51bd7]2753        }
2754
2755        virtual void visit( Constant * ) override final {
[dd6d7c6]2756                // Handled in visit( ConstantEpxr * ).
2757                // In the new tree, Constant fields are inlined into containing ConstantExpression.
2758                assert( 0 );
[6d51bd7]2759        }
2760
[dd6d7c6]2761        virtual void visit( Attribute * old ) override final {
2762                this->node = new ast::Attribute(
2763                        old->name,
2764                        GET_ACCEPT_V( parameters, Expr )
2765                );
[6d51bd7]2766        }
[b336af9]2767
2768        virtual void visit( AttrExpr * ) override final {
[dd6d7c6]2769                assertf( false, "AttrExpr deprecated in new AST." );
[b336af9]2770        }
[6d51bd7]2771};
2772
[6f8e87d]2773#undef GET_LABELS_V
2774#undef GET_ACCEPT_V
2775#undef GET_ACCEPT_1
2776
[74dbbf6]2777std::list< ast::ptr< ast::Decl > > convert( const std::list< Declaration * > && translationUnit ) {
[6d51bd7]2778        ConverterOldToNew c;
2779        std::list< ast::ptr< ast::Decl > > decls;
2780        for(auto d : translationUnit) {
2781                d->accept( c );
2782                decls.emplace_back( c.decl() );
2783        }
[8abee136]2784        deleteAll(translationUnit);
[6d51bd7]2785        return decls;
[6f8e87d]2786}
Note: See TracBrowser for help on using the repository browser.