source: src/AST/Convert.cpp @ af1e8f56

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since af1e8f56 was 20a5977, checked in by Aaron Moss <a3moss@…>, 6 years ago

Added kind to ConstantExpr? and some Expr prints

  • Property mode set to 100644
File size: 69.7 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Convert.cpp -- Convert between the new and old syntax trees.
8//
9// Author           : Thierry Delisle
10// Created On       : Thu May 09 15::37::05 2019
11// Last Modified By : Andrew Beach
12// Last Modified On : Tue May 21 15:30:00 2019
13// Update Count     : 5
14//
15
16#include "Convert.hpp"
17
18#include <unordered_map>
19
20#include "AST/Attribute.hpp"
21#include "AST/Decl.hpp"
22#include "AST/Expr.hpp"
23#include "AST/Init.hpp"
24#include "AST/Stmt.hpp"
25#include "AST/TypeSubstitution.hpp"
26
27#include "SynTree/Attribute.h"
28#include "SynTree/Declaration.h"
29#include "SynTree/TypeSubstitution.h"
30
31//================================================================================================
32// Utilities
33template<template <class...> class C>
34struct to {
35        template<typename T>
36        static auto from( T && v ) -> C< typename T::value_type > {
37                C< typename T::value_type > l;
38                std::move(std::begin(v), std::end(v), std::back_inserter(l));
39                return l;
40        }
41};
42
43//================================================================================================
44class ConverterNewToOld : public ast::Visitor {
45        BaseSyntaxNode * node = nullptr;
46        using Cache = std::unordered_map< const ast::Node *, BaseSyntaxNode * >;
47        Cache cache;
48
49        template<typename T>
50        struct Getter {
51                ConverterNewToOld & visitor;
52
53                template<typename U, enum ast::Node::ref_type R>
54                T * accept1( const ast::ptr_base<U, R> & ptr ) {
55                        if ( ! ptr ) return nullptr;
56                        ptr->accept( visitor );
57                        T * ret = strict_dynamic_cast< T * >( visitor.node );
58                        visitor.node = nullptr;
59                        return ret;
60                }
61
62                template<typename U>
63                std::list< T * > acceptL( const U & container ) {
64                        std::list< T * > ret;
65                        for (auto ptr : container ) {
66                                ret.emplace_back( accept1( ptr ) );
67                        }
68                        return ret;
69                }
70        };
71
72    template<typename T>
73    Getter<T> get() {
74        return Getter<T>{ *this };
75    }
76
77        Label makeLabel(Statement * labelled, const ast::Label& label) {
78                return Label(
79                        label.name,
80                        labelled,
81                        get<Attribute>().acceptL(label.attributes)
82                );
83        }
84
85        template<template <class...> class C>
86        std::list<Label> makeLabelL(Statement * labelled, const C<ast::Label>& labels) {
87                std::list<Label> ret;
88                for (auto label : labels) {
89                        ret.push_back( makeLabel(labelled, label) );
90                }
91                return ret;
92        }
93
94        /// get new qualifiers from old type
95        Type::Qualifiers cv( const ast::Type * ty ) { return { ty->qualifiers.val }; }
96
97        /// returns true and sets `node` if in cache
98        bool inCache( const ast::Node * node ) {
99                auto it = cache.find( node );
100                if ( it == cache.end() ) return false;
101                this->node = it->second;
102                return true;
103        }
104
105public:
106        Declaration * decl( const ast::Decl * declNode ) {
107                return get<Declaration>().accept1( ast::ptr<ast::Decl>( declNode ) );
108        }
109
110private:
111        void declPostamble( Declaration * decl, const ast::Decl * node ) {
112                decl->location = node->location;
113                // name comes from constructor
114                // linkage comes from constructor
115                decl->extension = node->extension;
116                decl->uniqueId = node->uniqueId;
117                // storageClasses comes from constructor
118                this->node = decl;
119        }
120
121        const ast::DeclWithType * declWithTypePostamble (
122                        DeclarationWithType * decl, const ast::DeclWithType * node ) {
123                declPostamble( decl, node );
124                decl->mangleName = node->mangleName;
125                decl->scopeLevel = node->scopeLevel;
126                decl->asmName = get<Expression>().accept1( node->asmName );
127                // attributes comes from constructor
128                decl->isDeleted = node->isDeleted;
129                // fs comes from constructor
130                cache.emplace( node, decl );
131                return nullptr;
132        }
133
134        const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
135                if ( inCache( node ) ) return nullptr;
136                auto decl = new ObjectDecl(
137                        node->name,
138                        Type::StorageClasses( node->storage.val ),
139                        LinkageSpec::Spec( node->linkage.val ),
140                        get<Expression>().accept1( node->bitfieldWidth ),
141                        get<Type>().accept1( node->type ),
142                        get<Initializer>().accept1( node->init ),
143                        get<Attribute>().acceptL( node->attributes ),
144                        Type::FuncSpecifiers( node->funcSpec.val )
145                );
146                return declWithTypePostamble( decl, node );
147        }
148
149        const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
150                if ( inCache( node ) ) return nullptr;
151                auto decl = new FunctionDecl(
152                        node->name,
153                        Type::StorageClasses( node->storage.val ),
154                        LinkageSpec::Spec( node->linkage.val ),
155                        get<FunctionType>().accept1( node->type ),
156                        get<CompoundStmt>().accept1( node->stmts ),
157                        get<Attribute>().acceptL( node->attributes ),
158                        Type::FuncSpecifiers( node->funcSpec.val )
159                );
160                decl->withExprs = get<Expression>().acceptL( node->withExprs );
161                return declWithTypePostamble( decl, node );
162        }
163
164        // NamedTypeDecl
165        const ast::Decl * namedTypePostamble( NamedTypeDecl * decl, const ast::NamedTypeDecl * node ) {
166                declPostamble( decl, node );
167                // base comes from constructor
168                decl->parameters = get<TypeDecl>().acceptL( node->params );
169                decl->assertions = get<DeclarationWithType>().acceptL( node->assertions );
170                return nullptr;
171        }
172
173        const ast::Decl * visit( const ast::TypeDecl * node ) override final {
174                if ( inCache( node ) ) return nullptr;
175                auto decl = new TypeDecl(
176                        node->name,
177                        Type::StorageClasses( node->storage.val ),
178                        get<Type>().accept1( node->base ),
179                        (TypeDecl::Kind)(unsigned)node->kind,
180                        node->sized,
181                        get<Type>().accept1( node->init )
182                );
183                cache.emplace( node, decl );
184                return namedTypePostamble( decl, node );
185        }
186
187        const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
188                auto decl = new TypedefDecl(
189                        node->name,
190                        node->location,
191                        Type::StorageClasses( node->storage.val ),
192            get<Type>().accept1( node->base ),
193                        LinkageSpec::Spec( node->linkage.val )
194                );
195                return namedTypePostamble( decl, node );
196        }
197
198        const ast::Decl * aggregatePostamble( AggregateDecl * decl, const ast::AggregateDecl * node ) {
199                decl->members = get<Declaration>().acceptL( node->members );
200                decl->parameters = get<TypeDecl>().acceptL( node->params );
201                decl->body = node->body;
202                // attributes come from constructor
203                decl->parent = get<AggregateDecl>().accept1( node->parent );
204                cache.emplace( node, decl );
205                return nullptr;
206        }
207
208        const ast::Decl * visit( const ast::StructDecl * node ) override final {
209                if ( inCache( node ) ) return nullptr;
210                auto decl = new StructDecl(
211                        node->name,
212                        node->kind,
213                        get<Attribute>().acceptL( node->attributes ),
214                        LinkageSpec::Spec( node->linkage.val )
215                );
216                return aggregatePostamble( decl, node );
217        }
218
219        const ast::Decl * visit( const ast::UnionDecl * node ) override final {
220                if ( inCache( node ) ) return nullptr;
221                auto decl = new UnionDecl(
222                        node->name,
223                        get<Attribute>().acceptL( node->attributes ),
224                        LinkageSpec::Spec( node->linkage.val )
225                );
226                return aggregatePostamble( decl, node );
227        }
228
229        const ast::Decl * visit( const ast::EnumDecl * node ) override final {
230                if ( inCache( node ) ) return nullptr;
231                auto decl = new EnumDecl(
232                        node->name,
233                        get<Attribute>().acceptL( node->attributes ),
234                        LinkageSpec::Spec( node->linkage.val )
235                );
236                return aggregatePostamble( decl, node );
237        }
238
239        const ast::Decl * visit( const ast::TraitDecl * node ) override final {
240                if ( inCache( node ) ) return nullptr;
241                auto decl = new TraitDecl(
242                        node->name,
243                        {},
244                        LinkageSpec::Spec( node->linkage.val )
245                );
246                return aggregatePostamble( decl, node );
247        }
248
249        const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
250                auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) );
251                declPostamble( decl, node );
252                return nullptr;
253        }
254
255        const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
256                auto decl = new StaticAssertDecl(
257                        get<Expression>().accept1( node->cond ),
258                        get<ConstantExpr>().accept1( node->msg )
259                );
260                declPostamble( decl, node );
261                return nullptr;
262        }
263
264        const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) {
265                stmt->location = node->location;
266                stmt->labels = makeLabelL( stmt, node->labels );
267                cache.emplace( node, stmt );
268                this->node = stmt;
269                return nullptr;
270        }
271
272        const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
273                if ( inCache( node ) ) return nullptr;
274                auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) );
275                stmtPostamble( stmt, node );
276                return nullptr;
277        }
278
279        const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
280                if ( inCache( node ) ) return nullptr;
281                auto stmt = new ExprStmt( get<Expression>().accept1( node->expr ) );
282                return stmtPostamble( stmt, node );
283        }
284
285        const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
286                if ( inCache( node ) ) return nullptr;
287                auto stmt = new AsmStmt(
288                        node->isVolatile,
289                        get<Expression>().accept1( node->instruction ),
290                        get<Expression>().acceptL( node->output ),
291                        get<Expression>().acceptL( node->input ),
292                        get<ConstantExpr>().acceptL( node->clobber ),
293                        makeLabelL( nullptr, node->gotoLabels ) // What are these labelling?
294                );
295                return stmtPostamble( stmt, node );
296        }
297
298        const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
299                if ( inCache( node ) ) return nullptr;
300                auto stmt = new DirectiveStmt( node->directive );
301                return stmtPostamble( stmt, node );
302        }
303
304        const ast::Stmt * visit( const ast::IfStmt * node ) override final {
305                if ( inCache( node ) ) return nullptr;
306                auto stmt = new IfStmt(
307                        get<Expression>().accept1( node->cond ),
308                        get<Statement>().accept1( node->thenPart ),
309                        get<Statement>().accept1( node->elsePart ),
310                        get<Statement>().acceptL( node->inits )
311                );
312                return stmtPostamble( stmt, node );
313        }
314
315        const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
316                if ( inCache( node ) ) return nullptr;
317                auto stmt = new SwitchStmt(
318                        get<Expression>().accept1( node->cond ),
319                        get<Statement>().acceptL( node->stmts )
320                );
321                return stmtPostamble( stmt, node );
322        }
323
324        const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
325                if ( inCache( node ) ) return nullptr;
326                auto stmt = new CaseStmt(
327                        get<Expression>().accept1( node->cond ),
328                        get<Statement>().acceptL( node->stmts ),
329                        node->isDefault()
330                );
331                return stmtPostamble( stmt, node );
332        }
333
334        const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
335                if ( inCache( node ) ) return nullptr;
336                auto inits = get<Statement>().acceptL( node->inits );
337                auto stmt = new WhileStmt(
338                        get<Expression>().accept1( node->cond ),
339                        get<Statement>().accept1( node->body ),
340                        inits,
341                        node->isDoWhile
342                );
343                return stmtPostamble( stmt, node );
344        }
345
346        const ast::Stmt * visit( const ast::ForStmt * node ) override final {
347                if ( inCache( node ) ) return nullptr;
348                auto stmt = new ForStmt(
349                        get<Statement>().acceptL( node->inits ),
350                        get<Expression>().accept1( node->cond ),
351                        get<Expression>().accept1( node->inc ),
352                        get<Statement>().accept1( node->body )
353                );
354                return stmtPostamble( stmt, node );
355        }
356
357        const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
358                if ( inCache( node ) ) return nullptr;
359                BranchStmt * stmt;
360                if (node->computedTarget) {
361                        stmt = new BranchStmt( get<Expression>().accept1( node->computedTarget ),
362                                BranchStmt::Goto );
363                } else {
364                        BranchStmt::Type type;
365                        switch (node->kind) {
366                        #define CASE(n) \
367                        case ast::BranchStmt::n: \
368                                type = BranchStmt::n; \
369                                break
370                        CASE(Goto);
371                        CASE(Break);
372                        CASE(Continue);
373                        CASE(FallThrough);
374                        CASE(FallThroughDefault);
375                        #undef CASE
376                        default:
377                                assertf(false, "Invalid ast::BranchStmt::Kind: %d\n", node->kind);
378                        }
379
380                        // The labels here are also weird.
381                        stmt = new BranchStmt( makeLabel( nullptr, node->originalTarget ), type );
382                        stmt->target = makeLabel( stmt, node->target );
383                }
384                return stmtPostamble( stmt, node );
385        }
386
387        const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
388                if ( inCache( node ) ) return nullptr;
389                auto stmt = new ReturnStmt( get<Expression>().accept1( node->expr ) );
390                return stmtPostamble( stmt, node );
391        }
392
393        const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
394                if ( inCache( node ) ) return nullptr;
395                ThrowStmt::Kind kind;
396                switch (node->kind) {
397                case ast::ThrowStmt::Terminate:
398                        kind = ThrowStmt::Terminate;
399                        break;
400                case ast::ThrowStmt::Resume:
401                        kind = ThrowStmt::Resume;
402                        break;
403                default:
404                        assertf(false, "Invalid ast::ThrowStmt::Kind: %d\n", node->kind);
405                }
406                auto stmt = new ThrowStmt(
407                        kind,
408                        get<Expression>().accept1( node->expr ),
409                        get<Expression>().accept1( node->target )
410                );
411                return stmtPostamble( stmt, node );
412        }
413
414        const ast::Stmt * visit( const ast::TryStmt * node ) override final {
415                if ( inCache( node ) ) return nullptr;
416                auto handlers = get<CatchStmt>().acceptL( node->handlers );
417                auto stmt = new TryStmt(
418                        get<CompoundStmt>().accept1( node->body ),
419                        handlers,
420                        get<FinallyStmt>().accept1( node->finally )
421                );
422                return stmtPostamble( stmt, node );
423        }
424
425        const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
426                if ( inCache( node ) ) return nullptr;
427                CatchStmt::Kind kind;
428                switch (node->kind) {
429                case ast::CatchStmt::Terminate:
430                        kind = CatchStmt::Terminate;
431                        break;
432                case ast::CatchStmt::Resume:
433                        kind = CatchStmt::Resume;
434                        break;
435                default:
436                        assertf(false, "Invalid ast::CatchStmt::Kind: %d\n", node->kind);
437                }
438                auto stmt = new CatchStmt(
439                        kind,
440                        get<Declaration>().accept1( node->decl ),
441                        get<Expression>().accept1( node->cond ),
442                        get<Statement>().accept1( node->body )
443                );
444                return stmtPostamble( stmt, node );
445        }
446
447        const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
448                if ( inCache( node ) ) return nullptr;
449                auto stmt = new FinallyStmt( get<CompoundStmt>().accept1( node->body ) );
450                return stmtPostamble( stmt, node );
451        }
452
453        const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
454                if ( inCache( node ) ) return nullptr;
455                auto stmt = new WaitForStmt;
456                stmt->clauses.reserve( node->clauses.size() );
457                for ( auto clause : node->clauses ) {
458                        stmt->clauses.push_back({{
459                                        get<Expression>().accept1( clause.target.func ),
460                                        get<Expression>().acceptL( clause.target.args ),
461                                },
462                                get<Statement>().accept1( clause.stmt ),
463                                get<Expression>().accept1( clause.cond ),
464                        });
465                }
466                stmt->timeout = {
467                        get<Expression>().accept1( node->timeout.time ),
468                        get<Statement>().accept1( node->timeout.stmt ),
469                        get<Expression>().accept1( node->timeout.cond ),
470                };
471                stmt->orelse = {
472                        get<Statement>().accept1( node->orElse.stmt ),
473                        get<Expression>().accept1( node->orElse.cond ),
474                };
475                return stmtPostamble( stmt, node );
476        }
477
478        const ast::Stmt * visit( const ast::WithStmt * node ) override final {
479                if ( inCache( node ) ) return nullptr;
480                auto stmt = new WithStmt(
481                        get<Expression>().acceptL( node->exprs ),
482                        get<Statement>().accept1( node->stmt )
483                );
484                return stmtPostamble( stmt, node );
485        }
486
487        const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
488                if ( inCache( node ) ) return nullptr;
489                auto stmt = new NullStmt();
490                stmtPostamble( stmt, node );
491                return nullptr;
492        }
493
494        const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
495                if ( inCache( node ) ) return nullptr;
496                auto stmt = new DeclStmt( get<Declaration>().accept1( node->decl ) );
497                return stmtPostamble( stmt, node );
498        }
499
500        const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
501                if ( inCache( node ) ) return nullptr;
502                auto stmt = new ImplicitCtorDtorStmt{
503                        get<Statement>().accept1( node->callStmt )
504                };
505                return stmtPostamble( stmt, node );
506        }
507
508        TypeSubstitution * convertTypeSubstitution(const ast::TypeSubstitution * src) {
509
510                TypeSubstitution *rslt = new TypeSubstitution();
511
512                for (decltype(src->begin()) src_i = src->begin(); src_i != src->end(); src_i++) {
513                        rslt->add( src_i->first,
514                                   get<Type>().accept1(src_i->second) );
515                }
516
517                for (decltype(src->beginVar()) src_i = src->beginVar(); src_i != src->endVar(); src_i++) {
518                        rslt->addVar( src_i->first,
519                                      get<Expression>().accept1(src_i->second) );
520                }
521
522                return rslt;
523        }
524
525        void convertInferUnion(std::map<UniqueId,ParamEntry> &tgtInferParams,
526                                                   std::vector<UniqueId>         &tgtResnSlots,
527                                                   const ast::Expr::InferUnion   &srcInferred ) {
528
529                assert( tgtInferParams.empty() );
530                assert( tgtResnSlots.empty() );
531
532                if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
533                        const ast::InferredParams &srcParams = srcInferred.inferParamsConst();
534                        for (auto srcParam : srcParams) {
535                                tgtInferParams[srcParam.first] = ParamEntry(
536                                        srcParam.second.decl,
537                                        get<Type>().accept1(srcParam.second.actualType),
538                                        get<Type>().accept1(srcParam.second.formalType),
539                                        get<Expression>().accept1(srcParam.second.expr)
540                                );
541                        }
542                } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
543                        const ast::ResnSlots &srcSlots = srcInferred.resnSlotsConst();
544                        for (auto srcSlot : srcSlots) {
545                                tgtResnSlots.push_back(srcSlot);
546                        }
547                }
548        }
549
550        Expression * visitBaseExpr_skipResultType(const ast::Expr * src, Expression * tgt) {
551
552                tgt->location  = src->location;
553                tgt->env       = convertTypeSubstitution(src->env);
554                tgt->extension = src->extension;
555
556                convertInferUnion(tgt->inferParams, tgt->resnSlots, src->inferred);
557                return tgt;
558        }
559
560        Expression * visitBaseExpr(const ast::Expr * src, Expression * tgt) {
561
562                tgt->result = get<Type>().accept1(src->result);
563                return visitBaseExpr_skipResultType(src, tgt);
564        }
565
566        const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
567                auto expr = visitBaseExpr( node,
568                        new ApplicationExpr(
569                                get<Expression>().accept1(node->func),
570                                get<Expression>().acceptL(node->args)
571                        )
572                );
573                this->node = expr;
574                return nullptr;
575        }
576
577        const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
578                auto expr = visitBaseExpr( node,
579                        new UntypedExpr(
580                                get<Expression>().accept1(node->func),
581                                get<Expression>().acceptL(node->args)
582                        )
583                );
584                this->node = expr;
585                return nullptr;
586        }
587
588        const ast::Expr * visit( const ast::NameExpr * node ) override final {
589                auto expr = visitBaseExpr( node,
590                        new NameExpr(
591                                node->name
592                        )
593                );
594                this->node = expr;
595                return nullptr;
596        }
597
598        const ast::Expr * visit( const ast::AddressExpr * node ) override final {
599                auto expr = visitBaseExpr( node,
600                        new AddressExpr(
601                                get<Expression>().accept1(node->arg)
602                        )
603                );
604                this->node = expr;
605                return nullptr;
606        }
607
608        const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
609                auto expr = visitBaseExpr( node,
610                        new LabelAddressExpr(
611                                makeLabel(nullptr, node->arg)
612                        )
613                );
614                this->node = expr;
615                return nullptr;
616        }
617
618        const ast::Expr * visit( const ast::CastExpr * node ) override final {
619                auto expr = visitBaseExpr( node,
620                        new CastExpr(
621                                get<Expression>().accept1(node->arg),
622                                (node->isGenerated == ast::GeneratedCast)
623                        )
624                );
625                this->node = expr;
626                return nullptr;
627        }
628
629        const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
630                KeywordCastExpr::Target castTarget = KeywordCastExpr::NUMBER_OF_TARGETS;
631                switch (node->target) {
632                        case ast::KeywordCastExpr::Coroutine:
633                                castTarget = KeywordCastExpr::Coroutine;
634                                break;
635                        case ast::KeywordCastExpr::Thread:
636                                castTarget = KeywordCastExpr::Thread;
637                                break;
638                        case ast::KeywordCastExpr::Monitor:
639                                castTarget = KeywordCastExpr::Monitor;
640                                break;
641                        default:
642                                break;
643                }
644                assert ( castTarget < KeywordCastExpr::NUMBER_OF_TARGETS );
645                auto expr = visitBaseExpr( node,
646                        new KeywordCastExpr(
647                                get<Expression>().accept1(node->arg),
648                                castTarget
649                        )
650                );
651                this->node = expr;
652                return nullptr;
653        }
654
655        const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
656                auto expr = visitBaseExpr_skipResultType( node,
657                        new VirtualCastExpr(
658                                get<Expression>().accept1(node->arg),
659                                get<Type>().accept1(node->result)
660                        )
661                );
662                this->node = expr;
663                return nullptr;
664        }
665
666        const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
667                auto expr = visitBaseExpr( node,
668                        new UntypedMemberExpr(
669                                get<Expression>().accept1(node->member),
670                                get<Expression>().accept1(node->aggregate)
671                        )
672                );
673                this->node = expr;
674                return nullptr;
675        }
676
677        const ast::Expr * visit( const ast::MemberExpr * node ) override final {
678                auto expr = visitBaseExpr( node,
679                        new MemberExpr(
680                                inCache(node->member) ?
681                                        dynamic_cast<DeclarationWithType *>(this->node) :
682                                        get<DeclarationWithType>().accept1(node->member),
683                                get<Expression>().accept1(node->aggregate)
684                        )
685                );
686                this->node = expr;
687                return nullptr;
688        }
689
690        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
691                auto expr = visitBaseExpr( node,
692                        new VariableExpr(
693                                inCache(node->var) ?
694                                        dynamic_cast<DeclarationWithType *>(this->node) :
695                                        get<DeclarationWithType>().accept1(node->var)
696                        )
697                );
698                this->node = expr;
699                return nullptr;
700        }
701
702        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
703                ConstantExpr *rslt = nullptr;
704                switch ( node->kind ) {
705                case ast::ConstantExpr::Integer:
706                        rslt = new ConstantExpr{Constant{
707                                get<Type>().accept1( node->result ),
708                                node->rep,
709                                (unsigned long long) node->intValue()
710                        }};
711                        break;
712                case ast::ConstantExpr::FloatingPoint:
713                        rslt = new ConstantExpr{Constant{
714                                get<Type>().accept1(node->result),
715                                node->rep,
716                                (double) node->floatValue()
717                        }};
718                        break;
719                case ast::ConstantExpr::String:
720                        rslt = new ConstantExpr{Constant::from_string( node->rep )};
721                        break;
722                }
723                assert(rslt);
724                auto expr = visitBaseExpr( node, rslt );
725                this->node = expr;
726                return nullptr;
727        }
728
729        const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
730                assert (node->expr || node->type);
731                assert (! (node->expr && node->type));
732                SizeofExpr *rslt;
733                if (node->expr) {
734                        rslt = new SizeofExpr(
735                                get<Expression>().accept1(node->expr)
736                        );
737                        assert (!rslt->isType);
738                }
739                if (node->type) {
740                        rslt = new SizeofExpr(
741                                get<Type>().accept1(node->type)
742                        );
743                        assert (rslt->isType);
744                }
745                auto expr = visitBaseExpr( node, rslt );
746                this->node = expr;
747                return nullptr;
748        }
749
750        const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
751                assert (node->expr || node->type);
752                assert (! (node->expr && node->type));
753                AlignofExpr *rslt;
754                if (node->expr) {
755                        rslt = new AlignofExpr(
756                                get<Expression>().accept1(node->expr)
757                        );
758                        assert (!rslt->isType);
759                }
760                if (node->type) {
761                        rslt = new AlignofExpr(
762                                get<Type>().accept1(node->type)
763                        );
764                        assert (rslt->isType);
765                }
766                auto expr = visitBaseExpr( node, rslt );
767                this->node = expr;
768                return nullptr;
769        }
770
771        const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
772                auto expr = visitBaseExpr( node,
773                        new UntypedOffsetofExpr(
774                                get<Type>().accept1(node->type),
775                                node->member
776                        )
777                );
778                this->node = expr;
779                return nullptr;
780        }
781
782        const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
783                auto expr = visitBaseExpr( node,
784                        new OffsetofExpr(
785                                get<Type>().accept1(node->type),
786                                inCache(node->member) ?
787                                        dynamic_cast<DeclarationWithType *>(this->node) :
788                                        get<DeclarationWithType>().accept1(node->member)
789                        )
790                );
791                this->node = expr;
792                return nullptr;
793        }
794
795        const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
796                auto expr = visitBaseExpr( node,
797                        new OffsetPackExpr(
798                                get<StructInstType>().accept1(node->type)
799                        )
800                );
801                this->node = expr;
802                return nullptr;
803        }
804
805        const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
806                assert (node->isAnd == ast::LogicalFlag::AndExpr ||
807                                node->isAnd == ast::LogicalFlag::OrExpr );
808                auto expr = visitBaseExpr( node,
809                        new LogicalExpr(
810                                get<Expression>().accept1(node->arg1),
811                                get<Expression>().accept1(node->arg2),
812                                (node->isAnd == ast::LogicalFlag::AndExpr)
813                        )
814                );
815                this->node = expr;
816                return nullptr;
817        }
818
819        const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
820                auto expr = visitBaseExpr( node,
821                        new ConditionalExpr(
822                                get<Expression>().accept1(node->arg1),
823                                get<Expression>().accept1(node->arg2),
824                                get<Expression>().accept1(node->arg3)
825                        )
826                );
827                this->node = expr;
828                return nullptr;
829        }
830
831        const ast::Expr * visit( const ast::CommaExpr * node ) override final {
832                auto expr = visitBaseExpr( node,
833                        new CommaExpr(
834                                get<Expression>().accept1(node->arg1),
835                                get<Expression>().accept1(node->arg2)
836                        )
837                );
838                this->node = expr;
839                return nullptr;
840        }
841
842        const ast::Expr * visit( const ast::TypeExpr * node ) override final {
843                auto expr = visitBaseExpr( node,
844                        new TypeExpr(
845                                get<Type>().accept1(node->type)
846                        )
847                );
848                this->node = expr;
849                return nullptr;
850        }
851
852        const ast::Expr * visit( const ast::AsmExpr * node ) override final {
853                auto expr = visitBaseExpr( node,
854                        new AsmExpr(
855                                get<Expression>().accept1(node->inout),
856                                get<Expression>().accept1(node->constraint),
857                                get<Expression>().accept1(node->operand)
858                        )
859                );
860                this->node = expr;
861                return nullptr;
862        }
863
864        const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
865                auto rslt = new ImplicitCopyCtorExpr(
866                        get<ApplicationExpr>().accept1(node->callExpr)
867                );
868
869                rslt->tempDecls = get<ObjectDecl>().acceptL(node->tempDecls);
870                rslt->returnDecls = get<ObjectDecl>().acceptL(node->returnDecls);
871                rslt->dtors = get<Expression>().acceptL(node->dtors);
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::ThrowStmt::Kind kind;
1738                switch (old->kind) {
1739                case ThrowStmt::Terminate:
1740                        kind = ast::ThrowStmt::Terminate;
1741                        break;
1742                case ThrowStmt::Resume:
1743                        kind = ast::ThrowStmt::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::CatchStmt::Kind kind;
1774                switch (old->kind) {
1775                case CatchStmt::Terminate:
1776                        kind = ast::CatchStmt::Terminate;
1777                        break;
1778                case CatchStmt::Resume:
1779                        kind = ast::CatchStmt::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                this->node = new ast::ImplicitCtorDtorStmt(
1871                        old->location,
1872                        GET_ACCEPT_1(callStmt, Stmt),
1873                        GET_LABELS_V(old->labels)
1874                );
1875                cache.emplace( old, this->node );
1876        }
1877
1878        ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) {
1879
1880                if (!old) return nullptr;
1881
1882                ast::TypeSubstitution *rslt = new ast::TypeSubstitution();
1883
1884                for (decltype(old->begin()) old_i = old->begin(); old_i != old->end(); old_i++) {
1885                        rslt->add( old_i->first,
1886                                   getAccept1<ast::Type>(old_i->second) );
1887                }
1888
1889                for (decltype(old->beginVar()) old_i = old->beginVar(); old_i != old->endVar(); old_i++) {
1890                        rslt->addVar( old_i->first,
1891                                      getAccept1<ast::Expr>(old_i->second) );
1892                }
1893
1894                return rslt;
1895        }
1896
1897        void convertInferUnion(ast::Expr::InferUnion               &newInferred,
1898                                                   const std::map<UniqueId,ParamEntry> &oldInferParams,
1899                                                   const std::vector<UniqueId>         &oldResnSlots) {
1900
1901                assert( oldInferParams.empty() || oldResnSlots.empty() );
1902                assert( newInferred.mode == ast::Expr::InferUnion::Empty );
1903
1904                if ( !oldInferParams.empty() ) {
1905                        ast::InferredParams &tgt = newInferred.inferParams();
1906                        for (auto old : oldInferParams) {
1907                                tgt[old.first] = ast::ParamEntry(
1908                                        old.second.decl,
1909                                        getAccept1<ast::Type>(old.second.actualType),
1910                                        getAccept1<ast::Type>(old.second.formalType),
1911                                        getAccept1<ast::Expr>(old.second.expr)
1912                                );
1913                        }
1914                } else if ( !oldResnSlots.empty() ) {
1915                        ast::ResnSlots &tgt = newInferred.resnSlots();
1916                        for (auto old : oldResnSlots) {
1917                                tgt.push_back(old);
1918                        }
1919                }
1920        }
1921
1922        ast::Expr * visitBaseExpr_SkipResultType(Expression * old, ast::Expr * nw) {
1923
1924                nw->env    = convertTypeSubstitution(old->env);
1925
1926                nw->extension = old->extension;
1927                convertInferUnion(nw->inferred, old->inferParams, old->resnSlots);
1928
1929                return nw;
1930        }
1931
1932        ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
1933
1934                nw->result = GET_ACCEPT_1(result, Type);
1935                return visitBaseExpr_SkipResultType(old, nw);;
1936        }
1937
1938        virtual void visit( ApplicationExpr * old ) override final {
1939                this->node = visitBaseExpr( old,
1940                        new ast::ApplicationExpr(
1941                                old->location,
1942                                GET_ACCEPT_1(function, Expr),
1943                                GET_ACCEPT_V(args, Expr)
1944                        )
1945                );
1946        }
1947
1948        virtual void visit( UntypedExpr * old ) override final {
1949                this->node = visitBaseExpr( old,
1950                        new ast::UntypedExpr(
1951                                old->location,
1952                                GET_ACCEPT_1(function, Expr),
1953                                GET_ACCEPT_V(args, Expr)
1954                        )
1955                );
1956        }
1957
1958        virtual void visit( NameExpr * old ) override final {
1959                this->node = visitBaseExpr( old,
1960                        new ast::NameExpr(
1961                                old->location,
1962                                old->get_name()
1963                        )
1964                );
1965        }
1966
1967        virtual void visit( CastExpr * old ) override final {
1968                this->node = visitBaseExpr( old,
1969                        new ast::CastExpr(
1970                                old->location,
1971                                GET_ACCEPT_1(arg, Expr),
1972                                old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
1973                        )
1974                );
1975        }
1976
1977        virtual void visit( KeywordCastExpr * old) override final {
1978                ast::KeywordCastExpr::Target castTarget = ast::KeywordCastExpr::NUMBER_OF_TARGETS;
1979                switch (old->target) {
1980                        case KeywordCastExpr::Coroutine:
1981                                castTarget = ast::KeywordCastExpr::Coroutine;
1982                                break;
1983                        case KeywordCastExpr::Thread:
1984                                castTarget = ast::KeywordCastExpr::Thread;
1985                                break;
1986                        case KeywordCastExpr::Monitor:
1987                                castTarget = ast::KeywordCastExpr::Monitor;
1988                                break;
1989                        default:
1990                                break;
1991                }
1992                assert ( castTarget < ast::KeywordCastExpr::NUMBER_OF_TARGETS );
1993                this->node = visitBaseExpr( old,
1994                        new ast::KeywordCastExpr(
1995                                old->location,
1996                                GET_ACCEPT_1(arg, Expr),
1997                                castTarget
1998                        )
1999                );
2000        }
2001
2002        virtual void visit( VirtualCastExpr * old ) override final {
2003                this->node = visitBaseExpr_SkipResultType( old,
2004                        new ast::VirtualCastExpr(
2005                                old->location,
2006                                GET_ACCEPT_1(arg, Expr),
2007                                GET_ACCEPT_1(result, Type)
2008                        )
2009                );
2010        }
2011
2012        virtual void visit( AddressExpr * old ) override final {
2013                this->node = visitBaseExpr( old,
2014                        new ast::AddressExpr(
2015                                old->location,
2016                                GET_ACCEPT_1(arg, Expr)
2017                        )
2018                );
2019        }
2020
2021        virtual void visit( LabelAddressExpr * old ) override final {
2022                this->node = visitBaseExpr( old,
2023                        new ast::LabelAddressExpr(
2024                                old->location,
2025                                make_label(&old->arg)
2026                        )
2027                );
2028        }
2029
2030        virtual void visit( UntypedMemberExpr * old ) override final {
2031                this->node = visitBaseExpr( old,
2032                        new ast::UntypedMemberExpr(
2033                                old->location,
2034                                GET_ACCEPT_1(member, Expr),
2035                                GET_ACCEPT_1(aggregate, Expr)
2036                        )
2037                );
2038        }
2039
2040        virtual void visit( MemberExpr * old ) override final {
2041                this->node = visitBaseExpr( old,
2042                        new ast::MemberExpr(
2043                                old->location,
2044                                inCache(old->member) ?
2045                                        dynamic_cast<ast::DeclWithType *>(this->node) :
2046                                        GET_ACCEPT_1(member, DeclWithType),
2047                                GET_ACCEPT_1(aggregate, Expr)
2048                        )
2049                );
2050        }
2051
2052        virtual void visit( VariableExpr * old ) override final {
2053                this->node = visitBaseExpr( old,
2054                        new ast::VariableExpr(
2055                                old->location,
2056                                inCache(old->var) ?
2057                                        dynamic_cast<ast::DeclWithType *>(this->node) :
2058                                        GET_ACCEPT_1(var, DeclWithType)
2059                        )
2060                );
2061        }
2062
2063        bool isIntlikeConstantType(const Type *t) {
2064                if ( const BasicType * basicType = dynamic_cast< const BasicType * >( t ) ) {
2065                        if ( basicType->isInteger() ) {
2066                                return true;
2067                        }
2068                } else if ( dynamic_cast< const OneType * >( t ) ) {
2069                        return true;
2070                } else if ( dynamic_cast< const ZeroType * >( t ) ) {
2071                        return true;
2072                } else if ( dynamic_cast< const PointerType * >( t ) ) {
2073                        // null pointer constants, with zero int-values
2074                        return true;
2075                }
2076                return false;
2077        }
2078
2079        int isFloatlikeConstantType(const Type *t) {
2080                if ( const BasicType * bty = dynamic_cast< const BasicType * >( t ) ) {
2081                        if ( ! bty->isInteger() ) {
2082                                return true;
2083                        }
2084                }
2085                return false;
2086        }
2087
2088        int isStringlikeConstantType(const Type *t) {
2089                if ( const ArrayType * aty = dynamic_cast< const ArrayType * >( t ) ) {
2090                        if ( const BasicType * bty = dynamic_cast< const BasicType * >( aty->base ) ) {
2091                           if ( bty->kind == BasicType::Kind::Char ) {
2092                                   return true;
2093                           }
2094                        }
2095                }
2096                return false;
2097        }
2098
2099        virtual void visit( ConstantExpr * old ) override final {
2100                ast::ConstantExpr *rslt = nullptr;
2101                if (isIntlikeConstantType(old->result)) {
2102                        rslt = new ast::ConstantExpr(
2103                                old->location,
2104                                GET_ACCEPT_1(result, Type),
2105                                old->constant.get_value(),
2106                                (unsigned long long) old->intValue()
2107                        );
2108                } else if (isFloatlikeConstantType(old->result)) {
2109                        rslt = new ast::ConstantExpr(
2110                                old->location,
2111                                GET_ACCEPT_1(result, Type),
2112                                old->constant.get_value(),
2113                                (double) old->constant.get_dval()
2114                        );
2115                } else if (isStringlikeConstantType(old->result)) {
2116                        rslt = ast::ConstantExpr::from_string(
2117                                old->location,
2118                                old->constant.get_value()
2119                        );
2120                }
2121                assert(rslt);
2122                this->node = visitBaseExpr( old, rslt );
2123        }
2124
2125        virtual void visit( SizeofExpr * old ) override final {
2126                assert (old->expr || old->type);
2127                assert (! (old->expr && old->type));
2128                ast::SizeofExpr *rslt;
2129                if (old->expr) {
2130                        assert(!old->isType);
2131                        rslt = new ast::SizeofExpr(
2132                                old->location,
2133                                GET_ACCEPT_1(expr, Expr)
2134                        );
2135                }
2136                if (old->type) {
2137                        assert(old->isType);
2138                        rslt = new ast::SizeofExpr(
2139                                old->location,
2140                                GET_ACCEPT_1(type, Type)
2141                        );
2142                }
2143                this->node = visitBaseExpr( old, rslt );
2144        }
2145
2146        virtual void visit( AlignofExpr * old ) override final {
2147                assert (old->expr || old->type);
2148                assert (! (old->expr && old->type));
2149                ast::AlignofExpr *rslt;
2150                if (old->expr) {
2151                        assert(!old->isType);
2152                        rslt = new ast::AlignofExpr(
2153                                old->location,
2154                                GET_ACCEPT_1(expr, Expr)
2155                        );
2156                }
2157                if (old->type) {
2158                        assert(old->isType);
2159                        rslt = new ast::AlignofExpr(
2160                                old->location,
2161                                GET_ACCEPT_1(type, Type)
2162                        );
2163                }
2164                this->node = visitBaseExpr( old, rslt );
2165        }
2166
2167        virtual void visit( UntypedOffsetofExpr * old ) override final {
2168                this->node = visitBaseExpr( old,
2169                        new ast::UntypedOffsetofExpr(
2170                                old->location,
2171                                GET_ACCEPT_1(type, Type),
2172                                old->member
2173                        )
2174                );
2175        }
2176
2177        virtual void visit( OffsetofExpr * old ) override final {
2178                this->node = visitBaseExpr( old,
2179                        new ast::OffsetofExpr(
2180                                old->location,
2181                                GET_ACCEPT_1(type, Type),
2182                                inCache(old->member) ?
2183                                        dynamic_cast<ast::DeclWithType *>(this->node) :
2184                                        GET_ACCEPT_1(member, DeclWithType)
2185                        )
2186                );
2187        }
2188
2189        virtual void visit( OffsetPackExpr * old ) override final {
2190                this->node = visitBaseExpr( old,
2191                        new ast::OffsetPackExpr(
2192                                old->location,
2193                                GET_ACCEPT_1(type, StructInstType)
2194                        )
2195                );
2196        }
2197
2198        virtual void visit( LogicalExpr * old ) override final {
2199                this->node = visitBaseExpr( old,
2200                        new ast::LogicalExpr(
2201                                old->location,
2202                                GET_ACCEPT_1(arg1, Expr),
2203                                GET_ACCEPT_1(arg2, Expr),
2204                                old->get_isAnd() ?
2205                                        ast::LogicalFlag::AndExpr :
2206                                        ast::LogicalFlag::OrExpr
2207                        )
2208                );
2209        }
2210
2211        virtual void visit( ConditionalExpr * old ) override final {
2212                this->node = visitBaseExpr( old,
2213                        new ast::ConditionalExpr(
2214                                old->location,
2215                                GET_ACCEPT_1(arg1, Expr),
2216                                GET_ACCEPT_1(arg2, Expr),
2217                                GET_ACCEPT_1(arg3, Expr)
2218                        )
2219                );
2220        }
2221
2222        virtual void visit( CommaExpr * old ) override final {
2223                this->node = visitBaseExpr( old,
2224                        new ast::CommaExpr(
2225                                old->location,
2226                                GET_ACCEPT_1(arg1, Expr),
2227                                GET_ACCEPT_1(arg2, Expr)
2228                        )
2229                );
2230        }
2231
2232        virtual void visit( TypeExpr * old ) override final {
2233                this->node = visitBaseExpr( old,
2234                        new ast::TypeExpr(
2235                                old->location,
2236                                GET_ACCEPT_1(type, Type)
2237                        )
2238                );
2239        }
2240
2241        virtual void visit( AsmExpr * old ) override final {
2242                this->node = visitBaseExpr( old,
2243                        new ast::AsmExpr(
2244                                old->location,
2245                                GET_ACCEPT_1(inout, Expr),
2246                                GET_ACCEPT_1(constraint, Expr),
2247                                GET_ACCEPT_1(operand, Expr)
2248                        )
2249                );
2250        }
2251
2252        virtual void visit( ImplicitCopyCtorExpr * old ) override final {
2253                auto rslt = new ast::ImplicitCopyCtorExpr(
2254                        old->location,
2255                        GET_ACCEPT_1(callExpr, ApplicationExpr)
2256                );
2257
2258                rslt->tempDecls = GET_ACCEPT_V(tempDecls, ObjectDecl);
2259                rslt->returnDecls = GET_ACCEPT_V(returnDecls, ObjectDecl);
2260                rslt->dtors = GET_ACCEPT_V(dtors, Expr);
2261
2262                this->node = visitBaseExpr( old, rslt );
2263        }
2264
2265        virtual void visit( ConstructorExpr * old ) override final {
2266                this->node = visitBaseExpr( old,
2267                        new ast::ConstructorExpr(
2268                                old->location,
2269                                GET_ACCEPT_1(callExpr, Expr)
2270                        )
2271                );
2272        }
2273
2274        virtual void visit( CompoundLiteralExpr * old ) override final {
2275                this->node = visitBaseExpr_SkipResultType( old,
2276                        new ast::CompoundLiteralExpr(
2277                                old->location,
2278                                GET_ACCEPT_1(result, Type),
2279                                GET_ACCEPT_1(initializer, Init)
2280                        )
2281                );
2282        }
2283
2284        virtual void visit( RangeExpr * old ) override final {
2285                this->node = visitBaseExpr( old,
2286                        new ast::RangeExpr(
2287                                old->location,
2288                                GET_ACCEPT_1(low, Expr),
2289                                GET_ACCEPT_1(high, Expr)
2290                        )
2291                );
2292        }
2293
2294        virtual void visit( UntypedTupleExpr * old ) override final {
2295                this->node = visitBaseExpr( old,
2296                        new ast::UntypedTupleExpr(
2297                                old->location,
2298                                GET_ACCEPT_V(exprs, Expr)
2299                        )
2300                );
2301        }
2302
2303        virtual void visit( TupleExpr * old ) override final {
2304                this->node = visitBaseExpr( old,
2305                        new ast::TupleExpr(
2306                                old->location,
2307                                GET_ACCEPT_V(exprs, Expr)
2308                        )
2309                );
2310        }
2311
2312        virtual void visit( TupleIndexExpr * old ) override final {
2313                this->node = visitBaseExpr( old,
2314                        new ast::TupleIndexExpr(
2315                                old->location,
2316                                GET_ACCEPT_1(tuple, Expr),
2317                                old->index
2318                        )
2319                );
2320        }
2321
2322        virtual void visit( TupleAssignExpr * old ) override final {
2323                this->node = visitBaseExpr_SkipResultType( old,
2324                        new ast::TupleAssignExpr(
2325                                old->location,
2326                                GET_ACCEPT_1(result, Type),
2327                                GET_ACCEPT_1(stmtExpr, StmtExpr)
2328                        )
2329                );
2330        }
2331
2332        virtual void visit( StmtExpr * old ) override final {
2333                auto rslt = new ast::StmtExpr(
2334                        old->location,
2335                        GET_ACCEPT_1(statements, CompoundStmt)
2336                );
2337                rslt->returnDecls = GET_ACCEPT_V(returnDecls, ObjectDecl);
2338                rslt->dtors       = GET_ACCEPT_V(dtors      , Expr);
2339
2340                this->node = visitBaseExpr_SkipResultType( old, rslt );
2341        }
2342
2343        virtual void visit( UniqueExpr * old ) override final {
2344                auto rslt = new ast::UniqueExpr(
2345                        old->location,
2346                        GET_ACCEPT_1(expr, Expr)
2347                );
2348                rslt->object = GET_ACCEPT_1(object, ObjectDecl);
2349                rslt->var    = GET_ACCEPT_1(var   , VariableExpr);
2350
2351                this->node = visitBaseExpr( old, rslt );
2352        }
2353
2354        virtual void visit( UntypedInitExpr * old ) override final {
2355                std::vector<ast::InitAlternative> initAlts;
2356                for (auto ia : old->initAlts) {
2357                        initAlts.push_back(ast::InitAlternative(
2358                                getAccept1< ast::Type, Type * >( ia.type ),
2359                                getAccept1< ast::Designation, Designation * >( ia.designation )
2360                        ));
2361                }
2362                this->node = visitBaseExpr( old,
2363                        new ast::UntypedInitExpr(
2364                                old->location,
2365                                GET_ACCEPT_1(expr, Expr),
2366                                std::move(initAlts)
2367                        )
2368                );
2369        }
2370
2371        virtual void visit( InitExpr * old ) override final {
2372                this->node = visitBaseExpr( old,
2373                        new ast::InitExpr(
2374                                old->location,
2375                                GET_ACCEPT_1(expr, Expr),
2376                                GET_ACCEPT_1(designation, Designation)
2377                        )
2378                );
2379        }
2380
2381        virtual void visit( DeletedExpr * old ) override final {
2382                this->node = visitBaseExpr( old,
2383                        new ast::DeletedExpr(
2384                                old->location,
2385                                GET_ACCEPT_1(expr, Expr),
2386                                inCache(old->deleteStmt) ?
2387                                        this->node :
2388                                        GET_ACCEPT_1(deleteStmt, Node)
2389                        )
2390                );
2391        }
2392
2393        virtual void visit( DefaultArgExpr * old ) override final {
2394                this->node = visitBaseExpr( old,
2395                        new ast::DefaultArgExpr(
2396                                old->location,
2397                                GET_ACCEPT_1(expr, Expr)
2398                        )
2399                );
2400        }
2401
2402        virtual void visit( GenericExpr * old ) override final {
2403                std::vector<ast::GenericExpr::Association> associations;
2404                for (auto association : old->associations) {
2405                        associations.push_back(ast::GenericExpr::Association(
2406                                getAccept1< ast::Type, Type * >( association.type ),
2407                                getAccept1< ast::Expr, Expression * >( association.expr )
2408                        ));
2409                }
2410                this->node = visitBaseExpr( old,
2411                        new ast::GenericExpr(
2412                                old->location,
2413                                GET_ACCEPT_1(control, Expr),
2414                                std::move(associations)
2415                        )
2416                );
2417        }
2418
2419        virtual void visit( VoidType * old ) override final {
2420                this->node = new ast::VoidType{ cv( old ) };
2421        }
2422
2423        virtual void visit( BasicType * old ) override final {
2424                this->node = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
2425        }
2426
2427        virtual void visit( PointerType * old ) override final {
2428                this->node = new ast::PointerType{
2429                        GET_ACCEPT_1( base, Type ),
2430                        GET_ACCEPT_1( dimension, Expr ),
2431                        (ast::LengthFlag)old->isVarLen,
2432                        (ast::DimensionFlag)old->isStatic,
2433                        cv( old )
2434                };
2435        }
2436
2437        virtual void visit( ArrayType * old ) override final {
2438                this->node = new ast::ArrayType{
2439                        GET_ACCEPT_1( base, Type ),
2440                        GET_ACCEPT_1( dimension, Expr ),
2441                        (ast::LengthFlag)old->isVarLen,
2442                        (ast::DimensionFlag)old->isStatic,
2443                        cv( old )
2444                };
2445        }
2446
2447        virtual void visit( ReferenceType * old ) override final {
2448                this->node = new ast::ReferenceType{
2449                        GET_ACCEPT_1( base, Type ),
2450                        cv( old )
2451                };
2452        }
2453
2454        virtual void visit( QualifiedType * old ) override final {
2455                this->node = new ast::QualifiedType{
2456                        GET_ACCEPT_1( parent, Type ),
2457                        GET_ACCEPT_1( child, Type ),
2458                        cv( old )
2459                };
2460        }
2461
2462        virtual void visit( FunctionType * old ) override final {
2463                auto ty = new ast::FunctionType {
2464                        (ast::ArgumentFlag)old->isVarArgs,
2465                        cv( old )
2466                };
2467                ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
2468                ty->params = GET_ACCEPT_V( parameters, DeclWithType );
2469                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
2470                this->node = ty;
2471        }
2472
2473        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
2474                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
2475                ty->params = GET_ACCEPT_V( parameters, Expr );
2476                ty->hoistType = old->hoistType;
2477        }
2478
2479        virtual void visit( StructInstType * old ) override final {
2480                ast::StructInstType * ty;
2481                if ( old->baseStruct ) {
2482                        ty = new ast::StructInstType{
2483                                GET_ACCEPT_1( baseStruct, StructDecl ),
2484                                cv( old ),
2485                                GET_ACCEPT_V( attributes, Attribute )
2486                        };
2487                } else {
2488                        ty = new ast::StructInstType{
2489                                old->name,
2490                                cv( old ),
2491                                GET_ACCEPT_V( attributes, Attribute )
2492                        };
2493                }
2494                postvisit( old, ty );
2495                this->node = ty;
2496        }
2497
2498        virtual void visit( UnionInstType * old ) override final {
2499                ast::UnionInstType * ty;
2500                if ( old->baseUnion ) {
2501                        ty = new ast::UnionInstType{
2502                                GET_ACCEPT_1( baseUnion, UnionDecl ),
2503                                cv( old ),
2504                                GET_ACCEPT_V( attributes, Attribute )
2505                        };
2506                } else {
2507                        ty = new ast::UnionInstType{
2508                                old->name,
2509                                cv( old ),
2510                                GET_ACCEPT_V( attributes, Attribute )
2511                        };
2512                }
2513                postvisit( old, ty );
2514                this->node = ty;
2515        }
2516
2517        virtual void visit( EnumInstType * old ) override final {
2518                ast::EnumInstType * ty;
2519                if ( old->baseEnum ) {
2520                        ty = new ast::EnumInstType{
2521                                GET_ACCEPT_1( baseEnum, EnumDecl ),
2522                                cv( old ),
2523                                GET_ACCEPT_V( attributes, Attribute )
2524                        };
2525                } else {
2526                        ty = new ast::EnumInstType{
2527                                old->name,
2528                                cv( old ),
2529                                GET_ACCEPT_V( attributes, Attribute )
2530                        };
2531                }
2532                postvisit( old, ty );
2533                this->node = ty;
2534        }
2535
2536        virtual void visit( TraitInstType * old ) override final {
2537                ast::TraitInstType * ty;
2538                if ( old->baseTrait ) {
2539                        ty = new ast::TraitInstType{
2540                                GET_ACCEPT_1( baseTrait, TraitDecl ),
2541                                cv( old ),
2542                                GET_ACCEPT_V( attributes, Attribute )
2543                        };
2544                } else {
2545                        ty = new ast::TraitInstType{
2546                                old->name,
2547                                cv( old ),
2548                                GET_ACCEPT_V( attributes, Attribute )
2549                        };
2550                }
2551                postvisit( old, ty );
2552                this->node = ty;
2553        }
2554
2555        virtual void visit( TypeInstType * old ) override final {
2556                ast::TypeInstType * ty;
2557                if ( old->baseType ) {
2558                        ty = new ast::TypeInstType{
2559                                old->name,
2560                                GET_ACCEPT_1( baseType, TypeDecl ),
2561                                cv( old ),
2562                                GET_ACCEPT_V( attributes, Attribute )
2563                        };
2564                } else {
2565                        ty = new ast::TypeInstType{
2566                                old->name,
2567                                old->isFtype ? ast::TypeVar::Ftype : ast::TypeVar::Dtype,
2568                                cv( old ),
2569                                GET_ACCEPT_V( attributes, Attribute )
2570                        };
2571                }
2572                postvisit( old, ty );
2573                this->node = ty;
2574        }
2575
2576        virtual void visit( TupleType * old ) override final {
2577                this->node = new ast::TupleType{
2578                        GET_ACCEPT_V( types, Type ),
2579                        // members generated by TupleType c'tor
2580                        cv( old )
2581                };
2582        }
2583
2584        virtual void visit( TypeofType * old ) override final {
2585                this->node = new ast::TypeofType{
2586                        GET_ACCEPT_1( expr, Expr ),
2587                        (ast::TypeofType::Kind)old->is_basetypeof,
2588                        cv( old )
2589                };
2590        }
2591
2592        virtual void visit( AttrType * ) override final {
2593                assertf( false, "AttrType deprecated in new AST." );
2594        }
2595
2596        virtual void visit( VarArgsType * old ) override final {
2597                this->node = new ast::VarArgsType{ cv( old ) };
2598        }
2599
2600        virtual void visit( ZeroType * old ) override final {
2601                this->node = new ast::ZeroType{ cv( old ) };
2602        }
2603
2604        virtual void visit( OneType * old ) override final {
2605                this->node = new ast::OneType{ cv( old ) };
2606        }
2607
2608        virtual void visit( GlobalScopeType * ) override final {
2609                this->node = new ast::GlobalScopeType{};
2610        }
2611
2612        virtual void visit( Designation * old ) override final {
2613                this->node = new ast::Designation(
2614                        old->location,
2615                        GET_ACCEPT_V(designators, Expr)
2616                );
2617        }
2618
2619        virtual void visit( SingleInit * old ) override final {
2620                this->node = new ast::SingleInit(
2621                        old->location,
2622                        GET_ACCEPT_1(value, Expr),
2623                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
2624                );
2625        }
2626
2627        virtual void visit( ListInit * old ) override final {
2628                this->node = new ast::ListInit(
2629                        old->location,
2630                        GET_ACCEPT_V(initializers, Init),
2631                        GET_ACCEPT_V(designations, Designation),
2632                        (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::DoConstruct
2633                );
2634        }
2635
2636        virtual void visit( ConstructorInit * old ) override final {
2637                this->node = new ast::ConstructorInit(
2638                        old->location,
2639                        GET_ACCEPT_1(ctor, Stmt),
2640                        GET_ACCEPT_1(dtor, Stmt),
2641                        GET_ACCEPT_1(init, Init)
2642                );
2643        }
2644
2645        virtual void visit( Constant * ) override final {
2646                // Handled in visit( ConstantEpxr * ).
2647                // In the new tree, Constant fields are inlined into containing ConstantExpression.
2648                assert( 0 );
2649        }
2650
2651        virtual void visit( Attribute * old ) override final {
2652                this->node = new ast::Attribute(
2653                        old->name,
2654                        GET_ACCEPT_V( parameters, Expr )
2655                );
2656        }
2657
2658        virtual void visit( AttrExpr * ) override final {
2659                assertf( false, "AttrExpr deprecated in new AST." );
2660        }
2661};
2662
2663#undef GET_LABELS_V
2664#undef GET_ACCEPT_V
2665#undef GET_ACCEPT_1
2666
2667std::list< ast::ptr< ast::Decl > > convert( const std::list< Declaration * > && translationUnit ) {
2668        ConverterOldToNew c;
2669        std::list< ast::ptr< ast::Decl > > decls;
2670        for(auto d : translationUnit) {
2671                d->accept( c );
2672                decls.emplace_back( c.decl() );
2673        }
2674        deleteAll(translationUnit);
2675        return decls;
2676}
Note: See TracBrowser for help on using the repository browser.