Ignore:
Timestamp:
Nov 13, 2023, 3:43:43 AM (23 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
25f2798
Parents:
0030b508 (diff), 2174191 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/GenType.cc

    r0030b508 rfc12f05  
    1919#include <sstream>                // for operator<<, ostringstream, basic_os...
    2020
    21 #include "CodeGenerator.h"        // for CodeGenerator
    22 #include "SynTree/Declaration.h"  // for DeclarationWithType
    23 #include "SynTree/Expression.h"   // for Expression
    24 #include "SynTree/Type.h"         // for PointerType, Type, FunctionType
    25 #include "SynTree/Visitor.h"      // for Visitor
     21#include "AST/Print.hpp"          // for print
     22#include "AST/Vector.hpp"         // for vector
     23#include "CodeGeneratorNew.hpp"   // for CodeGenerator_new
     24#include "Common/UniqueName.h"    // for UniqueName
    2625
    2726namespace CodeGen {
    28         struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
    29                 std::string typeString;
    30                 GenType( const std::string &typeString, const Options &options );
    31 
    32                 void previsit( BaseSyntaxNode * );
    33                 void postvisit( BaseSyntaxNode * );
    34 
    35                 void postvisit( FunctionType * funcType );
    36                 void postvisit( VoidType * voidType );
    37                 void postvisit( BasicType * basicType );
    38                 void postvisit( PointerType * pointerType );
    39                 void postvisit( ArrayType * arrayType );
    40                 void postvisit( ReferenceType * refType );
    41                 void postvisit( StructInstType * structInst );
    42                 void postvisit( UnionInstType * unionInst );
    43                 void postvisit( EnumInstType * enumInst );
    44                 void postvisit( TypeInstType * typeInst );
    45                 void postvisit( TupleType  * tupleType );
    46                 void postvisit( VarArgsType * varArgsType );
    47                 void postvisit( ZeroType * zeroType );
    48                 void postvisit( OneType * oneType );
    49                 void postvisit( GlobalScopeType * globalType );
    50                 void postvisit( TraitInstType * inst );
    51                 void postvisit( TypeofType * typeof );
    52                 void postvisit( VTableType * vtable );
    53                 void postvisit( QualifiedType * qualType );
    54 
    55           private:
    56                 void handleQualifiers( Type *type );
    57                 std::string handleGeneric( ReferenceToType * refType );
    58                 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    59 
    60                 Options options;
    61         };
    62 
    63         std::string genType( Type *type, const std::string &baseString, const Options &options ) {
    64                 PassVisitor<GenType> gt( baseString, options );
     27
     28namespace {
     29
     30#warning Remove the _new when old version is removed.
     31struct GenType_new :
     32                public ast::WithShortCircuiting,
     33                public ast::WithVisitorRef<GenType_new> {
     34        std::string result;
     35        GenType_new( const std::string &typeString, const Options &options );
     36
     37        void previsit( ast::Node const * );
     38        void postvisit( ast::Node const * );
     39
     40        void postvisit( ast::FunctionType const * type );
     41        void postvisit( ast::VoidType const * type );
     42        void postvisit( ast::BasicType const * type );
     43        void postvisit( ast::PointerType const * type );
     44        void postvisit( ast::ArrayType const * type );
     45        void postvisit( ast::ReferenceType const * type );
     46        void postvisit( ast::StructInstType const * type );
     47        void postvisit( ast::UnionInstType const * type );
     48        void postvisit( ast::EnumInstType const * type );
     49        void postvisit( ast::TypeInstType const * type );
     50        void postvisit( ast::TupleType const * type );
     51        void postvisit( ast::VarArgsType const * type );
     52        void postvisit( ast::ZeroType const * type );
     53        void postvisit( ast::OneType const * type );
     54        void postvisit( ast::GlobalScopeType const * type );
     55        void postvisit( ast::TraitInstType const * type );
     56        void postvisit( ast::TypeofType const * type );
     57        void postvisit( ast::VTableType const * type );
     58        void postvisit( ast::QualifiedType const * type );
     59
     60private:
     61        void handleQualifiers( ast::Type const *type );
     62        std::string handleGeneric( ast::BaseInstType const * type );
     63        void genArray( const ast::CV::Qualifiers &qualifiers, ast::Type const *base, ast::Expr const *dimension, bool isVarLen, bool isStatic );
     64        std::string genParamList( const ast::vector<ast::Type> & );
     65
     66        Options options;
     67};
     68
     69GenType_new::GenType_new( const std::string &typeString, const Options &options ) : result( typeString ), options( options ) {}
     70
     71void GenType_new::previsit( ast::Node const * ) {
     72        // Turn off automatic recursion for all nodes, to allow each visitor to
     73        // precisely control the order in which its children are visited.
     74        visit_children = false;
     75}
     76
     77void GenType_new::postvisit( ast::Node const * node ) {
     78        std::stringstream ss;
     79        ast::print( ss, node );
     80        assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );
     81}
     82
     83void GenType_new::postvisit( ast::VoidType const * type ) {
     84        result = "void " + result;
     85        handleQualifiers( type );
     86}
     87
     88void GenType_new::postvisit( ast::BasicType const * type ) {
     89        ast::BasicType::Kind kind = type->kind;
     90        assert( 0 <= kind && kind < ast::BasicType::NUMBER_OF_BASIC_TYPES );
     91        result = std::string( ast::BasicType::typeNames[kind] ) + " " + result;
     92        handleQualifiers( type );
     93}
     94
     95void GenType_new::genArray( const ast::CV::Qualifiers & qualifiers, ast::Type const * base, ast::Expr const *dimension, bool isVarLen, bool isStatic ) {
     96        std::ostringstream os;
     97        if ( result != "" ) {
     98                if ( result[ 0 ] == '*' ) {
     99                        os << "(" << result << ")";
     100                } else {
     101                        os << result;
     102                }
     103        }
     104        os << "[";
     105        if ( isStatic ) {
     106                os << "static ";
     107        }
     108        if ( qualifiers.is_const ) {
     109                os << "const ";
     110        }
     111        if ( qualifiers.is_volatile ) {
     112                os << "volatile ";
     113        }
     114        if ( qualifiers.is_restrict ) {
     115                os << "__restrict ";
     116        }
     117        if ( qualifiers.is_atomic ) {
     118                os << "_Atomic ";
     119        }
     120        if ( dimension != 0 ) {
     121                ast::Pass<CodeGenerator_new>::read( dimension, os, options );
     122        } else if ( isVarLen ) {
     123                // no dimension expression on a VLA means it came in with the * token
     124                os << "*";
     125        }
     126        os << "]";
     127
     128        result = os.str();
     129
     130        base->accept( *visitor );
     131}
     132
     133void GenType_new::postvisit( ast::PointerType const * type ) {
     134        if ( type->isStatic || type->isVarLen || type->dimension ) {
     135                genArray( type->qualifiers, type->base, type->dimension, type->isVarLen, type->isStatic );
     136        } else {
     137                handleQualifiers( type );
     138                if ( result[ 0 ] == '?' ) {
     139                        result = "* " + result;
     140                } else {
     141                        result = "*" + result;
     142                }
     143                type->base->accept( *visitor );
     144        }
     145}
     146
     147void GenType_new::postvisit( ast::ArrayType const * type ) {
     148        genArray( type->qualifiers, type->base, type->dimension, type->isVarLen, type->isStatic );
     149}
     150
     151void GenType_new::postvisit( ast::ReferenceType const * type ) {
     152        assertf( !options.genC, "Reference types should not reach code generation." );
     153        handleQualifiers( type );
     154        result = "&" + result;
     155        type->base->accept( *visitor );
     156}
     157
     158void GenType_new::postvisit( ast::FunctionType const * type ) {
     159        std::ostringstream os;
     160
     161        if ( result != "" ) {
     162                if ( result[ 0 ] == '*' ) {
     163                        os << "(" << result << ")";
     164                } else {
     165                        os << result;
     166                }
     167        }
     168
     169        if ( type->params.empty() ) {
     170                if ( type->isVarArgs ) {
     171                        os << "()";
     172                } else {
     173                        os << "(void)";
     174                }
     175        } else {
     176                os << "(" ;
     177
     178                os << genParamList( type->params );
     179
     180                if ( type->isVarArgs ) {
     181                        os << ", ...";
     182                }
     183                os << ")";
     184        }
     185
     186        result = os.str();
     187
     188        if ( type->returns.size() == 0 ) {
     189                result = "void " + result;
     190        } else {
     191                type->returns.front()->accept( *visitor );
     192        }
     193
     194        // Add forall clause.
     195        if( !type->forall.empty() && !options.genC ) {
     196                //assertf( !options.genC, "FunctionDecl type parameters should not reach code generation." );
    65197                std::ostringstream os;
    66 
    67                 if ( ! type->get_attributes().empty() ) {
    68                         PassVisitor<CodeGenerator> cg( os, options );
    69                         cg.pass.genAttributes( type->get_attributes() );
    70                 } // if
    71 
    72                 type->accept( gt );
    73                 return os.str() + gt.pass.typeString;
    74         }
    75 
    76         std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
    77                 return genType( type, baseString, Options(pretty, genC, lineMarks, false ) );
    78         }
    79 
    80         std::string genPrettyType( Type * type, const std::string & baseString ) {
    81                 return genType( type, baseString, true, false );
    82         }
    83 
    84         GenType::GenType( const std::string &typeString, const Options &options ) : typeString( typeString ), options( options ) {}
    85 
    86         // *** BaseSyntaxNode
    87         void GenType::previsit( BaseSyntaxNode * ) {
    88                 // turn off automatic recursion for all nodes, to allow each visitor to
    89                 // precisely control the order in which its children are visited.
    90                 visit_children = false;
    91         }
    92 
    93         void GenType::postvisit( BaseSyntaxNode * node ) {
    94                 std::stringstream ss;
    95                 node->print( ss );
    96                 assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );
    97         }
    98 
    99         void GenType::postvisit( VoidType * voidType ) {
    100                 typeString = "void " + typeString;
    101                 handleQualifiers( voidType );
    102         }
    103 
    104         void GenType::postvisit( BasicType * basicType ) {
    105                 BasicType::Kind kind = basicType->kind;
    106                 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
    107                 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
    108                 handleQualifiers( basicType );
    109         }
    110 
    111         void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) {
     198                ast::Pass<CodeGenerator_new> cg( os, options );
     199                os << "forall(";
     200                cg.core.genCommaList( type->forall );
     201                os << ")" << std::endl;
     202                result = os.str() + result;
     203        }
     204}
     205
     206std::string GenType_new::handleGeneric( ast::BaseInstType const * type ) {
     207        if ( !type->params.empty() ) {
    112208                std::ostringstream os;
    113                 if ( typeString != "" ) {
    114                         if ( typeString[ 0 ] == '*' ) {
    115                                 os << "(" << typeString << ")";
    116                         } else {
    117                                 os << typeString;
    118                         } // if
    119                 } // if
    120                 os << "[";
    121 
    122                 if ( isStatic ) {
    123                         os << "static ";
    124                 } // if
    125                 if ( qualifiers.is_const ) {
    126                         os << "const ";
    127                 } // if
    128                 if ( qualifiers.is_volatile ) {
    129                         os << "volatile ";
    130                 } // if
    131                 if ( qualifiers.is_restrict ) {
    132                         os << "__restrict ";
    133                 } // if
    134                 if ( qualifiers.is_atomic ) {
    135                         os << "_Atomic ";
    136                 } // if
    137                 if ( dimension != 0 ) {
    138                         PassVisitor<CodeGenerator> cg( os, options );
    139                         dimension->accept( cg );
    140                 } else if ( isVarLen ) {
    141                         // no dimension expression on a VLA means it came in with the * token
    142                         os << "*";
    143                 } // if
    144                 os << "]";
    145 
    146                 typeString = os.str();
    147 
    148                 base->accept( *visitor );
    149         }
    150 
    151         void GenType::postvisit( PointerType * pointerType ) {
    152                 assert( pointerType->base != 0);
    153                 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) {
    154                         genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() );
    155                 } else {
    156                         handleQualifiers( pointerType );
    157                         if ( typeString[ 0 ] == '?' ) {
    158                                 typeString = "* " + typeString;
    159                         } else {
    160                                 typeString = "*" + typeString;
    161                         } // if
    162                         pointerType->base->accept( *visitor );
    163                 } // if
    164         }
    165 
    166         void GenType::postvisit( ArrayType * arrayType ) {
    167                 genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() );
    168         }
    169 
    170         void GenType::postvisit( ReferenceType * refType ) {
    171                 assert( 0 != refType->base );
    172                 assertf( ! options.genC, "Reference types should not reach code generation." );
    173                 handleQualifiers( refType );
    174                 typeString = "&" + typeString;
    175                 refType->base->accept( *visitor );
    176         }
    177 
    178         void GenType::postvisit( FunctionType * funcType ) {
    179                 std::ostringstream os;
    180 
    181                 if ( typeString != "" ) {
    182                         if ( typeString[ 0 ] == '*' ) {
    183                                 os << "(" << typeString << ")";
    184                         } else {
    185                                 os << typeString;
    186                         } // if
    187                 } // if
    188 
    189                 /************* parameters ***************/
    190 
    191                 const std::list<DeclarationWithType *> &pars = funcType->parameters;
    192 
    193                 if ( pars.empty() ) {
    194                         if ( funcType->get_isVarArgs() ) {
    195                                 os << "()";
    196                         } else {
    197                                 os << "(void)";
    198                         } // if
    199                 } else {
    200                         PassVisitor<CodeGenerator> cg( os, options );
    201                         os << "(" ;
    202 
    203                         cg.pass.genCommaList( pars.begin(), pars.end() );
    204 
    205                         if ( funcType->get_isVarArgs() ) {
    206                                 os << ", ...";
    207                         } // if
    208                         os << ")";
    209                 } // if
    210 
    211                 typeString = os.str();
    212 
    213                 if ( funcType->returnVals.size() == 0 ) {
    214                         typeString = "void " + typeString;
    215                 } else {
    216                         funcType->returnVals.front()->get_type()->accept( *visitor );
    217                 } // if
    218 
    219                 // add forall
    220                 if( ! funcType->forall.empty() && ! options.genC ) {
    221                         // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    222                         std::ostringstream os;
    223                         PassVisitor<CodeGenerator> cg( os, options );
    224                         os << "forall(";
    225                         cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );
    226                         os << ")" << std::endl;
    227                         typeString = os.str() + typeString;
    228                 }
    229         }
    230 
    231         std::string GenType::handleGeneric( ReferenceToType * refType ) {
    232                 if ( ! refType->parameters.empty() ) {
    233                         std::ostringstream os;
    234                         PassVisitor<CodeGenerator> cg( os, options );
    235                         os << "(";
    236                         cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() );
    237                         os << ") ";
    238                         return os.str();
    239                 }
    240                 return "";
    241         }
    242 
    243         void GenType::postvisit( StructInstType * structInst )  {
    244                 typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;
    245                 if ( options.genC ) typeString = "struct " + typeString;
    246                 handleQualifiers( structInst );
    247         }
    248 
    249         void GenType::postvisit( UnionInstType * unionInst ) {
    250                 typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;
    251                 if ( options.genC ) typeString = "union " + typeString;
    252                 handleQualifiers( unionInst );
    253         }
    254 
    255         void GenType::postvisit( EnumInstType * enumInst ) {
    256                 if ( enumInst->baseEnum && enumInst->baseEnum->base ) {
    257                         typeString = genType(enumInst->baseEnum->base, typeString, options);
    258                 } else {
    259                         typeString = enumInst->name + " " + typeString;
    260                         if ( options.genC ) {
    261                                 typeString = "enum " + typeString;
    262                         }
    263                 }
    264                 handleQualifiers( enumInst );
    265         }
    266 
    267         void GenType::postvisit( TypeInstType * typeInst ) {
    268                 assertf( ! options.genC, "Type instance types should not reach code generation." );
    269                 typeString = typeInst->name + " " + typeString;
    270                 handleQualifiers( typeInst );
    271         }
    272 
    273         void GenType::postvisit( TupleType * tupleType ) {
    274                 assertf( ! options.genC, "Tuple types should not reach code generation." );
    275                 unsigned int i = 0;
    276                 std::ostringstream os;
    277                 os << "[";
    278                 for ( Type * t : *tupleType ) {
    279                         i++;
    280                         os << genType( t, "", options ) << (i == tupleType->size() ? "" : ", ");
    281                 }
    282                 os << "] ";
    283                 typeString = os.str() + typeString;
    284         }
    285 
    286         void GenType::postvisit( VarArgsType * varArgsType ) {
    287                 typeString = "__builtin_va_list " + typeString;
    288                 handleQualifiers( varArgsType );
    289         }
    290 
    291         void GenType::postvisit( ZeroType * zeroType ) {
    292                 // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    293                 typeString = (options.pretty ? "zero_t " : "long int ") + typeString;
    294                 handleQualifiers( zeroType );
    295         }
    296 
    297         void GenType::postvisit( OneType * oneType ) {
    298                 // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    299                 typeString = (options.pretty ? "one_t " : "long int ") + typeString;
    300                 handleQualifiers( oneType );
    301         }
    302 
    303         void GenType::postvisit( GlobalScopeType * globalType ) {
    304                 assertf( ! options.genC, "Global scope type should not reach code generation." );
    305                 handleQualifiers( globalType );
    306         }
    307 
    308         void GenType::postvisit( TraitInstType * inst ) {
    309                 assertf( ! options.genC, "Trait types should not reach code generation." );
    310                 typeString = inst->name + " " + typeString;
    311                 handleQualifiers( inst );
    312         }
    313 
    314         void GenType::postvisit( TypeofType * typeof ) {
    315                 std::ostringstream os;
    316                 PassVisitor<CodeGenerator> cg( os, options );
    317                 os << "typeof(";
    318                 typeof->expr->accept( cg );
    319                 os << ") " << typeString;
    320                 typeString = os.str();
    321                 handleQualifiers( typeof );
    322         }
    323 
    324         void GenType::postvisit( VTableType * vtable ) {
    325                 assertf( ! options.genC, "Virtual table types should not reach code generation." );
    326                 std::ostringstream os;
    327                 os << "vtable(" << genType( vtable->base, "", options ) << ") " << typeString;
    328                 typeString = os.str();
    329                 handleQualifiers( vtable );
    330         }
    331 
    332         void GenType::postvisit( QualifiedType * qualType ) {
    333                 assertf( ! options.genC, "Qualified types should not reach code generation." );
    334                 std::ostringstream os;
    335                 os << genType( qualType->parent, "", options ) << "." << genType( qualType->child, "", options ) << typeString;
    336                 typeString = os.str();
    337                 handleQualifiers( qualType );
    338         }
    339 
    340         void GenType::handleQualifiers( Type * type ) {
    341                 if ( type->get_const() ) {
    342                         typeString = "const " + typeString;
    343                 } // if
    344                 if ( type->get_volatile() ) {
    345                         typeString = "volatile " + typeString;
    346                 } // if
    347                 if ( type->get_restrict() ) {
    348                         typeString = "__restrict " + typeString;
    349                 } // if
    350                 if ( type->get_atomic() ) {
    351                         typeString = "_Atomic " + typeString;
    352                 } // if
    353         }
     209                ast::Pass<CodeGenerator_new> cg( os, options );
     210                os << "(";
     211                cg.core.genCommaList( type->params );
     212                os << ") ";
     213                return os.str();
     214        }
     215        return "";
     216}
     217
     218void GenType_new::postvisit( ast::StructInstType const * type )  {
     219        result = type->name + handleGeneric( type ) + " " + result;
     220        if ( options.genC ) result = "struct " + result;
     221        handleQualifiers( type );
     222}
     223
     224void GenType_new::postvisit( ast::UnionInstType const * type ) {
     225        result = type->name + handleGeneric( type ) + " " + result;
     226        if ( options.genC ) result = "union " + result;
     227        handleQualifiers( type );
     228}
     229
     230void GenType_new::postvisit( ast::EnumInstType const * type ) {
     231        if ( type->base && type->base->base ) {
     232                result = genType( type->base->base, result, options );
     233        } else {
     234                result = type->name + " " + result;
     235                if ( options.genC ) {
     236                        result = "enum " + result;
     237                }
     238        }
     239        handleQualifiers( type );
     240}
     241
     242void GenType_new::postvisit( ast::TypeInstType const * type ) {
     243        assertf( !options.genC, "TypeInstType should not reach code generation." );
     244        result = type->name + " " + result;
     245        handleQualifiers( type );
     246}
     247
     248void GenType_new::postvisit( ast::TupleType const * type ) {
     249        assertf( !options.genC, "TupleType should not reach code generation." );
     250        unsigned int i = 0;
     251        std::ostringstream os;
     252        os << "[";
     253        for ( ast::ptr<ast::Type> const & t : type->types ) {
     254                i++;
     255                os << genType( t, "", options ) << (i == type->size() ? "" : ", ");
     256        }
     257        os << "] ";
     258        result = os.str() + result;
     259}
     260
     261void GenType_new::postvisit( ast::VarArgsType const * type ) {
     262        result = "__builtin_va_list " + result;
     263        handleQualifiers( type );
     264}
     265
     266void GenType_new::postvisit( ast::ZeroType const * type ) {
     267        // Ideally these wouldn't hit codegen at all, but should be safe to make them ints.
     268        result = (options.pretty ? "zero_t " : "long int ") + result;
     269        handleQualifiers( type );
     270}
     271
     272void GenType_new::postvisit( ast::OneType const * type ) {
     273        // Ideally these wouldn't hit codegen at all, but should be safe to make them ints.
     274        result = (options.pretty ? "one_t " : "long int ") + result;
     275        handleQualifiers( type );
     276}
     277
     278void GenType_new::postvisit( ast::GlobalScopeType const * type ) {
     279        assertf( !options.genC, "GlobalScopeType should not reach code generation." );
     280        handleQualifiers( type );
     281}
     282
     283void GenType_new::postvisit( ast::TraitInstType const * type ) {
     284        assertf( !options.genC, "TraitInstType should not reach code generation." );
     285        result = type->name + " " + result;
     286        handleQualifiers( type );
     287}
     288
     289void GenType_new::postvisit( ast::TypeofType const * type ) {
     290        std::ostringstream os;
     291        os << "typeof(";
     292        ast::Pass<CodeGenerator_new>::read( type, os, options );
     293        os << ") " << result;
     294        result = os.str();
     295        handleQualifiers( type );
     296}
     297
     298void GenType_new::postvisit( ast::VTableType const * type ) {
     299        assertf( !options.genC, "Virtual table types should not reach code generation." );
     300        std::ostringstream os;
     301        os << "vtable(" << genType( type->base, "", options ) << ") " << result;
     302        result = os.str();
     303        handleQualifiers( type );
     304}
     305
     306void GenType_new::postvisit( ast::QualifiedType const * type ) {
     307        assertf( !options.genC, "QualifiedType should not reach code generation." );
     308        std::ostringstream os;
     309        os << genType( type->parent, "", options ) << "." << genType( type->child, "", options ) << result;
     310        result = os.str();
     311        handleQualifiers( type );
     312}
     313
     314void GenType_new::handleQualifiers( ast::Type const * type ) {
     315        if ( type->is_const() ) {
     316                result = "const " + result;
     317        }
     318        if ( type->is_volatile() ) {
     319                result = "volatile " + result;
     320        }
     321        if ( type->is_restrict() ) {
     322                result = "__restrict " + result;
     323        }
     324        if ( type->is_atomic() ) {
     325                result = "_Atomic " + result;
     326        }
     327}
     328
     329std::string GenType_new::genParamList( const ast::vector<ast::Type> & range ) {
     330        auto cur = range.begin();
     331        auto end = range.end();
     332        if ( cur == end ) return "";
     333        std::ostringstream oss;
     334        UniqueName param( "__param_" );
     335        while ( true ) {
     336                oss << genType( *cur++, options.genC ? param.newName() : "", options );
     337                if ( cur == end ) break;
     338                oss << ", ";
     339        }
     340        return oss.str();
     341}
     342
     343} // namespace
     344
     345std::string genType( ast::Type const * type, const std::string & base, const Options & options ) {
     346        std::ostringstream os;
     347        if ( !type->attributes.empty() ) {
     348                ast::Pass<CodeGenerator_new> cg( os, options );
     349                cg.core.genAttributes( type->attributes );
     350        }
     351
     352        return os.str() + ast::Pass<GenType_new>::read( type, base, options );
     353}
     354
     355std::string genTypeNoAttr( ast::Type const * type, const std::string & base, const Options & options ) {
     356        return ast::Pass<GenType_new>::read( type, base, options );
     357}
     358
    354359} // namespace CodeGen
    355360
Note: See TracChangeset for help on using the changeset viewer.