source: src/AST/Convert.cpp @ 92538ab

ADTast-experimentalenumpthread-emulationqualifiedEnum
Last change on this file since 92538ab was 92538ab, checked in by JiadaL <j82liang@…>, 2 years ago

Resolve conflict

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