Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r77a2994 rb81fd95  
    1919#include <string>                         // for string, operator==
    2020
    21 #include <iostream>
    22 
    23 #include "Common/Examine.h"               // for isMainFor
    2421#include "Common/PassVisitor.h"           // for PassVisitor
    2522#include "Common/SemanticError.h"         // for SemanticError
     
    3734#include "SynTree/Type.h"                 // for StructInstType, Type, PointerType
    3835#include "SynTree/Visitor.h"              // for Visitor, acceptAll
    39 #include "Virtual/Tables.h"
    4036
    4137class Attribute;
    4238
    4339namespace Concurrency {
    44         inline static std::string getVTableName( std::string const & exception_name ) {
    45                 return exception_name.empty() ? std::string() : Virtual::vtableTypeName(exception_name);
    46         }
    47 
    4840        //=============================================================================================
    4941        // Pass declarations
     
    6254          public:
    6355
    64                 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name,
    65                         std::string&& getter_name, std::string&& context_error, std::string&& exception_name,
    66                         bool needs_main, AggregateDecl::Aggregate cast_target ) :
    67                   type_name( type_name ), field_name( field_name ), getter_name( getter_name ),
    68                   context_error( context_error ), vtable_name( getVTableName( exception_name ) ),
    69                   needs_main( needs_main ), cast_target( cast_target ) {}
     56                ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, AggregateDecl::Aggregate cast_target ) :
     57                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ), needs_main( needs_main ), cast_target( cast_target ) {}
    7058
    7159                virtual ~ConcurrentSueKeyword() {}
     
    7563
    7664                void handle( StructDecl * );
    77                 void addVtableForward( StructDecl * );
    7865                FunctionDecl * forwardDeclare( StructDecl * );
    7966                ObjectDecl * addField( StructDecl * );
     
    8976                const std::string getter_name;
    9077                const std::string context_error;
    91                 const std::string vtable_name;
    9278                bool needs_main;
    9379                AggregateDecl::Aggregate cast_target;
     
    9581                StructDecl   * type_decl = nullptr;
    9682                FunctionDecl * dtor_decl = nullptr;
    97                 StructDecl * vtable_decl = nullptr;
    9883        };
    9984
     
    116101                        "get_thread",
    117102                        "thread keyword requires threads to be in scope, add #include <thread.hfa>\n",
    118                         "",
    119103                        true,
    120104                        AggregateDecl::Thread
     
    149133                        "get_coroutine",
    150134                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>\n",
    151                         "CoroutineCancelled",
    152135                        true,
    153136                        AggregateDecl::Coroutine
     
    184167                        "get_monitor",
    185168                        "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>\n",
    186                         "",
    187169                        false,
    188170                        AggregateDecl::Monitor
     
    216198                        "get_generator",
    217199                        "Unable to find builtin type $generator\n",
    218                         "",
    219200                        true,
    220201                        AggregateDecl::Generator
     
    250231
    251232        private:
     233                DeclarationWithType * is_main( FunctionDecl * );
    252234                bool is_real_suspend( FunctionDecl * );
    253235
     
    377359                        handle( decl );
    378360                }
    379                 else if ( !vtable_decl && vtable_name == decl->name && decl->body ) {
    380                         vtable_decl = decl;
    381                 }
    382                 // Might be able to get ride of is target.
    383                 assert( is_target(decl) == (cast_target == decl->kind) );
    384361                return decl;
    385362        }
    386363
    387364        DeclarationWithType * ConcurrentSueKeyword::postmutate( FunctionDecl * decl ) {
    388                 if ( type_decl && isDestructorFor( decl, type_decl ) )
    389                         dtor_decl = decl;
    390                 else if ( vtable_name.empty() )
    391                         ;
    392                 else if ( auto param = isMainFor( decl, cast_target ) ) {
    393                         // This should never trigger.
    394                         assert( vtable_decl );
    395                         // Should be safe because of isMainFor.
    396                         StructInstType * struct_type = static_cast<StructInstType *>(
    397                                 static_cast<ReferenceType *>( param->get_type() )->base );
    398                         assert( struct_type );
    399 
    400                         declsToAddAfter.push_back( Virtual::makeVtableInstance( vtable_decl, {
    401                                 new TypeExpr( struct_type->clone() ),
    402                         }, struct_type, nullptr ) );
    403                 }
    404 
     365                if( !type_decl ) return decl;
     366                if( !CodeGen::isDestructor( decl->name ) ) return decl;
     367
     368                auto params = decl->type->parameters;
     369                if( params.size() != 1 ) return decl;
     370
     371                auto type = dynamic_cast<ReferenceType*>( params.front()->get_type() );
     372                if( !type ) return decl;
     373
     374                auto stype = dynamic_cast<StructInstType*>( type->base );
     375                if( !stype ) return decl;
     376                if( stype->baseStruct != type_decl ) return decl;
     377
     378                if( !dtor_decl ) dtor_decl = decl;
    405379                return decl;
    406380        }
     
    426400                if( !dtor_decl ) SemanticError( decl, context_error );
    427401
    428                 addVtableForward( decl );
    429402                FunctionDecl * func = forwardDeclare( decl );
    430403                ObjectDecl * field = addField( decl );
    431404                addRoutines( field, func );
    432         }
    433 
    434         void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) {
    435                 if ( vtable_decl ) {
    436                         declsToAddBefore.push_back( Virtual::makeVtableForward( vtable_decl, {
    437                                 new TypeExpr( new StructInstType( noQualifiers, decl ) ),
    438                         } ) );
    439                 // Its only an error if we want a vtable and don't have one.
    440                 } else if ( ! vtable_name.empty() ) {
    441                         SemanticError( decl, context_error );
    442                 }
    443405        }
    444406
     
    566528        // Suspend keyword implementation
    567529        //=============================================================================================
     530        DeclarationWithType * SuspendKeyword::is_main( FunctionDecl * func) {
     531                if(func->name != "main") return nullptr;
     532                if(func->type->parameters.size() != 1) return nullptr;
     533
     534                auto param = func->type->parameters.front();
     535
     536                auto type  = dynamic_cast<ReferenceType * >(param->get_type());
     537                if(!type) return nullptr;
     538
     539                auto obj   = dynamic_cast<StructInstType *>(type->base);
     540                if(!obj) return nullptr;
     541
     542                if(!obj->baseStruct->is_generator()) return nullptr;
     543
     544                return param;
     545        }
     546
    568547        bool SuspendKeyword::is_real_suspend( FunctionDecl * func ) {
    569548                if(isMangled(func->linkage)) return false; // the real suspend isn't mangled
     
    586565
    587566                // Is this the main of a generator?
    588                 auto param = isMainFor( func, AggregateDecl::Aggregate::Generator );
     567                auto param = is_main( func );
    589568                if(!param) return;
    590569
     
    931910                                        {
    932911                                                new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ),
    933                                                 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) ),
    934                                                 new SingleInit( new ConstantExpr( Constant::from_bool( false ) ) )
     912                                                new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) )
    935913                                        },
    936914                                        noDesignators,
     
    10551033// tab-width: 4 //
    10561034// End: //
    1057 
Note: See TracChangeset for help on using the changeset viewer.