source: src/AST/Convert.cpp @ bd12159

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since bd12159 was c36298d, checked in by Michael Brooks <mlbrooks@…>, 5 years ago

Fixed handling of "literals.cfa" string-detail test cases by simplifying constant analysis. Now a ConstantExpr? is a minial passthrough from parser to code generator, with special-case analysis only for integer values. Awareness of how to build a string-constant type is back in ExpressionNode?.cc; now, this knowlede is only needed there. AST conversion no longer specializes string-int-float constants; it just converts types and passes values through. Unused constant API features are removed, notably from-to-float and from-string.

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