source: src/AST/Convert.cpp@ 8d70648

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 8d70648 was 8d70648, checked in by Aaron Moss <a3moss@…>, 6 years ago

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

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