source: src/AST/Convert.cpp @ 46da46b

ast-experimental
Last change on this file since 46da46b was 46da46b, checked in by Fangren Yu <f37yu@…>, 13 months ago

current progress

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