source: src/AST/Convert.cpp @ 044ae62

ADT
Last change on this file since 044ae62 was 044ae62, checked in by JiadaL <j82liang@…>, 12 months ago

Merge branch 'master' into ADT

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