source: src/AST/Convert.cpp @ 15934a6

arm-ehcleanup-dtorsjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since 15934a6 was 15934a6, checked in by Aaron Moss <a3moss@…>, 3 years ago

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

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