source: src/AST/Convert.cpp @ 4962741

ADTast-experimentalpthread-emulation
Last change on this file since 4962741 was 1931bb01, checked in by Andrew Beach <ajbeach@…>, 23 months ago

Converted 'Validate A' to the new AST. There some utility changes as well.

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