source: src/AST/Convert.cpp @ eb779d5

Last change on this file since eb779d5 was eb779d5, checked in by caparsons <caparson@…>, 8 months ago

Implemented corun statement

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