source: src/AST/Convert.cpp @ 043a5b6

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

Extended dereference operator hack to destroy clause

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