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

ADT ast-experimental
Last change on this file since 8fd1b7c was 6e1e2d0, checked in by caparsons <caparson@…>, 2 years ago

resolved merge conflicts

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