source: src/AST/Convert.cpp @ 0aedb01

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 0aedb01 was 0aedb01, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Fix error introduced in merge

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