source: src/AST/Convert.cpp @ 8d70648

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 8d70648 was 8d70648, checked in by Aaron Moss <a3moss@…>, 5 years ago

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

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