source: src/AST/Convert.cpp @ 07d867b

arm-ehjacob/cs343-translationnew-astnew-ast-unique-expr
Last change on this file since 07d867b was 07d867b, checked in by Fangren Yu <f37yu@…>, 16 months ago

attempt to fix inferparams

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