source: src/AST/Print.cpp@ e4b6cf78

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since e4b6cf78 was 335f2d8, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Fixed some warnings and implemented memberExpr ctor and extractResultType

  • Property mode set to 100644
File size: 17.0 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 --
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 "Decl.hpp"
19#include "Expr.hpp"
20#include "Stmt.hpp"
21#include "Type.hpp"
22#include "TypeSubstitution.hpp"
23
24#include "Common/utility.h" // for group_iterate
25
26using namespace std;
27
28namespace ast {
29
30template <typename C, typename... T>
31constexpr auto make_array(T&&... values) ->
32 array<C,sizeof...(T)>
33{
34 return array<C,sizeof...(T)>{
35 forward<T>(values)...
36 };
37}
38
39class Printer : public Visitor {
40public:
41 ostream & os;
42 Indenter indent;
43 bool short_mode;
44
45 Printer(ostream & os, Indenter indent, bool short_mode) : os( os ), indent( indent ), short_mode(short_mode) {}
46
47private:
48 template< typename C >
49 void printAll( const C & c ) {
50 for ( const auto & i : c ) {
51 if ( i ) {
52 os << indent;
53 i->accept( *this );
54 // need an endl after each element because it's not
55 // easy to know when each individual item should end
56 os << endl;
57 } // if
58 } // for
59 }
60
61
62 static const char* Names[];
63
64 struct Names {
65 static constexpr auto FuncSpecifiers = make_array<const char*>(
66 "inline", "_Noreturn", "fortran"
67 );
68
69 static constexpr auto StorageClasses = make_array<const char*>(
70 "extern", "static", "auto", "register", "_Thread_local"
71 );
72
73 static constexpr auto Qualifiers = make_array<const char*>(
74 "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic"
75 );
76 };
77
78 template<typename storage_t, size_t N>
79 void print(const storage_t & storage, const array<const char *, N> & Names ) {
80 if ( storage.any() ) {
81 for ( size_t i = 0; i < Names.size(); i += 1 ) {
82 if ( storage[i] ) {
83 os << Names[i] << ' ';
84 }
85 }
86 }
87 }
88
89 void print( const ast::Function::Specs & specs ) {
90 print(specs, Names::FuncSpecifiers);
91 }
92
93 void print( const ast::Storage::Classes & storage ) {
94 print(storage, Names::StorageClasses);
95 }
96
97 void print( const ast::CV::Qualifiers & qualifiers ) {
98 print(qualifiers, Names::Qualifiers);
99 }
100
101 void print( const ast::AggregateDecl * node ) {
102 os << node->typeString() << " " << node->name << ":";
103 if ( node->linkage != Linkage::Cforall ) {
104 os << " " << Linkage::name( node->linkage );
105 } // if
106 os << " with body : " << (node->body ? "yes " : "no ");
107
108 if ( ! node->params.empty() ) {
109 os << endl << indent << "... with parameters" << endl;
110 ++indent;
111 printAll( node->params );
112 --indent;
113 } // if
114 if ( ! node->members.empty() ) {
115 os << endl << indent << "... with members" << endl;
116 ++indent;
117 printAll( node->members );
118 --indent;
119 } // if
120 if ( ! node->attributes.empty() ) {
121 os << endl << indent << "... with attributes" << endl;
122 ++indent;
123 printAll( node->attributes );
124 --indent;
125 } // if
126 os << endl;
127 }
128
129 void print( const ast::NamedTypeDecl * node ) {
130 if ( !node->name.empty() ) os << node->name << ": ";
131
132 if ( node->linkage != Linkage::Cforall ) {
133 os << Linkage::name( node->linkage ) << " ";
134 } // if
135 print( node->storage );
136 os << node->typeString();
137 if ( node->base ) {
138 os << " for ";
139 ++indent;
140 node->base->accept( *this );
141 --indent;
142 } // if
143 if ( ! node->params.empty() ) {
144 os << endl << indent << "... with parameters" << endl;
145 ++indent;
146 printAll( node->params );
147 --indent;
148 } // if
149 if ( ! node->assertions.empty() ) {
150 os << endl << indent << "... with assertions" << endl;
151 ++indent;
152 printAll( node->assertions );
153 --indent;
154 } // if
155 }
156
157public:
158 virtual const ast::DeclWithType * visit( const ast::ObjectDecl * node ) {
159 if ( !node->name.empty() ) os << node->name << ": ";
160
161 if ( node->linkage != Linkage::Cforall ) {
162 os << Linkage::name( node->linkage ) << " ";
163 } // if
164
165 print( node->storage );
166
167 if ( node->type ) {
168 node->type->accept( *this );
169 } else {
170 os << " untyped entity ";
171 } // if
172
173 if ( node->init ) {
174 os << " with initializer (" << (
175 node->init->maybeConstructed
176 ? "maybe constructed"
177 : "not constructed"
178 ) << ")" << endl << indent+1;
179
180 ++indent;
181 node->init->accept( *this );
182 --indent;
183 os << endl;
184 } // if
185
186 if ( ! node->attributes.empty() ) {
187 os << endl << indent << "... with attributes:" << endl;
188 ++indent;
189 printAll( node->attributes );
190 --indent;
191 }
192
193 if ( node->bitfieldWidth ) {
194 os << indent << " with bitfield width ";
195 node->bitfieldWidth->accept( *this );
196 } // if
197 return node;
198 }
199
200 virtual const ast::DeclWithType * visit( const ast::FunctionDecl * node ) {
201 if ( !node->name.empty() ) {
202 os << node->name << ": ";
203 } // if
204 if ( node->linkage != Linkage::Cforall ) {
205 os << Linkage::name( node->linkage ) << " ";
206 } // if
207
208 printAll( node->attributes );
209
210 print( node->storage );
211 print( node->funcSpec );
212
213 if ( node->type ) {
214 node->type->accept( *this );
215 } else {
216 os << "untyped entity ";
217 } // if
218
219 if ( node->stmts ) {
220 os << indent << "... with body" << endl << indent+1;
221 ++indent;
222 node->stmts->accept( *this );
223 --indent;
224 } // if
225 return node;
226 }
227
228 virtual const ast::Decl * visit( const ast::StructDecl * node ) {
229 print(node);
230 return node;
231 }
232
233 virtual const ast::Decl * visit( const ast::UnionDecl * node ) {
234 print(node);
235 return node;
236 }
237
238 virtual const ast::Decl * visit( const ast::EnumDecl * node ) {
239 print(node);
240 return node;
241 }
242
243 virtual const ast::Decl * visit( const ast::TraitDecl * node ) {
244 print(node);
245 return node;
246 }
247
248 virtual const ast::Decl * visit( const ast::TypeDecl * node ) {
249 print( node );
250 if ( node->init ) {
251 os << endl << indent << "with type initializer: ";
252 ++indent;
253 node->init->accept( *this );
254 --indent;
255 }
256 return node;
257 }
258
259 virtual const ast::Decl * visit( const ast::TypedefDecl * node ) {
260 print( node );
261 return node;
262 }
263
264 virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) {
265 node->stmt->accept( *this );
266 return node;
267 }
268
269 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * node ) {
270 os << "Static Assert with condition: ";
271 ++indent;
272 node->cond->accept( *this );
273 --indent;
274 os << endl << indent << "and message: ";
275 ++indent;
276 node->msg->accept( *this );
277 --indent;
278 os << endl;
279 return node;
280 }
281
282 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * node ) {
283 os << "CompoundStmt" << endl;
284 ++indent;
285 printAll( node->kids );
286 --indent;
287 return node;
288 }
289
290 virtual const ast::Stmt * visit( const ast::ExprStmt * node ) {
291 ++indent;
292 os << "Expression Statement:" << endl << indent;
293 node->expr->accept( *this );
294 --indent;
295 return node;
296 }
297
298 virtual const ast::Stmt * visit( const ast::AsmStmt * node ) {
299 os << "Assembler Statement:" << endl;
300 ++indent;
301 os << indent << "instruction: " << endl << indent;
302 node->instruction->accept( *this );
303 if ( ! node->output.empty() ) {
304 os << endl << indent+1 << "output: " << endl;
305 printAll( node->output );
306 } // if
307 if ( ! node->input.empty() ) {
308 os << indent+1 << "input: " << endl;
309 printAll( node->input );
310 } // if
311 if ( ! node->clobber.empty() ) {
312 os << indent+1 << "clobber: " << endl;
313 printAll( node->clobber );
314 } // if
315 --indent;
316 return node;
317 }
318
319 virtual const ast::Stmt * visit( const ast::DirectiveStmt * node ) {
320 os << "GCC Directive:" << node->directive << endl;
321 return node;
322 }
323
324 virtual const ast::Stmt * visit( const ast::IfStmt * node ) {
325 os << "If on condition: " << endl;
326 os << indent+1;
327 ++indent;
328 node->cond->accept( *this );
329 --indent;
330
331 if ( !node->inits.empty() ) {
332 os << indent << "... with initialization: \n";
333 ++indent;
334 for ( const Stmt * stmt : node->inits ) {
335 os << indent;
336 stmt->accept( *this );
337 }
338 --indent;
339 os << endl;
340 }
341
342 os << indent << "... then: " << endl;
343
344 ++indent;
345 os << indent;
346 node->thenPart->accept( *this );
347 --indent;
348
349 if ( node->elsePart != 0 ) {
350 os << indent << "... else: " << endl;
351 ++indent;
352 os << indent;
353 node->elsePart->accept( *this );
354 --indent;
355 } // if
356 return node;
357 }
358
359 virtual const ast::Stmt * visit( const ast::WhileStmt * node ) {
360 return node;
361 }
362
363 virtual const ast::Stmt * visit( const ast::ForStmt * node ) {
364 return node;
365 }
366
367 virtual const ast::Stmt * visit( const ast::SwitchStmt * node ) {
368 return node;
369 }
370
371 virtual const ast::Stmt * visit( const ast::CaseStmt * node ) {
372 return node;
373 }
374
375 virtual const ast::Stmt * visit( const ast::BranchStmt * node ) {
376 return node;
377 }
378
379 virtual const ast::Stmt * visit( const ast::ReturnStmt * node ) {
380 return node;
381 }
382
383 virtual const ast::Stmt * visit( const ast::ThrowStmt * node ) {
384 return node;
385 }
386
387 virtual const ast::Stmt * visit( const ast::TryStmt * node ) {
388 return node;
389 }
390
391 virtual const ast::Stmt * visit( const ast::CatchStmt * node ) {
392 return node;
393 }
394
395 virtual const ast::Stmt * visit( const ast::FinallyStmt * node ) {
396 return node;
397 }
398
399 virtual const ast::Stmt * visit( const ast::WaitForStmt * node ) {
400 return node;
401 }
402
403 virtual const ast::Stmt * visit( const ast::WithStmt * node ) {
404 return node;
405 }
406
407 virtual const ast::NullStmt * visit( const ast::NullStmt * node ) {
408 return node;
409 }
410
411 virtual const ast::Stmt * visit( const ast::DeclStmt * node ) {
412 return node;
413 }
414
415 virtual const ast::Stmt * visit( const ast::ImplicitCtorDtorStmt * node ) {
416 return node;
417 }
418
419 virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) {
420 return node;
421 }
422
423 virtual const ast::Expr * visit( const ast::UntypedExpr * node ) {
424 return node;
425 }
426
427 virtual const ast::Expr * visit( const ast::NameExpr * node ) {
428 return node;
429 }
430
431 virtual const ast::Expr * visit( const ast::AddressExpr * node ) {
432 return node;
433 }
434
435 virtual const ast::Expr * visit( const ast::LabelAddressExpr * node ) {
436 return node;
437 }
438
439 virtual const ast::Expr * visit( const ast::CastExpr * node ) {
440 return node;
441 }
442
443 virtual const ast::Expr * visit( const ast::KeywordCastExpr * node ) {
444 return node;
445 }
446
447 virtual const ast::Expr * visit( const ast::VirtualCastExpr * node ) {
448 return node;
449 }
450
451 virtual const ast::Expr * visit( const ast::UntypedMemberExpr * node ) {
452 return node;
453 }
454
455 virtual const ast::Expr * visit( const ast::MemberExpr * node ) {
456 return node;
457 }
458
459 virtual const ast::Expr * visit( const ast::VariableExpr * node ) {
460 return node;
461 }
462
463 virtual const ast::Expr * visit( const ast::ConstantExpr * node ) {
464 return node;
465 }
466
467 virtual const ast::Expr * visit( const ast::SizeofExpr * node ) {
468 return node;
469 }
470
471 virtual const ast::Expr * visit( const ast::AlignofExpr * node ) {
472 return node;
473 }
474
475 virtual const ast::Expr * visit( const ast::UntypedOffsetofExpr * node ) {
476 return node;
477 }
478
479 virtual const ast::Expr * visit( const ast::OffsetofExpr * node ) {
480 return node;
481 }
482
483 virtual const ast::Expr * visit( const ast::OffsetPackExpr * node ) {
484 return node;
485 }
486
487 virtual const ast::Expr * visit( const ast::LogicalExpr * node ) {
488 return node;
489 }
490
491 virtual const ast::Expr * visit( const ast::ConditionalExpr * node ) {
492 return node;
493 }
494
495 virtual const ast::Expr * visit( const ast::CommaExpr * node ) {
496 return node;
497 }
498
499 virtual const ast::Expr * visit( const ast::TypeExpr * node ) {
500 return node;
501 }
502
503 virtual const ast::Expr * visit( const ast::AsmExpr * node ) {
504 return node;
505 }
506
507 virtual const ast::Expr * visit( const ast::ImplicitCopyCtorExpr * node ) {
508 return node;
509 }
510
511 virtual const ast::Expr * visit( const ast::ConstructorExpr * node ) {
512 return node;
513 }
514
515 virtual const ast::Expr * visit( const ast::CompoundLiteralExpr * node ) {
516 return node;
517 }
518
519 virtual const ast::Expr * visit( const ast::RangeExpr * node ) {
520 return node;
521 }
522
523 virtual const ast::Expr * visit( const ast::UntypedTupleExpr * node ) {
524 return node;
525 }
526
527 virtual const ast::Expr * visit( const ast::TupleExpr * node ) {
528 return node;
529 }
530
531 virtual const ast::Expr * visit( const ast::TupleIndexExpr * node ) {
532 return node;
533 }
534
535 virtual const ast::Expr * visit( const ast::TupleAssignExpr * node ) {
536 return node;
537 }
538
539 virtual const ast::Expr * visit( const ast::StmtExpr * node ) {
540 return node;
541 }
542
543 virtual const ast::Expr * visit( const ast::UniqueExpr * node ) {
544 return node;
545 }
546
547 virtual const ast::Expr * visit( const ast::UntypedInitExpr * node ) {
548 return node;
549 }
550
551 virtual const ast::Expr * visit( const ast::InitExpr * node ) {
552 return node;
553 }
554
555 virtual const ast::Expr * visit( const ast::DeletedExpr * node ) {
556 return node;
557 }
558
559 virtual const ast::Expr * visit( const ast::DefaultArgExpr * node ) {
560 return node;
561 }
562
563 virtual const ast::Expr * visit( const ast::GenericExpr * node ) {
564 return node;
565 }
566
567 virtual const ast::Type * visit( const ast::VoidType * node ) {
568 return node;
569 }
570
571 virtual const ast::Type * visit( const ast::BasicType * node ) {
572 return node;
573 }
574
575 virtual const ast::Type * visit( const ast::PointerType * node ) {
576 return node;
577 }
578
579 virtual const ast::Type * visit( const ast::ArrayType * node ) {
580 return node;
581 }
582
583 virtual const ast::Type * visit( const ast::ReferenceType * node ) {
584 return node;
585 }
586
587 virtual const ast::Type * visit( const ast::QualifiedType * node ) {
588 return node;
589 }
590
591 virtual const ast::Type * visit( const ast::FunctionType * node ) {
592 return node;
593 }
594
595 virtual const ast::Type * visit( const ast::StructInstType * node ) {
596 return node;
597 }
598
599 virtual const ast::Type * visit( const ast::UnionInstType * node ) {
600 return node;
601 }
602
603 virtual const ast::Type * visit( const ast::EnumInstType * node ) {
604 return node;
605 }
606
607 virtual const ast::Type * visit( const ast::TraitInstType * node ) {
608 return node;
609 }
610
611 virtual const ast::Type * visit( const ast::TypeInstType * node ) {
612 return node;
613 }
614
615 virtual const ast::Type * visit( const ast::TupleType * node ) {
616 return node;
617 }
618
619 virtual const ast::Type * visit( const ast::TypeofType * node ) {
620 return node;
621 }
622
623 virtual const ast::Type * visit( const ast::VarArgsType * node ) {
624 return node;
625 }
626
627 virtual const ast::Type * visit( const ast::ZeroType * node ) {
628 return node;
629 }
630
631 virtual const ast::Type * visit( const ast::OneType * node ) {
632 return node;
633 }
634
635 virtual const ast::Type * visit( const ast::GlobalScopeType * node ) {
636 return node;
637 }
638
639 virtual const ast::Designation * visit( const ast::Designation * node ) {
640 if ( node->designators.empty() ) return node;
641 os << "... designated by: " << std::endl;
642 ++indent;
643 for ( const ast::Expr * d : node->designators ) {
644 os << indent;
645 d->accept( *this );
646 os << std::endl;
647 }
648 --indent;
649 return node;
650 }
651
652 virtual const ast::Init * visit( const ast::SingleInit * node ) {
653 os << "Simple Initializer: ";
654 node->value->accept( *this );
655 return node;
656 }
657
658 virtual const ast::Init * visit( const ast::ListInit * node ) {
659 os << "Compound initializer: " << std::endl;
660 ++indent;
661 for ( auto p : group_iterate( node->designations, node->initializers ) ) {
662 const ast::Designation * d = std::get<0>(p);
663 const ast::Init * init = std::get<1>(p);
664 os << indent;
665 init->accept( *this );
666 os << std::endl;
667 if ( ! d->designators.empty() ) {
668 os << indent;
669 d->accept( *this );
670 }
671 }
672 --indent;
673 return node;
674 }
675
676 virtual const ast::Init * visit( const ast::ConstructorInit * node ) {
677 os << "Constructor initializer: " << std::endl;
678 if ( node->ctor ) {
679 os << indent << "... initially constructed with ";
680 ++indent;
681 node->ctor->accept( *this );
682 --indent;
683 }
684
685 if ( node->dtor ) {
686 os << indent << "... destructed with ";
687 ++indent;
688 node->dtor->accept( *this );
689 --indent;
690 }
691
692 if ( node->init ) {
693 os << indent << "... with fallback C-style initializer: ";
694 ++indent;
695 node->init->accept( *this );
696 --indent;
697 }
698 return node;
699 }
700
701 virtual const ast::Attribute * visit( const ast::Attribute * node ) {
702 if ( node->empty() ) return node;
703 os << "Attribute with name: " << node->name;
704 if ( node->params.empty() ) return node;
705 os << " with parameters: " << std::endl;
706 ++indent;
707 printAll( node->params );
708 --indent;
709 return node;
710 }
711
712 virtual const ast::TypeSubstitution * visit( const ast::TypeSubstitution * node ) {
713 os << indent << "Types:" << std::endl;
714 for ( const auto& i : *node ) {
715 os << indent+1 << i.first << " -> ";
716 indent += 2;
717 i.second->accept( *this );
718 indent -= 2;
719 os << std::endl;
720 }
721 os << indent << "Non-types:" << std::endl;
722 for ( auto i = node->beginVar(); i != node->endVar(); ++i ) {
723 os << indent+1 << i->first << " -> ";
724 indent += 2;
725 i->second->accept( *this );
726 indent -= 2;
727 os << std::endl;
728 }
729 return node;
730 }
731
732};
733
734void print( ostream & os, const ast::Node * node, Indenter indent ) {
735 Printer printer { os, indent, false };
736 node->accept(printer);
737}
738
739void printShort( ostream & os, const ast::Node * node, Indenter indent ) {
740 Printer printer { os, indent, true };
741 node->accept(printer);
742}
743
744// Annoyingly these needed to be defined out of line to avoid undefined references.
745// The size here needs to be explicit but at least the compiler will produce an error
746// if the wrong size is specified
747constexpr array<const char*, 3> Printer::Names::FuncSpecifiers;
748constexpr array<const char*, 5> Printer::Names::StorageClasses;
749constexpr array<const char*, 6> Printer::Names::Qualifiers;
750}
Note: See TracBrowser for help on using the repository browser.