source: src/AST/Convert.cpp @ ef5ef56

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since ef5ef56 was 8abee136, checked in by Michael Brooks <mlbrooks@…>, 5 years ago

early bug fixes from running conversion old-new-old, just before resolver

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