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

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 746ae82 was 746ae82, checked in by Aaron Moss <a3moss@…>, 6 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.