source: src/AST/Convert.cpp @ 746ae82

ADTarm-ehcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 746ae82 was 746ae82, checked in by Aaron Moss <a3moss@…>, 4 years ago

Finish conversion visitors for Type

  • Property mode set to 100644
File size: 48.0 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 : Tue May 21 15:30:00 2019
13// Update Count     : 5
14//
15
16#include "Convert.hpp"
17
18#include <unordered_map>
19
20#include "AST/Attribute.hpp"
21#include "AST/Decl.hpp"
22#include "AST/Expr.hpp"
23#include "AST/Init.hpp"
24#include "AST/Stmt.hpp"
25#include "AST/TypeSubstitution.hpp"
26
27#include "SynTree/Attribute.h"
28#include "SynTree/Declaration.h"
29#include "SynTree/TypeSubstitution.h"
30
31//================================================================================================
32// Utilities
33template<template <class...> class C>
34struct to {
35        template<typename T>
36        static auto from( T && v ) -> C< typename T::value_type > {
37                C< typename T::value_type > l;
38                std::move(std::begin(v), std::end(v), std::back_inserter(l));
39                return l;
40        }
41};
42
43//================================================================================================
44class ConverterNewToOld : public ast::Visitor {
45        BaseSyntaxNode * node = nullptr;
46        using Cache = std::unordered_map< const ast::Node *, BaseSyntaxNode * >;
47        Cache cache;
48
49        template<typename T>
50        struct Getter {
51                ConverterNewToOld & visitor;
52
53                template<typename U, enum ast::Node::ref_type R>
54                T * accept1( const ast::ptr_base<U, R> & ptr ) {
55                        if ( ! ptr ) return nullptr;
56                        ptr->accept( visitor );
57                        T * ret = strict_dynamic_cast< T * >( visitor.node );
58                        visitor.node = nullptr;
59                        return ret;
60                }
61
62                template<typename U>
63                std::list< T * > acceptL( const U & container ) {
64                        std::list< T * > ret;
65                        for (auto ptr : container ) {
66                                ret.emplace_back( accept1( ptr ) );
67                        }
68                        return ret;
69                }
70        };
71
72    template<typename T>
73    Getter<T> get() {
74        return Getter<T>{ *this };
75    }
76
77        Label makeLabel(Statement * labelled, const ast::Label& label) {
78                return Label(
79                        label.name,
80                        labelled,
81                        get<Attribute>().acceptL(label.attributes)
82                );
83        }
84
85        template<template <class...> class C>
86        std::list<Label> makeLabelL(Statement * labelled, const C<ast::Label>& labels) {
87                std::list<Label> ret;
88                for (auto label : labels) {
89                        ret.push_back( makeLabel(labelled, label) );
90                }
91                return ret;
92        }
93
94        /// get new qualifiers from old type
95        Type::Qualifiers cv( const ast::Type * ty ) { return { ty->qualifiers.val }; }
96
97        /// returns true and sets `node` if in cache
98        bool inCache( const ast::Node * node ) {
99                auto it = cache.find( node );
100                if ( it == cache.end() ) return false;
101                this->node = it->second;
102                return true;
103        }
104
105public:
106        Declaration * decl( const ast::Decl * declNode ) {
107                return get<Declaration>().accept1( ast::ptr<ast::Decl>( declNode ) );
108        }
109
110private:
111        void declPostamble( Declaration * decl, const ast::Decl * node ) {
112                decl->location = node->location;
113                // name comes from constructor
114                // linkage comes from constructor
115                decl->extension = node->extension;
116                decl->uniqueId = node->uniqueId;
117                // storageClasses comes from constructor
118                this->node = decl;
119        }
120
121        const ast::DeclWithType * declWithTypePostamble (
122                        DeclarationWithType * decl, const ast::DeclWithType * node ) {
123                declPostamble( decl, node );
124                decl->mangleName = node->mangleName;
125                decl->scopeLevel = node->scopeLevel;
126                decl->asmName = get<Expression>().accept1( node->asmName );
127                // attributes comes from constructor
128                decl->isDeleted = node->isDeleted;
129                // fs comes from constructor
130                cache.emplace( node, decl );
131                return nullptr;
132        }
133
134        const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
135                if ( inCache( node ) ) return nullptr;
136                auto decl = new ObjectDecl(
137                        node->name,
138                        Type::StorageClasses( node->storage.val ),
139                        LinkageSpec::Spec( node->linkage.val ),
140                        get<Expression>().accept1( node->bitfieldWidth ),
141                        get<Type>().accept1( node->type ),
142                        get<Initializer>().accept1( node->init ),
143                        get<Attribute>().acceptL( node->attributes ),
144                        Type::FuncSpecifiers( node->funcSpec.val )
145                );
146                return declWithTypePostamble( decl, node );
147        }
148
149        const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
150                if ( inCache( node ) ) return nullptr;
151                auto decl = new FunctionDecl(
152                        node->name,
153                        Type::StorageClasses( node->storage.val ),
154                        LinkageSpec::Spec( node->linkage.val ),
155                        get<FunctionType>().accept1( node->type ),
156                        get<CompoundStmt>().accept1( node->stmts ),
157                        get<Attribute>().acceptL( node->attributes ),
158                        Type::FuncSpecifiers( node->funcSpec.val )
159                );
160                decl->withExprs = get<Expression>().acceptL( node->withExprs );
161                return declWithTypePostamble( decl, node );
162        }
163
164        // NamedTypeDecl
165        const ast::Decl * namedTypePostamble( NamedTypeDecl * decl, const ast::NamedTypeDecl * node ) {
166                declPostamble( decl, node );
167                // base comes from constructor
168                decl->parameters = get<TypeDecl>().acceptL( node->params );
169                decl->assertions = get<DeclarationWithType>().acceptL( node->assertions );
170                return nullptr;
171        }
172
173        const ast::Decl * visit( const ast::TypeDecl * node ) override final {
174                if ( inCache( node ) ) return nullptr;
175                auto decl = new TypeDecl(
176                        node->name,
177                        Type::StorageClasses( node->storage.val ),
178                        get<Type>().accept1( node->base ),
179                        (TypeDecl::Kind)(unsigned)node->kind,
180                        node->sized,
181                        get<Type>().accept1( node->init )
182                );
183                cache.emplace( node, decl );
184                return namedTypePostamble( decl, node );
185        }
186
187        const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
188                auto decl = new TypedefDecl(
189                        node->name,
190                        node->location,
191                        Type::StorageClasses( node->storage.val ),
192            get<Type>().accept1( node->base ),
193                        LinkageSpec::Spec( node->linkage.val )
194                );
195                return namedTypePostamble( decl, node );
196        }
197
198        const ast::Decl * aggregatePostamble( AggregateDecl * decl, const ast::AggregateDecl * node ) {
199                decl->members = get<Declaration>().acceptL( node->members );
200                decl->parameters = get<TypeDecl>().acceptL( node->params );
201                decl->body = node->body;
202                // attributes come from constructor
203                decl->parent = get<AggregateDecl>().accept1( node->parent );
204                cache.emplace( node, decl );
205                return nullptr;
206        }
207
208        const ast::Decl * visit( const ast::StructDecl * node ) override final {
209                if ( inCache( node ) ) return nullptr;
210                auto decl = new StructDecl(
211                        node->name,
212                        node->kind,
213                        get<Attribute>().acceptL( node->attributes ),
214                        LinkageSpec::Spec( node->linkage.val )
215                );
216                return aggregatePostamble( decl, node );
217        }
218
219        const ast::Decl * visit( const ast::UnionDecl * node ) override final {
220                if ( inCache( node ) ) return nullptr;
221                auto decl = new UnionDecl(
222                        node->name,
223                        get<Attribute>().acceptL( node->attributes ),
224                        LinkageSpec::Spec( node->linkage.val )
225                );
226                return aggregatePostamble( decl, node );
227        }
228
229        const ast::Decl * visit( const ast::EnumDecl * node ) override final {
230                if ( inCache( node ) ) return nullptr;
231                auto decl = new EnumDecl(
232                        node->name,
233                        get<Attribute>().acceptL( node->attributes ),
234                        LinkageSpec::Spec( node->linkage.val )
235                );
236                return aggregatePostamble( decl, node );
237        }
238
239        const ast::Decl * visit( const ast::TraitDecl * node ) override final {
240                if ( inCache( node ) ) return nullptr;
241                auto decl = new TraitDecl(
242                        node->name,
243                        {},
244                        LinkageSpec::Spec( node->linkage.val )
245                );
246                return aggregatePostamble( decl, node );
247        }
248
249        const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
250                auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) );
251                declPostamble( decl, node );
252                return nullptr;
253        }
254
255        const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
256                auto decl = new StaticAssertDecl(
257                        get<Expression>().accept1( node->cond ),
258                        get<ConstantExpr>().accept1( node->msg )
259                );
260                declPostamble( decl, node );
261                return nullptr;
262        }
263
264        const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) {
265                stmt->location = node->location;
266                stmt->labels = makeLabelL( stmt, node->labels );
267                this->node = stmt;
268                return nullptr;
269        }
270
271        const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
272                auto stmt = new CompoundStmt( get<Statement>().acceptL( node->kids ) );
273                stmtPostamble( stmt, node );
274                return nullptr;
275        }
276
277        const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
278                auto stmt = new ExprStmt( get<Expression>().accept1( node->expr ) );
279                return stmtPostamble( stmt, node );
280        }
281
282        const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
283                auto stmt = new AsmStmt(
284                        node->isVolatile,
285                        get<Expression>().accept1( node->instruction ),
286                        get<Expression>().acceptL( node->output ),
287                        get<Expression>().acceptL( node->input ),
288                        get<ConstantExpr>().acceptL( node->clobber ),
289                        makeLabelL( nullptr, node->gotoLabels ) // What are these labelling?
290                );
291                return stmtPostamble( stmt, node );
292        }
293
294        const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
295                auto stmt = new DirectiveStmt( node->directive );
296                return stmtPostamble( stmt, node );
297        }
298
299        const ast::Stmt * visit( const ast::IfStmt * node ) override final {
300                auto stmt = new IfStmt(
301                        get<Expression>().accept1( node->cond ),
302                        get<Statement>().accept1( node->thenPart ),
303                        get<Statement>().accept1( node->elsePart ),
304                        get<Statement>().acceptL( node->inits )
305                );
306                return stmtPostamble( stmt, node );
307        }
308
309        const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
310                auto stmt = new SwitchStmt(
311                        get<Expression>().accept1( node->cond ),
312                        get<Statement>().acceptL( node->stmts )
313                );
314                return stmtPostamble( stmt, node );
315        }
316
317        const ast::Stmt * visit( const ast::CaseStmt * node ) override final {
318                auto stmt = new CaseStmt(
319                        get<Expression>().accept1( node->cond ),
320                        get<Statement>().acceptL( node->stmts ),
321                        node->isDefault()
322                );
323                return stmtPostamble( stmt, node );
324        }
325
326        const ast::Stmt * visit( const ast::WhileStmt * node ) override final {
327                auto inits = get<Statement>().acceptL( node->inits );
328                auto stmt = new WhileStmt(
329                        get<Expression>().accept1( node->cond ),
330                        get<Statement>().accept1( node->body ),
331                        inits,
332                        node->isDoWhile
333                );
334                return stmtPostamble( stmt, node );
335        }
336
337        const ast::Stmt * visit( const ast::ForStmt * node ) override final {
338                auto stmt = new ForStmt(
339                        get<Statement>().acceptL( node->inits ),
340                        get<Expression>().accept1( node->cond ),
341                        get<Expression>().accept1( node->inc ),
342                        get<Statement>().accept1( node->body )
343                );
344                return stmtPostamble( stmt, node );
345        }
346
347        const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
348                BranchStmt * stmt;
349                if (node->computedTarget) {
350                        stmt = new BranchStmt( get<Expression>().accept1( node->computedTarget ),
351                                BranchStmt::Goto );
352                } else {
353                        BranchStmt::Type type;
354                        switch (node->kind) {
355                        #define CASE(n) \
356                        case ast::BranchStmt::n: \
357                                type = BranchStmt::n; \
358                                break
359                        CASE(Goto);
360                        CASE(Break);
361                        CASE(Continue);
362                        CASE(FallThrough);
363                        CASE(FallThroughDefault);
364                        #undef CASE
365                        default:
366                                assertf(false, "Invalid ast::BranchStmt::Kind: %d\n", node->kind);
367                        }
368
369                        // The labels here are also weird.
370                        stmt = new BranchStmt( makeLabel( nullptr, node->originalTarget ), type );
371                        stmt->target = makeLabel( stmt, node->target );
372                }
373                return stmtPostamble( stmt, node );
374        }
375
376        const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
377                auto stmt = new ReturnStmt( get<Expression>().accept1( node->expr ) );
378                return stmtPostamble( stmt, node );
379        }
380
381        const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
382                ThrowStmt::Kind kind;
383                switch (node->kind) {
384                case ast::ThrowStmt::Terminate:
385                        kind = ThrowStmt::Terminate;
386                        break;
387                case ast::ThrowStmt::Resume:
388                        kind = ThrowStmt::Resume;
389                        break;
390                default:
391                        assertf(false, "Invalid ast::ThrowStmt::Kind: %d\n", node->kind);
392                }
393                auto stmt = new ThrowStmt(
394                        kind,
395                        get<Expression>().accept1( node->expr ),
396                        get<Expression>().accept1( node->target )
397                );
398                return stmtPostamble( stmt, node );
399        }
400
401        const ast::Stmt * visit( const ast::TryStmt * node ) override final {
402                auto handlers = get<CatchStmt>().acceptL( node->handlers );
403                auto stmt = new TryStmt(
404                        get<CompoundStmt>().accept1( node->body ),
405                        handlers,
406                        get<FinallyStmt>().accept1( node->finally )
407                );
408                return stmtPostamble( stmt, node );
409        }
410
411        const ast::Stmt * visit( const ast::CatchStmt * node ) override final {
412                CatchStmt::Kind kind;
413                switch (node->kind) {
414                case ast::CatchStmt::Terminate:
415                        kind = CatchStmt::Terminate;
416                        break;
417                case ast::CatchStmt::Resume:
418                        kind = CatchStmt::Resume;
419                        break;
420                default:
421                        assertf(false, "Invalid ast::CatchStmt::Kind: %d\n", node->kind);
422                }
423                auto stmt = new CatchStmt(
424                        kind,
425                        get<Declaration>().accept1( node->decl ),
426                        get<Expression>().accept1( node->cond ),
427                        get<Statement>().accept1( node->body )
428                );
429                return stmtPostamble( stmt, node );
430        }
431
432        const ast::Stmt * visit( const ast::FinallyStmt * node ) override final {
433                auto stmt = new FinallyStmt( get<CompoundStmt>().accept1( node->body ) );
434                return stmtPostamble( stmt, node );
435        }
436
437        const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
438                auto stmt = new WaitForStmt;
439                stmt->clauses.reserve( node->clauses.size() );
440                for ( auto clause : node->clauses ) {
441                        stmt->clauses.push_back({{
442                                        get<Expression>().accept1( clause.target.func ),
443                                        get<Expression>().acceptL( clause.target.args ),
444                                },
445                                get<Statement>().accept1( clause.stmt ),
446                                get<Expression>().accept1( clause.cond ),
447                        });
448                }
449                stmt->timeout = {
450                        get<Expression>().accept1( node->timeout.time ),
451                        get<Statement>().accept1( node->timeout.stmt ),
452                        get<Expression>().accept1( node->timeout.cond ),
453                };
454                stmt->orelse = {
455                        get<Statement>().accept1( node->orElse.stmt ),
456                        get<Expression>().accept1( node->orElse.cond ),
457                };
458                return stmtPostamble( stmt, node );
459        }
460
461        const ast::Stmt * visit( const ast::WithStmt * node ) override final {
462                auto stmt = new WithStmt(
463                        get<Expression>().acceptL( node->exprs ),
464                        get<Statement>().accept1( node->stmt )
465                );
466                return stmtPostamble( stmt, node );
467        }
468
469        const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
470                auto stmt = new NullStmt();
471                stmtPostamble( stmt, node );
472                return nullptr;
473        }
474
475        const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
476                auto stmt = new DeclStmt( get<Declaration>().accept1( node->decl ) );
477                return stmtPostamble( stmt, node );
478        }
479
480        const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
481                (void)node;
482                return nullptr;
483        }
484
485        TypeSubstitution * convertTypeSubstitution(const ast::TypeSubstitution * src) {
486
487                TypeSubstitution *rslt = new TypeSubstitution();
488
489                for (decltype(src->begin()) src_i = src->begin(); src_i != src->end(); src_i++) {
490                        rslt->add( src_i->first,
491                                   get<Type>().accept1(src_i->second) );
492                }
493
494                for (decltype(src->beginVar()) src_i = src->beginVar(); src_i != src->endVar(); src_i++) {
495                        rslt->addVar( src_i->first,
496                                      get<Expression>().accept1(src_i->second) );
497                }
498
499                return rslt;
500        }
501
502        void convertInferUnion(std::map<UniqueId,ParamEntry> &tgtInferParams,
503                                                   std::vector<UniqueId>         &tgtResnSlots,
504                                                   const ast::Expr::InferUnion   &srcInferred ) {
505
506                assert( tgtInferParams.empty() );
507                assert( tgtResnSlots.empty() );
508
509                if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
510                        const ast::InferredParams &srcParams = srcInferred.inferParamsConst();
511                        for (auto srcParam : srcParams) {
512                                tgtInferParams[srcParam.first] = ParamEntry(
513                                        srcParam.second.decl,
514                                        get<Type>().accept1(srcParam.second.actualType),
515                                        get<Type>().accept1(srcParam.second.formalType),
516                                        get<Expression>().accept1(srcParam.second.expr)
517                                );
518                        }
519                } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
520                        const ast::ResnSlots &srcSlots = srcInferred.resnSlotsConst();
521                        for (auto srcSlot : srcSlots) {
522                                tgtResnSlots.push_back(srcSlot);
523                        }
524                }
525        }
526
527        Expression * visitBaseExpr(const ast::Expr * src, Expression * tgt) {
528
529                tgt->location = src->location;
530
531                tgt->result = get<Type>().accept1(src->result);
532                tgt->env    = convertTypeSubstitution(src->env);
533
534                tgt->extension = src->extension;
535                convertInferUnion(tgt->inferParams, tgt->resnSlots, src->inferred);
536
537                return tgt;
538        }
539
540        const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
541                auto expr = visitBaseExpr( node,
542                        new ApplicationExpr(
543                                get<Expression>().accept1(node->func),
544                                get<Expression>().acceptL(node->args)
545                        )
546                );
547                this->node = expr;
548                return nullptr;
549        }
550
551        const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
552                auto expr = visitBaseExpr( node,
553                        new UntypedExpr(
554                                get<Expression>().accept1(node->func),
555                                get<Expression>().acceptL(node->args)
556                        )
557                );
558                this->node = expr;
559                return nullptr;
560        }
561
562        const ast::Expr * visit( const ast::NameExpr * node ) override final {
563                auto expr = visitBaseExpr( node,
564                        new NameExpr(
565                                node->name
566                        )
567                );
568                this->node = expr;
569                return nullptr;
570        }
571
572        const ast::Expr * visit( const ast::AddressExpr * node ) override final {
573                (void)node;
574                return nullptr;
575        }
576
577        const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
578                (void)node;
579                return nullptr;
580        }
581
582        const ast::Expr * visit( const ast::CastExpr * node ) override final {
583                (void)node;
584                return nullptr;
585        }
586
587        const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
588                (void)node;
589                return nullptr;
590        }
591
592        const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
593                (void)node;
594                return nullptr;
595        }
596
597        const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
598                (void)node;
599                return nullptr;
600        }
601
602        const ast::Expr * visit( const ast::MemberExpr * node ) override final {
603                (void)node;
604                return nullptr;
605        }
606
607        const ast::Expr * visit( const ast::VariableExpr * node ) override final {
608                (void)node;
609                return nullptr;
610        }
611
612        const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
613                (void)node;
614                return nullptr;
615        }
616
617        const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
618                (void)node;
619                return nullptr;
620        }
621
622        const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
623                (void)node;
624                return nullptr;
625        }
626
627        const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
628                (void)node;
629                return nullptr;
630        }
631
632        const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
633                (void)node;
634                return nullptr;
635        }
636
637        const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
638                (void)node;
639                return nullptr;
640        }
641
642        const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
643                (void)node;
644                return nullptr;
645        }
646
647        const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
648                (void)node;
649                return nullptr;
650        }
651
652        const ast::Expr * visit( const ast::CommaExpr * node ) override final {
653                (void)node;
654                return nullptr;
655        }
656
657        const ast::Expr * visit( const ast::TypeExpr * node ) override final {
658                (void)node;
659                return nullptr;
660        }
661
662        const ast::Expr * visit( const ast::AsmExpr * node ) override final {
663                (void)node;
664                return nullptr;
665        }
666
667        const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
668                (void)node;
669                return nullptr;
670        }
671
672        const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
673                (void)node;
674                return nullptr;
675        }
676
677        const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
678                (void)node;
679                return nullptr;
680        }
681
682        const ast::Expr * visit( const ast::RangeExpr * node ) override final {
683                (void)node;
684                return nullptr;
685        }
686
687        const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
688                (void)node;
689                return nullptr;
690        }
691
692        const ast::Expr * visit( const ast::TupleExpr * node ) override final {
693                (void)node;
694                return nullptr;
695        }
696
697        const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
698                (void)node;
699                return nullptr;
700        }
701
702        const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
703                (void)node;
704                return nullptr;
705        }
706
707        const ast::Expr * visit( const ast::StmtExpr * node ) override final {
708                (void)node;
709                return nullptr;
710        }
711
712        const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
713                (void)node;
714                return nullptr;
715        }
716
717        const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
718                (void)node;
719                return nullptr;
720        }
721
722        const ast::Expr * visit( const ast::InitExpr * node ) override final {
723                (void)node;
724                return nullptr;
725        }
726
727        const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
728                (void)node;
729                return nullptr;
730        }
731
732        const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
733                (void)node;
734                return nullptr;
735        }
736
737        const ast::Expr * visit( const ast::GenericExpr * node ) override final {
738                (void)node;
739                return nullptr;
740        }
741
742        const ast::Type * visit( const ast::VoidType * node ) override final {
743                this->node = new VoidType{ cv( node ) };
744                return nullptr;
745        }
746
747        const ast::Type * visit( const ast::BasicType * node ) override final {
748                this->node = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind };
749                return nullptr;
750        }
751
752        const ast::Type * visit( const ast::PointerType * node ) override final {
753                this->node = new PointerType{
754                        cv( node ),
755                        get<Type>().accept1( node->base ),
756                        get<Expression>().accept1( node->dimension ),
757                        (bool)node->isVarLen,
758                        (bool)node->isStatic
759                };
760                return nullptr;
761        }
762
763        const ast::Type * visit( const ast::ArrayType * node ) override final {
764                this->node = new ArrayType{
765                        cv( node ),
766                        get<Type>().accept1( node->base ),
767                        get<Expression>().accept1( node->dimension ),
768                        (bool)node->isVarLen,
769                        (bool)node->isStatic
770                };
771                return nullptr;
772        }
773
774        const ast::Type * visit( const ast::ReferenceType * node ) override final {
775                this->node = new ReferenceType{
776                        cv( node ),
777                        get<Type>().accept1( node->base )
778                };
779                return nullptr;
780        }
781
782        const ast::Type * visit( const ast::QualifiedType * node ) override final {
783                this->node = new QualifiedType{
784                        cv( node ),
785                        get<Type>().accept1( node->parent ),
786                        get<Type>().accept1( node->child )
787                };
788                return nullptr;
789        }
790
791        const ast::Type * visit( const ast::FunctionType * node ) override final {
792                auto ty = new FunctionType {
793                        cv( node ), 
794                        (bool)node->isVarArgs
795                };
796                ty->returnVals = get<DeclarationWithType>().acceptL( node->returns );
797                ty->parameters = get<DeclarationWithType>().acceptL( node->params );
798                ty->forall = get<TypeDecl>().acceptL( node->forall );
799                this->node = ty;
800                return nullptr;
801        }
802
803        void postvisit( const ast::ReferenceToType * old, ReferenceToType * ty ) {
804                ty->forall = get<TypeDecl>().acceptL( old->forall );
805                ty->parameters = get<Expression>().acceptL( old->params );
806                ty->hoistType = old->hoistType;
807        }
808
809        const ast::Type * visit( const ast::StructInstType * node ) override final {
810                StructInstType * ty;
811                if ( node->base ) {
812                        ty = new StructInstType{
813                                cv( node ),
814                                get<StructDecl>().accept1( node->base ),
815                                get<Attribute>().acceptL( node->attributes )
816                        };
817                } else {
818                        ty = new StructInstType{
819                                cv( node ),
820                                node->name,
821                                get<Attribute>().acceptL( node->attributes )
822                        };
823                }
824                postvisit( node, ty );
825                this->node = ty;
826                return nullptr;
827        }
828
829        const ast::Type * visit( const ast::UnionInstType * node ) override final {
830                UnionInstType * ty;
831                if ( node->base ) {
832                        ty = new UnionInstType{
833                                cv( node ),
834                                get<UnionDecl>().accept1( node->base ),
835                                get<Attribute>().acceptL( node->attributes )
836                        };
837                } else {
838                        ty = new UnionInstType{
839                                cv( node ),
840                                node->name,
841                                get<Attribute>().acceptL( node->attributes )
842                        };
843                }
844                postvisit( node, ty );
845                this->node = ty;
846                return nullptr;
847        }
848
849        const ast::Type * visit( const ast::EnumInstType * node ) override final {
850                EnumInstType * ty;
851                if ( node->base ) {
852                        ty = new EnumInstType{
853                                cv( node ),
854                                get<EnumDecl>().accept1( node->base ),
855                                get<Attribute>().acceptL( node->attributes )
856                        };
857                } else {
858                        ty = new EnumInstType{
859                                cv( node ),
860                                node->name,
861                                get<Attribute>().acceptL( node->attributes )
862                        };
863                }
864                postvisit( node, ty );
865                this->node = ty;
866                return nullptr;
867        }
868
869        const ast::Type * visit( const ast::TraitInstType * node ) override final {
870                TraitInstType * ty;
871                if ( node->base ) {
872                        ty = new TraitInstType{
873                                cv( node ),
874                                get<TraitDecl>().accept1( node->base ),
875                                get<Attribute>().acceptL( node->attributes )
876                        };
877                } else {
878                        ty = new TraitInstType{
879                                cv( node ),
880                                node->name,
881                                get<Attribute>().acceptL( node->attributes )
882                        };
883                }
884                postvisit( node, ty );
885                this->node = ty;
886                return nullptr;
887        }
888
889        const ast::Type * visit( const ast::TypeInstType * node ) override final {
890                TypeInstType * ty;
891                if ( node->base ) {
892                        ty = new TypeInstType{
893                                cv( node ),
894                                node->name,
895                                get<TypeDecl>().accept1( node->base ),
896                                get<Attribute>().acceptL( node->attributes )
897                        };
898                } else {
899                        ty = new TypeInstType{
900                                cv( node ),
901                                node->name,
902                                node->kind == ast::TypeVar::Ftype,
903                                get<Attribute>().acceptL( node->attributes )
904                        };
905                }
906                postvisit( node, ty );
907                this->node = ty;
908                return nullptr;
909        }
910
911        const ast::Type * visit( const ast::TupleType * node ) override final {
912                this->node = new TupleType{
913                        cv( node ),
914                        get<Type>().acceptL( node->types )
915                        // members generated by TupleType c'tor
916                };
917                return nullptr;
918        }
919
920        const ast::Type * visit( const ast::TypeofType * node ) override final {
921                this->node = new TypeofType{
922                        cv( node ),
923                        get<Expression>().accept1( node->expr ),
924                        (bool)node->kind
925                };
926                return nullptr;
927        }
928
929        const ast::Type * visit( const ast::VarArgsType * node ) override final {
930                this->node = new VarArgsType{ cv( node ) };
931                return nullptr;
932        }
933
934        const ast::Type * visit( const ast::ZeroType * node ) override final {
935                this->node = new ZeroType{ cv( node ) };
936                return nullptr;
937        }
938
939        const ast::Type * visit( const ast::OneType * node ) override final {
940                this->node = new OneType{ cv( node ) };
941                return nullptr;
942        }
943
944        const ast::Type * visit( const ast::GlobalScopeType * ) override final {
945                this->node = new GlobalScopeType{};
946                return nullptr;
947        }
948
949        const ast::Designation * visit( const ast::Designation * node ) override final {
950                (void)node;
951                return nullptr;
952        }
953
954        const ast::Init * visit( const ast::SingleInit * node ) override final {
955                (void)node;
956                return nullptr;
957        }
958
959        const ast::Init * visit( const ast::ListInit * node ) override final {
960                (void)node;
961                return nullptr;
962        }
963
964        const ast::Init * visit( const ast::ConstructorInit * node ) override final {
965                (void)node;
966                return nullptr;
967        }
968
969        const ast::Attribute * visit( const ast::Attribute * node ) override final {
970                (void)node;
971                return nullptr;
972        }
973
974        const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
975                (void)node;
976                return nullptr;
977        }
978};
979
980std::list< Declaration * > convert( std::list< ast::ptr< ast::Decl > > && translationUnit ) {
981        ConverterNewToOld c;
982        std::list< Declaration * > decls;
983        for(auto d : translationUnit) {
984                decls.emplace_back( c.decl( d ) );
985                delete d;
986        }
987        return decls;
988}
989
990//================================================================================================
991
992class ConverterOldToNew : public Visitor {
993public:
994        ast::Decl * decl() {
995                return strict_dynamic_cast< ast::Decl * >( node );
996        }
997private:
998        /// conversion output
999        ast::Node * node;
1000        /// cache of nodes that might be referenced by readonly<> for de-duplication
1001        std::unordered_map< BaseSyntaxNode *, ast::Node * > cache;
1002
1003        // Local Utilities:
1004
1005        template<typename NewT, typename OldT>
1006        NewT * getAccept1( OldT old ) {
1007                if ( ! old ) return nullptr;
1008                old->accept(*this);
1009                return strict_dynamic_cast< NewT * >( node );
1010        }
1011
1012#       define GET_ACCEPT_1(child, type) \
1013                getAccept1< ast::type, decltype( old->child ) >( old->child )
1014
1015        template<typename NewT, typename OldC>
1016        std::vector< ast::ptr<NewT> > getAcceptV( OldC& old ) {
1017                std::vector< ast::ptr<NewT> > ret;
1018                ret.reserve( old.size() );
1019                for ( auto a : old ) {
1020                        a->accept( *this );
1021                        ret.emplace_back( strict_dynamic_cast< NewT * >(node) );
1022                }
1023                return ret;
1024        }
1025
1026#       define GET_ACCEPT_V(child, type) \
1027                getAcceptV< ast::type, decltype( old->child ) >( old->child )
1028
1029        ast::Label make_label(Label* old) {
1030                return ast::Label(
1031                        old->labelled->location,
1032                        old->name,
1033                        GET_ACCEPT_V(attributes, Attribute)
1034                );
1035        }
1036
1037        template<template <class...> class C>
1038        C<ast::Label> make_labels(C<Label> olds) {
1039                C<ast::Label> ret;
1040                for (auto oldn : olds) {
1041                        ret.push_back( make_label( &oldn ) );
1042                }
1043                return ret;
1044        }
1045
1046#       define GET_LABELS_V(labels) \
1047                to<std::vector>::from( make_labels( std::move( labels ) ) )
1048       
1049        static ast::CV::Qualifiers cv( Type * ty ) { return { ty->get_qualifiers().val }; }
1050
1051        /// returns true and sets `node` if in cache
1052        bool inCache( BaseSyntaxNode * old ) {
1053                auto it = cache.find( old );
1054                if ( it == cache.end() ) return false;
1055                node = it->second;
1056                return true;
1057        }
1058
1059        // Now all the visit functions:
1060
1061        virtual void visit( ObjectDecl * old ) override final {
1062                if ( inCache( old ) ) return;
1063                auto decl = new ast::ObjectDecl(
1064                        old->location,
1065                        old->name,
1066                        GET_ACCEPT_1(type, Type),
1067                        GET_ACCEPT_1(init, Init),
1068                        { old->get_storageClasses().val },
1069                        { old->linkage.val },
1070                        GET_ACCEPT_1(bitfieldWidth, Expr),
1071                        GET_ACCEPT_V(attributes, Attribute),
1072                        { old->get_funcSpec().val }
1073                );
1074                decl->scopeLevel = old->scopeLevel;
1075                decl->mangleName = old->mangleName;
1076                decl->isDeleted  = old->isDeleted;
1077                decl->uniqueId   = old->uniqueId;
1078                decl->extension  = old->extension;
1079                cache.emplace( old, decl );
1080
1081                this->node = decl;
1082        }
1083
1084        virtual void visit( FunctionDecl * old ) override final {
1085                if ( inCache( old ) ) return;
1086                // TODO
1087                auto decl = (ast::FunctionDecl *)nullptr;
1088                cache.emplace( old, decl );
1089        }
1090
1091        virtual void visit( StructDecl * old ) override final {
1092                if ( inCache( old ) ) return;
1093                auto decl = new ast::StructDecl(
1094                        old->location,
1095                        old->name,
1096                        old->kind,
1097                        GET_ACCEPT_V(attributes, Attribute),
1098                        { old->linkage.val }
1099                );
1100                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1101                decl->body   = old->body;
1102                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1103                decl->members    = GET_ACCEPT_V(members, Decl);
1104                decl->extension  = old->extension;
1105                decl->uniqueId   = old->uniqueId;
1106                decl->storage    = { old->storageClasses.val };
1107                cache.emplace( old, decl );
1108
1109                this->node = decl;
1110        }
1111
1112        virtual void visit( UnionDecl * old ) override final {
1113                if ( inCache( old ) ) return;
1114                auto decl = new ast::UnionDecl(
1115                        old->location,
1116                        old->name,
1117                        GET_ACCEPT_V(attributes, Attribute),
1118                        { old->linkage.val }
1119                );
1120                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1121                decl->body   = old->body;
1122                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1123                decl->members    = GET_ACCEPT_V(members, Decl);
1124                decl->extension  = old->extension;
1125                decl->uniqueId   = old->uniqueId;
1126                decl->storage    = { old->storageClasses.val };
1127                cache.emplace( old, decl );
1128
1129                this->node = decl;
1130        }
1131
1132        virtual void visit( EnumDecl * old ) override final {
1133                if ( inCache( old ) ) return;
1134                auto decl = new ast::UnionDecl(
1135                        old->location,
1136                        old->name,
1137                        GET_ACCEPT_V(attributes, Attribute),
1138                        { old->linkage.val }
1139                );
1140                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1141                decl->body   = old->body;
1142                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1143                decl->members    = GET_ACCEPT_V(members, Decl);
1144                decl->extension  = old->extension;
1145                decl->uniqueId   = old->uniqueId;
1146                decl->storage    = { old->storageClasses.val };
1147                cache.emplace( old, decl );
1148
1149                this->node = decl;
1150        }
1151
1152        virtual void visit( TraitDecl * old ) override final {
1153                if ( inCache( old ) ) return;
1154                auto decl = new ast::UnionDecl(
1155                        old->location,
1156                        old->name,
1157                        GET_ACCEPT_V(attributes, Attribute),
1158                        { old->linkage.val }
1159                );
1160                decl->parent = GET_ACCEPT_1(parent, AggregateDecl);
1161                decl->body   = old->body;
1162                decl->params = GET_ACCEPT_V(parameters, TypeDecl);
1163                decl->members    = GET_ACCEPT_V(members, Decl);
1164                decl->extension  = old->extension;
1165                decl->uniqueId   = old->uniqueId;
1166                decl->storage    = { old->storageClasses.val };
1167                cache.emplace( old, decl );
1168
1169                this->node = decl;
1170        }
1171
1172        virtual void visit( TypeDecl * old ) override final {
1173                if ( inCache( old ) ) return;
1174                // TODO
1175                auto decl = (ast::TypeDecl *)nullptr;
1176                cache.emplace( old, decl );
1177        }
1178
1179        virtual void visit( TypedefDecl * old ) override final {
1180                auto decl = new ast::TypedefDecl(
1181                        old->location,
1182                        old->name,
1183                        { old->storageClasses.val },
1184                        GET_ACCEPT_1(base, Type),
1185                        { old->linkage.val }
1186                );
1187                decl->assertions = GET_ACCEPT_V(assertions, DeclWithType);
1188                decl->params     = GET_ACCEPT_V(parameters, TypeDecl);
1189                decl->extension  = old->extension;
1190                decl->uniqueId   = old->uniqueId;
1191                decl->storage    = { old->storageClasses.val };
1192
1193                this->node = decl;
1194        }
1195
1196        virtual void visit( AsmDecl * ) override final {
1197
1198        }
1199
1200        virtual void visit( StaticAssertDecl * ) override final {
1201
1202        }
1203
1204        virtual void visit( CompoundStmt * old ) override final {
1205                auto stmt = new ast::CompoundStmt(
1206                        old->location,
1207                        to<std::list>::from( GET_ACCEPT_V(kids, Stmt) ),
1208                        GET_LABELS_V(old->labels)
1209                );
1210
1211                this->node = stmt;
1212        }
1213
1214        virtual void visit( ExprStmt * old ) override final {
1215                this->node = new ast::ExprStmt(
1216                        old->location,
1217                        GET_ACCEPT_1(expr, Expr),
1218                        GET_LABELS_V(old->labels)
1219                );
1220        }
1221
1222        virtual void visit( AsmStmt * old ) override final {
1223                this->node = new ast::AsmStmt(
1224                        old->location,
1225                        old->voltile,
1226                        GET_ACCEPT_1(instruction, Expr),
1227                        GET_ACCEPT_V(output, Expr),
1228                        GET_ACCEPT_V(input, Expr),
1229                        GET_ACCEPT_V(clobber, ConstantExpr),
1230                        GET_LABELS_V(old->gotolabels),
1231                        GET_LABELS_V(old->labels)
1232                );
1233        }
1234
1235        virtual void visit( DirectiveStmt * old ) override final {
1236                this->node = new ast::DirectiveStmt(
1237                        old->location,
1238                        old->directive,
1239                        GET_LABELS_V(old->labels)
1240                );
1241        }
1242
1243        virtual void visit( IfStmt * old ) override final {
1244                this->node = new ast::IfStmt(
1245                        old->location,
1246                        GET_ACCEPT_1(condition, Expr),
1247                        GET_ACCEPT_1(thenPart, Stmt),
1248                        GET_ACCEPT_1(elsePart, Stmt),
1249                        GET_ACCEPT_V(initialization, Stmt),
1250                        GET_LABELS_V(old->labels)
1251                );
1252        }
1253
1254        virtual void visit( SwitchStmt * old ) override final {
1255                this->node = new ast::SwitchStmt(
1256                        old->location,
1257                        GET_ACCEPT_1(condition, Expr),
1258                        GET_ACCEPT_V(statements, Stmt),
1259                        GET_LABELS_V(old->labels)
1260                );
1261        }
1262
1263        virtual void visit( CaseStmt * old ) override final {
1264                this->node = new ast::CaseStmt(
1265                        old->location,
1266                        GET_ACCEPT_1(condition, Expr),
1267                        GET_ACCEPT_V(stmts, Stmt),
1268                        GET_LABELS_V(old->labels)
1269                );
1270        }
1271
1272        virtual void visit( WhileStmt * old ) override final {
1273                this->node = new ast::WhileStmt(
1274                        old->location,
1275                        GET_ACCEPT_1(condition, Expr),
1276                        GET_ACCEPT_1(body, Stmt),
1277                        GET_ACCEPT_V(initialization, Stmt),
1278                        old->isDoWhile,
1279                        GET_LABELS_V(old->labels)
1280                );
1281        }
1282
1283        virtual void visit( ForStmt * old ) override final {
1284                this->node = new ast::ForStmt(
1285                        old->location,
1286                        GET_ACCEPT_V(initialization, Stmt),
1287                        GET_ACCEPT_1(condition, Expr),
1288                        GET_ACCEPT_1(increment, Expr),
1289                        GET_ACCEPT_1(body, Stmt),
1290                        GET_LABELS_V(old->labels)
1291                );
1292        }
1293
1294        virtual void visit( BranchStmt * old ) override final {
1295                if (old->computedTarget) {
1296                        this->node = new ast::BranchStmt(
1297                                old->location,
1298                                GET_ACCEPT_1(computedTarget, Expr),
1299                                GET_LABELS_V(old->labels)
1300                        );
1301                } else {
1302                        ast::BranchStmt::Kind kind;
1303                        switch (old->type) {
1304                        #define CASE(n) \
1305                        case BranchStmt::n: \
1306                                kind = ast::BranchStmt::n; \
1307                                break
1308                        CASE(Goto);
1309                        CASE(Break);
1310                        CASE(Continue);
1311                        CASE(FallThrough);
1312                        CASE(FallThroughDefault);
1313                        #undef CASE
1314                        default:
1315                                assertf(false, "Invalid BranchStmt::Type %d\n", old->type);
1316                        }
1317
1318                        Label label = old->originalTarget;
1319                        auto stmt = new ast::BranchStmt(
1320                                old->location,
1321                                kind,
1322                                make_label(&label),
1323                                GET_LABELS_V(old->labels)
1324                        );
1325                        stmt->target = make_label(&old->target);
1326                        this->node = stmt;
1327                }
1328        }
1329
1330        virtual void visit( ReturnStmt * old ) override final {
1331                this->node = new ast::ReturnStmt(
1332                        old->location,
1333                        GET_ACCEPT_1(expr, Expr),
1334                        GET_LABELS_V(old->labels)
1335                );
1336        }
1337
1338        virtual void visit( ThrowStmt * old ) override final {
1339                ast::ThrowStmt::Kind kind;
1340                switch (old->kind) {
1341                case ThrowStmt::Terminate:
1342                        kind = ast::ThrowStmt::Terminate;
1343                        break;
1344                case ThrowStmt::Resume:
1345                        kind = ast::ThrowStmt::Resume;
1346                        break;
1347                default:
1348                        assertf(false, "Invalid ThrowStmt::Kind %d\n", old->kind);
1349                }
1350
1351                this->node = new ast::ThrowStmt(
1352                        old->location,
1353                        kind,
1354                        GET_ACCEPT_1(expr, Expr),
1355                        GET_ACCEPT_1(target, Expr),
1356                        GET_LABELS_V(old->labels)
1357                );
1358        }
1359
1360        virtual void visit( TryStmt * old ) override final {
1361                this->node = new ast::TryStmt(
1362                        old->location,
1363                        GET_ACCEPT_1(block, CompoundStmt),
1364                        GET_ACCEPT_V(handlers, CatchStmt),
1365                        GET_ACCEPT_1(finallyBlock, FinallyStmt),
1366                        GET_LABELS_V(old->labels)
1367                );
1368        }
1369
1370        virtual void visit( CatchStmt * old ) override final {
1371                ast::CatchStmt::Kind kind;
1372                switch (old->kind) {
1373                case CatchStmt::Terminate:
1374                        kind = ast::CatchStmt::Terminate;
1375                        break;
1376                case CatchStmt::Resume:
1377                        kind = ast::CatchStmt::Resume;
1378                        break;
1379                default:
1380                        assertf(false, "Invalid CatchStmt::Kind %d\n", old->kind);
1381                }
1382
1383                this->node = new ast::CatchStmt(
1384                        old->location,
1385                        kind,
1386                        GET_ACCEPT_1(decl, Decl),
1387                        GET_ACCEPT_1(cond, Expr),
1388                        GET_ACCEPT_1(body, Stmt),
1389                        GET_LABELS_V(old->labels)
1390                );
1391        }
1392
1393        virtual void visit( FinallyStmt * old ) override final {
1394                this->node = new ast::FinallyStmt(
1395                        old->location,
1396                        GET_ACCEPT_1(block, CompoundStmt),
1397                        GET_LABELS_V(old->labels)
1398                );
1399        }
1400
1401        virtual void visit( WaitForStmt * old ) override final {
1402                ast::WaitForStmt * stmt = new ast::WaitForStmt(
1403                        old->location,
1404                        GET_LABELS_V(old->labels)
1405                );
1406
1407                stmt->clauses.reserve( old->clauses.size() );
1408                for (size_t i = 0 ; i < old->clauses.size() ; ++i) {
1409                        stmt->clauses.push_back({
1410                                ast::WaitForStmt::Target{
1411                                        GET_ACCEPT_1(clauses[i].target.function, Expr),
1412                                        GET_ACCEPT_V(clauses[i].target.arguments, Expr)
1413                                },
1414                                GET_ACCEPT_1(clauses[i].statement, Stmt),
1415                                GET_ACCEPT_1(clauses[i].condition, Expr)
1416                        });
1417                }
1418                stmt->timeout = {
1419                        GET_ACCEPT_1(timeout.time, Expr),
1420                        GET_ACCEPT_1(timeout.statement, Stmt),
1421                        GET_ACCEPT_1(timeout.condition, Expr),
1422                };
1423                stmt->orElse = {
1424                        GET_ACCEPT_1(timeout.statement, Stmt),
1425                        GET_ACCEPT_1(timeout.condition, Expr),
1426                };
1427
1428                this->node = stmt;
1429        }
1430
1431        virtual void visit( WithStmt * old ) override final {
1432                this->node = new ast::WithStmt(
1433                        old->location,
1434                        GET_ACCEPT_V(exprs, Expr),
1435                        GET_ACCEPT_1(stmt, Stmt),
1436                        GET_LABELS_V(old->labels)
1437                );
1438        }
1439
1440        virtual void visit( NullStmt * old ) override final {
1441                this->node = new ast::NullStmt(
1442                        old->location,
1443                        GET_LABELS_V(old->labels)
1444                );
1445        }
1446
1447        virtual void visit( DeclStmt * old ) override final {
1448                this->node = new ast::DeclStmt(
1449                        old->location,
1450                        GET_ACCEPT_1(decl, Decl),
1451                        GET_LABELS_V(old->labels)
1452                );
1453        }
1454
1455        virtual void visit( ImplicitCtorDtorStmt * old ) override final {
1456                this->node = new ast::ImplicitCtorDtorStmt(
1457                        old->location,
1458                        GET_ACCEPT_1(callStmt, Stmt),
1459                        GET_LABELS_V(old->labels)
1460                );
1461        }
1462
1463        ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) {
1464
1465                ast::TypeSubstitution *rslt = new ast::TypeSubstitution();
1466
1467                for (decltype(old->begin()) old_i = old->begin(); old_i != old->end(); old_i++) {
1468                        rslt->add( old_i->first,
1469                                   getAccept1<ast::Type>(old_i->second) );
1470                }
1471
1472                for (decltype(old->beginVar()) old_i = old->beginVar(); old_i != old->endVar(); old_i++) {
1473                        rslt->addVar( old_i->first,
1474                                      getAccept1<ast::Expr>(old_i->second) );
1475                }
1476
1477                return rslt;
1478        }
1479
1480        void convertInferUnion(ast::Expr::InferUnion               &newInferred,
1481                                                   const std::map<UniqueId,ParamEntry> &oldInferParams,
1482                                                   const std::vector<UniqueId>         &oldResnSlots) {
1483
1484                assert( oldInferParams.empty() || oldResnSlots.empty() );
1485                assert( newInferred.mode == ast::Expr::InferUnion::Empty );
1486
1487                if ( !oldInferParams.empty() ) {
1488                        ast::InferredParams &tgt = newInferred.inferParams();
1489                        for (auto old : oldInferParams) {
1490                                tgt[old.first] = ast::ParamEntry(
1491                                        old.second.decl,
1492                                        getAccept1<ast::Type>(old.second.actualType),
1493                                        getAccept1<ast::Type>(old.second.formalType),
1494                                        getAccept1<ast::Expr>(old.second.expr)
1495                                );
1496                        }
1497                } else if ( !oldResnSlots.empty() ) {
1498                        ast::ResnSlots &tgt = newInferred.resnSlots();
1499                        for (auto old : oldResnSlots) {
1500                                tgt.push_back(old);
1501                        }
1502                }
1503        }
1504
1505        ast::Expr * visitBaseExpr(Expression * old, ast::Expr * nw) {
1506
1507                nw->result = GET_ACCEPT_1(result, Type);
1508                nw->env    = convertTypeSubstitution(old->env);
1509
1510                nw->extension = old->extension;
1511                convertInferUnion(nw->inferred, old->inferParams, old->resnSlots);
1512
1513                return nw;
1514        }
1515
1516        virtual void visit( ApplicationExpr * old ) override final {
1517                this->node = visitBaseExpr( old,
1518                        new ast::ApplicationExpr(
1519                                old->location,
1520                                GET_ACCEPT_1(function, Expr),
1521                                GET_ACCEPT_V(args, Expr)
1522                        )
1523                );
1524        }
1525
1526        virtual void visit( UntypedExpr * old ) override final {
1527                this->node = visitBaseExpr( old,
1528                        new ast::UntypedExpr(
1529                                old->location,
1530                                GET_ACCEPT_1(function, Expr),
1531                                GET_ACCEPT_V(args, Expr)
1532                        )
1533                );
1534        }
1535
1536        virtual void visit( NameExpr * old ) override final {
1537                this->node = visitBaseExpr( old,
1538                        new ast::NameExpr(
1539                                old->location,
1540                                old->get_name()
1541                        )
1542                );
1543        }
1544
1545        virtual void visit( CastExpr * old ) override final {
1546                this->node = visitBaseExpr( old,
1547                        new ast::CastExpr(
1548                                old->location,
1549                                nullptr, // cast's "to" type is expr's result type; converted in visitBaseExpr
1550                                old->isGenerated ? ast::GeneratedCast : ast::ExplicitCast
1551                        )
1552                );
1553        }
1554
1555        virtual void visit( KeywordCastExpr * ) override final {
1556
1557        }
1558
1559        virtual void visit( VirtualCastExpr * ) override final {
1560
1561        }
1562
1563        virtual void visit( AddressExpr * ) override final {
1564
1565        }
1566
1567        virtual void visit( LabelAddressExpr * ) override final {
1568
1569        }
1570
1571        virtual void visit( UntypedMemberExpr * ) override final {
1572
1573        }
1574
1575        virtual void visit( MemberExpr * ) override final {
1576
1577        }
1578
1579        virtual void visit( VariableExpr * ) override final {
1580
1581        }
1582
1583        virtual void visit( ConstantExpr * ) override final {
1584
1585        }
1586
1587        virtual void visit( SizeofExpr * ) override final {
1588
1589        }
1590
1591        virtual void visit( AlignofExpr * ) override final {
1592
1593        }
1594
1595        virtual void visit( UntypedOffsetofExpr * ) override final {
1596
1597        }
1598
1599        virtual void visit( OffsetofExpr * ) override final {
1600
1601        }
1602
1603        virtual void visit( OffsetPackExpr * ) override final {
1604
1605        }
1606
1607        virtual void visit( LogicalExpr * ) override final {
1608
1609        }
1610
1611        virtual void visit( ConditionalExpr * ) override final {
1612
1613        }
1614
1615        virtual void visit( CommaExpr * ) override final {
1616
1617        }
1618
1619        virtual void visit( TypeExpr * ) override final {
1620
1621        }
1622
1623        virtual void visit( AsmExpr * ) override final {
1624
1625        }
1626
1627        virtual void visit( ImplicitCopyCtorExpr * ) override final {
1628
1629        }
1630
1631        virtual void visit( ConstructorExpr *  ) override final {
1632
1633        }
1634
1635        virtual void visit( CompoundLiteralExpr * ) override final {
1636
1637        }
1638
1639        virtual void visit( RangeExpr * ) override final {
1640
1641        }
1642
1643        virtual void visit( UntypedTupleExpr * ) override final {
1644
1645        }
1646
1647        virtual void visit( TupleExpr * ) override final {
1648
1649        }
1650
1651        virtual void visit( TupleIndexExpr * ) override final {
1652
1653        }
1654
1655        virtual void visit( TupleAssignExpr * ) override final {
1656
1657        }
1658
1659        virtual void visit( StmtExpr *  ) override final {
1660
1661        }
1662
1663        virtual void visit( UniqueExpr *  ) override final {
1664
1665        }
1666
1667        virtual void visit( UntypedInitExpr *  ) override final {
1668
1669        }
1670
1671        virtual void visit( InitExpr *  ) override final {
1672
1673        }
1674
1675        virtual void visit( DeletedExpr * ) override final {
1676
1677        }
1678
1679        virtual void visit( DefaultArgExpr * ) override final {
1680
1681        }
1682
1683        virtual void visit( GenericExpr * ) override final {
1684
1685        }
1686
1687        virtual void visit( VoidType * old ) override final {
1688                this->node = new ast::VoidType{ cv( old ) };
1689        }
1690
1691        virtual void visit( BasicType * old ) override final {
1692                this->node = new ast::BasicType{ (ast::BasicType::Kind)(unsigned)old->kind, cv( old ) };
1693        }
1694
1695        virtual void visit( PointerType * old ) override final {
1696                this->node = new ast::PointerType{
1697                        GET_ACCEPT_1( base, Type ),
1698                        GET_ACCEPT_1( dimension, Expr ),
1699                        (ast::LengthFlag)old->isVarLen,
1700                        (ast::DimensionFlag)old->isStatic,
1701                        cv( old )
1702                };
1703        }
1704
1705        virtual void visit( ArrayType * old ) override final {
1706                this->node = new ast::ArrayType{
1707                        GET_ACCEPT_1( base, Type ),
1708                        GET_ACCEPT_1( dimension, Expr ),
1709                        (ast::LengthFlag)old->isVarLen,
1710                        (ast::DimensionFlag)old->isStatic,
1711                        cv( old )
1712                };
1713        }
1714
1715        virtual void visit( ReferenceType * old ) override final {
1716                this->node = new ast::ReferenceType{
1717                        GET_ACCEPT_1( base, Type ),
1718                        cv( old )
1719                };
1720        }
1721
1722        virtual void visit( QualifiedType * old ) override final {
1723                this->node = new ast::QualifiedType{
1724                        GET_ACCEPT_1( parent, Type ),
1725                        GET_ACCEPT_1( child, Type ),
1726                        cv( old )
1727                };
1728        }
1729
1730        virtual void visit( FunctionType * old ) override final {
1731                auto ty = new ast::FunctionType {
1732                        (ast::ArgumentFlag)old->isVarArgs,
1733                        cv( old )
1734                };
1735                ty->returns = GET_ACCEPT_V( returnVals, DeclWithType );
1736                ty->params = GET_ACCEPT_V( parameters, DeclWithType );
1737                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
1738                this->node = ty;
1739        }
1740
1741        void postvisit( ReferenceToType * old, ast::ReferenceToType * ty ) {
1742                ty->forall = GET_ACCEPT_V( forall, TypeDecl );
1743                ty->params = GET_ACCEPT_V( parameters, Expr );
1744                ty->hoistType = old->hoistType;
1745        }
1746
1747        virtual void visit( StructInstType * old ) override final {
1748                ast::StructInstType * ty;
1749                if ( old->baseStruct ) {
1750                        ty = new ast::StructInstType{
1751                                GET_ACCEPT_1( baseStruct, StructDecl ),
1752                                cv( old ),
1753                                GET_ACCEPT_V( attributes, Attribute )
1754                        };
1755                } else {
1756                        ty = new ast::StructInstType{
1757                                old->name,
1758                                cv( old ),
1759                                GET_ACCEPT_V( attributes, Attribute )
1760                        };
1761                }
1762                postvisit( old, ty );
1763                this->node = ty;
1764        }
1765
1766        virtual void visit( UnionInstType * old ) override final {
1767                ast::UnionInstType * ty;
1768                if ( old->baseUnion ) {
1769                        ty = new ast::UnionInstType{
1770                                GET_ACCEPT_1( baseUnion, UnionDecl ),
1771                                cv( old ),
1772                                GET_ACCEPT_V( attributes, Attribute )
1773                        };
1774                } else {
1775                        ty = new ast::UnionInstType{
1776                                old->name,
1777                                cv( old ),
1778                                GET_ACCEPT_V( attributes, Attribute )
1779                        };
1780                }
1781                postvisit( old, ty );
1782                this->node = ty;
1783        }
1784
1785        virtual void visit( EnumInstType * old ) override final {
1786                ast::EnumInstType * ty;
1787                if ( old->baseEnum ) {
1788                        ty = new ast::EnumInstType{
1789                                GET_ACCEPT_1( baseEnum, EnumDecl ),
1790                                cv( old ),
1791                                GET_ACCEPT_V( attributes, Attribute )
1792                        };
1793                } else {
1794                        ty = new ast::EnumInstType{
1795                                old->name,
1796                                cv( old ),
1797                                GET_ACCEPT_V( attributes, Attribute )
1798                        };
1799                }
1800                postvisit( old, ty );
1801                this->node = ty;
1802        }
1803
1804        virtual void visit( TraitInstType * old ) override final {
1805                ast::TraitInstType * ty;
1806                if ( old->baseTrait ) {
1807                        ty = new ast::TraitInstType{
1808                                GET_ACCEPT_1( baseTrait, TraitDecl ),
1809                                cv( old ),
1810                                GET_ACCEPT_V( attributes, Attribute )
1811                        };
1812                } else {
1813                        ty = new ast::TraitInstType{
1814                                old->name,
1815                                cv( old ),
1816                                GET_ACCEPT_V( attributes, Attribute )
1817                        };
1818                }
1819                postvisit( old, ty );
1820                this->node = ty;
1821        }
1822
1823        virtual void visit( TypeInstType * old ) override final {
1824                ast::TypeInstType * ty;
1825                if ( old->baseType ) {
1826                        ty = new ast::TypeInstType{
1827                                old->name,
1828                                GET_ACCEPT_1( baseType, TypeDecl ),
1829                                cv( old ),
1830                                GET_ACCEPT_V( attributes, Attribute )
1831                        };
1832                } else {
1833                        ty = new ast::TypeInstType{
1834                                old->name,
1835                                old->isFtype ? ast::TypeVar::Ftype : ast::TypeVar::Dtype,
1836                                cv( old ),
1837                                GET_ACCEPT_V( attributes, Attribute )
1838                        };
1839                }
1840                postvisit( old, ty );
1841                this->node = ty;
1842        }
1843
1844        virtual void visit( TupleType * old ) override final {
1845                this->node = new ast::TupleType{
1846                        GET_ACCEPT_V( types, Type ),
1847                        // members generated by TupleType c'tor
1848                        cv( old )
1849                };
1850        }
1851
1852        virtual void visit( TypeofType * old ) override final {
1853                this->node = new ast::TypeofType{
1854                        GET_ACCEPT_1( expr, Expr ),
1855                        (ast::TypeofType::Kind)old->is_basetypeof,
1856                        cv( old )
1857                };
1858        }
1859
1860        virtual void visit( AttrType * ) override final {
1861                assertf( false, "AttrType deprecated in new AST." );
1862        }
1863
1864        virtual void visit( VarArgsType * old ) override final {
1865                this->node = new ast::VarArgsType{ cv( old ) };
1866        }
1867
1868        virtual void visit( ZeroType * old ) override final {
1869                this->node = new ast::ZeroType{ cv( old ) };
1870        }
1871
1872        virtual void visit( OneType * old ) override final {
1873                this->node = new ast::OneType{ cv( old ) };
1874        }
1875
1876        virtual void visit( GlobalScopeType * ) override final {
1877                this->node = new ast::GlobalScopeType{};
1878        }
1879
1880        virtual void visit( Designation * ) override final {
1881
1882        }
1883
1884        virtual void visit( SingleInit * ) override final {
1885
1886        }
1887
1888        virtual void visit( ListInit * ) override final {
1889
1890        }
1891
1892        virtual void visit( ConstructorInit * ) override final {
1893
1894        }
1895
1896        virtual void visit( Constant * ) override final {
1897
1898        }
1899
1900        virtual void visit( Attribute * ) override final {
1901
1902        }
1903
1904        virtual void visit( AttrExpr * ) override final {
1905
1906                assert( 0 );
1907        }
1908};
1909
1910#undef GET_LABELS_V
1911#undef GET_ACCEPT_V
1912#undef GET_ACCEPT_1
1913
1914std::list< ast::ptr< ast::Decl > > convert( const std::list< Declaration * > && translationUnit ) {
1915        ConverterOldToNew c;
1916        std::list< ast::ptr< ast::Decl > > decls;
1917        for(auto d : translationUnit) {
1918                d->accept( c );
1919                decls.emplace_back( c.decl() );
1920                delete d;
1921        }
1922        return decls;
1923}
Note: See TracBrowser for help on using the repository browser.