source: src/AST/Convert.cpp @ 514a791

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 514a791 was 514a791, checked in by Aaron Moss <a3moss@…>, 5 years ago

Fix compile errors on previous push

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