Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Print.cpp

    r835d6e8 r71806e0  
    2929namespace ast {
    3030
    31 namespace {
    32 
    33 template<typename C, typename... T>
    34 constexpr array<C, sizeof...(T)> make_array( T&&... values ) {
    35         return array<C, sizeof...(T)>{ std::forward<T>( values )... };
    36 }
    37 
    38 namespace Names {
    39         static constexpr auto FuncSpecifiers = make_array<const char*>(
    40                 "inline", "_Noreturn", "fortran"
    41         );
    42 
    43         static constexpr auto StorageClasses = make_array<const char*>(
    44                 "extern", "static", "auto", "register", "__thread", "_Thread_local"
    45         );
    46 
    47         static constexpr auto Qualifiers = make_array<const char*>(
    48                 "const", "restrict", "volatile", "mutex", "_Atomic"
    49         );
    50 }
    51 
    52 template<typename bits_t, size_t N>
    53 void print( ostream & os, const bits_t & bits,
    54                 const array<const char *, N> & names ) {
    55         if ( !bits.any() ) return;
    56         for ( size_t i = 0 ; i < N ; i += 1 ) {
    57                 if ( bits[i] ) {
    58                         os << names[i] << ' ';
    59                 }
    60         }
     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        };
    6137}
    6238
     
    10480        static const char* Names[];
    10581
     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
    106119        void print( const std::vector<ast::Label> & labels ) {
    107120                if ( labels.empty() ) return;
     
    217230                }
    218231
    219                 ast::print( os, node->storage );
     232                print( node->storage );
    220233                os << node->typeString();
    221234
     
    259272
    260273        void preprint( const ast::Type * node ) {
    261                 ast::print( os, node->qualifiers );
     274                print( node->qualifiers );
    262275        }
    263276
     
    265278                print( node->forall );
    266279                print( node->assertions );
    267                 ast::print( os, node->qualifiers );
     280                print( node->qualifiers );
    268281        }
    269282
    270283        void preprint( const ast::BaseInstType * node ) {
    271284                print( node->attributes );
    272                 ast::print( os, node->qualifiers );
     285                print( node->qualifiers );
    273286        }
    274287
     
    281294                }
    282295
    283                 ast::print( os, node->storage );
     296                print( node->storage );
    284297
    285298                if ( node->type ) {
     
    325338                if ( ! short_mode ) printAll( node->attributes );
    326339
    327                 ast::print( os, node->storage );
    328                 ast::print( os, node->funcSpec );
     340                print( node->storage );
     341                print( node->funcSpec );
     342
     343
    329344
    330345                if ( node->type && node->isTypeFixed ) {
     
    369384                                --indent;
    370385                        }
    371                 }
    372 
    373                 if ( ! node->withExprs.empty() ) {
    374                         // Not with a clause, but the 'with clause'.
    375                         ++indent;
    376                         os << " with clause" << endl << indent;
    377                         printAll( node->withExprs );
    378                         --indent;
    379386                }
    380387
     
    739746        virtual const ast::Stmt * visit( const ast::SuspendStmt * node ) override final {
    740747                os << "Suspend Statement";
    741                 switch (node->kind) {
    742                 case ast::SuspendStmt::None     : os << " with implicit target"; break;
    743                 case ast::SuspendStmt::Generator: os << " for generator"; break;
    744                 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;
    745752                }
    746753                os << endl;
     
    16201627};
    16211628
    1622 } // namespace
    1623 
    16241629void print( ostream & os, const ast::Node * node, Indenter indent ) {
    16251630        Printer printer { os, indent, false };
     
    16321637}
    16331638
    1634 void print( ostream & os, Function::Specs specs ) {
    1635         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;
    16361645}
    1637 
    1638 void print( ostream & os, Storage::Classes storage ) {
    1639         print( os, storage, Names::StorageClasses );
    1640 }
    1641 
    1642 void print( ostream & os, CV::Qualifiers qualifiers ) {
    1643         print( os, qualifiers, Names::Qualifiers );
    1644 }
    1645 
    1646 } // namespace ast
Note: See TracChangeset for help on using the changeset viewer.