source: src/AST/Convert.cpp @ 20de6fb

arm-ehcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 20de6fb was 20de6fb, checked in by Michael Brooks <mlbrooks@…>, 4 years ago

finished draft past of converting expressions

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