source: src/AST/Convert.cpp @ 546e712

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 546e712 was 546e712, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Fix for 1 bug of N

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