Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Print.cpp

    rbccd70a r71806e0  
    1616#include "Print.hpp"
    1717
    18 #include "Attribute.hpp"
    1918#include "Decl.hpp"
    2019#include "Expr.hpp"
    21 #include "Init.hpp"
    2220#include "Stmt.hpp"
    2321#include "Type.hpp"
    2422#include "TypeSubstitution.hpp"
    2523#include "CompilationState.h"
    26 #include "Common/Iterate.hpp"
     24
     25#include "Common/utility.h" // for group_iterate
    2726
    2827using namespace std;
     
    3029namespace ast {
    3130
    32 namespace {
    33 
    34 template<typename C, typename... T>
    35 constexpr array<C, sizeof...(T)> make_array( T&&... values ) {
    36         return array<C, sizeof...(T)>{ std::forward<T>( values )... };
    37 }
    38 
    39 namespace 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 
    53 template<typename bits_t, size_t N>
    54 void 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         }
     31template <typename C, typename... T>
     32constexpr array<C,sizeof...(T)> make_array(T&&... values)
     33{
     34        return array<C,sizeof...(T)>{
     35                std::forward<T>(values)...
     36        };
    6237}
    6338
     
    10580        static const char* Names[];
    10681
     82        struct Names {
     83                static constexpr auto FuncSpecifiers = make_array<const char*>(
     84                        "inline", "_Noreturn", "fortran"
     85                );
     86
     87                static constexpr auto StorageClasses = make_array<const char*>(
     88                        "extern", "static", "auto", "register", "__thread", "_Thread_local"
     89                );
     90
     91                static constexpr auto Qualifiers = make_array<const char*>(
     92                        "const", "restrict", "volatile", "mutex", "_Atomic"
     93                );
     94        };
     95
     96        template<typename storage_t, size_t N>
     97        void print(const storage_t & storage, const array<const char *, N> & Names ) {
     98                if ( storage.any() ) {
     99                        for ( size_t i = 0; i < Names.size(); i += 1 ) {
     100                                if ( storage[i] ) {
     101                                        os << Names[i] << ' ';
     102                                }
     103                        }
     104                }
     105        }
     106
     107        void print( const ast::Function::Specs & specs ) {
     108                print(specs, Names::FuncSpecifiers);
     109        }
     110
     111        void print( const ast::Storage::Classes & storage ) {
     112                print(storage, Names::StorageClasses);
     113        }
     114
     115        void print( const ast::CV::Qualifiers & qualifiers ) {
     116                print(qualifiers, Names::Qualifiers);
     117        }
     118
    107119        void print( const std::vector<ast::Label> & labels ) {
    108120                if ( labels.empty() ) return;
     
    209221        }
    210222
    211     void print( const ast::WaitStmt * node ) {
    212                 if ( node->timeout_time ) {
    213                         os << indent-1 << "timeout of:" << endl;
    214                         node->timeout_time->accept( *this );
    215 
    216                         if ( node->timeout_stmt ) {
    217                                 os << indent-1 << "... with statment:" << endl;
    218                                 node->timeout_stmt->accept( *this );
    219                         }
    220 
    221                         if ( node->timeout_cond ) {
    222                                 os << indent-1 << "... with condition:" << endl;
    223                                 node->timeout_cond->accept( *this );
    224                         }
    225                 }
    226 
    227                 if ( node->else_stmt ) {
    228                         os << indent-1 << "else:" << endl;
    229                         node->else_stmt->accept( *this );
    230 
    231                         if ( node->else_cond ) {
    232                                 os << indent-1 << "... with condition:" << endl;
    233                                 node->else_cond->accept( *this );
    234                         }
    235                 }
    236         }
    237 
    238223        void preprint( const ast::NamedTypeDecl * node ) {
    239224                if ( ! node->name.empty() ) {
     
    245230                }
    246231
    247                 ast::print( os, node->storage );
     232                print( node->storage );
    248233                os << node->typeString();
    249234
     
    287272
    288273        void preprint( const ast::Type * node ) {
    289                 ast::print( os, node->qualifiers );
     274                print( node->qualifiers );
    290275        }
    291276
     
    293278                print( node->forall );
    294279                print( node->assertions );
    295                 ast::print( os, node->qualifiers );
     280                print( node->qualifiers );
    296281        }
    297282
    298283        void preprint( const ast::BaseInstType * node ) {
    299284                print( node->attributes );
    300                 ast::print( os, node->qualifiers );
     285                print( node->qualifiers );
    301286        }
    302287
     
    309294                }
    310295
    311                 ast::print( os, node->storage );
     296                print( node->storage );
    312297
    313298                if ( node->type ) {
     
    353338                if ( ! short_mode ) printAll( node->attributes );
    354339
    355                 ast::print( os, node->storage );
    356                 ast::print( os, node->funcSpec );
     340                print( node->storage );
     341                print( node->funcSpec );
     342
     343
    357344
    358345                if ( node->type && node->isTypeFixed ) {
     
    397384                                --indent;
    398385                        }
    399                 }
    400 
    401                 if ( ! node->withExprs.empty() ) {
    402                         // Not with a clause, but the 'with clause'.
    403                         ++indent;
    404                         os << " with clause" << endl << indent;
    405                         printAll( node->withExprs );
    406                         --indent;
    407386                }
    408387
     
    767746        virtual const ast::Stmt * visit( const ast::SuspendStmt * node ) override final {
    768747                os << "Suspend Statement";
    769                 switch (node->kind) {
    770                 case ast::SuspendStmt::None     : os << " with implicit target"; break;
    771                 case ast::SuspendStmt::Generator: os << " for generator"; break;
    772                 case ast::SuspendStmt::Coroutine: os << " for coroutine"; break;
     748                switch (node->type) {
     749                        case ast::SuspendStmt::None     : os << " with implicit target"; break;
     750                        case ast::SuspendStmt::Generator: os << " for generator"; break;
     751                        case ast::SuspendStmt::Coroutine: os << " for coroutine"; break;
    773752                }
    774753                os << endl;
     
    780759                }
    781760                ++indent;
    782 
    783                 return node;
    784         }
    785 
    786         virtual const ast::WhenClause * visit( const ast::WhenClause * node ) override final {
    787                 os << indent-1 << "target: ";
    788                 safe_print( node->target );
    789 
    790                 if ( node->stmt ) {
    791                         os << indent-1 << "... with statment:" << endl;
    792                         node->stmt->accept( *this );
    793                 }
    794 
    795                 if ( node->when_cond ) {
    796                         os << indent-1 << "... with when condition:" << endl;
    797                         node->when_cond->accept( *this );
    798                 }
    799761
    800762                return node;
     
    838800        virtual const ast::WaitForClause * visit( const ast::WaitForClause * node ) override final {
    839801                os << indent-1 << "target function: ";
    840                 safe_print( node->target );
     802                safe_print( node->target_func );
    841803
    842804                if ( !node->target_args.empty() ) {
     
    852814                }
    853815
    854                 if ( node->when_cond ) {
     816                if ( node->cond ) {
    855817                        os << indent-1 << "... with condition:" << endl;
    856                         node->when_cond->accept( *this );
    857                 }
    858 
    859                 return node;
    860         }
    861 
    862     virtual const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
    863                 os << "Waituntil Statement" << endl;
    864                 indent += 2;
    865                 for( const auto & clause : node->clauses ) {
    866                         clause->accept( *this );
    867                 }
    868         print(node);    // calls print( const ast::WaitStmt * node )
     818                        node->cond->accept( *this );
     819                }
     820
    869821                return node;
    870822        }
     
    16751627};
    16761628
    1677 } // namespace
    1678 
    16791629void print( ostream & os, const ast::Node * node, Indenter indent ) {
    16801630        Printer printer { os, indent, false };
     
    16871637}
    16881638
    1689 void print( ostream & os, Function::Specs specs ) {
    1690         print( os, specs, Names::FuncSpecifiers );
     1639// Annoyingly these needed to be defined out of line to avoid undefined references.
     1640// The size here needs to be explicit but at least the compiler will produce an error
     1641// if the wrong size is specified
     1642constexpr array<const char*, 3> Printer::Names::FuncSpecifiers;
     1643constexpr array<const char*, 6> Printer::Names::StorageClasses;
     1644constexpr array<const char*, 5> Printer::Names::Qualifiers;
    16911645}
    1692 
    1693 void print( ostream & os, Storage::Classes storage ) {
    1694         print( os, storage, Names::StorageClasses );
    1695 }
    1696 
    1697 void print( ostream & os, CV::Qualifiers qualifiers ) {
    1698         print( os, qualifiers, Names::Qualifiers );
    1699 }
    1700 
    1701 } // namespace ast
Note: See TracChangeset for help on using the changeset viewer.