Changes in / [04141f8:70df5f3]


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptDecl.cc

    r04141f8 r70df5f3  
    1010// Created On       : Tue Jul 20 04:10:50 2021
    1111// Last Modified By : Henry Xue
    12 // Last Modified On : Mon Jul 26 12:55:28 2021
    13 // Update Count     : 3
     12// Last Modified On : Thu Jul 22 10:40:55 2021
     13// Update Count     : 2
    1414//
    1515
    1616#include "ExceptDecl.h"
    1717
    18 #include <cassert>               // for assert
    19 #include <string>                // for string
    20 #include <sstream>               // for stringstream
    21 
    2218#include "Common/PassVisitor.h"  // for PassVisitor
    23 #include "Common/utility.h"      // for cloneAll
    2419#include "SynTree/Mutator.h"     // for mutateAll
    2520#include "Virtual/Tables.h"      // for helpers
     
    2722namespace ControlStruct {
    2823
    29 const std::list< Expression *> & makeParameters(
    30         const std::list< TypeDecl *> & forallClause
    31 ) {
    32         auto parameters = new std::list< Expression *>();
    33         for ( auto it = forallClause.begin(); it != forallClause.end(); it++ ) {
    34                 parameters->emplace_back( new TypeExpr(
    35                         new TypeInstType( noQualifiers, ( *it )->get_name(), false )
    36                 ) );
    37         }
    38         return *parameters;
    39 }
    40 
    41 TypeInstType * makeExceptInstType(
    42         const std::string & exceptionName,
    43         const std::list< Expression *> & parameters
    44 ) {
    45         TypeInstType * exceptInstType = new TypeInstType(
    46                 noQualifiers,
    47                 exceptionName,
    48                 false
    49         );
    50         cloneAll( parameters, exceptInstType->parameters );
    51         return exceptInstType;
    52 }
    53 
    54 // void (*copy)(exception_name parameters * this, exception_name parameters * that);
    55 FunctionType * makeCopyFnType(
    56         const std::string & exceptionName,
    57         const std::list< Expression *> & parameters
    58 ) {
    59         FunctionType * copyFnType = new FunctionType( noQualifiers, false );
    60         copyFnType->get_parameters().push_back( new ObjectDecl(
    61                 "this",
    62                 noStorageClasses,
    63                 LinkageSpec::Cforall,
    64                 nullptr,
    65                 new PointerType( noQualifiers,
    66                         makeExceptInstType( exceptionName, parameters ) ),
    67                 nullptr
    68         ) );
    69         copyFnType->get_parameters().push_back( new ObjectDecl(
    70                 "that",
    71                 noStorageClasses,
    72                 LinkageSpec::Cforall,
    73                 nullptr,
    74                 new PointerType( noQualifiers,
    75                         makeExceptInstType( exceptionName, parameters ) ),
    76                 nullptr
    77         ) );
    78         copyFnType->get_returnVals().push_back( new ObjectDecl(
    79                 "",
    80                 noStorageClasses,
    81                 LinkageSpec::Cforall,
    82                 nullptr,
    83                 new VoidType( noQualifiers ),
    84                 nullptr
    85         ) );
    86         return copyFnType;
    87 }
    88 
    89 // void (*^?{})(exception_name parameters & this);
    90 FunctionType * makeDtorFnType(
    91         const std::string & exceptionName,
    92         const std::list< Expression *> & parameters
    93 ) {
    94         FunctionType * dtorFnType = new FunctionType( noQualifiers, false );
    95         dtorFnType->get_parameters().push_back( new ObjectDecl(
    96                 "this",
    97                 noStorageClasses,
    98                 LinkageSpec::Cforall,
    99                 nullptr,
    100                 new ReferenceType( noQualifiers,
    101                         makeExceptInstType( exceptionName, parameters ) ),
    102                 nullptr
    103         ) );
    104         dtorFnType->get_returnVals().push_back( new ObjectDecl(
    105                 "",
    106                 noStorageClasses,
    107                 LinkageSpec::Cforall,
    108                 nullptr,
    109                 new VoidType( noQualifiers ),
    110                 nullptr
    111         ) );
    112         return dtorFnType;
    113 }
    114 
    115 // const char * (*msg)(exception_name parameters * this);
    116 FunctionType * makeMsgFnType(
    117         const std::string & exceptionName,
    118         const std::list< Expression *> & parameters
    119 ) {
    120         FunctionType * msgFnType = new FunctionType( noQualifiers, false );
    121         msgFnType->get_parameters().push_back( new ObjectDecl(
    122                 "this",
    123                 noStorageClasses,
    124                 LinkageSpec::Cforall,
    125                 nullptr,
    126                 new PointerType( noQualifiers,
    127                         makeExceptInstType( exceptionName, parameters ) ),
    128                 nullptr
    129         ) );
    130         msgFnType->get_returnVals().push_back( new ObjectDecl(
    131                 "",
    132                 noStorageClasses,
    133                 LinkageSpec::Cforall,
    134                 nullptr,
    135                 new PointerType( noQualifiers,
    136                         new BasicType( Type::Const, BasicType::Char ) ),
    137                 nullptr
    138         ) );
    139         return msgFnType;
    140 }
    141 
    142 StructDecl * ehmTypeIdStruct(
    143         const std::string & exceptionName,
    144         const std::list< TypeDecl *> & forallClause
    145 ) {
     24StructDecl * ehmTypeIdStruct( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
    14625        StructDecl * structDecl = new StructDecl( Virtual::typeIdType( exceptionName ) );
    14726        structDecl->members.push_back( new ObjectDecl(
     
    15534        ) );
    15635        structDecl->set_body( true );
    157         cloneAll( forallClause, structDecl->parameters );
    158         return structDecl;
    159 }
    160 
    161 ObjectDecl * ehmTypeIdValue(
    162         const std::string & exceptionName,
    163         const std::list< Expression *> & parameters
    164 ) {
    165         StructInstType * typeIdType = new StructInstType(
    166                 Type::Const,
    167                 Virtual::typeIdType( exceptionName )
    168         );
    169         cloneAll( parameters, typeIdType->parameters );
     36        if ( parameters ) {
     37                structDecl->parameters = *parameters;
     38        }
     39        return structDecl;
     40}
     41
     42ObjectDecl * ehmTypeIdValue( const std::string & exceptionName, std::list< Expression *> * parameters ) {
     43        StructInstType * structInstType = new StructInstType( Type::Const, Virtual::typeIdType( exceptionName ) );
     44        if ( parameters ) {
     45                structInstType->parameters = *parameters;
     46        }
    17047        return new ObjectDecl(
    17148                Virtual::typeIdName( exceptionName ),
     
    17350                LinkageSpec::Cforall,
    17451                nullptr,
    175                 typeIdType,
     52                structInstType,
    17653                new ListInit( { new SingleInit(
    17754                        new AddressExpr( new NameExpr( "__cfatid_exception_t" ) )
     
    18158}
    18259
    183 StructDecl * ehmExceptionStructDecl(
    184         const std::string & exceptionName,
    185         const std::list< TypeDecl *> & forallClause
    186 ) {
     60StructDecl * ehmExceptionStructDecl( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
    18761        StructDecl * structDecl = new StructDecl( exceptionName );
    188         cloneAll( forallClause, structDecl->parameters );
    189         return structDecl;
    190 }
    191 
    192 StructDecl * ehmVirtualTableStruct(
    193         const std::string & exceptionName,
    194         const std::list< TypeDecl *> & forallClause,
    195         const std::list< Expression *> & parameters
    196 ) {
    197         StructInstType * typeIdType = new StructInstType(
    198                 Type::Const,
    199                 Virtual::typeIdType( exceptionName )
    200         );
    201         cloneAll( parameters, typeIdType->parameters );
     62        if ( parameters ) {
     63                structDecl->parameters = *parameters;
     64        }
     65        return structDecl;
     66}
     67
     68StructDecl * ehmVirtualTableStruct( const std::string & exceptionName, std::list< TypeDecl *> * parameters ) {
     69        // _EHM_TYPE_ID_TYPE(exception_name) parameters const * __cfavir_typeid;
    20270        ObjectDecl * typeId = new ObjectDecl(
    20371                "__cfavir_typeid",
     
    20573                LinkageSpec::Cforall,
    20674                nullptr,
    207                 new PointerType( noQualifiers, typeIdType ),
    208                 nullptr
    209         );
     75                new PointerType( noQualifiers,
     76                        new StructInstType( Type::Const, Virtual::typeIdType( exceptionName ) ) ),
     77                nullptr
     78        );
     79
     80        // size_t size;
    21081        ObjectDecl * size = new ObjectDecl(
    21182                "size",
     
    21687                nullptr
    21788        );
     89       
     90        // void (*copy)(exception_name parameters * this, exception_name parameters * other);
     91        FunctionType * copyFnType = new FunctionType( noQualifiers, false );
     92        copyFnType->get_parameters().push_back( new ObjectDecl(
     93                "this",
     94                noStorageClasses,
     95                LinkageSpec::Cforall,
     96                nullptr,
     97                new PointerType( noQualifiers,
     98                        new TypeInstType( noQualifiers, exceptionName, false ) ),
     99                nullptr
     100        ) );
     101        copyFnType->get_parameters().push_back( new ObjectDecl(
     102                "other",
     103                noStorageClasses,
     104                LinkageSpec::Cforall,
     105                nullptr,
     106                new PointerType( noQualifiers,
     107                        new TypeInstType( noQualifiers, exceptionName, false ) ),
     108                nullptr
     109        ) );
     110        copyFnType->get_returnVals().push_back( new ObjectDecl(
     111                "",
     112                noStorageClasses,
     113                LinkageSpec::Cforall,
     114                nullptr,
     115                new VoidType( noQualifiers ),
     116                nullptr
     117        ) );
    218118        ObjectDecl * copy = new ObjectDecl(
    219119                "copy",
     
    221121                LinkageSpec::Cforall,
    222122                nullptr,
    223                 new PointerType( noQualifiers,
    224                         makeCopyFnType( exceptionName, parameters ) ),
    225                 nullptr
    226         );
     123                new PointerType( noQualifiers, copyFnType ),
     124                nullptr
     125        );
     126
     127        // void (*^?{})(exception_name parameters & this);
     128        FunctionType * dtorFnType = new FunctionType( noQualifiers, false );
     129        dtorFnType->get_parameters().push_back( new ObjectDecl(
     130                "this",
     131                noStorageClasses,
     132                LinkageSpec::Cforall,
     133                nullptr,
     134                new ReferenceType( noQualifiers,
     135                        new TypeInstType( noQualifiers, exceptionName, false ) ),
     136                nullptr
     137        ) );
     138        dtorFnType->get_returnVals().push_back( new ObjectDecl(
     139                "",
     140                noStorageClasses,
     141                LinkageSpec::Cforall,
     142                nullptr,
     143                new VoidType( noQualifiers ),
     144                nullptr
     145        ) );
    227146        ObjectDecl * dtor = new ObjectDecl(
    228147                "^?{}",
     
    230149                LinkageSpec::Cforall,
    231150                nullptr,
    232                 new PointerType( noQualifiers,
    233                         makeDtorFnType( exceptionName, parameters ) ),
    234                 nullptr
    235         );
     151                new PointerType( noQualifiers, dtorFnType ),
     152                nullptr
     153        );
     154
     155        // const char * (*msg)(exception_name parameters * this);
     156        FunctionType * msgFnType = new FunctionType( noQualifiers, false );
     157        msgFnType->get_parameters().push_back( new ObjectDecl(
     158                "this",
     159                noStorageClasses,
     160                LinkageSpec::Cforall,
     161                nullptr,
     162                new PointerType( noQualifiers,
     163                        new TypeInstType( noQualifiers, exceptionName, false ) ),
     164                nullptr
     165        ) );
     166        msgFnType->get_returnVals().push_back( new ObjectDecl(
     167                "",
     168                noStorageClasses,
     169                LinkageSpec::Cforall,
     170                nullptr,
     171                new PointerType( noQualifiers, new BasicType( Type::Const, BasicType::Char ) ),
     172                nullptr
     173        ) );
    236174        ObjectDecl * msg = new ObjectDecl(
    237175                "msg",
     
    239177                LinkageSpec::Cforall,
    240178                nullptr,
    241                 new PointerType( noQualifiers,
    242                         makeMsgFnType( exceptionName, parameters ) ),
    243                 nullptr
    244         );
     179                new PointerType( noQualifiers, msgFnType ),
     180                nullptr
     181        );
     182
    245183        StructDecl * structDecl = new StructDecl( Virtual::vtableTypeName( exceptionName ) );
    246184        structDecl->members.push_back( typeId );
     
    250188        structDecl->members.push_back( msg );
    251189        structDecl->set_body( true );
    252         cloneAll( forallClause, structDecl->parameters );
    253         return structDecl;
    254 }
    255 
    256 StructDecl * ehmExceptionStruct(
    257         const std::string & exceptionName,
    258         const std::list< TypeDecl *> & forallClause,
    259         const std::list< Expression *> & parameters,
    260         const std::list< Declaration *> & members
    261 ) {
    262         StructInstType * vtableType = new StructInstType(
    263                 Type::Const,
    264                 Virtual::vtableTypeName( exceptionName )
    265         );
    266         cloneAll( parameters, vtableType->parameters );
     190        if ( parameters ) {
     191                structDecl->parameters = *parameters;
     192        }
     193        return structDecl;
     194}
     195
     196StructDecl * ehmExceptionStruct( const std::string & exceptionName, const std::list<Declaration*> & members,
     197                                                                 std::list<TypeDecl *> * parameters ) {
    267198        StructDecl * structDecl = new StructDecl( exceptionName );
    268199        structDecl->members = members;
     
    272203                LinkageSpec::Cforall,
    273204                nullptr,
    274                 new PointerType( noQualifiers, vtableType ),
     205                new PointerType( noQualifiers,
     206                        new StructInstType( Type::Const, Virtual::vtableTypeName( exceptionName ) ) ),
    275207                nullptr
    276208        ) );
    277209        structDecl->set_body( true );
    278         cloneAll( forallClause, structDecl->parameters );
    279         return structDecl;
    280 }
    281 
    282 ObjectDecl * ehmExternVtable(
    283         const std::string & exceptionName,
    284         const std::list< Expression *> & parameters,
    285         const std::string & tableName
    286 ) {
    287         StructInstType * vtableType = new StructInstType(
    288                 Type::Const,
    289                 Virtual::vtableTypeName( exceptionName )
    290         );
    291         cloneAll( parameters, vtableType->parameters );
     210        if ( parameters ) {
     211                structDecl->parameters = *parameters;
     212        }
     213        return structDecl;
     214}
     215
     216ObjectDecl * ehmExternVtable( const std::string & exceptionName, const std::string & tableName,
     217                                                          std::list< Expression *> * parameters ) {
     218        StructInstType * structInstType = new StructInstType( Type::Const, Virtual::vtableTypeName(exceptionName) );
     219        if ( parameters ) {
     220                structInstType->parameters = *parameters;
     221        }
    292222        return new ObjectDecl(
    293223                tableName,
     
    295225                LinkageSpec::Cforall,
    296226                nullptr,
    297                 vtableType,
    298                 nullptr
    299         );
    300 }
    301 
    302 FunctionDecl * ehmDefineCopy(
    303         const std::string & exceptionName,
    304         const std::list< Expression *> & parameters
    305 ) {
     227                structInstType,
     228                nullptr
     229        );
     230}
     231
     232FunctionDecl * ehmDefineCopy( const std::string & exceptionName ) {
     233        FunctionType * copyFnType = new FunctionType( noQualifiers, false );
     234        copyFnType->get_parameters().push_back( new ObjectDecl(
     235                "this",
     236                noStorageClasses,
     237                LinkageSpec::Cforall,
     238                nullptr,
     239                new PointerType( noQualifiers,
     240                        new TypeInstType( noQualifiers, exceptionName, false ) ),
     241                nullptr
     242        ) );
     243        copyFnType->get_parameters().push_back( new ObjectDecl(
     244                "that",
     245                noStorageClasses,
     246                LinkageSpec::Cforall,
     247                nullptr,
     248                new PointerType( noQualifiers,
     249                        new TypeInstType( noQualifiers, exceptionName, false ) ),
     250                nullptr
     251        ) );
     252        copyFnType->get_returnVals().push_back( new ObjectDecl(
     253                "",
     254                noStorageClasses,
     255                LinkageSpec::Cforall,
     256                nullptr,
     257                new VoidType( noQualifiers ),
     258                nullptr
     259        ) );
    306260        return new FunctionDecl(
    307261                "copy",
    308262                noStorageClasses,
    309263                LinkageSpec::Cforall,
    310                 makeCopyFnType( exceptionName, parameters ),
     264                copyFnType,
    311265                new CompoundStmt( {
    312266                        new ExprStmt( new UntypedExpr( new NameExpr( "?=?" ), {
     
    318272}
    319273
    320 FunctionDecl * ehmDefineMsg(
    321         const std::string & exceptionName,
    322         const std::list< Expression *> & parameters
    323 ) {
    324         std::stringstream msg;
    325         msg << exceptionName;
    326         if ( !parameters.empty() ) { // forall variant, add parameters
    327                 msg << "(";
    328                 for ( auto it = parameters.begin(); it != parameters.end(); it++ ) {
    329                         ( *it )->print( msg );
    330                         if ( it + 1 == parameters.end() ) {
    331                                 msg << ")"; // end of list, close bracket
    332                         } else {
    333                                 msg << ", "; // otherwise use comma as separator
    334                         }
    335                 }
    336         }
     274FunctionDecl * ehmDefineMsg( const std::string & exceptionName ) {
     275        FunctionType * msgFnType = new FunctionType( noQualifiers, false );
     276        msgFnType->get_parameters().push_back( new ObjectDecl(
     277                "this",
     278                noStorageClasses,
     279                LinkageSpec::Cforall,
     280                nullptr,
     281                new PointerType( noQualifiers,
     282                        new TypeInstType( noQualifiers, exceptionName, false ) ),
     283                nullptr
     284        ) );
     285        msgFnType->get_returnVals().push_back( new ObjectDecl(
     286                "",
     287                noStorageClasses,
     288                LinkageSpec::Cforall,
     289                nullptr,
     290                new PointerType( noQualifiers, new BasicType( Type::Const, BasicType::Char ) ),
     291                nullptr
     292        ) );
    337293        return new FunctionDecl(
    338294                "msg",
    339295                noStorageClasses,
    340296                LinkageSpec::Cforall,
    341                 makeMsgFnType( exceptionName, parameters ),
     297                msgFnType,
    342298                new CompoundStmt( {
    343                         new ReturnStmt( new ConstantExpr( Constant::from_string( msg.str() ) ) )
     299                        new ReturnStmt( new ConstantExpr( Constant::from_string( exceptionName ) ) )
    344300                } )
    345301        );
    346302}
    347303
    348 ObjectDecl * ehmVirtualTable(
    349         const std::string & exceptionName,
    350         const std::list< Expression *> & parameters,
    351         const std::string & tableName
    352 ) {
    353         StructInstType * sizeofType = new StructInstType( noQualifiers, exceptionName );
    354         cloneAll( parameters, sizeofType->parameters );
     304ObjectDecl * ehmVirtualTable( const std::string & exceptionName, const std::string & tableName ) {
    355305        std::list< Initializer *> inits {
    356306                new SingleInit( new AddressExpr(
    357307                        new NameExpr( Virtual::typeIdName( exceptionName ) ) ) ),
    358                 new SingleInit( new SizeofExpr( sizeofType ) ),
     308                new SingleInit( new SizeofExpr(
     309                        new StructInstType( noQualifiers, exceptionName ) ) ),
    359310                new SingleInit( new NameExpr( "copy" ) ),
    360311                new SingleInit( new NameExpr( "^?{}" ) ),
     
    368319                new Designation( { new NameExpr( "msg" ) } )
    369320        };
    370         StructInstType * vtableType = new StructInstType(
    371                 Type::Const,
    372                 Virtual::vtableTypeName( exceptionName )
    373         );
    374         cloneAll( parameters, vtableType->parameters );
    375321        return new ObjectDecl(
    376322                tableName,
     
    378324                LinkageSpec::Cforall,
    379325                nullptr,
    380                 vtableType,
     326                new StructInstType( Type::Const, Virtual::vtableTypeName( exceptionName ) ),
    381327                new ListInit( inits, desig )
    382328        );
     
    385331class ExceptDeclCore : public WithDeclsToAdd {
    386332public:
    387         // translates exception decls
    388         Declaration * postmutate( StructDecl * structDecl );
    389 
    390         // translates vtable decls
    391         DeclarationWithType * postmutate( ObjectDecl * objectDecl );
     333        Declaration * postmutate( StructDecl * structDecl ); // translates exception decls
     334        DeclarationWithType * postmutate( ObjectDecl * objectDecl ); // translates vtable decls
    392335};
    393336
     
    395338        if ( structDecl->is_exception() ) {
    396339                const std::string & exceptionName = structDecl->get_name();
    397                 const std::list< TypeDecl *> & forallClause = structDecl->get_parameters();
    398                 const std::list< Expression *> & parameters = makeParameters( forallClause );
    399                 const std::list< Declaration *> & members = structDecl->get_members();
    400 
    401                 declsToAddBefore.push_back( ehmTypeIdStruct( exceptionName, forallClause ) );
    402                 if ( forallClause.empty() ) { // non-forall variant
    403                         declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, parameters ) );
    404                 }
    405                 declsToAddBefore.push_back( ehmExceptionStructDecl( exceptionName, forallClause ) );
    406                 declsToAddBefore.push_back( ehmVirtualTableStruct( exceptionName, forallClause, parameters ) );
    407                 return ehmExceptionStruct( exceptionName, forallClause, parameters, members );
     340                declsToAddBefore.push_back( ehmTypeIdStruct( exceptionName, nullptr ) );
     341                declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, nullptr ) );
     342                declsToAddBefore.push_back( ehmExceptionStructDecl( exceptionName, nullptr ) );
     343                declsToAddBefore.push_back( ehmVirtualTableStruct( exceptionName, nullptr ) );
     344                return ehmExceptionStruct( exceptionName, structDecl->get_members(), nullptr );
    408345        }
    409346        return structDecl;
     
    418355                const std::string & exceptionName = base->get_name();
    419356                const std::string & tableName = objectDecl->get_name();
    420                 const std::list< Expression *> parameters = base->get_parameters();
    421 
    422                 if ( objectDecl->get_storageClasses().is_extern ) { // if extern
    423                         return ehmExternVtable( exceptionName, parameters, tableName );
     357                if ( objectDecl->get_storageClasses().is_extern ) {
     358                        return ehmExternVtable( exceptionName, tableName, nullptr );
     359                } else {
     360                        declsToAddBefore.push_back( ehmDefineCopy( exceptionName ) );
     361                        declsToAddBefore.push_back( ehmDefineMsg( exceptionName ) );
     362                        return ehmVirtualTable( exceptionName, tableName );
    424363                }
    425                 // else, non-extern
    426                 if ( !parameters.empty() ) { // forall variant
    427                         declsToAddBefore.push_back( ehmTypeIdValue( exceptionName, parameters ) );
    428                 }
    429                 declsToAddBefore.push_back( ehmDefineCopy( exceptionName, parameters ) );
    430                 declsToAddBefore.push_back( ehmDefineMsg( exceptionName, parameters ) );
    431                 return ehmVirtualTable( exceptionName, parameters, tableName );
    432364        }
    433365        return objectDecl;
Note: See TracChangeset for help on using the changeset viewer.