source: src/AST/Convert.cpp @ 157a816

arm-ehenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 157a816 was 157a816, checked in by Andrew Beach <ajbeach@…>, 4 years ago

Convert supports SymTab::dereferenceOperator and some sue declarations return the proper type now.

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