source: src/AST/Convert.cpp @ 729df21

ADTast-experimentalenumpthread-emulationqualifiedEnum
Last change on this file since 729df21 was b230091, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Added a 'missing' TypeInstType? constructor and rewrote some calls to use it.

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