source: src/AST/Convert.cpp @ 9a0cd9c

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

Fill in missing Decl conversions

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