source: src/AST/Convert.cpp @ 2c04369

arm-ehcleanup-dtorsjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since 2c04369 was 2c04369, checked in by Andrew Beach <ajbeach@…>, 3 years ago

Fixed some problems in convert. One of which was better solved by removing the FindSpecialDeclarations? hack.

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