Changeset 168c007 for src/Concurrency


Ignore:
Timestamp:
Mar 21, 2017, 12:50:27 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
da6d4566, f5392c1
Parents:
94a8123 (diff), e04b636 (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:/u/cforall/software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r94a8123 r168c007  
    1717#include "Concurrency/Keywords.h"
    1818
     19#include "SymTab/AddVisit.h"
    1920#include "SynTree/Declaration.h"
    2021#include "SynTree/Expression.h"
     
    2930        namespace {
    3031                const std::list<Label> noLabels;
     32                const std::list< Attribute * > noAttributes;
    3133                Type::StorageClasses noStorage;
    3234                Type::Qualifiers noQualifiers;
     
    6365        //                                           void main( MyCoroutine * this );
    6466        //
    65         class CoroutineKeyword final : public Mutator {
     67        class CoroutineKeyword final : public Visitor {
     68            template< typename Visitor >
     69            friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
    6670          public:
    6771
    68                 static void implement( std::list< Declaration * > & translationUnit ) {}
     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;
    6987        };
    7088
     
    97115
    98116                using Visitor::visit;
    99                 virtual void visit( FunctionDecl *functionDecl ) override final;
    100                 virtual void visit(   StructDecl *functionDecl ) override final;
     117                virtual void visit( FunctionDecl * decl ) override final;
     118                virtual void visit(   StructDecl * decl ) override final;
    101119
    102120                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     
    111129          private:
    112130                StructDecl* monitor_decl = nullptr;
     131                StructDecl* guard_decl = nullptr;
    113132        };
    114133
     
    124143
    125144        //=============================================================================================
     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        //=============================================================================================
    126253        // Mutex keyword implementation
    127254        //=============================================================================================
     
    137264                if( ! body ) return;
    138265
    139                 assert(monitor_decl);
     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
    140269                addStatments( body, mutexArgs );
    141270        }
     
    146275                        monitor_decl = decl;
    147276                }
     277                else if( decl->get_name() == "monitor_guard_t" ) {
     278                        assert( !guard_decl );
     279                        guard_decl = decl;
     280                }
    148281        }
    149282
     
    175308
    176309                //Make sure that typed isn't mutex
    177                 if( ! base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
     310                if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
    178311        }
    179312
    180313        void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
    181 
    182314                ObjectDecl * monitors = new ObjectDecl(
    183315                        "__monitors",
     
    218350                                new StructInstType(
    219351                                        noQualifiers,
    220                                         "monitor_guard_t"
     352                                        guard_decl
    221353                                ),
    222354                                new ListInit(
     
    224356                                                new SingleInit( new VariableExpr( monitors ) ),
    225357                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
    226                                         }
     358                                        },
     359                                        noDesignators,
     360                                        true
    227361                                )
    228362                        ))
    229363                );
    230364
    231                 //monitor_desc * __monitors[] = { a, b };
     365                //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
    232366                body->push_front( new DeclStmt( noLabels, monitors) );
    233367        }
Note: See TracChangeset for help on using the changeset viewer.