source: src/AST/Print.cpp@ b0ec971

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 stuck-waitfor-destruct
Last change on this file since b0ec971 was b0ec971, checked in by Aaron Moss <a3moss@…>, 7 years ago

Added ast::Type printers

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