source: src/AST/Convert.cpp @ f5bace8

ADTast-experimentalenumpthread-emulationqualifiedEnum
Last change on this file since f5bace8 was 39d8950, checked in by Andrew Beach <ajbeach@…>, 2 years ago

Thread global information through resolution. Non-top-level calls to the resolver have a bit of a hack but improvements would require changes to the Pass helpers.

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