Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Concurrency/Keywords.cc

    r43cedfb1 r09f357ec  
    1616#include "Concurrency/Keywords.h"
    1717
    18 #include <cassert>                        // for assert
    19 #include <string>                         // for string, operator==
    20 
    21 #include <iostream>
    22 
    23 #include "Common/Examine.h"               // for isMainFor
    24 #include "Common/PassVisitor.h"           // for PassVisitor
    25 #include "Common/SemanticError.h"         // for SemanticError
    26 #include "Common/utility.h"               // for deleteAll, map_range
    27 #include "CodeGen/OperatorTable.h"        // for isConstructor
    28 #include "ControlStruct/LabelGenerator.h" // for LebelGenerator
    29 #include "InitTweak/InitTweak.h"          // for getPointerBase
    30 #include "SynTree/LinkageSpec.h"          // for Cforall
    31 #include "SynTree/Constant.h"             // for Constant
    32 #include "SynTree/Declaration.h"          // for StructDecl, FunctionDecl, ObjectDecl
    33 #include "SynTree/Expression.h"           // for VariableExpr, ConstantExpr, Untype...
    34 #include "SynTree/Initializer.h"          // for SingleInit, ListInit, Initializer ...
    35 #include "SynTree/Label.h"                // for Label
    36 #include "SynTree/Statement.h"            // for CompoundStmt, DeclStmt, ExprStmt
    37 #include "SynTree/Type.h"                 // for StructInstType, Type, PointerType
    38 #include "SynTree/Visitor.h"              // for Visitor, acceptAll
    39 #include "Virtual/Tables.h"
     18#include <cassert>                 // for assert
     19#include <string>                  // for string, operator==
     20
     21#include "Common/PassVisitor.h"    // for PassVisitor
     22#include "Common/SemanticError.h"  // for SemanticError
     23#include "Common/utility.h"        // for deleteAll, map_range
     24#include "CodeGen/OperatorTable.h" // for isConstructor
     25#include "InitTweak/InitTweak.h"   // for getPointerBase
     26#include "SynTree/LinkageSpec.h"   // for Cforall
     27#include "SynTree/Constant.h"      // for Constant
     28#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
     29#include "SynTree/Expression.h"    // for VariableExpr, ConstantExpr, Untype...
     30#include "SynTree/Initializer.h"   // for SingleInit, ListInit, Initializer ...
     31#include "SynTree/Label.h"         // for Label
     32#include "SynTree/Statement.h"     // for CompoundStmt, DeclStmt, ExprStmt
     33#include "SynTree/Type.h"          // for StructInstType, Type, PointerType
     34#include "SynTree/Visitor.h"       // for Visitor, acceptAll
    4035
    4136class Attribute;
    4237
    4338namespace 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 
    48         // Only detects threads constructed with the keyword thread.
    49         inline static bool isThread( DeclarationWithType * decl ) {
    50                 Type * baseType = decl->get_type()->stripDeclarator();
    51                 StructInstType * instType = dynamic_cast<StructInstType *>( baseType );
    52                 if ( nullptr == instType ) { return false; }
    53                 return instType->baseStruct->is_thread();
    54         }
    55 
    5639        //=============================================================================================
    5740        // Pass declarations
     
    7053          public:
    7154
    72                 ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name,
    73                         std::string&& getter_name, std::string&& context_error, std::string&& exception_name,
    74                         bool needs_main, AggregateDecl::Aggregate cast_target ) :
    75                   type_name( type_name ), field_name( field_name ), getter_name( getter_name ),
    76                   context_error( context_error ), exception_name( exception_name ),
    77                   vtable_name( getVTableName( exception_name ) ),
    78                   needs_main( needs_main ), cast_target( cast_target ) {}
     55                ConcurrentSueKeyword( std::string&& type_name, std::string&& field_name, std::string&& getter_name, std::string&& context_error, bool needs_main, AggregateDecl::Aggregate 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 ) {}
    7957
    8058                virtual ~ConcurrentSueKeyword() {}
     
    8462
    8563                void handle( StructDecl * );
    86                 void addVtableForward( StructDecl * );
    8764                FunctionDecl * forwardDeclare( StructDecl * );
    8865                ObjectDecl * addField( StructDecl * );
     
    9875                const std::string getter_name;
    9976                const std::string context_error;
    100                 const std::string exception_name;
    101                 const std::string vtable_name;
    10277                bool needs_main;
    10378                AggregateDecl::Aggregate cast_target;
     
    10580                StructDecl   * type_decl = nullptr;
    10681                FunctionDecl * dtor_decl = nullptr;
    107                 StructDecl * except_decl = nullptr;
    108                 StructDecl * vtable_decl = nullptr;
    10982        };
    11083
     
    11588        //      int data;                                  int data;
    11689        //      a_struct_t more_data;                      a_struct_t more_data;
    117         //                                =>             $thread __thrd_d;
     90        //                                =>             thread_desc __thrd_d;
    11891        // };                                        };
    119         //                                           static inline $thread * get_thread( MyThread * this ) { return &this->__thrd_d; }
     92        //                                           static inline thread_desc * get_thread( MyThread * this ) { return &this->__thrd_d; }
    12093        //
    12194        class ThreadKeyword final : public ConcurrentSueKeyword {
     
    12396
    12497                ThreadKeyword() : ConcurrentSueKeyword(
    125                         "$thread",
     98                        "thread_desc",
    12699                        "__thrd",
    127100                        "get_thread",
    128101                        "thread keyword requires threads to be in scope, add #include <thread.hfa>\n",
    129                         "ThreadCancelled",
    130102                        true,
    131103                        AggregateDecl::Thread
     
    148120        //      int data;                                  int data;
    149121        //      a_struct_t more_data;                      a_struct_t more_data;
    150         //                                =>             $coroutine __cor_d;
     122        //                                =>             coroutine_desc __cor_d;
    151123        // };                                        };
    152         //                                           static inline $coroutine * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
     124        //                                           static inline coroutine_desc * get_coroutine( MyCoroutine * this ) { return &this->__cor_d; }
    153125        //
    154126        class CoroutineKeyword final : public ConcurrentSueKeyword {
     
    156128
    157129                CoroutineKeyword() : ConcurrentSueKeyword(
    158                         "$coroutine",
     130                        "coroutine_desc",
    159131                        "__cor",
    160132                        "get_coroutine",
    161133                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>\n",
    162                         "CoroutineCancelled",
    163134                        true,
    164135                        AggregateDecl::Coroutine
     
    175146                }
    176147        };
    177 
    178 
    179148
    180149        //-----------------------------------------------------------------------------
     
    183152        //      int data;                                  int data;
    184153        //      a_struct_t more_data;                      a_struct_t more_data;
    185         //                                =>             $monitor __mon_d;
     154        //                                =>             monitor_desc __mon_d;
    186155        // };                                        };
    187         //                                           static inline $monitor * get_coroutine( MyMonitor * this ) { return &this->__cor_d; }
     156        //                                           static inline monitor_desc * get_coroutine( MyMonitor * this ) { return &this->__cor_d; }
    188157        //
    189158        class MonitorKeyword final : public ConcurrentSueKeyword {
     
    191160
    192161                MonitorKeyword() : ConcurrentSueKeyword(
    193                         "$monitor",
     162                        "monitor_desc",
    194163                        "__mon",
    195164                        "get_monitor",
    196165                        "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>\n",
    197                         "",
    198166                        false,
    199167                        AggregateDecl::Monitor
     
    212180
    213181        //-----------------------------------------------------------------------------
    214         //Handles generator type declarations :
    215         // generator MyGenerator {                   struct MyGenerator {
    216         //      int data;                                  int data;
    217         //      a_struct_t more_data;                      a_struct_t more_data;
    218         //                                =>             int __gen_next;
    219         // };                                        };
    220         //
    221         class GeneratorKeyword final : public ConcurrentSueKeyword {
    222           public:
    223 
    224                 GeneratorKeyword() : ConcurrentSueKeyword(
    225                         "$generator",
    226                         "__generator_state",
    227                         "get_generator",
    228                         "Unable to find builtin type $generator\n",
    229                         "",
    230                         true,
    231                         AggregateDecl::Generator
    232                 )
    233                 {}
    234 
    235                 virtual ~GeneratorKeyword() {}
    236 
    237                 virtual bool is_target( StructDecl * decl ) override final { return decl->is_generator(); }
    238 
    239                 static void implement( std::list< Declaration * > & translationUnit ) {
    240                         PassVisitor< GeneratorKeyword > impl;
    241                         mutateAll( translationUnit, impl );
    242                 }
    243         };
    244 
    245 
    246         //-----------------------------------------------------------------------------
    247         class SuspendKeyword final : public WithStmtsToAdd, public WithGuards {
    248         public:
    249                 SuspendKeyword() = default;
    250                 virtual ~SuspendKeyword() = default;
    251 
    252                 void  premutate( FunctionDecl * );
    253                 DeclarationWithType * postmutate( FunctionDecl * );
    254 
    255                 Statement * postmutate( SuspendStmt * );
    256 
    257                 static void implement( std::list< Declaration * > & translationUnit ) {
    258                         PassVisitor< SuspendKeyword > impl;
    259                         mutateAll( translationUnit, impl );
    260                 }
    261 
    262         private:
    263                 bool is_real_suspend( FunctionDecl * );
    264 
    265                 Statement * make_generator_suspend( SuspendStmt * );
    266                 Statement * make_coroutine_suspend( SuspendStmt * );
    267 
    268                 struct LabelPair {
    269                         Label obj;
    270                         int   idx;
    271                 };
    272 
    273                 LabelPair make_label() {
    274                         labels.push_back( gen.newLabel("generator") );
    275                         return { labels.back(), int(labels.size()) };
    276                 }
    277 
    278                 DeclarationWithType * in_generator = nullptr;
    279                 FunctionDecl * decl_suspend = nullptr;
    280                 std::vector<Label> labels;
    281                 ControlStruct::LabelGenerator & gen = *ControlStruct::LabelGenerator::getGenerator();
    282         };
    283 
    284         //-----------------------------------------------------------------------------
    285182        //Handles mutex routines definitions :
    286183        // void foo( A * mutex a, B * mutex b,  int i ) {                  void foo( A * a, B * b,  int i ) {
    287         //                                                                       $monitor * __monitors[] = { get_monitor(a), get_monitor(b) };
     184        //                                                                       monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
    288185        //                                                                       monitor_guard_t __guard = { __monitors, 2 };
    289186        //    /*Some code*/                                       =>           /*Some code*/
     
    298195                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl*, bool & first );
    299196                void validate( DeclarationWithType * );
    300                 void addDtorStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    301                 void addStatements( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    302                 void addThreadDtorStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args );
     197                void addDtorStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
     198                void addStatments( FunctionDecl* func, CompoundStmt *, const std::list<DeclarationWithType * > &);
    303199
    304200                static void implement( std::list< Declaration * > & translationUnit ) {
     
    311207                StructDecl* guard_decl = nullptr;
    312208                StructDecl* dtor_guard_decl = nullptr;
    313                 StructDecl* thread_guard_decl = nullptr;
    314209
    315210                static std::unique_ptr< Type > generic_func;
     
    326221        //Handles mutex routines definitions :
    327222        // void foo( A * mutex a, B * mutex b,  int i ) {                  void foo( A * a, B * b,  int i ) {
    328         //                                                                       $monitor * __monitors[] = { get_monitor(a), get_monitor(b) };
     223        //                                                                       monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
    329224        //                                                                       monitor_guard_t __guard = { __monitors, 2 };
    330225        //    /*Some code*/                                       =>           /*Some code*/
     
    356251                CoroutineKeyword        ::implement( translationUnit );
    357252                MonitorKeyword  ::implement( translationUnit );
    358                 GeneratorKeyword  ::implement( translationUnit );
    359                 SuspendKeyword    ::implement( translationUnit );
    360253        }
    361254
     
    390283                        handle( decl );
    391284                }
    392                 else if ( !except_decl && exception_name == decl->name && decl->body ) {
    393                         except_decl = decl;
    394                 }
    395                 else if ( !vtable_decl && vtable_name == decl->name && decl->body ) {
    396                         vtable_decl = decl;
    397                 }
    398                 // Might be able to get ride of is target.
    399                 assert( is_target(decl) == (cast_target == decl->kind) );
    400285                return decl;
    401286        }
    402287
    403288        DeclarationWithType * ConcurrentSueKeyword::postmutate( FunctionDecl * decl ) {
    404                 if ( type_decl && isDestructorFor( decl, type_decl ) )
    405                         dtor_decl = decl;
    406                 else if ( vtable_name.empty() )
    407                         ;
    408                 else if( !decl->has_body() )
    409                         ;
    410                 else if ( auto param = isMainFor( decl, cast_target ) ) {
    411                         // This should never trigger.
    412                         assert( vtable_decl );
    413                         // Should be safe because of isMainFor.
    414                         StructInstType * struct_type = static_cast<StructInstType *>(
    415                                 static_cast<ReferenceType *>( param->get_type() )->base );
    416                         assert( struct_type );
    417 
    418                         std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) };
    419                         ObjectDecl * vtable_object = Virtual::makeVtableInstance(
    420                                 vtable_decl->makeInst( poly_args ), struct_type, nullptr );
    421                         declsToAddAfter.push_back( vtable_object );
    422                         declsToAddAfter.push_back( Virtual::makeGetExceptionFunction(
    423                                 vtable_object, except_decl->makeInst( std::move( poly_args ) )
    424                         ) );
    425                 }
    426 
     289                if( !type_decl ) return decl;
     290                if( !CodeGen::isDestructor( decl->name ) ) return decl;
     291
     292                auto params = decl->type->parameters;
     293                if( params.size() != 1 ) return decl;
     294
     295                auto type = dynamic_cast<ReferenceType*>( params.front()->get_type() );
     296                if( !type ) return decl;
     297
     298                auto stype = dynamic_cast<StructInstType*>( type->base );
     299                if( !stype ) return decl;
     300                if( stype->baseStruct != type_decl ) return decl;
     301
     302                if( !dtor_decl ) dtor_decl = decl;
    427303                return decl;
    428304        }
     
    430306        Expression * ConcurrentSueKeyword::postmutate( KeywordCastExpr * cast ) {
    431307                if ( cast_target == cast->target ) {
    432                         // convert (thread &)t to ($thread &)*get_thread(t), etc.
     308                        // convert (thread &)t to (thread_desc &)*get_thread(t), etc.
    433309                        if( !type_decl ) SemanticError( cast, context_error );
    434310                        if( !dtor_decl ) SemanticError( cast, context_error );
     
    448324                if( !dtor_decl ) SemanticError( decl, context_error );
    449325
    450                 addVtableForward( decl );
    451326                FunctionDecl * func = forwardDeclare( decl );
    452327                ObjectDecl * field = addField( decl );
    453328                addRoutines( field, func );
    454         }
    455 
    456         void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) {
    457                 if ( vtable_decl ) {
    458                         std::list< Expression * > poly_args = {
    459                                 new TypeExpr( new StructInstType( noQualifiers, decl ) ),
    460                         };
    461                         declsToAddBefore.push_back( Virtual::makeGetExceptionForward(
    462                                 vtable_decl->makeInst( poly_args ),
    463                                 except_decl->makeInst( poly_args )
    464                         ) );
    465                         declsToAddBefore.push_back( Virtual::makeVtableForward(
    466                                 vtable_decl->makeInst( move( poly_args ) ) ) );
    467                 // Its only an error if we want a vtable and don't have one.
    468                 } else if ( ! vtable_name.empty() ) {
    469                         SemanticError( decl, context_error );
    470                 }
    471329        }
    472330
     
    519377                        get_type,
    520378                        nullptr,
    521                         { new Attribute("const") },
     379                        noAttributes,
    522380                        Type::Inline
    523381                );
     
    576434                                                new CastExpr(
    577435                                                        new VariableExpr( func->get_functionType()->get_parameters().front() ),
    578                                                         func->get_functionType()->get_parameters().front()->get_type()->stripReferences()->clone(),
    579                                                         false
     436                                                        func->get_functionType()->get_parameters().front()->get_type()->stripReferences()->clone()
    580437                                                )
    581438                                        )
     
    589446
    590447                declsToAddAfter.push_back( get_decl );
    591         }
    592 
    593         //=============================================================================================
    594         // Suspend keyword implementation
    595         //=============================================================================================
    596         bool SuspendKeyword::is_real_suspend( FunctionDecl * func ) {
    597                 if(isMangled(func->linkage)) return false; // the real suspend isn't mangled
    598                 if(func->name != "__cfactx_suspend") return false; // the real suspend has a specific name
    599                 if(func->type->parameters.size() != 0) return false; // Too many parameters
    600                 if(func->type->returnVals.size() != 0) return false; // Too many return values
    601 
    602                 return true;
    603         }
    604 
    605         void SuspendKeyword::premutate( FunctionDecl * func ) {
    606                 GuardValue(in_generator);
    607                 in_generator = nullptr;
    608 
    609                 // Is this the real suspend?
    610                 if(is_real_suspend(func)) {
    611                         decl_suspend = decl_suspend ? decl_suspend : func;
    612                         return;
    613                 }
    614 
    615                 // Is this the main of a generator?
    616                 auto param = isMainFor( func, AggregateDecl::Aggregate::Generator );
    617                 if(!param) return;
    618 
    619                 if(func->type->returnVals.size() != 0) SemanticError(func->location, "Generator main must return void");
    620 
    621                 in_generator = param;
    622                 GuardValue(labels);
    623                 labels.clear();
    624         }
    625 
    626         DeclarationWithType * SuspendKeyword::postmutate( FunctionDecl * func ) {
    627                 if( !func->statements ) return func; // Not the actual definition, don't do anything
    628                 if( !in_generator     ) return func; // Not in a generator, don't do anything
    629                 if( labels.empty()    ) return func; // Generator has no states, nothing to do, could throw a warning
    630 
    631                 // This is a generator main, we need to add the following code to the top
    632                 // static void * __generator_labels[] = {&&s0, &&s1, ...};
    633                 // goto * __generator_labels[gen.__generator_state];
    634                 const auto & loc = func->location;
    635 
    636                 const auto first_label = gen.newLabel("generator");
    637 
    638                 // for each label add to declaration
    639                 std::list<Initializer*> inits = { new SingleInit( new LabelAddressExpr( first_label ) ) };
    640                 for(const auto & label : labels) {
    641                         inits.push_back(
    642                                 new SingleInit(
    643                                         new LabelAddressExpr( label )
    644                                 )
    645                         );
    646                 }
    647                 auto init = new ListInit(std::move(inits), noDesignators, true);
    648                 labels.clear();
    649 
    650                 // create decl
    651                 auto decl = new ObjectDecl(
    652                         "__generator_labels",
    653                         Type::StorageClasses( Type::Static ),
    654                         LinkageSpec::AutoGen,
    655                         nullptr,
    656                         new ArrayType(
    657                                 Type::Qualifiers(),
    658                                 new PointerType(
    659                                         Type::Qualifiers(),
    660                                         new VoidType( Type::Qualifiers() )
    661                                 ),
    662                                 nullptr,
    663                                 false, false
    664                         ),
    665                         init
    666                 );
    667 
    668                 // create the goto
    669                 assert(in_generator);
    670 
    671                 auto go_decl = new ObjectDecl(
    672                         "__generator_label",
    673                         noStorageClasses,
    674                         LinkageSpec::AutoGen,
    675                         nullptr,
    676                         new PointerType(
    677                                 Type::Qualifiers(),
    678                                 new VoidType( Type::Qualifiers() )
    679                         ),
    680                         new SingleInit(
    681                                 new UntypedExpr(
    682                                         new NameExpr("?[?]"),
    683                                         {
    684                                                 new NameExpr("__generator_labels"),
    685                                                 new UntypedMemberExpr(
    686                                                         new NameExpr("__generator_state"),
    687                                                         new VariableExpr( in_generator )
    688                                                 )
    689                                         }
    690                                 )
    691                         )
    692                 );
    693                 go_decl->location = loc;
    694 
    695                 auto go = new BranchStmt(
    696                         new VariableExpr( go_decl ),
    697                         BranchStmt::Goto
    698                 );
    699                 go->location = loc;
    700                 go->computedTarget->location = loc;
    701 
    702                 auto noop = new NullStmt({ first_label });
    703                 noop->location = loc;
    704 
    705                 // wrap everything in a nice compound
    706                 auto body = new CompoundStmt({
    707                         new DeclStmt( decl ),
    708                         new DeclStmt( go_decl ),
    709                         go,
    710                         noop,
    711                         func->statements
    712                 });
    713                 body->location   = loc;
    714                 func->statements = body;
    715 
    716                 return func;
    717         }
    718 
    719         Statement * SuspendKeyword::postmutate( SuspendStmt * stmt ) {
    720                 SuspendStmt::Type type = stmt->type;
    721                 if(type == SuspendStmt::None) {
    722                         // This suspend has a implicit target, find it
    723                         type = in_generator ? SuspendStmt::Generator : SuspendStmt::Coroutine;
    724                 }
    725 
    726                 // Check that the target makes sense
    727                 if(!in_generator && type == SuspendStmt::Generator) SemanticError( stmt->location, "'suspend generator' must be used inside main of generator type.");
    728 
    729                 // Act appropriately
    730                 switch(type) {
    731                         case SuspendStmt::Generator: return make_generator_suspend(stmt);
    732                         case SuspendStmt::Coroutine: return make_coroutine_suspend(stmt);
    733                         default: abort();
    734                 }
    735         }
    736 
    737         Statement * SuspendKeyword::make_generator_suspend( SuspendStmt * stmt ) {
    738                 assert(in_generator);
    739                 // Target code is :
    740                 //   gen.__generator_state = X;
    741                 //   { THEN }
    742                 //   return;
    743                 //   __gen_X:;
    744 
    745                 // Save the location and delete the old statement, we only need the location from this point on
    746                 auto loc = stmt->location;
    747 
    748                 // Build the label and get its index
    749                 auto label = make_label();
    750 
    751                 // Create the context saving statement
    752                 auto save = new ExprStmt( new UntypedExpr(
    753                         new NameExpr( "?=?" ),
    754                         {
    755                                 new UntypedMemberExpr(
    756                                         new NameExpr("__generator_state"),
    757                                         new VariableExpr( in_generator )
    758                                 ),
    759                                 new ConstantExpr(
    760                                         Constant::from_int( label.idx )
    761                                 )
    762                         }
    763                 ));
    764                 assert(save->expr);
    765                 save->location = loc;
    766                 stmtsToAddBefore.push_back( save );
    767 
    768                 // if we have a then add it here
    769                 auto then = stmt->then;
    770                 stmt->then = nullptr;
    771                 delete stmt;
    772                 if(then) stmtsToAddBefore.push_back( then );
    773 
    774                 // Create the return statement
    775                 auto ret = new ReturnStmt( nullptr );
    776                 ret->location = loc;
    777                 stmtsToAddBefore.push_back( ret );
    778 
    779                 // Create the null statement with the created label
    780                 auto noop = new NullStmt({ label.obj });
    781                 noop->location = loc;
    782 
    783                 // Return the null statement to take the place of the previous statement
    784                 return noop;
    785         }
    786 
    787         Statement * SuspendKeyword::make_coroutine_suspend( SuspendStmt * stmt ) {
    788                 if(stmt->then) SemanticError( stmt->location, "Compound statement following coroutines is not implemented.");
    789 
    790                 // Save the location and delete the old statement, we only need the location from this point on
    791                 auto loc = stmt->location;
    792                 delete stmt;
    793 
    794                 // Create the call expression
    795                 if(!decl_suspend) SemanticError( loc, "suspend keyword applied to coroutines requires coroutines to be in scope, add #include <coroutine.hfa>\n");
    796                 auto expr = new UntypedExpr( VariableExpr::functionPointer( decl_suspend ) );
    797                 expr->location = loc;
    798 
    799                 // Change this statement into a regular expr
    800                 assert(expr);
    801                 auto nstmt = new ExprStmt( expr );
    802                 nstmt->location = loc;
    803                 return nstmt;
    804         }
    805 
     448
     449                // get_decl->fixUniqueId();
     450        }
    806451
    807452        //=============================================================================================
     
    813458                bool first = false;
    814459                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl, first );
    815                 bool const isDtor = CodeGen::isDestructor( decl->name );
     460                bool isDtor = CodeGen::isDestructor( decl->name );
    816461
    817462                // Is this function relevant to monitors
     
    861506
    862507                // Instrument the body
    863                 if ( isDtor && isThread( mutexArgs.front() ) ) {
    864                         if( !thread_guard_decl ) {
    865                                 SemanticError( decl, "thread destructor requires threads to be in scope, add #include <thread.hfa>\n" );
    866                         }
    867                         addThreadDtorStatements( decl, body, mutexArgs );
    868                 }
    869                 else if ( isDtor ) {
    870                         addDtorStatements( decl, body, mutexArgs );
     508                if( isDtor ) {
     509                        addDtorStatments( decl, body, mutexArgs );
    871510                }
    872511                else {
    873                         addStatements( decl, body, mutexArgs );
     512                        addStatments( decl, body, mutexArgs );
    874513                }
    875514        }
     
    877516        void MutexKeyword::postvisit(StructDecl* decl) {
    878517
    879                 if( decl->name == "$monitor" && decl->body ) {
     518                if( decl->name == "monitor_desc" && decl->body ) {
    880519                        assert( !monitor_decl );
    881520                        monitor_decl = decl;
     
    888527                        assert( !dtor_guard_decl );
    889528                        dtor_guard_decl = decl;
    890                 }
    891                 else if( decl->name == "thread_dtor_guard_t" && decl->body ) {
    892                         assert( !thread_guard_decl );
    893                         thread_guard_decl = decl;
    894529                }
    895530        }
     
    930565        }
    931566
    932         void MutexKeyword::addDtorStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     567        void MutexKeyword::addDtorStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
    933568                Type * arg_type = args.front()->get_type()->clone();
    934569                arg_type->set_mutex( false );
     
    948583                        new SingleInit( new UntypedExpr(
    949584                                new NameExpr( "get_monitor" ),
    950                                 {  new CastExpr( new VariableExpr( args.front() ), arg_type, false ) }
     585                                {  new CastExpr( new VariableExpr( args.front() ), arg_type ) }
    951586                        ))
    952587                );
     
    969604                                        {
    970605                                                new SingleInit( new AddressExpr( new VariableExpr( monitors ) ) ),
    971                                                 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) ),
    972                                                 new SingleInit( new ConstantExpr( Constant::from_bool( false ) ) )
     606                                                new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )
    973607                                        },
    974608                                        noDesignators,
     
    978612                );
    979613
    980                 //$monitor * __monitors[] = { get_monitor(a), get_monitor(b) };
    981                 body->push_front( new DeclStmt( monitors ) );
    982         }
    983 
    984         void MutexKeyword::addThreadDtorStatements(
    985                         FunctionDecl*, CompoundStmt * body,
    986                         const std::list<DeclarationWithType * > & args ) {
    987                 assert( args.size() == 1 );
    988                 DeclarationWithType * arg = args.front();
    989                 Type * arg_type = arg->get_type()->clone();
    990                 assert( arg_type->get_mutex() );
    991                 arg_type->set_mutex( false );
    992 
    993                 // thread_dtor_guard_t __guard = { this, intptr( 0 ) };
    994                 body->push_front(
    995                         new DeclStmt( new ObjectDecl(
    996                                 "__guard",
    997                                 noStorageClasses,
    998                                 LinkageSpec::Cforall,
    999                                 nullptr,
    1000                                 new StructInstType(
    1001                                         noQualifiers,
    1002                                         thread_guard_decl
    1003                                 ),
    1004                                 new ListInit(
    1005                                         {
    1006                                                 new SingleInit( new CastExpr( new VariableExpr( arg ), arg_type ) ),
    1007                                                 new SingleInit( new UntypedExpr(
    1008                                                         new NameExpr( "intptr" ), {
    1009                                                                 new ConstantExpr( Constant::from_int( 0 ) ),
    1010                                                         }
    1011                                                 ) ),
    1012                                         },
    1013                                         noDesignators,
    1014                                         true
    1015                                 )
    1016                         ))
    1017                 );
    1018         }
    1019 
    1020         void MutexKeyword::addStatements( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     614                //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     615                body->push_front( new DeclStmt( monitors) );
     616        }
     617
     618        void MutexKeyword::addStatments( FunctionDecl* func, CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
    1021619                ObjectDecl * monitors = new ObjectDecl(
    1022620                        "__monitors",
     
    1043641                                        return new SingleInit( new UntypedExpr(
    1044642                                                new NameExpr( "get_monitor" ),
    1045                                                 {  new CastExpr( new VariableExpr( var ), type, false ) }
     643                                                {  new CastExpr( new VariableExpr( var ), type ) }
    1046644                                        ) );
    1047645                                })
     
    1067665                                                new SingleInit( new VariableExpr( monitors ) ),
    1068666                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ),
    1069                                                 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone(), false ) )
     667                                                new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) )
    1070668                                        },
    1071669                                        noDesignators,
     
    1075673                );
    1076674
    1077                 //$monitor * __monitors[] = { get_monitor(a), get_monitor(b) };
     675                //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
    1078676                body->push_front( new DeclStmt( monitors) );
    1079677        }
     
    1083681        //=============================================================================================
    1084682        void ThreadStarter::previsit( StructDecl * decl ) {
    1085                 if( decl->name == "$thread" && decl->body ) {
     683                if( decl->name == "thread_desc" && decl->body ) {
    1086684                        assert( !thread_decl );
    1087685                        thread_decl = decl;
     
    1129727// tab-width: 4 //
    1130728// End: //
    1131 
Note: See TracChangeset for help on using the changeset viewer.