source: src/AST/Print.cpp@ aa14aafe

Last change on this file since aa14aafe was b6f2e7ab, checked in by Andrew Beach <ajbeach@…>, 13 months ago

Removed SizeofExpr::expr and AlignofExpr::expr, expressions that would be stored there are wrapped in TypeofType and stored in the type field. Some special cases to hide the typeof in code generation were added. In addition, initializer length is calculated in more cases so that the full type of more arrays is known sooner. Other than that, most of the code changes were just stripping out the conditional code and checks no longer needed. Some tests had to be updated, because the typeof is not hidden in dumps and the resolver replaces known typeof expressions with the type. The extension case caused some concern but it appears that just hides warnings in the expression which no longer exists.

  • Property mode set to 100644
File size: 41.6 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 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// Print.cpp -- Print an AST (or sub-tree) to a stream.
8//
9// Author : Thierry Delisle
10// Created On : Tue May 21 16:20:15 2019
11// Last Modified By :
12// Last Modified On :
13// Update Count :
14//
15
16#include "Print.hpp"
17
18#include "Attribute.hpp"
19#include "Decl.hpp"
20#include "Expr.hpp"
21#include "Init.hpp"
22#include "Stmt.hpp"
23#include "Type.hpp"
24#include "TypeSubstitution.hpp"
25#include "CompilationState.hpp"
26#include "Common/Iterate.hpp"
27
28using namespace std;
29
30namespace ast {
31
32namespace {
33
34template<typename C, typename... T>
35constexpr array<C, sizeof...(T)> make_array( T&&... values ) {
36 return array<C, sizeof...(T)>{ std::forward<T>( values )... };
37}
38
39namespace Names {
40 static constexpr auto FuncSpecifiers = make_array<const char*>(
41 "inline", "_Noreturn", "fortran"
42 );
43
44 static constexpr auto StorageClasses = make_array<const char*>(
45 "extern", "static", "auto", "register", "__thread", "_Thread_local"
46 );
47
48 static constexpr auto Qualifiers = make_array<const char*>(
49 "const", "restrict", "volatile", "mutex", "_Atomic"
50 );
51}
52
53template<typename bits_t, size_t N>
54void print( ostream & os, const bits_t & bits,
55 const array<const char *, N> & names ) {
56 if ( !bits.any() ) return;
57 for ( size_t i = 0 ; i < N ; i += 1 ) {
58 if ( bits[i] ) {
59 os << names[i] << ' ';
60 }
61 }
62}
63
64class Printer final : public Visitor {
65public:
66 ostream & os;
67 Indenter indent;
68 bool short_mode;
69
70 Printer(ostream & os, Indenter indent, bool short_mode) : os( os ), indent( indent ), short_mode(short_mode) {}
71
72private:
73 template< typename C >
74 void printAll( const C & c ) {
75 for ( const auto & i : c ) {
76 if ( i ) {
77 os << indent;
78 i->accept( *this );
79 // need an endl after each element because it's not
80 // easy to know when each individual item should end
81 os << endl;
82 } // if
83 } // for
84 }
85
86 /// call if mandatory field is missing
87 void undefined() {
88 os << "UNDEFINED";
89 }
90
91 /// call for fields that should be mandatory
92 void safe_print( const ast::Node * n ) {
93 if ( n ) n->accept( *this );
94 else undefined();
95 }
96
97 /// call to print short form. Incorporates features of safe_print()
98 void short_print( const ast::Decl * n ) {
99 if ( ! n ) { undefined(); return; }
100 bool old_short = short_mode; short_mode = true;
101 n->accept( *this );
102 short_mode = old_short;
103 }
104
105 void print( const std::vector<ast::Label> & labels ) {
106 if ( labels.empty() ) return;
107 os << indent << "... Labels: {";
108 bool isFirst = true;
109 for ( const Label & l : labels ) {
110 if ( isFirst ) { isFirst = false; } else { os << ","; }
111 os << l;
112 }
113 os << "}" << endl;
114 }
115
116 void print( const ast::Expr::InferUnion & inferred, unsigned level = 0 ) {
117 if (inferred.data.resnSlots && !inferred.data.resnSlots->empty()) {
118 os << indent << "with " << inferred.data.resnSlots->size()
119 << " pending inference slots" << endl;
120 }
121 if (inferred.data.inferParams && !inferred.data.inferParams->empty()) {
122 os << indent << "with inferred parameters " << level << ":" << endl;
123 ++indent;
124 for ( const auto & i : *inferred.data.inferParams ) {
125 os << indent;
126 short_print( i.second.declptr );
127 os << endl;
128 print( i.second.expr->inferred, level+1 );
129 }
130 --indent;
131 }
132 }
133
134 void print( const ast::FunctionType::ForallList & forall ) {
135 if ( forall.empty() ) return;
136 os << "forall" << endl;
137 ++indent;
138 printAll( forall );
139 os << indent;
140 --indent;
141 }
142
143 void print( const ast::FunctionType::AssertionList & assts ) {
144 if (assts.empty()) return;
145 os << "with assertions" << endl;
146 ++indent;
147 printAll(assts);
148 os << indent;
149 --indent;
150 }
151
152 void print( const std::vector<ptr<Attribute>> & attrs ) {
153 if ( attrs.empty() ) return;
154 os << "with attributes" << endl;
155 ++indent;
156 printAll( attrs );
157 --indent;
158 }
159
160 void print( const std::vector<ptr<Expr>> & params ) {
161 if ( params.empty() ) return;
162 os << endl << indent << "... with parameters" << endl;
163 ++indent;
164 printAll( params );
165 --indent;
166 }
167
168 void print( const ast::AggregateDecl * node ) {
169 os << node->typeString() << " " << node->name;
170
171 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
172 os << " " << Linkage::name( node->linkage );
173 }
174
175 auto ptrToEnum = dynamic_cast<const ast::EnumDecl *>(node);
176 if ( ! short_mode && ptrToEnum && ptrToEnum->base ) {
177 os << endl << indent << "... with base type" << endl;
178 ++indent;
179 os << indent;
180 ptrToEnum->base->accept( *this );
181 --indent;
182 }
183
184 os << " " << (node->body ? "with" : "without") << " body";
185
186 if ( ! node->params.empty() ) {
187 os << endl << indent << "... with parameters" << endl;
188 ++indent;
189 printAll( node->params );
190 --indent;
191 }
192
193 if ( ! short_mode && ! node->members.empty() ) {
194 os << endl << indent << "... with members" << endl;
195 ++indent;
196 printAll( node->members );
197 --indent;
198 }
199
200 if ( ! short_mode && ! node->attributes.empty() ) {
201 os << endl << indent << "... with attributes" << endl;
202 ++indent;
203 printAll( node->attributes );
204 --indent;
205 }
206
207
208
209 os << endl;
210 }
211
212 void print( const ast::WaitStmt * node ) {
213 if ( node->timeout_time ) {
214 os << indent-1 << "timeout of:" << endl;
215 node->timeout_time->accept( *this );
216
217 if ( node->timeout_stmt ) {
218 os << indent-1 << "... with statment:" << endl;
219 node->timeout_stmt->accept( *this );
220 }
221
222 if ( node->timeout_cond ) {
223 os << indent-1 << "... with condition:" << endl;
224 node->timeout_cond->accept( *this );
225 }
226 }
227
228 if ( node->else_stmt ) {
229 os << indent-1 << "else:" << endl;
230 node->else_stmt->accept( *this );
231
232 if ( node->else_cond ) {
233 os << indent-1 << "... with condition:" << endl;
234 node->else_cond->accept( *this );
235 }
236 }
237 }
238
239 void preprint( const ast::NamedTypeDecl * node ) {
240 if ( ! node->name.empty() ) {
241 os << node->name << ": ";
242 }
243
244 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
245 os << Linkage::name( node->linkage ) << " ";
246 }
247
248 ast::print( os, node->storage );
249 os << node->typeString();
250
251 if ( node->base ) {
252 os << " for ";
253 ++indent;
254 node->base->accept( *this );
255 --indent;
256 }
257
258 if ( ! node->assertions.empty() ) {
259 os << endl << indent << "... with assertions" << endl;
260 ++indent;
261 printAll( node->assertions );
262 --indent;
263 }
264 }
265
266 void postprint( const ast::Expr * node ) {
267 print( node->inferred );
268
269 if ( node->result ) {
270 os << endl << indent << "... with resolved type:" << endl;
271 ++indent;
272 os << indent;
273 node->result->accept( *this );
274 --indent;
275 }
276
277 if ( node->env ) {
278 os << endl << indent << "... with environment:" << endl;
279 ++indent;
280 node->env->accept( *this );
281 --indent;
282 }
283
284 if ( node->extension ) {
285 os << endl << indent << "... with extension";
286 }
287 }
288
289 void preprint( const ast::Type * node ) {
290 ast::print( os, node->qualifiers );
291 }
292
293 void preprint( const ast::FunctionType * node ) {
294 print( node->forall );
295 print( node->assertions );
296 ast::print( os, node->qualifiers );
297 }
298
299 void preprint( const ast::BaseInstType * node ) {
300 print( node->attributes );
301 ast::print( os, node->qualifiers );
302 }
303
304public:
305 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final {
306 if ( ! node->name.empty() ) os << node->name << ": ";
307
308 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
309 os << Linkage::name( node->linkage ) << " ";
310 }
311
312 ast::print( os, node->storage );
313
314 if ( node->type ) {
315 node->type->accept( *this );
316 } else {
317 os << "untyped entity";
318 }
319
320 if ( ! short_mode && node->init ) {
321 ++indent;
322 os << " with initializer (" << (
323 node->init->maybeConstructed
324 ? "maybe constructed"
325 : "not constructed"
326 ) << ")" << endl << indent;
327 node->init->accept( *this );
328 --indent;
329 os << endl;
330 }
331
332 if ( ! short_mode && ! node->attributes.empty() ) {
333 os << endl << indent << "... with attributes:" << endl;
334 ++indent;
335 printAll( node->attributes );
336 --indent;
337 }
338
339 if ( node->bitfieldWidth ) {
340 os << indent << " with bitfield width ";
341 node->bitfieldWidth->accept( *this );
342 }
343
344 return node;
345 }
346
347 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final {
348 if ( !node->name.empty() ) os << node->name << ": ";
349
350 if ( ! short_mode && node->linkage != Linkage::Cforall ) {
351 os << Linkage::name( node->linkage ) << " ";
352 }
353
354 if ( ! short_mode ) printAll( node->attributes );
355
356 ast::print( os, node->storage );
357 ast::print( os, node->funcSpec );
358
359 if ( node->type && node->isTypeFixed ) {
360 node->type->accept( *this );
361 } else {
362 if (!node->type_params.empty()) {
363 os << "forall" << endl;
364 ++indent;
365 printAll(node->type_params);
366 os << indent;
367 --indent;
368
369 if (!node->assertions.empty()) {
370 os << "with assertions" << endl;
371 ++indent;
372 printAll(node->assertions);
373 os << indent;
374 --indent;
375 }
376 }
377
378 os << "function" << endl;
379 if ( ! node->params.empty() ) {
380 os << indent << "... with parameters" << endl;
381 ++indent;
382 printAll( node->params );
383 if ( node->type->isVarArgs ) {
384 os << indent << "and a variable number of other arguments" << endl;
385 }
386 --indent;
387 } else if ( node->type->isVarArgs ) {
388 os << indent+1 << "accepting unspecified arguments" << endl;
389 }
390
391 os << indent << "... returning";
392 if ( node->returns.empty() ) {
393 os << " nothing" << endl;
394 } else {
395 os << endl;
396 ++indent;
397 printAll( node->returns );
398 --indent;
399 }
400 }
401
402 if ( ! node->withExprs.empty() ) {
403 // Not with a clause, but the 'with clause'.
404 ++indent;
405 os << " with clause" << endl << indent;
406 printAll( node->withExprs );
407 --indent;
408 }
409
410 if ( ! short_mode && node->stmts ) {
411 ++indent;
412 os << " with body" << endl << indent;
413 node->stmts->accept( *this );
414 --indent;
415 }
416
417 return node;
418 }
419
420 virtual const ast::Decl * visit( const ast::StructDecl * node ) override final {
421 print(node);
422 return node;
423 }
424
425 virtual const ast::DeclWithType * visit( const ast::InlineMemberDecl * node ) override final {
426 os << "inline ";
427 if ( ! node->name.empty() ) os << node->name;
428
429 return node;
430 }
431
432 virtual const ast::Decl * visit( const ast::UnionDecl * node ) override final {
433 print(node);
434 return node;
435 }
436
437 virtual const ast::Decl * visit( const ast::EnumDecl * node ) override final {
438 print(node);
439 return node;
440 }
441
442 virtual const ast::Decl * visit( const ast::TraitDecl * node ) override final {
443 print(node);
444 return node;
445 }
446
447 virtual const ast::Decl * visit( const ast::TypeDecl * node ) override final {
448 preprint( node );
449 if ( ! short_mode && node->init ) {
450 os << endl << indent << "with type initializer: ";
451 ++indent;
452 node->init->accept( *this );
453 --indent;
454 }
455
456 return node;
457 }
458
459 virtual const ast::Decl * visit( const ast::TypedefDecl * node ) override final {
460 preprint( node );
461 return node;
462 }
463
464 virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final {
465 safe_print( node->stmt );
466 return node;
467 }
468
469 virtual const ast::DirectiveDecl * visit( const ast::DirectiveDecl * node ) override final {
470 safe_print( node->stmt );
471 return node;
472 }
473
474 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) override final {
475 os << "Static Assert with condition: ";
476 ++indent;
477 safe_print( node->cond );
478 os << endl << indent-1 << "and message: ";
479 safe_print( node->msg );
480 --indent;
481 os << endl;
482
483 return node;
484 }
485
486 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) override final {
487 os << "Compound Statement:" << endl;
488 ++indent;
489 printAll( node->kids );
490 --indent;
491 return node;
492 }
493
494 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) override final {
495 ++indent;
496 os << "Expression Statement:" << endl << indent;
497 safe_print( node->expr );
498 --indent;
499 return node;
500 }
501
502 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) override final {
503 os << "Assembler Statement:" << endl;
504 ++indent;
505 os << indent-1 << "instruction:" << endl << indent;
506 safe_print( node->instruction );
507 if ( ! node->output.empty() ) {
508 os << endl << indent << "output:" << endl;
509 printAll( node->output );
510 } // if
511 if ( ! node->input.empty() ) {
512 os << indent << "input:" << endl;
513 printAll( node->input );
514 } // if
515 if ( ! node->clobber.empty() ) {
516 os << indent << "clobber:" << endl;
517 printAll( node->clobber );
518 } // if
519 --indent;
520 return node;
521 }
522
523 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) override final {
524 os << "GCC Directive: " << node->directive << endl;
525 return node;
526 }
527
528 virtual const ast::Stmt * visit( const ast::IfStmt * node ) override final {
529 os << "If on condition:" << endl;
530 ++indent;
531 os << indent;
532 safe_print( node->cond );
533 --indent;
534
535 if ( ! node->inits.empty() ) {
536 os << indent << "... with initialization:" << endl;
537 ++indent;
538 for ( const ast::Stmt * stmt : node->inits ) {
539 os << indent;
540 safe_print( stmt );
541 }
542 --indent;
543 os << endl;
544 }
545
546 os << indent << "... then:" << endl;
547
548 ++indent;
549 os << indent;
550 safe_print( node->then );
551 --indent;
552
553 if ( node->else_ != 0 ) {
554 os << indent << "... else:" << endl;
555 ++indent;
556 os << indent;
557 node->else_->accept( *this );
558 --indent;
559 } // if
560 return node;
561 }
562
563 virtual const ast::Stmt * visit( const ast::WhileDoStmt * node ) override final {
564 if ( node->isDoWhile ) { os << "Do-"; }
565 os << "While on condition:" << endl;
566 ++indent;
567 safe_print( node->cond );
568
569 if ( ! node->inits.empty() ) {
570 os << indent-1 << "... with inits:" << endl;
571 printAll( node->inits );
572 }
573
574 os << indent-1 << "... with body:" << endl;
575 safe_print( node->body );
576
577 if ( node->else_ ) {
578 os << indent-1 << "... with else:" << endl;
579 os << indent;
580 node->else_->accept( *this );
581 }
582
583 --indent;
584
585 return node;
586 }
587
588 virtual const ast::Stmt * visit( const ast::ForStmt * node ) override final {
589 os << "For Statement" << endl;
590
591 if ( ! node->inits.empty() ) {
592 os << indent << "... initialization:" << endl;
593 ++indent;
594 for ( const ast::Stmt * stmt : node->inits ) {
595 os << indent+1;
596 safe_print( stmt );
597 }
598 --indent;
599 }
600
601 if ( node->cond ) {
602 os << indent << "... condition:" << endl;
603 ++indent;
604 os << indent;
605 node->cond->accept( *this );
606 --indent;
607 }
608
609 if ( node->inc ) {
610 os << indent << "... increment:" << endl;
611 ++indent;
612 os << indent;
613 node->inc->accept( *this );
614 --indent;
615 }
616
617 if ( node->body ) {
618 os << indent << "... with body:" << endl;
619 ++indent;
620 os << indent;
621 node->body->accept( *this );
622 --indent;
623 }
624
625 if ( node->else_ ) {
626 os << indent << "... with else:" << endl;
627 ++indent;
628 os << indent;
629 node->else_->accept( *this );
630 --indent;
631 }
632
633 os << endl;
634 print( node->labels );
635
636 return node;
637 }
638
639 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) override final {
640 os << "Switch on condition: ";
641 safe_print( node->cond );
642 os << endl;
643
644 ++indent;
645 for ( const ast::CaseClause * stmt : node->cases ) {
646 stmt->accept( *this );
647 }
648 --indent;
649
650 return node;
651 }
652
653 virtual const ast::CaseClause * visit( const ast::CaseClause * node ) override final {
654 if ( node->isDefault() ) {
655 os << indent << "Default ";
656 } else {
657 os << indent << "Case ";
658 safe_print( node->cond );
659 } // if
660 os << endl;
661
662 ++indent;
663 for ( const ast::Stmt * stmt : node->stmts ) {
664 os << indent;
665 stmt->accept( *this );
666 }
667 --indent;
668
669 return node;
670 }
671
672 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) override final {
673 os << "Branch (" << node->kindName() << ")" << endl;
674 ++indent;
675 if ( ! node->target.empty() ) {
676 os << indent << "with target: " << node->target << endl;
677 }
678
679 if ( ! node->originalTarget.empty() ) {
680 os << indent << "with original target: " << node->originalTarget << endl;
681 }
682
683 if ( node->computedTarget ) {
684 os << indent << "with computed target: ";
685 node->computedTarget->accept( *this );
686 os << endl;
687 }
688 --indent;
689
690 return node;
691 }
692
693 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) override final {
694 os << "Return Statement, returning";
695 if ( node->expr ) {
696 ++indent;
697 os << ":" << endl << indent;
698 node->expr->accept( *this );
699 --indent;
700 } else {
701 os << " void";
702 }
703 os << endl;
704
705 return node;
706 }
707
708 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) override final {
709 if ( node->target ) os << "Non-Local ";
710
711 switch( node->kind ) {
712 case ast::ExceptionKind::Terminate: os << "Terminate "; break;
713 case ast::ExceptionKind::Resume: os << "Resume "; break;
714 }
715
716 ++indent;
717 os << "Throw Statement, raising: ";
718 safe_print( node->expr );
719 if ( node->target ) {
720 os << "... at: ";
721 node->target->accept( *this );
722 }
723 --indent;
724
725 return node;
726 }
727
728 virtual const ast::Stmt * visit( const ast::TryStmt * node ) override final {
729 ++indent;
730 os << "Try Statement" << endl << indent-1
731 << "... with block:" << endl << indent;
732 safe_print( node->body );
733
734 os << indent-1 << "... and handlers:" << endl;
735 for ( const ast::CatchClause * stmt : node->handlers ) {
736 os << indent;
737 stmt->accept( *this );
738 }
739
740 if ( node->finally ) {
741 os << indent-1 << "... and finally:" << endl << indent;
742 node->finally->accept( *this );
743 }
744 --indent;
745
746 return node;
747 }
748
749 virtual const ast::CatchClause * visit( const ast::CatchClause * node ) override final {
750 os << "Catch ";
751 switch ( node->kind ) {
752 case ast::ExceptionKind::Terminate: os << "Terminate "; break;
753 case ast::ExceptionKind::Resume: os << "Resume "; break;
754 }
755 os << "Statement" << endl << indent;
756
757 ++indent;
758 os << "... catching: ";
759 short_print( node->decl );
760 os << endl;
761
762 if ( node->cond ) {
763 os << indent-1 << "... with conditional:" << endl << indent;
764 node->cond->accept( *this );
765 }
766
767 os << indent-1 << "... with block:" << endl << indent;
768 safe_print( node->body );
769 --indent;
770
771 return node;
772 }
773
774 virtual const ast::FinallyClause * visit( const ast::FinallyClause * node ) override final {
775 os << "Finally Statement" << endl;
776 os << indent << "... with block:" << endl;
777 ++indent;
778 os << indent;
779 safe_print( node->body );
780 --indent;
781
782 return node;
783 }
784
785 virtual const ast::Stmt * visit( const ast::SuspendStmt * node ) override final {
786 os << "Suspend Statement";
787 switch (node->kind) {
788 case ast::SuspendStmt::None : os << " with implicit target"; break;
789 case ast::SuspendStmt::Generator: os << " for generator"; break;
790 case ast::SuspendStmt::Coroutine: os << " for coroutine"; break;
791 }
792 os << endl;
793
794 ++indent;
795 if(node->then) {
796 os << indent << " with post statement :" << endl;
797 safe_print( node->then );
798 }
799 ++indent;
800
801 return node;
802 }
803
804 virtual const ast::WhenClause * visit( const ast::WhenClause * node ) override final {
805 os << indent-1 << "target: ";
806 safe_print( node->target );
807
808 if ( node->stmt ) {
809 os << indent-1 << "... with statment:" << endl;
810 node->stmt->accept( *this );
811 }
812
813 if ( node->when_cond ) {
814 os << indent-1 << "... with when condition:" << endl;
815 node->when_cond->accept( *this );
816 }
817
818 return node;
819 }
820
821 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) override final {
822 os << "Waitfor Statement" << endl;
823 indent += 2;
824 for( const auto & clause : node->clauses ) {
825 clause->accept( *this );
826 }
827
828 if ( node->timeout_time ) {
829 os << indent-1 << "timeout of:" << endl;
830 node->timeout_time->accept( *this );
831
832 if ( node->timeout_stmt ) {
833 os << indent-1 << "... with statment:" << endl;
834 node->timeout_stmt->accept( *this );
835 }
836
837 if ( node->timeout_cond ) {
838 os << indent-1 << "... with condition:" << endl;
839 node->timeout_cond->accept( *this );
840 }
841 }
842
843 if ( node->else_stmt ) {
844 os << indent-1 << "else:" << endl;
845 node->else_stmt->accept( *this );
846
847 if ( node->else_cond ) {
848 os << indent-1 << "... with condition:" << endl;
849 node->else_cond->accept( *this );
850 }
851 }
852
853 return node;
854 }
855
856 virtual const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final {
857 os << indent-1 << "target function: ";
858 safe_print( node->target );
859
860 if ( !node->target_args.empty() ) {
861 os << endl << indent-1 << "... with arguments:" << endl;
862 for( const ast::Expr * arg : node->target_args ) {
863 arg->accept( *this );
864 }
865 }
866
867 if ( node->stmt ) {
868 os << indent-1 << "... with statment:" << endl;
869 node->stmt->accept( *this );
870 }
871
872 if ( node->when_cond ) {
873 os << indent-1 << "... with condition:" << endl;
874 node->when_cond->accept( *this );
875 }
876
877 return node;
878 }
879
880 virtual const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
881 os << "Waituntil Statement" << endl;
882 indent += 2;
883 for( const auto & clause : node->clauses ) {
884 clause->accept( *this );
885 }
886 // calls print( const ast::WaitStmt * node )
887 print(node);
888 return node;
889 }
890
891 virtual const ast::Decl * visit( const ast::WithStmt * node ) override final {
892 os << "With statement" << endl;
893 os << indent << "... with expressions:" << endl;
894 ++indent;
895 printAll( node->exprs );
896 os << indent-1 << "... with statement:" << endl << indent;
897 safe_print( node->stmt );
898 --indent;
899
900 return node;
901 }
902
903 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) override final {
904 os << "Null Statement" << endl;
905 print( node->labels );
906
907 return node;
908 }
909
910 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) override final {
911 os << "Declaration of ";
912 safe_print( node->decl );
913
914 return node;
915 }
916
917 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) override final {
918 os << "Implicit Ctor Dtor Statement" << endl;
919 os << indent << "... with Ctor/Dtor: ";
920 ++indent;
921 safe_print( node->callStmt );
922 --indent;
923 os << endl;
924
925 return node;
926 }
927
928 virtual const ast::Stmt * visit( const ast::MutexStmt * node ) override final {
929 os << "Mutex Statement" << endl;
930 os << indent << "... with Mutex Parameters: ";
931 ++indent;
932 printAll( node->mutexObjs );
933 --indent;
934 os << indent << "... with Statement: ";
935 ++indent;
936 safe_print( node->stmt );
937 --indent;
938 os << endl;
939
940 return node;
941 }
942
943 virtual const ast::Stmt * visit( const ast::CorunStmt * node ) override final {
944 os << "Corun Statement" << endl;
945 os << indent << "... with Statement: ";
946 ++indent;
947 safe_print( node->stmt );
948 --indent;
949 os << endl;
950
951 return node;
952 }
953
954 virtual const ast::Stmt * visit( const ast::CoforStmt * node ) override final {
955 os << "Cofor Statement" << endl;
956
957 if ( ! node->inits.empty() ) {
958 os << indent << "... initialization:" << endl;
959 ++indent;
960 for ( const ast::Stmt * stmt : node->inits ) {
961 os << indent+1;
962 safe_print( stmt );
963 }
964 --indent;
965 }
966
967 if ( node->cond ) {
968 os << indent << "... condition:" << endl;
969 ++indent;
970 os << indent;
971 node->cond->accept( *this );
972 --indent;
973 }
974
975 if ( node->inc ) {
976 os << indent << "... increment:" << endl;
977 ++indent;
978 os << indent;
979 node->inc->accept( *this );
980 --indent;
981 }
982
983 if ( node->body ) {
984 os << indent << "... with body:" << endl;
985 ++indent;
986 os << indent;
987 node->body->accept( *this );
988 --indent;
989 }
990 os << endl;
991 print( node->labels );
992
993 return node;
994 }
995
996 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
997 ++indent;
998 os << "Application of" << endl << indent;
999 safe_print( node->func );
1000 os << endl;
1001 if ( ! node->args.empty() ) {
1002 os << indent << "... to arguments" << endl;
1003 printAll( node->args );
1004 }
1005 --indent;
1006 postprint( node );
1007
1008 return node;
1009 }
1010
1011 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) override final {
1012 ++indent;
1013 os << "Applying untyped:" << endl;
1014 os << indent;
1015 safe_print( node->func );
1016 os << endl << indent-1 << "...to:" << endl;
1017 printAll( node->args );
1018 --indent;
1019 postprint( node );
1020
1021 return node;
1022 }
1023
1024 virtual const ast::Expr * visit( const ast::NameExpr * node ) override final {
1025 os << "Name: " << node->name;
1026 postprint( node );
1027
1028 return node;
1029 }
1030
1031 virtual const ast::Expr * visit( const ast::QualifiedNameExpr * node ) override final {
1032 os << "QualifiedNameExpr: " << std::endl;
1033 os << ++indent << "Type: ";
1034 safe_print( node->type_decl );
1035 os << std::endl;
1036 os << indent << "Name: " << node->name << std::endl;
1037 --indent;
1038 postprint( node );
1039 return node;
1040 }
1041
1042 virtual const ast::Expr * visit( const ast::AddressExpr * node ) override final {
1043 os << "Address of:" << endl;
1044 ++indent;
1045 os << indent;
1046 safe_print( node->arg );
1047
1048 --indent;
1049
1050 return node;
1051 }
1052
1053 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) override final {
1054 os << "Address of label:" << node->arg;
1055
1056 return node;
1057 }
1058
1059 virtual const ast::Expr * visit( const ast::CastExpr * node ) override final {
1060 ++indent;
1061 os << (node->isGenerated ? "Generated" : "Explicit") << " Cast of:" << endl << indent;
1062 safe_print( node->arg );
1063 os << endl << indent-1 << "... to:";
1064 if ( ! node->result ) {
1065 os << " ";
1066 undefined();
1067 } else if ( node->result->isVoid() ) {
1068 os << " nothing";
1069 } else {
1070 os << endl << indent;
1071 node->result->accept( *this );
1072 } // if
1073 --indent;
1074 postprint( node );
1075
1076 return node;
1077 }
1078
1079 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) override final {
1080 ++indent;
1081 os << "Keyword Cast of:" << endl << indent;
1082 safe_print( node->arg );
1083 --indent;
1084 os << endl << indent << "... to: " << node->targetString();
1085 postprint( node );
1086
1087 return node;
1088 }
1089
1090 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) override final {
1091 ++indent;
1092 os << "Virtual Cast of:" << endl << indent;
1093 safe_print( node->arg );
1094 os << endl << indent-1 << "... to:";
1095 if ( ! node->result ) {
1096 os << " unknown";
1097 } else {
1098 os << endl << indent;
1099 node->result->accept( *this );
1100 }
1101 --indent;
1102 postprint( node );
1103
1104 return node;
1105 }
1106
1107 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) override final {
1108 ++indent;
1109 os << "Untyped Member Expression, with field: " << endl << indent;
1110 safe_print( node->member );
1111 os << indent-1 << "... from aggregate:" << endl << indent;
1112 safe_print( node->aggregate );
1113 --indent;
1114 postprint( node );
1115
1116 return node;
1117 }
1118
1119 virtual const ast::Expr * visit( const ast::MemberExpr * node ) override final {
1120 ++indent;
1121 os << "Member Expression, with field:" << endl << indent;
1122 safe_print( node->member );
1123 os << endl << indent-1 << "... from aggregate:" << endl << indent;
1124 safe_print( node->aggregate );
1125 --indent;
1126 postprint( node );
1127
1128 return node;
1129 }
1130
1131 virtual const ast::Expr * visit( const ast::VariableExpr * node ) override final {
1132 os << "Variable Expression: ";
1133 short_print( node->var );
1134 postprint( node );
1135
1136 return node;
1137 }
1138
1139 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) override final {
1140 os << "Constant Expression (" << node->rep;
1141 if ( node->result ) {
1142 os << ": ";
1143 node->result->accept( *this );
1144 }
1145 os << ")";
1146 postprint( node );
1147
1148 return node;
1149 }
1150
1151 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) override final {
1152 os << "Sizeof Expression on: ";
1153 ++indent;
1154 node->type->accept( *this );
1155 --indent;
1156 postprint( node );
1157
1158 return node;
1159 }
1160
1161 virtual const ast::Expr * visit( const ast::CountExpr * node ) override final {
1162 os << "Count Expression on: ";
1163 ++indent;
1164 if ( node->type ) node->type->accept( *this );
1165 else safe_print( node->expr );
1166 --indent;
1167 postprint( node );
1168 return node;
1169 }
1170
1171 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
1172 os << "Alignof Expression on: ";
1173 ++indent;
1174 node->type->accept( *this );
1175 --indent;
1176 postprint( node );
1177
1178 return node;
1179 }
1180
1181 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) override final {
1182 os << "Untyped Offsetof Expression on member " << node->member << " of ";
1183 ++indent;
1184 safe_print( node->type );
1185 --indent;
1186 postprint( node );
1187
1188 return node;
1189 }
1190
1191 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) override final {
1192 os << "Offsetof Expression on member " << node->member->name << " of ";
1193 ++indent;
1194 safe_print( node->type );
1195 --indent;
1196 postprint( node );
1197
1198 return node;
1199 }
1200
1201 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) override final {
1202 os << "Offset Pack Expression on: ";
1203 ++indent;
1204 safe_print( node->type );
1205 --indent;
1206 postprint( node );
1207
1208 return node;
1209 }
1210
1211 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) override final {
1212 os << "Short-circuited operation (" << (node->isAnd ? "and" : "or") << ") on: ";
1213 safe_print( node->arg1 );
1214 os << " and ";
1215 safe_print( node->arg2 );
1216 postprint( node );
1217
1218 return node;
1219 }
1220
1221 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) override final {
1222 ++indent;
1223 os << "Conditional expression on:" << endl << indent;
1224 safe_print( node->arg1 );
1225 os << indent-1 << "First alternative:" << endl << indent;
1226 safe_print( node->arg2 );
1227 os << indent-1 << "Second alternative:" << endl << indent;
1228 safe_print( node->arg3 );
1229 --indent;
1230 postprint( node );
1231
1232 return node;
1233 }
1234
1235 virtual const ast::Expr * visit( const ast::CommaExpr * node ) override final {
1236 ++indent;
1237 os << "Comma Expression:" << endl << indent;
1238 safe_print( node->arg1 );
1239 os << endl << indent;
1240 safe_print( node->arg2 );
1241 --indent;
1242 postprint( node );
1243
1244 return node;
1245 }
1246
1247 virtual const ast::Expr * visit( const ast::TypeExpr * node ) override final {
1248 safe_print( node->type );
1249 postprint( node );
1250
1251 return node;
1252 }
1253
1254 virtual const ast::Expr * visit( const ast::DimensionExpr * node ) override final {
1255 os << "Type-Sys Value: " << node->name;
1256 postprint( node );
1257
1258 return node;
1259 }
1260
1261 virtual const ast::Expr * visit( const ast::AsmExpr * node ) override final {
1262 os << "Asm Expression:" << endl;
1263 ++indent;
1264 if ( !node->inout.empty() ) os << "[" << node->inout << "] ";
1265 if ( node->constraint ) node->constraint->accept( *this );
1266 if ( node->operand ) node->operand->accept( *this );
1267 --indent;
1268
1269 return node;
1270 }
1271
1272 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) override final {
1273 ++indent;
1274 os << "Implicit Copy Constructor Expression:" << endl << indent;
1275 safe_print( node->callExpr );
1276 --indent;
1277 postprint( node );
1278
1279 return node;
1280 }
1281
1282 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) override final {
1283 os << "Constructor Expression:" << endl << indent+1;
1284 indent += 2;
1285 safe_print( node->callExpr );
1286 indent -= 2;
1287 postprint( node );
1288
1289 return node;
1290 }
1291
1292 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) override final {
1293 ++indent;
1294 os << "Compound Literal Expression: " << endl << indent;
1295 safe_print( node->result );
1296 os << indent;
1297 safe_print( node->init );
1298 --indent;
1299 postprint( node );
1300
1301 return node;
1302 }
1303
1304 virtual const ast::Expr * visit( const ast::RangeExpr * node ) override final {
1305 os << "Range Expression: ";
1306 safe_print( node->low );
1307 os << " ... ";
1308 safe_print( node->high );
1309 postprint( node );
1310
1311 return node;
1312 }
1313
1314 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) override final {
1315 os << "Untyped Tuple:" << endl;
1316 ++indent;
1317 printAll( node->exprs );
1318 --indent;
1319 postprint( node );
1320
1321 return node;
1322 }
1323
1324 virtual const ast::Expr * visit( const ast::TupleExpr * node ) override final {
1325 os << "Tuple:" << endl;
1326 ++indent;
1327 printAll( node->exprs );
1328 --indent;
1329 postprint( node );
1330
1331 return node;
1332 }
1333
1334 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) override final {
1335 os << "Tuple Index Expression, with tuple:" << endl;
1336 ++indent;
1337 os << indent;
1338 safe_print( node->tuple );
1339 os << indent << "with index: " << node->index << endl;
1340 --indent;
1341 postprint( node );
1342
1343 return node;
1344 }
1345
1346 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) override final {
1347 os << "Tuple Assignment Expression, with stmt expr:" << endl;
1348 ++indent;
1349 os << indent;
1350 safe_print( node->stmtExpr );
1351 --indent;
1352 postprint( node );
1353
1354 return node;
1355 }
1356
1357 virtual const ast::Expr * visit( const ast::StmtExpr * node ) override final {
1358 ++indent;
1359 os << "Statement Expression:" << endl << indent;
1360 safe_print( node->stmts );
1361 if ( ! node->returnDecls.empty() ) {
1362 os << indent << "... with returnDecls: ";
1363 printAll( node->returnDecls );
1364 }
1365 if ( ! node->dtors.empty() ) {
1366 os << indent << "... with dtors: ";
1367 printAll( node->dtors );
1368 }
1369 --indent;
1370 postprint( node );
1371
1372 return node;
1373 }
1374
1375 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) override final {
1376 ++indent;
1377 os << "Unique Expression with id: " << node->id << endl << indent;
1378 safe_print( node->expr );
1379 if ( node->object ) {
1380 os << indent-1 << "... with decl: ";
1381 short_print( node->object );
1382 }
1383 --indent;
1384 postprint( node );
1385
1386 return node;
1387 }
1388
1389 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) override final {
1390 ++indent;
1391 os << "Untyped Init Expression" << endl << indent;
1392 safe_print( node->expr );
1393 if ( ! node->initAlts.empty() ) {
1394 for ( const InitAlternative & alt : node->initAlts ) {
1395 os << indent << "InitAlternative: ";
1396 safe_print( alt.type );
1397 safe_print( alt.designation );
1398 }
1399 }
1400 --indent;
1401
1402 return node;
1403 }
1404
1405 virtual const ast::Expr * visit( const ast::InitExpr * node ) override final {
1406 ++indent;
1407 os << "Init Expression" << endl << indent;
1408 safe_print( node->expr );
1409 os << indent << "... with designation: ";
1410 safe_print( node->designation );
1411 --indent;
1412
1413 return node;
1414 }
1415
1416 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) override final {
1417 ++indent;
1418 os << "Deleted Expression" << endl << indent;
1419 safe_print( node->expr );
1420 os << endl << indent << "... deleted by: ";
1421 safe_print( node->deleteStmt );
1422 --indent;
1423
1424 return node;
1425 }
1426
1427 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) override final {
1428 ++indent;
1429 os << "Default Argument Expression" << endl << indent;
1430 safe_print( node->expr );
1431 --indent;
1432
1433 return node;
1434 }
1435
1436 virtual const ast::Expr * visit( const ast::GenericExpr * node ) override final {
1437 ++indent;
1438 os << "C11 _Generic Expression" << endl << indent;
1439 safe_print( node->control );
1440 os << endl << indent << "... with associations:" << endl;
1441 for ( const auto & assoc : node->associations ) {
1442 os << indent;
1443 if ( assoc.type ) {
1444 os << "... type: ";
1445 assoc.type->accept( *this );
1446 os << endl << indent << "... expression: ";
1447 safe_print( assoc.expr );
1448 } else {
1449 os << "... default: ";
1450 safe_print( assoc.expr );
1451 }
1452 os << endl;
1453 }
1454 --indent;
1455
1456 return node;
1457 }
1458
1459 virtual const ast::Type * visit( const ast::VoidType * node ) override final {
1460 preprint( node );
1461 os << "void";
1462 return node;
1463 }
1464
1465 virtual const ast::Type * visit( const ast::BasicType * node ) override final {
1466 preprint( node );
1467 os << ast::BasicType::typeNames[ node->kind ];
1468 return node;
1469 }
1470
1471 virtual const ast::Type * visit( const ast::PointerType * node ) override final {
1472 preprint( node );
1473 if ( ! node->isArray() ) {
1474 os << "pointer to ";
1475 } else {
1476 os << "decayed ";
1477 if ( node->isStatic ) {
1478 os << "static ";
1479 }
1480
1481 if ( node->isVarLen ) {
1482 os << "variable length array of ";
1483 } else if ( node->dimension ) {
1484 os << "array of ";
1485 node->dimension->accept( *this );
1486 os << " ";
1487 }
1488 }
1489 safe_print( node->base );
1490
1491 return node;
1492 }
1493
1494 virtual const ast::Type * visit( const ast::ArrayType * node ) override final {
1495 preprint( node );
1496 if ( node->isStatic ) {
1497 os << "static ";
1498 }
1499
1500 if ( node->isVarLen ) {
1501 os << "variable length array of ";
1502 } else if ( node->dimension ) {
1503 os << "array of ";
1504 } else {
1505 os << "open array of ";
1506 }
1507
1508 safe_print( node->base );
1509
1510 if ( node->dimension ) {
1511 os << " with dimension of ";
1512 node->dimension->accept( *this );
1513 }
1514
1515 return node;
1516 }
1517
1518 virtual const ast::Type * visit( const ast::ReferenceType * node ) override final {
1519 preprint( node );
1520 os << "reference to ";
1521 safe_print( node->base );
1522
1523 return node;
1524 }
1525
1526 virtual const ast::Type * visit( const ast::QualifiedType * node ) override final {
1527 preprint( node );
1528 ++indent;
1529 os << "Qualified Type:" << endl << indent;
1530 safe_print( node->parent );
1531 os << endl << indent;
1532 safe_print( node->child );
1533 os << endl;
1534 --indent;
1535
1536 return node;
1537 }
1538
1539 virtual const ast::Type * visit( const ast::FunctionType * node ) override final {
1540 preprint( node );
1541
1542 os << "function" << endl;
1543 if ( ! node->params.empty() ) {
1544 os << indent << "... with parameters" << endl;
1545 ++indent;
1546 printAll( node->params );
1547 if ( node->isVarArgs ) {
1548 os << indent << "and a variable number of other arguments" << endl;
1549 }
1550 --indent;
1551 } else if ( node->isVarArgs ) {
1552 os << indent+1 << "accepting unspecified arguments" << endl;
1553 }
1554
1555 os << indent << "... returning";
1556 if ( node->returns.empty() ) {
1557 os << " nothing" << endl;
1558 } else {
1559 os << endl;
1560 ++indent;
1561 printAll( node->returns );
1562 --indent;
1563 }
1564
1565 return node;
1566 }
1567
1568 virtual const ast::Type * visit( const ast::StructInstType * node ) override final {
1569 preprint( node );
1570 os << "instance of struct " << node->name;
1571 if ( node->base ) {
1572 os << " " << ( node->base->body ? "with" : "without" ) << " body";
1573 }
1574 print( node->params );
1575
1576 return node;
1577 }
1578
1579 virtual const ast::Type * visit( const ast::UnionInstType * node ) override final {
1580 preprint( node );
1581 os << "instance of union " << node->name;
1582 if ( node->base ) {
1583 os << " " << ( node->base->body ? "with" : "without" ) << " body";
1584 }
1585 print( node->params );
1586
1587 return node;
1588 }
1589
1590 virtual const ast::Type * visit( const ast::EnumInstType * node ) override final {
1591 preprint( node );
1592 os << "instance of enum " << node->name;
1593 if ( node->base ) {
1594 os << " " << ( node->base->body ? "with" : "without" ) << " body";
1595 }
1596 print( node->params );
1597
1598 return node;
1599 }
1600
1601 virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
1602 preprint( node );
1603 os << "instance of trait " << node->name;
1604 print( node->params );
1605
1606 return node;
1607 }
1608
1609 virtual const ast::Type * visit( const ast::TypeInstType * node ) override final {
1610 preprint( node );
1611 const auto & _name = deterministic_output && isUnboundType(node) ? "[unbound]" : node->typeString();
1612 os << "instance of type " << _name
1613 << " (" << (node->kind == ast::TypeDecl::Ftype ? "" : "not ") << "function type)";
1614 print( node->params );
1615
1616 return node;
1617 }
1618
1619 virtual const ast::Type * visit( const ast::TupleType * node ) override final {
1620 preprint( node );
1621 os << "tuple of types" << endl;
1622 ++indent;
1623 printAll( node->types );
1624 --indent;
1625
1626 return node;
1627 }
1628
1629 virtual const ast::Type * visit( const ast::TypeofType * node ) override final {
1630 preprint( node );
1631 if ( node->kind == ast::TypeofType::Basetypeof ) { os << "base-"; }
1632 os << "type-of expression ";
1633 safe_print( node->expr );
1634
1635 return node;
1636 }
1637
1638 virtual const ast::Type * visit( const ast::VTableType * node ) override final {
1639 preprint( node );
1640 os << "vtable for ";
1641 safe_print( node->base );
1642
1643 return node;
1644 }
1645
1646 virtual const ast::Type * visit( const ast::VarArgsType * node ) override final {
1647 preprint( node );
1648 os << "builtin var args pack";
1649 return node;
1650 }
1651
1652 virtual const ast::Type * visit( const ast::ZeroType * node ) override final {
1653 preprint( node );
1654 os << "zero_t";
1655 return node;
1656 }
1657
1658 virtual const ast::Type * visit( const ast::OneType * node ) override final {
1659 preprint( node );
1660 os << "one_t";
1661 return node;
1662 }
1663
1664 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) override final {
1665 preprint( node );
1666 os << "Global Scope Type";
1667 return node;
1668 }
1669
1670 virtual const ast::Designation * visit( const ast::Designation * node ) override final {
1671 if ( node->designators.empty() ) return node;
1672 os << "... designated by: " << endl;
1673 ++indent;
1674 for ( const ast::Expr * d : node->designators ) {
1675 os << indent;
1676 d->accept( *this );
1677 os << endl;
1678 }
1679 --indent;
1680 return node;
1681 }
1682
1683 virtual const ast::Init * visit( const ast::SingleInit * node ) override final {
1684 os << "Simple Initializer: ";
1685 safe_print( node->value );
1686 return node;
1687 }
1688
1689 virtual const ast::Init * visit( const ast::ListInit * node ) override final {
1690 os << "Compound initializer: " << endl;
1691 ++indent;
1692 for ( auto p : group_iterate( node->designations, node->initializers ) ) {
1693 const ast::Designation * d = std::get<0>(p);
1694 const ast::Init * init = std::get<1>(p);
1695 os << indent;
1696 init->accept( *this );
1697 os << endl;
1698 if ( ! d->designators.empty() ) {
1699 os << indent;
1700 d->accept( *this );
1701 }
1702 }
1703 --indent;
1704 return node;
1705 }
1706
1707 virtual const ast::Init * visit( const ast::ConstructorInit * node ) override final {
1708 os << "Constructor initializer: " << endl;
1709 if ( node->ctor ) {
1710 os << indent << "... initially constructed with ";
1711 ++indent;
1712 node->ctor->accept( *this );
1713 --indent;
1714 }
1715
1716 if ( node->dtor ) {
1717 os << indent << "... destructed with ";
1718 ++indent;
1719 node->dtor->accept( *this );
1720 --indent;
1721 }
1722
1723 if ( node->init ) {
1724 os << indent << "... with fallback C-style initializer: ";
1725 ++indent;
1726 node->init->accept( *this );
1727 --indent;
1728 }
1729 return node;
1730 }
1731
1732 virtual const ast::Attribute * visit( const ast::Attribute * node ) override final {
1733 if ( node->empty() ) return node;
1734 os << "Attribute with name: " << node->name;
1735 if ( node->params.empty() ) return node;
1736 os << " with parameters: " << endl;
1737 ++indent;
1738 printAll( node->params );
1739 --indent;
1740 return node;
1741 }
1742
1743 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) override final {
1744 os << indent << "Types:" << endl;
1745 for ( const auto& i : *node ) {
1746 os << indent+1 << i.first.typeString() << " -> ";
1747 indent += 2;
1748 safe_print( i.second );
1749 indent -= 2;
1750 os << endl;
1751 }
1752 return node;
1753 }
1754
1755};
1756
1757} // namespace
1758
1759void print( ostream & os, const ast::Node * node, Indenter indent ) {
1760 Printer printer { os, indent, false };
1761 node->accept(printer);
1762}
1763
1764void printShort( ostream & os, const ast::Decl * node, Indenter indent ) {
1765 Printer printer { os, indent, true };
1766 node->accept(printer);
1767}
1768
1769void print( ostream & os, Function::Specs specs ) {
1770 print( os, specs, Names::FuncSpecifiers );
1771}
1772
1773void print( ostream & os, Storage::Classes storage ) {
1774 print( os, storage, Names::StorageClasses );
1775}
1776
1777void print( ostream & os, CV::Qualifiers qualifiers ) {
1778 print( os, qualifiers, Names::Qualifiers );
1779}
1780
1781} // namespace ast
Note: See TracBrowser for help on using the repository browser.