source: src/AST/Convert.cpp @ f57dd25

arm-ehenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since f57dd25 was f57dd25, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Merge branch 'cleanup-dtors'

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