source: src/AST/Convert.cpp @ 8568319

arm-ehjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-expr
Last change on this file since 8568319 was 8568319, checked in by Michael Brooks <mlbrooks@…>, 3 years ago

fixed string constants getting extra quotes on roundtrip conversion

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