source: src/AST/Convert.cpp @ a935892

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

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

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