source: src/AST/Convert.cpp @ 7675f58

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 7675f58 was 7edd5c1, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Assorted fixes to the AST, found while I was trying to add more invarant checks.

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