source: src/AST/Convert.cpp @ 1259c35

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

Merge branch 'master' into cleanup-dtors

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