Ignore:
Timestamp:
Aug 27, 2018, 4:40:34 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b7c89aa
Parents:
f9feab8 (diff), 305581d (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' into cleanup-dtors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    rf9feab8 r90152a4  
    2525#include "InitTweak/InitTweak.h"   // for getPointerBase
    2626#include "Parser/LinkageSpec.h"    // for Cforall
    27 #include "SymTab/AddVisit.h"       // for acceptAndAdd
    2827#include "SynTree/Constant.h"      // for Constant
    2928#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     
    5453          public:
    5554
    56                 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main ) :
    57                   type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ) {}
     55                ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, KeywordCastExpr::Target cast_target ) :
     56                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ), cast_target( cast_target ) {}
    5857
    5958                virtual ~ConcurrentSueKeyword() {}
    6059
    61                 void postvisit( StructDecl * decl );
     60                Declaration * postmutate( StructDecl * decl );
    6261
    6362                void handle( StructDecl * );
     
    6766
    6867                virtual bool is_target( StructDecl * decl ) = 0;
     68
     69                Expression * postmutate( KeywordCastExpr * cast );
    6970
    7071          private:
     
    7475                const std::string context_error;
    7576                bool needs_main;
     77                KeywordCastExpr::Target cast_target;
    7678
    7779                StructDecl* type_decl = nullptr;
     
    9597                        "__thrd",
    9698                        "get_thread",
    97                         "thread keyword requires threads to be in scope, add #include <thread>",
    98                         true
     99                        "thread keyword requires threads to be in scope, add #include <thread.hfa>",
     100                        true,
     101                        KeywordCastExpr::Thread
    99102                )
    100103                {}
     
    106109                static void implement( std::list< Declaration * > & translationUnit ) {
    107110                        PassVisitor< ThreadKeyword > impl;
    108                         acceptAll( translationUnit, impl );
     111                        mutateAll( translationUnit, impl );
    109112                }
    110113        };
     
    126129                        "__cor",
    127130                        "get_coroutine",
    128                         "coroutine keyword requires coroutines to be in scope, add #include <coroutine>",
    129                         true
     131                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>",
     132                        true,
     133                        KeywordCastExpr::Coroutine
    130134                )
    131135                {}
     
    137141                static void implement( std::list< Declaration * > & translationUnit ) {
    138142                        PassVisitor< CoroutineKeyword > impl;
    139                         acceptAll( translationUnit, impl );
     143                        mutateAll( translationUnit, impl );
    140144                }
    141145        };
     
    157161                        "__mon",
    158162                        "get_monitor",
    159                         "monitor keyword requires monitors to be in scope, add #include <monitor>",
    160                         false
     163                        "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>",
     164                        false,
     165                        KeywordCastExpr::Monitor
    161166                )
    162167                {}
     
    168173                static void implement( std::list< Declaration * > & translationUnit ) {
    169174                        PassVisitor< MonitorKeyword > impl;
    170                         acceptAll( translationUnit, impl );
     175                        mutateAll( translationUnit, impl );
    171176                }
    172177        };
     
    186191                void postvisit(   StructDecl * decl );
    187192
    188                 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     193                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first );
    189194                void validate( DeclarationWithType * );
    190195                void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
     
    257262        // Generic keyword implementation
    258263        //=============================================================================================
    259         void ConcurrentSueKeyword::postvisit(StructDecl * decl) {
     264        void fixupGenerics(FunctionType * func, StructDecl * decl) {
     265                cloneAll(decl->parameters, func->forall);
     266                for ( TypeDecl * td : func->forall ) {
     267                        strict_dynamic_cast<StructInstType*>(
     268                                func->parameters.front()->get_type()->stripReferences()
     269                        )->parameters.push_back(
     270                                new TypeExpr( new TypeInstType( noQualifiers, td->name, td ) )
     271                        );
     272                }
     273        }
     274
     275        Declaration * ConcurrentSueKeyword::postmutate(StructDecl * decl) {
    260276                if( decl->name == type_name && decl->body ) {
    261277                        assert( !type_decl );
     
    265281                        handle( decl );
    266282                }
    267 
    268         }
     283                return decl;
     284        }
     285
     286        Expression * ConcurrentSueKeyword::postmutate( KeywordCastExpr * cast ) {
     287                if ( cast_target == cast->target ) {
     288                        // convert (thread &)t to (thread_desc &)*get_thread(t), etc.
     289                        if( !type_decl ) SemanticError( cast, context_error );
     290                        Expression * arg = cast->arg;
     291                        cast->arg = nullptr;
     292                        delete cast;
     293                        return new CastExpr(
     294                                UntypedExpr::createDeref(
     295                                        new UntypedExpr( new NameExpr( getter_name ), { arg } )
     296                                ),
     297                                new ReferenceType(
     298                                        noQualifiers,
     299                                        new StructInstType( noQualifiers, type_decl ) )
     300                                );
     301                }
     302                return cast;
     303        }
     304
    269305
    270306        void ConcurrentSueKeyword::handle( StructDecl * decl ) {
    271307                if( ! decl->body ) return;
    272308
    273                 if( !type_decl ) throw SemanticError( context_error, decl );
     309                if( !type_decl ) SemanticError( decl, context_error );
    274310
    275311                FunctionDecl * func = forwardDeclare( decl );
     
    301337                );
    302338
    303                 get_type->get_parameters().push_back( this_decl );
     339                get_type->get_parameters().push_back( this_decl->clone() );
    304340                get_type->get_returnVals().push_back(
    305341                        new ObjectDecl(
     
    318354                        )
    319355                );
     356                fixupGenerics(get_type, decl);
    320357
    321358                FunctionDecl * get_decl = new FunctionDecl(
     
    343380                                nullptr
    344381                        );
    345                 }
     382                        fixupGenerics(main_type, decl);
     383                }
     384
     385                delete this_decl;
    346386
    347387                declsToAddBefore.push_back( forward );
     
    377417                                        new MemberExpr(
    378418                                                field,
    379                                                 UntypedExpr::createDeref( new VariableExpr( func->get_functionType()->get_parameters().front() ) )
     419                                                new CastExpr(
     420                                                        new VariableExpr( func->get_functionType()->get_parameters().front() ),
     421                                                        func->get_functionType()->get_parameters().front()->get_type()->stripReferences()->clone()
     422                                                )
    380423                                        )
    381424                                )
     
    398441        void MutexKeyword::postvisit(FunctionDecl* decl) {
    399442
    400                 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
    401                 if( mutexArgs.empty() ) return;
    402 
    403                 if( CodeGen::isConstructor(decl->name) ) throw SemanticError( "constructors cannot have mutex parameters", decl );
    404 
     443                bool first = false;
     444                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first );
    405445                bool isDtor = CodeGen::isDestructor( decl->name );
    406446
    407                 if( isDtor && mutexArgs.size() != 1 ) throw SemanticError( "destructors can only have 1 mutex argument", decl );
    408 
     447                // Is this function relevant to monitors
     448                if( mutexArgs.empty() ) {
     449                        // If this is the destructor for a monitor it must be mutex
     450                        if(isDtor) {
     451                                Type* ty = decl->get_functionType()->get_parameters().front()->get_type();
     452
     453                                // If it's a copy, it's not a mutex
     454                                ReferenceType* rty = dynamic_cast< ReferenceType * >( ty );
     455                                if( ! rty ) return;
     456
     457                                // If we are not pointing directly to a type, it's not a mutex
     458                                Type* base = rty->get_base();
     459                                if( dynamic_cast< ReferenceType * >( base ) ) return;
     460                                if( dynamic_cast< PointerType * >( base ) ) return;
     461
     462                                // Check if its a struct
     463                                StructInstType * baseStruct = dynamic_cast< StructInstType * >( base );
     464                                if( !baseStruct ) return;
     465
     466                                // Check if its a monitor
     467                                if(baseStruct->baseStruct->is_monitor() || baseStruct->baseStruct->is_thread())
     468                                        SemanticError( decl, "destructors for structures declared as \"monitor\" must use mutex parameters\n" );
     469                        }
     470                        return;
     471                }
     472
     473                // Monitors can't be constructed with mutual exclusion
     474                if( CodeGen::isConstructor(decl->name) && !first ) SemanticError( decl, "constructors cannot have mutex parameters" );
     475
     476                // It makes no sense to have multiple mutex parameters for the destructor
     477                if( isDtor && mutexArgs.size() != 1 ) SemanticError( decl, "destructors can only have 1 mutex argument" );
     478
     479                // Make sure all the mutex arguments are monitors
    409480                for(auto arg : mutexArgs) {
    410481                        validate( arg );
    411482                }
    412483
     484                // Check if we need to instrument the body
    413485                CompoundStmt* body = decl->get_statements();
    414486                if( ! body ) return;
    415487
    416                 if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    417                 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    418                 if( !dtor_guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    419 
     488                // Do we have the required headers
     489                if( !monitor_decl || !guard_decl || !dtor_guard_decl )
     490                        SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor.hfa>\n" );
     491
     492                // Instrument the body
    420493                if( isDtor ) {
    421494                        addDtorStatments( decl, body, mutexArgs );
     
    428501        void MutexKeyword::postvisit(StructDecl* decl) {
    429502
    430                 if( decl->name == "monitor_desc" ) {
     503                if( decl->name == "monitor_desc" && decl->body ) {
    431504                        assert( !monitor_decl );
    432505                        monitor_decl = decl;
    433506                }
    434                 else if( decl->name == "monitor_guard_t" ) {
     507                else if( decl->name == "monitor_guard_t" && decl->body ) {
    435508                        assert( !guard_decl );
    436509                        guard_decl = decl;
    437510                }
    438                 else if( decl->name == "monitor_dtor_guard_t" ) {
     511                else if( decl->name == "monitor_dtor_guard_t" && decl->body ) {
    439512                        assert( !dtor_guard_decl );
    440513                        dtor_guard_decl = decl;
     
    442515        }
    443516
    444         std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {
     517        std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl, bool & first ) {
    445518                std::list<DeclarationWithType*> mutexArgs;
    446519
     520                bool once = true;
    447521                for( auto arg : decl->get_functionType()->get_parameters()) {
    448522                        //Find mutex arguments
     
    450524                        if( ! ty->get_mutex() ) continue;
    451525
     526                        if(once) {first = true;}
     527                        once = false;
     528
    452529                        //Append it to the list
    453530                        mutexArgs.push_back( arg );
     
    462539                //Makes sure it's not a copy
    463540                ReferenceType* rty = dynamic_cast< ReferenceType * >( ty );
    464                 if( ! rty ) throw SemanticError( "Mutex argument must be of reference type ", arg );
     541                if( ! rty ) SemanticError( arg, "Mutex argument must be of reference type " );
    465542
    466543                //Make sure the we are pointing directly to a type
    467544                Type* base = rty->get_base();
    468                 if( dynamic_cast< ReferenceType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg );
    469                 if( dynamic_cast< PointerType * >( base ) ) throw SemanticError( "Mutex argument have exactly one level of indirection ", arg );
     545                if( dynamic_cast< ReferenceType * >( base ) ) SemanticError( arg, "Mutex argument have exactly one level of indirection " );
     546                if( dynamic_cast< PointerType * >( base ) ) SemanticError( arg, "Mutex argument have exactly one level of indirection " );
    470547
    471548                //Make sure that typed isn't mutex
    472                 if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
     549                if( base->get_mutex() ) SemanticError( arg, "mutex keyword may only appear once per argument " );
    473550        }
    474551
     
    608685                if( type && type->get_baseStruct()->is_thread() ) {
    609686                        if( !thread_decl || !thread_ctor_seen ) {
    610                                 throw SemanticError("thread keyword requires threads to be in scope, add #include <thread>");
     687                                SemanticError( type->get_baseStruct()->location, "thread keyword requires threads to be in scope, add #include <thread.hfa>");
    611688                        }
    612689
Note: See TracChangeset for help on using the changeset viewer.