Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r42107b4 rceedde6  
    1919#include <string>                  // for string, operator==
    2020
    21 #include "Common/GC.h"             // for new_static_root
    2221#include "Common/PassVisitor.h"    // for PassVisitor
    2322#include "Common/SemanticError.h"  // for SemanticError
     
    192191                void postvisit(   StructDecl * decl );
    193192
    194                 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     193                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first );
    195194                void validate( DeclarationWithType * );
    196195                void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
     
    207206                StructDecl* dtor_guard_decl = nullptr;
    208207
    209                 static Type* generic_func;
     208                static std::unique_ptr< Type > generic_func;
    210209        };
    211210
    212         Type* MutexKeyword::generic_func = new_static_root<FunctionType>( noQualifiers, true );
     211        std::unique_ptr< Type > MutexKeyword::generic_func = std::unique_ptr< Type >(
     212                new FunctionType(
     213                        noQualifiers,
     214                        true
     215                )
     216        );
    213217
    214218        //-----------------------------------------------------------------------------
     
    284288                        // convert (thread &)t to (thread_desc &)*get_thread(t), etc.
    285289                        if( !type_decl ) SemanticError( cast, context_error );
     290                        Expression * arg = cast->arg;
     291                        cast->arg = nullptr;
     292                        delete cast;
    286293                        return new CastExpr(
    287294                                UntypedExpr::createDeref(
    288                                         new UntypedExpr( new NameExpr( getter_name ), { cast->arg } )
     295                                        new UntypedExpr( new NameExpr( getter_name ), { arg } )
    289296                                ),
    290297                                new ReferenceType(
     
    311318                StructDecl * forward = decl->clone();
    312319                forward->set_body( false );
     320                deleteAll( forward->get_members() );
    313321                forward->get_members().clear();
    314322
     
    375383                }
    376384
     385                delete this_decl;
     386
    377387                declsToAddBefore.push_back( forward );
    378388                if( needs_main ) declsToAddBefore.push_back( main_decl );
     
    431441        void MutexKeyword::postvisit(FunctionDecl* decl) {
    432442
    433                 std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
    434                 if( mutexArgs.empty() ) return;
    435 
    436                 if( CodeGen::isConstructor(decl->name) ) SemanticError( decl, "constructors cannot have mutex parameters" );
    437 
     443                bool first = false;
     444                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first );
    438445                bool isDtor = CodeGen::isDestructor( decl->name );
    439446
     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
    440477                if( isDtor && mutexArgs.size() != 1 ) SemanticError( decl, "destructors can only have 1 mutex argument" );
    441478
     479                // Make sure all the mutex arguments are monitors
    442480                for(auto arg : mutexArgs) {
    443481                        validate( arg );
    444482                }
    445483
     484                // Check if we need to instrument the body
    446485                CompoundStmt* body = decl->get_statements();
    447486                if( ! body ) return;
    448487
     488                // Do we have the required headers
    449489                if( !monitor_decl || !guard_decl || !dtor_guard_decl )
    450                         SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>" );
    451 
     490                        SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>\n" );
     491
     492                // Instrument the body
    452493                if( isDtor ) {
    453494                        addDtorStatments( decl, body, mutexArgs );
     
    474515        }
    475516
    476         std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl ) {
     517        std::list<DeclarationWithType*> MutexKeyword::findMutexArgs( FunctionDecl* decl, bool & first ) {
    477518                std::list<DeclarationWithType*> mutexArgs;
    478519
     520                bool once = true;
    479521                for( auto arg : decl->get_functionType()->get_parameters()) {
    480522                        //Find mutex arguments
    481523                        Type* ty = arg->get_type();
    482524                        if( ! ty->get_mutex() ) continue;
     525
     526                        if(once) {first = true;}
     527                        once = false;
    483528
    484529                        //Append it to the list
Note: See TracChangeset for help on using the changeset viewer.