source: src/AST/Print.cpp @ 335f2d8

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 335f2d8 was 335f2d8, checked in by Thierry Delisle <tdelisle@…>, 5 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.