Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    re04b636 r615a096  
    1717#include "Concurrency/Keywords.h"
    1818
    19 #include "SymTab/AddVisit.h"
    2019#include "SynTree/Declaration.h"
    2120#include "SynTree/Expression.h"
     
    3029        namespace {
    3130                const std::list<Label> noLabels;
    32                 const std::list< Attribute * > noAttributes;
    3331                Type::StorageClasses noStorage;
    3432                Type::Qualifiers noQualifiers;
     
    6563        //                                           void main( MyCoroutine * this );
    6664        //
    67         class CoroutineKeyword final : public Visitor {
    68             template< typename Visitor >
    69             friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
    70           public:
    71 
    72                 using Visitor::visit;
    73                 virtual void visit( StructDecl * decl ) override final;
    74 
    75                 void handle( StructDecl * );
    76                 Declaration * addField( StructDecl * );
    77                 void addRoutines( StructDecl *, Declaration * );
    78 
    79                 static void implement( std::list< Declaration * > & translationUnit ) {
    80                         CoroutineKeyword impl;
    81                         SymTab::acceptAndAdd( translationUnit, impl );
    82                 }
    83 
    84           private:
    85                 std::list< Declaration * > declsToAdd, declsToAddAfter;
    86                 StructDecl* coroutine_decl = nullptr;
     65        class CoroutineKeyword final : public Mutator {
     66          public:
     67
     68                static void implement( std::list< Declaration * > & translationUnit ) {}
    8769        };
    8870
     
    11597
    11698                using Visitor::visit;
    117                 virtual void visit( FunctionDecl * decl ) override final;
    118                 virtual void visit(   StructDecl * decl ) override final;
     99                virtual void visit( FunctionDecl *functionDecl ) override final;
     100                virtual void visit(   StructDecl *functionDecl ) override final;
    119101
    120102                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     
    129111          private:
    130112                StructDecl* monitor_decl = nullptr;
    131                 StructDecl* guard_decl = nullptr;
    132113        };
    133114
     
    143124
    144125        //=============================================================================================
    145         // Coroutine keyword implementation
    146         //=============================================================================================
    147         void CoroutineKeyword::visit(StructDecl * decl) {
    148                 if( decl->get_name() == "coroutine_desc" ) {
    149                         assert( !coroutine_decl );
    150                         coroutine_decl = decl;
    151                 }
    152                 else if ( decl->is_coroutine() ) {
    153                         handle( decl );
    154                 }
    155 
    156         }
    157 
    158         void CoroutineKeyword::handle( StructDecl * decl ) {
    159                 if( ! decl->has_body() ) return;
    160 
    161                 if( !coroutine_decl ) throw SemanticError( "coroutine keyword requires coroutines to be in scope, add #include <coroutine>", decl );
    162 
    163                 Declaration * field = addField( decl );
    164                 addRoutines( decl, field );
    165         }
    166 
    167         Declaration * CoroutineKeyword::addField( StructDecl * decl ) {
    168                 Declaration * cor = new ObjectDecl(
    169                         "__cor",
    170                         noStorage,
    171                         LinkageSpec::Cforall,
    172                         nullptr,
    173                         new StructInstType(
    174                                 noQualifiers,
    175                                 coroutine_decl
    176                         ),
    177                         nullptr
    178                 );
    179 
    180                 decl->get_members().push_back( cor );
    181 
    182                 return cor;
    183         }
    184 
    185         void CoroutineKeyword::addRoutines( StructDecl * decl, Declaration * field ) {
    186                 FunctionType * type = new FunctionType( noQualifiers, false );
    187                 type->get_parameters().push_back(
    188                         new ObjectDecl(
    189                                 "this",
    190                                 noStorage,
    191                                 LinkageSpec::Cforall,
    192                                 nullptr,
    193                                 new PointerType(
    194                                         noQualifiers,
    195                                         new StructInstType(
    196                                                 noQualifiers,
    197                                                 decl
    198                                         )
    199                                 ),
    200                                 nullptr
    201                         )
    202                 );
    203                 type->get_returnVals().push_back(
    204                         new ObjectDecl(
    205                                 "ret",
    206                                 noStorage,
    207                                 LinkageSpec::Cforall,
    208                                 nullptr,
    209                                 new PointerType(
    210                                         noQualifiers,
    211                                         new StructInstType(
    212                                                 noQualifiers,
    213                                                 coroutine_decl
    214                                         )
    215                                 ),
    216                                 nullptr
    217                         )
    218                 );
    219 
    220                 CompoundStmt * statement = new CompoundStmt( noLabels );
    221                 statement->push_back(
    222                         new ReturnStmt(
    223                                 noLabels,
    224                                 new AddressExpr(
    225                                         new UntypedMemberExpr(
    226                                                 new NameExpr( "__cor" ),
    227                                                 new UntypedExpr(
    228                                                         new NameExpr( "*?" ),
    229                                                         { new NameExpr( "this" ) }
    230                                                 )
    231                                         )
    232                                 )
    233                         )
    234                 );
    235 
    236                 FunctionDecl * get_decl = new FunctionDecl(
    237                         "get_coroutine",
    238                         Type::Static,
    239                         LinkageSpec::Cforall,
    240                         type,
    241                         statement,
    242                         noAttributes,
    243                         Type::Inline
    244                 );
    245 
    246                 declsToAddAfter.push_back( get_decl );
    247 
    248                 get_decl->fixUniqueId();
    249         }
    250        
    251 
    252         //=============================================================================================
    253126        // Mutex keyword implementation
    254127        //=============================================================================================
     
    264137                if( ! body ) return;
    265138
    266                 if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    267                 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    268 
     139                assert(monitor_decl);
    269140                addStatments( body, mutexArgs );
    270141        }
     
    275146                        monitor_decl = decl;
    276147                }
    277                 else if( decl->get_name() == "monitor_guard_t" ) {
    278                         assert( !guard_decl );
    279                         guard_decl = decl;
    280                 }
    281148        }
    282149
     
    308175
    309176                //Make sure that typed isn't mutex
    310                 if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
     177                if( ! base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
    311178        }
    312179
    313180        void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     181
    314182                ObjectDecl * monitors = new ObjectDecl(
    315183                        "__monitors",
     
    350218                                new StructInstType(
    351219                                        noQualifiers,
    352                                         guard_decl
     220                                        "monitor_guard_t"
    353221                                ),
    354222                                new ListInit(
     
    356224                                                new SingleInit( new VariableExpr( monitors ) ),
    357225                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
    358                                         },
    359                                         noDesignators,
    360                                         true
     226                                        }
    361227                                )
    362228                        ))
    363229                );
    364230
    365                 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     231                //monitor_desc * __monitors[] = { a, b };
    366232                body->push_front( new DeclStmt( noLabels, monitors) );
    367233        }
Note: See TracChangeset for help on using the changeset viewer.