Ignore:
Timestamp:
Nov 14, 2023, 12:19:09 PM (23 months ago)
Author:
caparson <caparson@…>
Branches:
master
Children:
1ccae59, 89a8bab
Parents:
df8ba61a (diff), 5625427 (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

    rdf8ba61a r8d182b1  
    2121#include "AST/Print.hpp"          // for print
    2222#include "AST/Vector.hpp"         // for vector
    23 #include "CodeGenerator.h"        // for CodeGenerator
    24 #include "CodeGeneratorNew.hpp"   // for CodeGenerator_new
    25 #include "SynTree/Declaration.h"  // for DeclarationWithType
    26 #include "SynTree/Expression.h"   // for Expression
    27 #include "SynTree/Type.h"         // for PointerType, Type, FunctionType
    28 #include "SynTree/Visitor.h"      // for Visitor
     23#include "CodeGeneratorNew.hpp"   // for CodeGenerator
     24#include "Common/UniqueName.h"    // for UniqueName
    2925
    3026namespace CodeGen {
    31         struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
    32                 std::string typeString;
    33                 GenType( const std::string &typeString, const Options &options );
    34 
    35                 void previsit( BaseSyntaxNode * );
    36                 void postvisit( BaseSyntaxNode * );
    37 
    38                 void postvisit( FunctionType * funcType );
    39                 void postvisit( VoidType * voidType );
    40                 void postvisit( BasicType * basicType );
    41                 void postvisit( PointerType * pointerType );
    42                 void postvisit( ArrayType * arrayType );
    43                 void postvisit( ReferenceType * refType );
    44                 void postvisit( StructInstType * structInst );
    45                 void postvisit( UnionInstType * unionInst );
    46                 void postvisit( EnumInstType * enumInst );
    47                 void postvisit( TypeInstType * typeInst );
    48                 void postvisit( TupleType  * tupleType );
    49                 void postvisit( VarArgsType * varArgsType );
    50                 void postvisit( ZeroType * zeroType );
    51                 void postvisit( OneType * oneType );
    52                 void postvisit( GlobalScopeType * globalType );
    53                 void postvisit( TraitInstType * inst );
    54                 void postvisit( TypeofType * typeof );
    55                 void postvisit( VTableType * vtable );
    56                 void postvisit( QualifiedType * qualType );
    57 
    58           private:
    59                 void handleQualifiers( Type *type );
    60                 std::string handleGeneric( ReferenceToType * refType );
    61                 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    62 
    63                 Options options;
    64         };
    65 
    66         std::string genType( Type *type, const std::string &baseString, const Options &options ) {
    67                 PassVisitor<GenType> gt( baseString, options );
    68                 std::ostringstream os;
    69 
    70                 if ( ! type->get_attributes().empty() ) {
    71                         PassVisitor<CodeGenerator> cg( os, options );
    72                         cg.pass.genAttributes( type->get_attributes() );
    73                 } // if
    74 
    75                 type->accept( gt );
    76                 return os.str() + gt.pass.typeString;
    77         }
    78 
    79         std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
    80                 return genType( type, baseString, Options(pretty, genC, lineMarks, false ) );
    81         }
    82 
    83         std::string genPrettyType( Type * type, const std::string & baseString ) {
    84                 return genType( type, baseString, true, false );
    85         }
    86 
    87         GenType::GenType( const std::string &typeString, const Options &options ) : typeString( typeString ), options( options ) {}
    88 
    89         // *** BaseSyntaxNode
    90         void GenType::previsit( BaseSyntaxNode * ) {
    91                 // turn off automatic recursion for all nodes, to allow each visitor to
    92                 // precisely control the order in which its children are visited.
    93                 visit_children = false;
    94         }
    95 
    96         void GenType::postvisit( BaseSyntaxNode * node ) {
    97                 std::stringstream ss;
    98                 node->print( ss );
    99                 assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );
    100         }
    101 
    102         void GenType::postvisit( VoidType * voidType ) {
    103                 typeString = "void " + typeString;
    104                 handleQualifiers( voidType );
    105         }
    106 
    107         void GenType::postvisit( BasicType * basicType ) {
    108                 BasicType::Kind kind = basicType->kind;
    109                 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
    110                 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
    111                 handleQualifiers( basicType );
    112         }
    113 
    114         void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) {
    115                 std::ostringstream os;
    116                 if ( typeString != "" ) {
    117                         if ( typeString[ 0 ] == '*' ) {
    118                                 os << "(" << typeString << ")";
    119                         } else {
    120                                 os << typeString;
    121                         } // if
    122                 } // if
    123                 os << "[";
    124 
    125                 if ( isStatic ) {
    126                         os << "static ";
    127                 } // if
    128                 if ( qualifiers.is_const ) {
    129                         os << "const ";
    130                 } // if
    131                 if ( qualifiers.is_volatile ) {
    132                         os << "volatile ";
    133                 } // if
    134                 if ( qualifiers.is_restrict ) {
    135                         os << "__restrict ";
    136                 } // if
    137                 if ( qualifiers.is_atomic ) {
    138                         os << "_Atomic ";
    139                 } // if
    140                 if ( dimension != 0 ) {
    141                         PassVisitor<CodeGenerator> cg( os, options );
    142                         dimension->accept( cg );
    143                 } else if ( isVarLen ) {
    144                         // no dimension expression on a VLA means it came in with the * token
    145                         os << "*";
    146                 } // if
    147                 os << "]";
    148 
    149                 typeString = os.str();
    150 
    151                 base->accept( *visitor );
    152         }
    153 
    154         void GenType::postvisit( PointerType * pointerType ) {
    155                 assert( pointerType->base != 0);
    156                 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) {
    157                         genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() );
    158                 } else {
    159                         handleQualifiers( pointerType );
    160                         if ( typeString[ 0 ] == '?' ) {
    161                                 typeString = "* " + typeString;
    162                         } else {
    163                                 typeString = "*" + typeString;
    164                         } // if
    165                         pointerType->base->accept( *visitor );
    166                 } // if
    167         }
    168 
    169         void GenType::postvisit( ArrayType * arrayType ) {
    170                 genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() );
    171         }
    172 
    173         void GenType::postvisit( ReferenceType * refType ) {
    174                 assert( 0 != refType->base );
    175                 assertf( ! options.genC, "Reference types should not reach code generation." );
    176                 handleQualifiers( refType );
    177                 typeString = "&" + typeString;
    178                 refType->base->accept( *visitor );
    179         }
    180 
    181         void GenType::postvisit( FunctionType * funcType ) {
    182                 std::ostringstream os;
    183 
    184                 if ( typeString != "" ) {
    185                         if ( typeString[ 0 ] == '*' ) {
    186                                 os << "(" << typeString << ")";
    187                         } else {
    188                                 os << typeString;
    189                         } // if
    190                 } // if
    191 
    192                 /************* parameters ***************/
    193 
    194                 const std::list<DeclarationWithType *> &pars = funcType->parameters;
    195 
    196                 if ( pars.empty() ) {
    197                         if ( funcType->get_isVarArgs() ) {
    198                                 os << "()";
    199                         } else {
    200                                 os << "(void)";
    201                         } // if
    202                 } else {
    203                         PassVisitor<CodeGenerator> cg( os, options );
    204                         os << "(" ;
    205 
    206                         cg.pass.genCommaList( pars.begin(), pars.end() );
    207 
    208                         if ( funcType->get_isVarArgs() ) {
    209                                 os << ", ...";
    210                         } // if
    211                         os << ")";
    212                 } // if
    213 
    214                 typeString = os.str();
    215 
    216                 if ( funcType->returnVals.size() == 0 ) {
    217                         typeString = "void " + typeString;
    218                 } else {
    219                         funcType->returnVals.front()->get_type()->accept( *visitor );
    220                 } // if
    221 
    222                 // add forall
    223                 if( ! funcType->forall.empty() && ! options.genC ) {
    224                         // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    225                         std::ostringstream os;
    226                         PassVisitor<CodeGenerator> cg( os, options );
    227                         os << "forall(";
    228                         cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );
    229                         os << ")" << std::endl;
    230                         typeString = os.str() + typeString;
    231                 }
    232         }
    233 
    234         std::string GenType::handleGeneric( ReferenceToType * refType ) {
    235                 if ( ! refType->parameters.empty() ) {
    236                         std::ostringstream os;
    237                         PassVisitor<CodeGenerator> cg( os, options );
    238                         os << "(";
    239                         cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() );
    240                         os << ") ";
    241                         return os.str();
    242                 }
    243                 return "";
    244         }
    245 
    246         void GenType::postvisit( StructInstType * structInst )  {
    247                 typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;
    248                 if ( options.genC ) typeString = "struct " + typeString;
    249                 handleQualifiers( structInst );
    250         }
    251 
    252         void GenType::postvisit( UnionInstType * unionInst ) {
    253                 typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;
    254                 if ( options.genC ) typeString = "union " + typeString;
    255                 handleQualifiers( unionInst );
    256         }
    257 
    258         void GenType::postvisit( EnumInstType * enumInst ) {
    259                 if ( enumInst->baseEnum && enumInst->baseEnum->base ) {
    260                         typeString = genType(enumInst->baseEnum->base, typeString, options);
    261                 } else {
    262                         typeString = enumInst->name + " " + typeString;
    263                         if ( options.genC ) {
    264                                 typeString = "enum " + typeString;
    265                         }
    266                 }
    267                 handleQualifiers( enumInst );
    268         }
    269 
    270         void GenType::postvisit( TypeInstType * typeInst ) {
    271                 assertf( ! options.genC, "Type instance types should not reach code generation." );
    272                 typeString = typeInst->name + " " + typeString;
    273                 handleQualifiers( typeInst );
    274         }
    275 
    276         void GenType::postvisit( TupleType * tupleType ) {
    277                 assertf( ! options.genC, "Tuple types should not reach code generation." );
    278                 unsigned int i = 0;
    279                 std::ostringstream os;
    280                 os << "[";
    281                 for ( Type * t : *tupleType ) {
    282                         i++;
    283                         os << genType( t, "", options ) << (i == tupleType->size() ? "" : ", ");
    284                 }
    285                 os << "] ";
    286                 typeString = os.str() + typeString;
    287         }
    288 
    289         void GenType::postvisit( VarArgsType * varArgsType ) {
    290                 typeString = "__builtin_va_list " + typeString;
    291                 handleQualifiers( varArgsType );
    292         }
    293 
    294         void GenType::postvisit( ZeroType * zeroType ) {
    295                 // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    296                 typeString = (options.pretty ? "zero_t " : "long int ") + typeString;
    297                 handleQualifiers( zeroType );
    298         }
    299 
    300         void GenType::postvisit( OneType * oneType ) {
    301                 // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    302                 typeString = (options.pretty ? "one_t " : "long int ") + typeString;
    303                 handleQualifiers( oneType );
    304         }
    305 
    306         void GenType::postvisit( GlobalScopeType * globalType ) {
    307                 assertf( ! options.genC, "Global scope type should not reach code generation." );
    308                 handleQualifiers( globalType );
    309         }
    310 
    311         void GenType::postvisit( TraitInstType * inst ) {
    312                 assertf( ! options.genC, "Trait types should not reach code generation." );
    313                 typeString = inst->name + " " + typeString;
    314                 handleQualifiers( inst );
    315         }
    316 
    317         void GenType::postvisit( TypeofType * typeof ) {
    318                 std::ostringstream os;
    319                 PassVisitor<CodeGenerator> cg( os, options );
    320                 os << "typeof(";
    321                 typeof->expr->accept( cg );
    322                 os << ") " << typeString;
    323                 typeString = os.str();
    324                 handleQualifiers( typeof );
    325         }
    326 
    327         void GenType::postvisit( VTableType * vtable ) {
    328                 assertf( ! options.genC, "Virtual table types should not reach code generation." );
    329                 std::ostringstream os;
    330                 os << "vtable(" << genType( vtable->base, "", options ) << ") " << typeString;
    331                 typeString = os.str();
    332                 handleQualifiers( vtable );
    333         }
    334 
    335         void GenType::postvisit( QualifiedType * qualType ) {
    336                 assertf( ! options.genC, "Qualified types should not reach code generation." );
    337                 std::ostringstream os;
    338                 os << genType( qualType->parent, "", options ) << "." << genType( qualType->child, "", options ) << typeString;
    339                 typeString = os.str();
    340                 handleQualifiers( qualType );
    341         }
    342 
    343         void GenType::handleQualifiers( Type * type ) {
    344                 if ( type->get_const() ) {
    345                         typeString = "const " + typeString;
    346                 } // if
    347                 if ( type->get_volatile() ) {
    348                         typeString = "volatile " + typeString;
    349                 } // if
    350                 if ( type->get_restrict() ) {
    351                         typeString = "__restrict " + typeString;
    352                 } // if
    353                 if ( type->get_atomic() ) {
    354                         typeString = "_Atomic " + typeString;
    355                 } // if
    356         }
    35727
    35828namespace {
    35929
    360 #warning Remove the _new when old version is removed.
    361 struct GenType_new :
     30struct GenType final :
    36231                public ast::WithShortCircuiting,
    363                 public ast::WithVisitorRef<GenType_new> {
     32                public ast::WithVisitorRef<GenType> {
    36433        std::string result;
    365         GenType_new( const std::string &typeString, const Options &options );
     34        GenType( const std::string &typeString, const Options &options );
    36635
    36736        void previsit( ast::Node const * );
     
    39766};
    39867
    399 GenType_new::GenType_new( const std::string &typeString, const Options &options ) : result( typeString ), options( options ) {}
    400 
    401 void GenType_new::previsit( ast::Node const * ) {
     68GenType::GenType( const std::string &typeString, const Options &options ) : result( typeString ), options( options ) {}
     69
     70void GenType::previsit( ast::Node const * ) {
    40271        // Turn off automatic recursion for all nodes, to allow each visitor to
    40372        // precisely control the order in which its children are visited.
     
    40574}
    40675
    407 void GenType_new::postvisit( ast::Node const * node ) {
     76void GenType::postvisit( ast::Node const * node ) {
    40877        std::stringstream ss;
    40978        ast::print( ss, node );
     
    41180}
    41281
    413 void GenType_new::postvisit( ast::VoidType const * type ) {
     82void GenType::postvisit( ast::VoidType const * type ) {
    41483        result = "void " + result;
    41584        handleQualifiers( type );
    41685}
    41786
    418 void GenType_new::postvisit( ast::BasicType const * type ) {
     87void GenType::postvisit( ast::BasicType const * type ) {
    41988        ast::BasicType::Kind kind = type->kind;
    42089        assert( 0 <= kind && kind < ast::BasicType::NUMBER_OF_BASIC_TYPES );
     
    42392}
    42493
    425 void GenType_new::genArray( const ast::CV::Qualifiers & qualifiers, ast::Type const * base, ast::Expr const *dimension, bool isVarLen, bool isStatic ) {
     94void GenType::genArray( const ast::CV::Qualifiers & qualifiers, ast::Type const * base, ast::Expr const *dimension, bool isVarLen, bool isStatic ) {
    42695        std::ostringstream os;
    42796        if ( result != "" ) {
     
    449118        }
    450119        if ( dimension != 0 ) {
    451                 ast::Pass<CodeGenerator_new>::read( dimension, os, options );
     120                ast::Pass<CodeGenerator>::read( dimension, os, options );
    452121        } else if ( isVarLen ) {
    453122                // no dimension expression on a VLA means it came in with the * token
     
    461130}
    462131
    463 void GenType_new::postvisit( ast::PointerType const * type ) {
     132void GenType::postvisit( ast::PointerType const * type ) {
    464133        if ( type->isStatic || type->isVarLen || type->dimension ) {
    465134                genArray( type->qualifiers, type->base, type->dimension, type->isVarLen, type->isStatic );
     
    475144}
    476145
    477 void GenType_new::postvisit( ast::ArrayType const * type ) {
     146void GenType::postvisit( ast::ArrayType const * type ) {
    478147        genArray( type->qualifiers, type->base, type->dimension, type->isVarLen, type->isStatic );
    479148}
    480149
    481 void GenType_new::postvisit( ast::ReferenceType const * type ) {
     150void GenType::postvisit( ast::ReferenceType const * type ) {
    482151        assertf( !options.genC, "Reference types should not reach code generation." );
    483152        handleQualifiers( type );
     
    486155}
    487156
    488 void GenType_new::postvisit( ast::FunctionType const * type ) {
     157void GenType::postvisit( ast::FunctionType const * type ) {
    489158        std::ostringstream os;
    490159
     
    526195                //assertf( !options.genC, "FunctionDecl type parameters should not reach code generation." );
    527196                std::ostringstream os;
    528                 ast::Pass<CodeGenerator_new> cg( os, options );
     197                ast::Pass<CodeGenerator> cg( os, options );
    529198                os << "forall(";
    530199                cg.core.genCommaList( type->forall );
     
    534203}
    535204
    536 std::string GenType_new::handleGeneric( ast::BaseInstType const * type ) {
     205std::string GenType::handleGeneric( ast::BaseInstType const * type ) {
    537206        if ( !type->params.empty() ) {
    538207                std::ostringstream os;
    539                 ast::Pass<CodeGenerator_new> cg( os, options );
     208                ast::Pass<CodeGenerator> cg( os, options );
    540209                os << "(";
    541210                cg.core.genCommaList( type->params );
     
    546215}
    547216
    548 void GenType_new::postvisit( ast::StructInstType const * type )  {
     217void GenType::postvisit( ast::StructInstType const * type )  {
    549218        result = type->name + handleGeneric( type ) + " " + result;
    550219        if ( options.genC ) result = "struct " + result;
     
    552221}
    553222
    554 void GenType_new::postvisit( ast::UnionInstType const * type ) {
     223void GenType::postvisit( ast::UnionInstType const * type ) {
    555224        result = type->name + handleGeneric( type ) + " " + result;
    556225        if ( options.genC ) result = "union " + result;
     
    558227}
    559228
    560 void GenType_new::postvisit( ast::EnumInstType const * type ) {
     229void GenType::postvisit( ast::EnumInstType const * type ) {
    561230        if ( type->base && type->base->base ) {
    562231                result = genType( type->base->base, result, options );
     
    570239}
    571240
    572 void GenType_new::postvisit( ast::TypeInstType const * type ) {
     241void GenType::postvisit( ast::TypeInstType const * type ) {
    573242        assertf( !options.genC, "TypeInstType should not reach code generation." );
    574243        result = type->name + " " + result;
     
    576245}
    577246
    578 void GenType_new::postvisit( ast::TupleType const * type ) {
     247void GenType::postvisit( ast::TupleType const * type ) {
    579248        assertf( !options.genC, "TupleType should not reach code generation." );
    580249        unsigned int i = 0;
     
    589258}
    590259
    591 void GenType_new::postvisit( ast::VarArgsType const * type ) {
     260void GenType::postvisit( ast::VarArgsType const * type ) {
    592261        result = "__builtin_va_list " + result;
    593262        handleQualifiers( type );
    594263}
    595264
    596 void GenType_new::postvisit( ast::ZeroType const * type ) {
     265void GenType::postvisit( ast::ZeroType const * type ) {
    597266        // Ideally these wouldn't hit codegen at all, but should be safe to make them ints.
    598267        result = (options.pretty ? "zero_t " : "long int ") + result;
     
    600269}
    601270
    602 void GenType_new::postvisit( ast::OneType const * type ) {
     271void GenType::postvisit( ast::OneType const * type ) {
    603272        // Ideally these wouldn't hit codegen at all, but should be safe to make them ints.
    604273        result = (options.pretty ? "one_t " : "long int ") + result;
     
    606275}
    607276
    608 void GenType_new::postvisit( ast::GlobalScopeType const * type ) {
     277void GenType::postvisit( ast::GlobalScopeType const * type ) {
    609278        assertf( !options.genC, "GlobalScopeType should not reach code generation." );
    610279        handleQualifiers( type );
    611280}
    612281
    613 void GenType_new::postvisit( ast::TraitInstType const * type ) {
     282void GenType::postvisit( ast::TraitInstType const * type ) {
    614283        assertf( !options.genC, "TraitInstType should not reach code generation." );
    615284        result = type->name + " " + result;
     
    617286}
    618287
    619 void GenType_new::postvisit( ast::TypeofType const * type ) {
     288void GenType::postvisit( ast::TypeofType const * type ) {
    620289        std::ostringstream os;
    621290        os << "typeof(";
    622         ast::Pass<CodeGenerator_new>::read( type, os, options );
     291        ast::Pass<CodeGenerator>::read( type, os, options );
    623292        os << ") " << result;
    624293        result = os.str();
     
    626295}
    627296
    628 void GenType_new::postvisit( ast::VTableType const * type ) {
     297void GenType::postvisit( ast::VTableType const * type ) {
    629298        assertf( !options.genC, "Virtual table types should not reach code generation." );
    630299        std::ostringstream os;
     
    634303}
    635304
    636 void GenType_new::postvisit( ast::QualifiedType const * type ) {
     305void GenType::postvisit( ast::QualifiedType const * type ) {
    637306        assertf( !options.genC, "QualifiedType should not reach code generation." );
    638307        std::ostringstream os;
     
    642311}
    643312
    644 void GenType_new::handleQualifiers( ast::Type const * type ) {
     313void GenType::handleQualifiers( ast::Type const * type ) {
    645314        if ( type->is_const() ) {
    646315                result = "const " + result;
     
    657326}
    658327
    659 std::string GenType_new::genParamList( const ast::vector<ast::Type> & range ) {
     328std::string GenType::genParamList( const ast::vector<ast::Type> & range ) {
    660329        auto cur = range.begin();
    661330        auto end = range.end();
    662331        if ( cur == end ) return "";
    663332        std::ostringstream oss;
    664         for ( unsigned int i = 0 ; ; ++i ) {
    665                 oss << genType( *cur++, "__param_" + std::to_string(i), options );
     333        UniqueName param( "__param_" );
     334        while ( true ) {
     335                oss << genType( *cur++, options.genC ? param.newName() : "", options );
    666336                if ( cur == end ) break;
    667337                oss << ", ";
     
    675345        std::ostringstream os;
    676346        if ( !type->attributes.empty() ) {
    677                 ast::Pass<CodeGenerator_new> cg( os, options );
     347                ast::Pass<CodeGenerator> cg( os, options );
    678348                cg.core.genAttributes( type->attributes );
    679349        }
    680350
    681         return os.str() + ast::Pass<GenType_new>::read( type, base, options );
     351        return os.str() + ast::Pass<GenType>::read( type, base, options );
    682352}
    683353
    684354std::string genTypeNoAttr( ast::Type const * type, const std::string & base, const Options & options ) {
    685         return ast::Pass<GenType_new>::read( type, base, options );
     355        return ast::Pass<GenType>::read( type, base, options );
    686356}
    687357
Note: See TracChangeset for help on using the changeset viewer.