Changeset bcda04c


Ignore:
Timestamp:
Mar 23, 2017, 11:37:27 AM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
bd4d011
Parents:
578b637
Message:

Fixed autogen constructors for concurrent sues

Location:
src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r578b637 rbcda04c  
    2121#include "SynTree/Expression.h"
    2222#include "SynTree/Initializer.h"
    23 #include "SynTree/Mutator.h"
    2423#include "SynTree/Statement.h"
    2524#include "SynTree/Type.h"
     
    3837        // Visitors declaration
    3938        //=============================================================================================
     39
     40        //-----------------------------------------------------------------------------
     41        //Handles sue type declarations :
     42        // sue MyType {                             struct MyType {
     43        //      int data;                                  int data;
     44        //      a_struct_t more_data;                      a_struct_t more_data;
     45        //                                =>             NewField_t newField;
     46        // };                                        };
     47        //                                           static inline NewField_t * getter_name( MyType * this ) { return &this->newField; }
     48        //
     49        class ConcurrentSueKeyword : public Visitor {
     50          protected:
     51            template< typename Visitor >
     52            friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
     53          public:
     54
     55                ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error ) :
     56                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ), context_error( context_error ) {}
     57
     58                virtual ~ConcurrentSueKeyword() {}
     59
     60                using Visitor::visit;
     61                virtual void visit( StructDecl * decl ) override final;
     62
     63                void handle( StructDecl * );
     64                FunctionDecl * forwardDeclare( StructDecl * );
     65                ObjectDecl * addField( StructDecl * );
     66                void addRoutines( StructDecl *, ObjectDecl *, FunctionDecl * );
     67
     68                virtual bool is_target( StructDecl * decl ) = 0;
     69
     70          private:
     71                const std::string type_name;
     72                const std::string field_name;
     73                const std::string getter_name;
     74                const std::string context_error;
     75
     76                std::list< Declaration * > declsToAdd, declsToAddAfter;
     77                StructDecl* type_decl = nullptr;
     78        };
     79
    4080
    4181        //-----------------------------------------------------------------------------
     
    4787        // };                                        };
    4888        //                                           static inline thread_desc * get_thread( MyThread * this ) { return &this->__thrd_d; }
    49         //                                           void main( MyThread * this );
    5089        //
    51         class ThreadKeyword final : public Mutator {
     90        class ThreadKeyword final : public ConcurrentSueKeyword {
    5291          public:
    5392
    54                 static void implement( std::list< Declaration * > & translationUnit ) {}
     93                ThreadKeyword() : ConcurrentSueKeyword(
     94                        "thread_desc",
     95                        "__thrd",
     96                        "get_thread",
     97                        "thread keyword requires threads to be in scope, add #include <thread>"
     98                )
     99                {}
     100
     101                virtual ~ThreadKeyword() {}
     102
     103                virtual bool is_target( StructDecl * decl ) override final { return decl->is_thread(); }
     104
     105                static void implement( std::list< Declaration * > & translationUnit ) {
     106                        ThreadKeyword impl;
     107                        SymTab::acceptAndAdd( translationUnit, impl );
     108                }
    55109        };
    56110
     
    63117        // };                                        };
    64118        //                                           static inline coroutine_desc * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
    65         //                                           void main( MyCoroutine * this );
    66119        //
    67         class CoroutineKeyword final : public Visitor {
    68             template< typename Visitor >
    69             friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
     120        class CoroutineKeyword final : public ConcurrentSueKeyword {
    70121          public:
    71122
    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 * );
     123                CoroutineKeyword() : ConcurrentSueKeyword(
     124                        "coroutine_desc",
     125                        "__cor",
     126                        "get_coroutine",
     127                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine>"
     128                )
     129                {}
     130
     131                virtual ~CoroutineKeyword() {}
     132
     133                virtual bool is_target( StructDecl * decl ) override final { return decl->is_coroutine(); }
    78134
    79135                static void implement( std::list< Declaration * > & translationUnit ) {
     
    81137                        SymTab::acceptAndAdd( translationUnit, impl );
    82138                }
    83 
    84           private:
    85                 std::list< Declaration * > declsToAdd, declsToAddAfter;
    86                 StructDecl* coroutine_decl = nullptr;
    87139        };
    88140
     
    95147        // };                                        };
    96148        //                                           static inline monitor_desc * get_coroutine( MyMonitor * this ) { return &this->__cor_d; }
    97         //                                           void main( MyMonitor * this );
    98149        //
    99         class MonitorKeyword final : public Mutator {
     150        class MonitorKeyword final : public ConcurrentSueKeyword {
    100151          public:
    101152
    102                 static void implement( std::list< Declaration * > & translationUnit ) {}
     153                MonitorKeyword() : ConcurrentSueKeyword(
     154                        "monitor_desc",
     155                        "__mon",
     156                        "get_monitor",
     157                        "monitor keyword requires monitors to be in scope, add #include <monitor>"
     158                )
     159                {}
     160
     161                virtual ~MonitorKeyword() {}
     162
     163                virtual bool is_target( StructDecl * decl ) override final { return decl->is_monitor(); }
     164
     165                static void implement( std::list< Declaration * > & translationUnit ) {
     166                        MonitorKeyword impl;
     167                        SymTab::acceptAndAdd( translationUnit, impl );
     168                }
    103169        };
    104170
     
    139205                CoroutineKeyword        ::implement( translationUnit );
    140206                MonitorKeyword  ::implement( translationUnit );
     207        }
     208
     209        void implementMutexFuncs( std::list< Declaration * > & translationUnit ) {
    141210                MutexKeyword    ::implement( translationUnit );
    142211        }
    143212
    144         //=============================================================================================
    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() ) {
     213        void implementThreadStarter( std::list< Declaration * > & translationUnit ) {
     214
     215        }
     216
     217        //=============================================================================================
     218        // Generic keyword implementation
     219        //=============================================================================================
     220        void ConcurrentSueKeyword::visit(StructDecl * decl) {
     221                if( decl->get_name() == type_name ) {
     222                        assert( !type_decl );
     223                        type_decl = decl;
     224                }
     225                else if ( is_target(decl) ) {
    153226                        handle( decl );
    154227                }
     
    156229        }
    157230
    158         void CoroutineKeyword::handle( StructDecl * decl ) {
     231        void ConcurrentSueKeyword::handle( StructDecl * decl ) {
    159232                if( ! decl->has_body() ) return;
    160233
    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",
     234                if( !type_decl ) throw SemanticError( context_error, decl );
     235
     236                FunctionDecl * func = forwardDeclare( decl );
     237                ObjectDecl * field = addField( decl );
     238                addRoutines( decl, field, func );
     239        }
     240
     241        FunctionDecl * ConcurrentSueKeyword::forwardDeclare( StructDecl * decl ) {
     242
     243                StructDecl * forward = decl->clone();
     244                forward->set_body( false );
     245                deleteAll( forward->get_members() );
     246                forward->get_members().clear();
     247
     248                FunctionType * type = new FunctionType( noQualifiers, false );
     249                ObjectDecl * this_decl = new ObjectDecl(
     250                        "this",
    170251                        noStorage,
    171252                        LinkageSpec::Cforall,
    172253                        nullptr,
    173                         new StructInstType(
     254                        new PointerType(
    174255                                noQualifiers,
    175                                 coroutine_decl
     256                                new StructInstType(
     257                                        noQualifiers,
     258                                        decl
     259                                )
    176260                        ),
    177261                        nullptr
    178262                );
    179263
    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                 );
     264                type->get_parameters().push_back( this_decl );
    203265                type->get_returnVals().push_back(
    204266                        new ObjectDecl(
     
    211273                                        new StructInstType(
    212274                                                noQualifiers,
    213                                                 coroutine_decl
     275                                                type_decl
    214276                                        )
    215277                                ),
     
    218280                );
    219281
     282                FunctionDecl * get_decl = new FunctionDecl(
     283                        getter_name,
     284                        Type::Static,
     285                        LinkageSpec::Cforall,
     286                        type,
     287                        nullptr,
     288                        noAttributes,
     289                        Type::Inline
     290                );
     291
     292                declsToAdd.push_back( forward );
     293                declsToAdd.push_back( get_decl );
     294
     295                return get_decl;
     296        }
     297
     298        ObjectDecl * ConcurrentSueKeyword::addField( StructDecl * decl ) {
     299                ObjectDecl * field = new ObjectDecl(
     300                        field_name,
     301                        noStorage,
     302                        LinkageSpec::Cforall,
     303                        nullptr,
     304                        new StructInstType(
     305                                noQualifiers,
     306                                type_decl
     307                        ),
     308                        nullptr
     309                );
     310
     311                decl->get_members().push_back( field );
     312
     313                return field;
     314        }
     315
     316        void ConcurrentSueKeyword::addRoutines( StructDecl * decl, ObjectDecl * field, FunctionDecl * func ) {
    220317                CompoundStmt * statement = new CompoundStmt( noLabels );
    221318                statement->push_back(
     
    223320                                noLabels,
    224321                                new AddressExpr(
    225                                         new UntypedMemberExpr(
    226                                                 new NameExpr( "__cor" ),
    227                                                 new UntypedExpr(
    228                                                         new NameExpr( "*?" ),
    229                                                         { new NameExpr( "this" ) }
    230                                                 )
     322                                        new MemberExpr(
     323                                                field,
     324                                                UntypedExpr::createDeref( new VariableExpr( func->get_functionType()->get_parameters().front() ) )
    231325                                        )
    232326                                )
     
    234328                );
    235329
    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                 );
     330                FunctionDecl * get_decl = func->clone();
     331
     332                get_decl->set_statements( statement );
    245333
    246334                declsToAddAfter.push_back( get_decl );
    247335
    248                 get_decl->fixUniqueId();
    249         }
    250        
     336                // get_decl->fixUniqueId();
     337        }
    251338
    252339        //=============================================================================================
  • src/Concurrency/Keywords.h

    r578b637 rbcda04c  
    2424namespace Concurrency {
    2525        void applyKeywords( std::list< Declaration * > & translationUnit );
     26        void implementMutexFuncs( std::list< Declaration * > & translationUnit );
     27        void implementThreadStarter( std::list< Declaration * > & translationUnit );
    2628};
    2729
  • src/Parser/lex.ll

    r578b637 rbcda04c  
    236236long                    { KEYWORD_RETURN(LONG); }
    237237lvalue                  { KEYWORD_RETURN(LVALUE); }                             // CFA
    238 _Monitor                { KEYWORD_RETURN(MONITOR); }                    // CFA
     238monitor         { KEYWORD_RETURN(MONITOR); }                    // CFA
    239239mutex                   { KEYWORD_RETURN(MUTEX); }                              // CFA
    240240_Noreturn               { KEYWORD_RETURN(NORETURN); }                   // C11
  • src/SymTab/Autogen.cc

    r578b637 rbcda04c  
    218218
    219219                /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map.
    220                 void gen( const FuncData & data ) {
     220                void gen( const FuncData & data, bool concurrent_type ) {
    221221                        if ( ! shouldGenerate( data.map, aggregateDecl ) ) return;
    222222                        FunctionType * ftype = data.genType( refType );
     223
     224                        if(concurrent_type && InitTweak::isDestructor( data.fname )) {
     225                                ftype->get_parameters().front()->get_type()->set_mutex( true );
     226                        }
     227
    223228                        cloneAll( typeParams, ftype->get_forall() );
    224229                        *out++ = genFunc( data.fname, ftype, functionNesting );
     
    403408                auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) );
    404409                for ( const FuncData & d : data ) {
    405                         generator.gen( d );
    406                 }
     410                        generator.gen( d, aggregateDecl->is_thread() || aggregateDecl->is_monitor() );
     411                }
     412
    407413                // field ctors are only generated if default constructor and copy constructor are both generated
    408414                unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );
  • src/SymTab/Validate.cc

    r578b637 rbcda04c  
    4343#include "Common/utility.h"
    4444#include "Common/UniqueName.h"
     45#include "Concurrency/Keywords.h"
    4546#include "Validate.h"
    4647#include "SynTree/Visitor.h"
     
    225226                ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    226227                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
     228                Concurrency::applyKeywords( translationUnit );
    227229                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
     230                Concurrency::implementMutexFuncs( translationUnit );
     231                Concurrency::implementThreadStarter( translationUnit );
    228232                acceptAll( translationUnit, epc );
    229233                ReturnChecker::checkFunctionReturns( translationUnit );
  • src/main.cc

    r578b637 rbcda04c  
    216216                } // if
    217217
     218                // OPTPRINT( "Concurrency" )
     219                // Concurrency::applyKeywords( translationUnit );
     220
    218221                // add the assignment statement after the initialization of a type parameter
    219222                OPTPRINT( "validate" )
     
    237240                OPTPRINT( "mutate" )
    238241                ControlStruct::mutate( translationUnit );
    239                 OPTPRINT( "Concurrency" )
    240                 Concurrency::applyKeywords( translationUnit );
    241242                OPTPRINT( "fixNames" )
    242243                CodeGen::fixNames( translationUnit );
  • src/tests/monitor.c

    r578b637 rbcda04c  
    44#include <thread>
    55
    6 struct global_t {
     6monitor global_t {
    77        int value;
    8         monitor_desc m;
    98};
    109
    1110void ?{}(global_t * this) {
    1211        this->value = 0;
    13 }
    14 
    15 monitor_desc * get_monitor( global_t * this ) {
    16         return &this->m;
    1712}
    1813
     
    4540
    4641int main(int argc, char* argv[]) {
    47         assert( global.m.entry_queue.tail != NULL );
     42        assert( global.__mon.entry_queue.tail != NULL );
    4843        processor p;
    4944        {
  • src/tests/multi-monitor.c

    r578b637 rbcda04c  
    66static int global12, global23, global13;
    77
    8 struct monitor_t {
    9         monitor_desc m;
    10 };
    11 
    12 monitor_desc * get_monitor( monitor_t * this ) {
    13         return &this->m;
    14 }
     8monitor monitor_t {};
    159
    1610static monitor_t m1, m2, m3;
Note: See TracChangeset for help on using the changeset viewer.