Changeset a362f97


Ignore:
Timestamp:
Jan 27, 2017, 3:27:34 PM (8 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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:
c0aa336
Parents:
6acb935 (diff), 0a86a30 (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' of plg2:software/cfa/cfa-cc

Files:
5 added
40 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/concurrency/thePlan.md

    r6acb935 ra362f97  
    11_Phase 1_ : Prototype
    2 Threads and Processors.
    3 Main needs to call process
     2done - Threads.
     3done - Main thread is a cfa thread.
     4done - SimpleBlockingLock.
     5done - Synchronisation points in thread destructors.
     6done - Processors & SpinLock.
    47
    58_Phase 2_ : Minimum Viable Product
    6 Main thread is a cfa thread
    7 Basic monitors for synchronisation and minimal lock support.
    8 No internal/external scheduling.
    9 Synchronisation points in thread destructors.
     9Monitor type and enter/leave mutex member routines
     10Monitors as a language feature (not calling enter/leave by hand)
     11Internal scheduling
    1012
    1113_Phase 3_ : Kernel features
    12 Threads features ex: detach
    13 Internal scheduling
    14 Clusters
     14Detach thread
     15Cluster migration
     16Preemption
    1517
    1618_Phase 4_ : Monitor features
  • src/Common/utility.h

    r6acb935 ra362f97  
    252252
    253253template< typename T >
    254 struct reverseIterate_t {
     254struct reverse_iterate_t {
    255255        T& ref;
    256256
    257         reverseIterate_t( T & ref ) : ref(ref) {}
     257        reverse_iterate_t( T & ref ) : ref(ref) {}
    258258
    259259        typedef typename T::reverse_iterator iterator;
     
    263263
    264264template< typename T >
    265 reverseIterate_t< T > reverseIterate( T & ref ) {
    266         return reverseIterate_t< T >( ref );
    267 }
    268 
     265reverse_iterate_t< T > reverseIterate( T & ref ) {
     266        return reverse_iterate_t< T >( ref );
     267}
     268
     269// -----------------------------------------------------------------------------
     270// Helper struct and function to support
     271// for ( val : group_iterate( container1, container2, ... ) ) {}
     272// syntax to have a for each that iterates multiple containers of the same length
     273// TODO: update to use variadic arguments
     274
     275template< typename T1, typename T2 >
     276struct group_iterate_t {
     277        group_iterate_t( const T1 & v1, const T2 & v2 ) : args(v1, v2) {
     278                assertf(v1.size() == v2.size(), "group iteration requires containers of the same size.");
     279        };
     280
     281        struct iterator {
     282                typedef std::tuple<typename T1::value_type, typename T2::value_type> value_type;
     283                typedef typename T1::iterator T1Iter;
     284                typedef typename T2::iterator T2Iter;
     285                typedef std::tuple<T1Iter, T2Iter> IterTuple;
     286                IterTuple it;
     287                iterator( T1Iter i1, T2Iter i2 ) : it( i1, i2 ) {}
     288                iterator operator++() {
     289                        return iterator( ++std::get<0>(it), ++std::get<1>(it) );
     290                }
     291                bool operator!=( const iterator &other ) const { return it != other.it; }
     292                value_type operator*() const { return std::make_tuple( *std::get<0>(it), *std::get<1>(it) ); }
     293        };
     294        iterator begin() { return iterator( std::get<0>(args).begin(), std::get<1>(args).begin() ); }
     295        iterator end() { return iterator( std::get<0>(args).end(), std::get<1>(args).end() ); }
     296
     297private:
     298        std::tuple<T1, T2> args;
     299};
     300
     301template< typename... Args >
     302group_iterate_t<Args...> group_iterate( const Args &... args ) {
     303        return group_iterate_t<Args...>(args...);
     304}
    269305#endif // _UTILITY_H
    270306
  • src/GenPoly/InstantiateGeneric.cc

    r6acb935 ra362f97  
    220220                        assert(paramType && "Aggregate parameters should be type expressions");
    221221
    222                         switch ( (*baseParam)->get_kind() ) {
    223                         case TypeDecl::Any: {
    224                                 // substitute parameter for otype; makes the type concrete or dynamic depending on the parameter
     222                        if ( (*baseParam)->isComplete() ) {
     223                                // substitute parameter for complete (otype or sized dtype) type; makes the struct concrete or dynamic depending on the parameter
    225224                                out.push_back( paramType->clone() );
    226225                                gt |= isPolyType( paramType->get_type() ) ? genericType::dynamic : genericType::concrete;
    227                                 break;
    228                         }
    229                         case TypeDecl::Dtype:
    230                                 // can pretend that any dtype is `void`
    231                                 out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    232                                 break;
    233                         case TypeDecl::Ftype:
    234                                 // can pretend that any ftype is `void (*)(void)`
    235                                 out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    236                                 break;
    237                         case TypeDecl::Ttype:
    238                                 assertf( false, "Ttype parameters are not currently allowed as parameters to generic types." );
    239                                 break;
     226                        } else switch ( (*baseParam)->get_kind() ) {
     227                                case TypeDecl::Dtype:
     228                                        // can pretend that any incomplete dtype is `void`
     229                                        out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     230                                        break;
     231                                case TypeDecl::Ftype:
     232                                        // can pretend that any ftype is `void (*)(void)`
     233                                        out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     234                                        break;
     235                                case TypeDecl::Ttype:
     236                                        assertf( false, "Ttype parameters are not currently allowed as parameters to generic types." );
     237                                        break;
     238                                case TypeDecl::Any:
     239                                        assertf( false, "otype parameters handled by baseParam->isComplete()." );
     240                                        break;
    240241                        }
    241242                }
  • src/GenPoly/Specialize.cc

    r6acb935 ra362f97  
    3535
    3636namespace GenPoly {
    37         class Specializer;
    3837        class Specialize final : public PolyMutator {
    39                 friend class Specializer;
    4038          public:
    4139                using PolyMutator::mutate;
     
    4745                // virtual Expression * mutate( CommaExpr *commaExpr );
    4846
    49                 Specializer * specializer = nullptr;
    5047                void handleExplicitParams( ApplicationExpr *appExpr );
     48                Expression * createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams );
     49                Expression * doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = nullptr );
     50
     51                std::string paramPrefix = "_p";
    5152        };
    5253
    53         class Specializer {
    54           public:
    55                 Specializer( Specialize & spec ) : spec( spec ), env( spec.env ), stmtsToAdd( spec.stmtsToAdd ) {}
    56                 virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) = 0;
    57                 virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) = 0;
    58                 virtual Expression *doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams = 0 );
    59 
    60           protected:
    61                 Specialize & spec;
    62                 std::string paramPrefix = "_p";
    63                 TypeSubstitution *& env;
    64                 std::list< Statement * > & stmtsToAdd;
    65         };
    66 
    67         // for normal polymorphic -> monomorphic function conversion
    68         class PolySpecializer : public Specializer {
    69           public:
    70                 PolySpecializer( Specialize & spec ) : Specializer( spec ) {}
    71                 virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) override;
    72                 virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) override;
    73         };
    74 
    75         // // for tuple -> non-tuple function conversion
    76         class TupleSpecializer : public Specializer {
    77           public:
    78                 TupleSpecializer( Specialize & spec ) : Specializer( spec ) {}
    79                 virtual bool needsSpecialization( Type * formalType, Type * actualType, TypeSubstitution * env ) override;
    80                 virtual Expression *createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) override;
    81         };
    82 
    8354        /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type.
    84         bool PolySpecializer::needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
     55        bool needsPolySpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
    8556                if ( env ) {
    8657                        using namespace ResolvExpr;
     
    10677        }
    10778
    108         /// Generates a thunk that calls `actual` with type `funType` and returns its address
    109         Expression * PolySpecializer::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
    110                 static UniqueName thunkNamer( "_thunk" );
    111 
    112                 FunctionType *newType = funType->clone();
    113                 if ( env ) {
    114                         // it is important to replace only occurrences of type variables that occur free in the
    115                         // thunk's type
    116                         env->applyFree( newType );
    117                 } // if
    118                 // create new thunk with same signature as formal type (C linkage, empty body)
    119                 FunctionDecl *thunkFunc = new FunctionDecl( thunkNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, newType, new CompoundStmt( noLabels ), false, false );
    120                 thunkFunc->fixUniqueId();
    121 
    122                 // thunks may be generated and not used - silence warning with attribute
    123                 thunkFunc->get_attributes().push_back( new Attribute( "unused" ) );
    124 
    125                 // thread thunk parameters into call to actual function, naming thunk parameters as we go
    126                 UniqueName paramNamer( paramPrefix );
    127                 ApplicationExpr *appExpr = new ApplicationExpr( actual );
    128                 for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) {
    129                         (*param )->set_name( paramNamer.newName() );
    130                         appExpr->get_args().push_back( new VariableExpr( *param ) );
    131                 } // for
    132                 appExpr->set_env( maybeClone( env ) );
    133                 if ( inferParams ) {
    134                         appExpr->get_inferParams() = *inferParams;
    135                 } // if
    136 
    137                 // handle any specializations that may still be present
    138                 std::string oldParamPrefix = paramPrefix;
    139                 paramPrefix += "p";
    140                 // save stmtsToAdd in oldStmts
    141                 std::list< Statement* > oldStmts;
    142                 oldStmts.splice( oldStmts.end(), stmtsToAdd );
    143                 spec.handleExplicitParams( appExpr );
    144                 paramPrefix = oldParamPrefix;
    145                 // write any statements added for recursive specializations into the thunk body
    146                 thunkFunc->get_statements()->get_kids().splice( thunkFunc->get_statements()->get_kids().end(), stmtsToAdd );
    147                 // restore oldStmts into stmtsToAdd
    148                 stmtsToAdd.splice( stmtsToAdd.end(), oldStmts );
    149 
    150                 // add return (or valueless expression) to the thunk
    151                 Statement *appStmt;
    152                 if ( funType->get_returnVals().empty() ) {
    153                         appStmt = new ExprStmt( noLabels, appExpr );
    154                 } else {
    155                         appStmt = new ReturnStmt( noLabels, appExpr );
    156                 } // if
    157                 thunkFunc->get_statements()->get_kids().push_back( appStmt );
    158 
    159                 // add thunk definition to queue of statements to add
    160                 stmtsToAdd.push_back( new DeclStmt( noLabels, thunkFunc ) );
    161                 // return address of thunk function as replacement expression
    162                 return new AddressExpr( new VariableExpr( thunkFunc ) );
    163         }
    164 
    165         Expression * Specializer::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
     79        bool needsTupleSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
     80                if ( FunctionType * ftype = getFunctionType( formalType ) ) {
     81                        return ftype->isTtype();
     82                }
     83                return false;
     84        }
     85
     86        bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
     87                return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType, env );
     88        }
     89
     90        Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
    16691                assertf( actual->has_result(), "attempting to specialize an untyped expression" );
    16792                if ( needsSpecialization( formalType, actual->get_result(), env ) ) {
     
    185110        }
    186111
    187         bool TupleSpecializer::needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
    188                 if ( FunctionType * ftype = getFunctionType( formalType ) ) {
    189                         return ftype->isTtype();
    190                 }
    191                 return false;
    192         }
    193 
    194112        /// restructures arg to match the structure of a single formal parameter. Assumes that atomic types are compatible (as the Resolver should have ensured this)
    195113        template< typename OutIterator >
     
    207125
    208126        /// restructures the ttype argument to match the structure of the formal parameters of the actual function.
    209         // [begin, end) are the formal parameters.
    210         // args is the list of arguments currently given to the actual function, the last of which needs to be restructured.
     127        /// [begin, end) are the formal parameters.
     128        /// args is the list of arguments currently given to the actual function, the last of which needs to be restructured.
    211129        template< typename Iterator, typename OutIterator >
    212130        void fixLastArg( Expression * last, Iterator begin, Iterator end, OutIterator out ) {
    213                 // safe_dynamic_cast for the assertion
    214                 safe_dynamic_cast< TupleType * >( last->get_result() );
    215                 unsigned idx = 0;
    216                 for ( ; begin != end; ++begin ) {
    217                         DeclarationWithType * formal = *begin;
    218                         Type * formalType = formal->get_type();
    219                         matchOneFormal( last, idx, formalType, out );
    220                 }
    221                 delete last;
    222         }
    223 
    224         Expression * TupleSpecializer::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
    225                 static UniqueName thunkNamer( "_tupleThunk" );
     131                if ( Tuples::isTtype( last->get_result() ) ) {
     132                        *out++ = last;
     133                } else {
     134                        // safe_dynamic_cast for the assertion
     135                        safe_dynamic_cast< TupleType * >( last->get_result() );
     136                        unsigned idx = 0;
     137                        for ( ; begin != end; ++begin ) {
     138                                DeclarationWithType * formal = *begin;
     139                                Type * formalType = formal->get_type();
     140                                matchOneFormal( last, idx, formalType, out );
     141                        }
     142                        delete last;
     143                }
     144        }
     145
     146        /// Generates a thunk that calls `actual` with type `funType` and returns its address
     147        Expression * Specialize::createThunkFunction( FunctionType *funType, Expression *actual, InferredParams *inferParams ) {
     148                static UniqueName thunkNamer( "_thunk" );
    226149
    227150                FunctionType *newType = funType->clone();
     
    253176                std::list< DeclarationWithType * >::iterator formalEnd = funType->get_parameters().end();
    254177
    255                 Expression * last = nullptr;
    256178                for ( DeclarationWithType* param : thunkFunc->get_functionType()->get_parameters() ) {
    257179                        // walk the parameters to the actual function alongside the parameters to the thunk to find the location where the ttype parameter begins to satisfy parameters in the actual function.
     
    259181                        assertf( formalBegin != formalEnd, "Reached end of formal parameters before finding ttype parameter" );
    260182                        if ( Tuples::isTtype((*formalBegin)->get_type()) ) {
    261                                 last = new VariableExpr( param );
     183                                fixLastArg( new VariableExpr( param ), actualBegin, actualEnd, back_inserter( appExpr->get_args() ) );
    262184                                break;
    263185                        }
     
    268190                        appExpr->get_args().push_back( new VariableExpr( param ) );
    269191                } // for
    270                 assert( last );
    271                 fixLastArg( last, actualBegin, actualEnd, back_inserter( appExpr->get_args() ) );
    272192                appExpr->set_env( maybeClone( env ) );
    273193                if ( inferParams ) {
     
    281201                std::list< Statement* > oldStmts;
    282202                oldStmts.splice( oldStmts.end(), stmtsToAdd );
    283                 spec.mutate( appExpr );
     203                mutate( appExpr );
    284204                paramPrefix = oldParamPrefix;
    285205                // write any statements added for recursive specializations into the thunk body
     
    311231                std::list< Expression* >::iterator actual;
    312232                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    313                         *actual = specializer->doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
     233                        *actual = doSpecialization( (*formal )->get_type(), *actual, &appExpr->get_inferParams() );
    314234                }
    315235        }
     
    322242                        // create thunks for the inferred parameters
    323243                        // don't need to do this for intrinsic calls, because they aren't actually passed
     244                        // need to handle explicit params before inferred params so that explicit params do not recieve a changed set of inferParams (and change them again)
     245                        // alternatively, if order starts to matter then copy appExpr's inferParams and pass them to handleExplicitParams.
     246                        handleExplicitParams( appExpr );
    324247                        for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
    325                                 inferParam->second.expr = specializer->doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get() );
     248                                inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get() );
    326249                        }
    327                         handleExplicitParams( appExpr );
    328250                }
    329251                return appExpr;
     
    333255                addrExpr->get_arg()->acceptMutator( *this );
    334256                assert( addrExpr->has_result() );
    335                 addrExpr->set_arg( specializer->doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
     257                addrExpr->set_arg( doSpecialization( addrExpr->get_result(), addrExpr->get_arg() ) );
    336258                return addrExpr;
    337259        }
     
    343265                        return castExpr;
    344266                }
    345                 Expression *specialized = specializer->doSpecialization( castExpr->get_result(), castExpr->get_arg() );
     267                Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() );
    346268                if ( specialized != castExpr->get_arg() ) {
    347269                        // assume here that the specialization incorporates the cast
     
    370292        void convertSpecializations( std::list< Declaration* >& translationUnit ) {
    371293                Specialize spec;
    372 
    373                 TupleSpecializer tupleSpec( spec );
    374                 spec.specializer = &tupleSpec;
    375                 mutateAll( translationUnit, spec );
    376 
    377                 PolySpecializer polySpec( spec );
    378                 spec.specializer = &polySpec;
    379294                mutateAll( translationUnit, spec );
    380295        }
  • src/InitTweak/FixGlobalInit.cc

    r6acb935 ra362f97  
    8484                        // for library code are run before constructors and destructors for user code,
    8585                        // specify a priority when building the library. Priorities 0-100 are reserved by gcc.
    86                         ctorParameters.push_back( new ConstantExpr( Constant::from_int( 101 ) ) );
    87                         dtorParameters.push_back( new ConstantExpr( Constant::from_int( 101 ) ) );
     86                        ctorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
     87                        dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
    8888                }
    8989                initFunction = new FunctionDecl( "_init_" + fixedName, DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
  • src/InitTweak/FixInit.cc

    r6acb935 ra362f97  
    2121#include <unordered_set>
    2222#include "InitTweak.h"
     23#include "GenInit.h"
    2324#include "FixInit.h"
    2425#include "FixGlobalInit.h"
     
    8687                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
    8788                        Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL );
    88                         Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );
    8989                        /// true if type does not need to be copy constructed to ensure correctness
    9090                        bool skipCopyConstruct( Type * type );
    9191                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr );
    92                         void destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
     92                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    9393
    9494                        TypeSubstitution * env;
     
    398398                Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) {
    399399                        assert( var );
    400                         return makeCtorDtor( fname, new AddressExpr( new VariableExpr( var ) ), cpArg );
    401                 }
    402 
    403                 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg ) {
    404                         assert( thisArg );
    405                         UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) );
    406                         untyped->get_args().push_back( thisArg );
    407                         if (cpArg) untyped->get_args().push_back( cpArg->clone() );
     400                        // arrays are not copy constructed, so this should always be an ExprStmt
     401                        ImplicitCtorDtorStmt * stmt = genCtorDtor( fname, var, cpArg );
     402                        ExprStmt * exprStmt = safe_dynamic_cast< ExprStmt * >( stmt->get_callStmt() );
     403                        Expression * untyped = exprStmt->get_expr();
    408404
    409405                        // resolve copy constructor
     
    420416                        } // if
    421417
    422                         delete untyped;
     418                        delete stmt;
    423419                        return resolved;
    424420                }
     
    456452                }
    457453
    458                 void ResolveCopyCtors::destructRet( Expression * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
    459                         impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( ret ) ) );
     454                void ResolveCopyCtors::destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
     455                        impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    460456                }
    461457
     
    487483                                if ( ! result->get_isLvalue() ) {
    488484                                        // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    489                                         destructRet( new VariableExpr( ret ), impCpCtorExpr );
     485                                        destructRet( ret, impCpCtorExpr );
    490486                                }
    491487                        } // for
     
    515511                                last->set_expr( makeCtorDtor( "?{}", ret, last->get_expr() ) );
    516512
    517                                 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( new VariableExpr( ret ) ) ) );
     513                                stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    518514                        } // if
    519515
  • src/InitTweak/GenInit.cc

    r6acb935 ra362f97  
    247247                        managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) );
    248248                }
     249        }
     250
     251        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
     252                // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
     253                assertf( objDecl, "genCtorDtor passed null objDecl" );
     254                std::list< Statement * > stmts;
     255                InitExpander srcParam( maybeClone( arg ) );
     256                SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), fname, back_inserter( stmts ), objDecl );
     257                assert( stmts.size() <= 1 );
     258                return stmts.size() == 1 ? safe_dynamic_cast< ImplicitCtorDtorStmt * >( stmts.front() ) : nullptr;
    249259        }
    250260
  • src/InitTweak/GenInit.h

    r6acb935 ra362f97  
    2828        void genInit( std::list< Declaration * > & translationUnit );
    2929
     30  /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument
     31  ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr );
     32
    3033        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
    3134        ConstructorInit * genCtorInit( ObjectDecl * objDecl );
  • src/InitTweak/InitTweak.cc

    r6acb935 ra362f97  
    327327                        } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) {
    328328                                return handleDerefCalledFunction( appExpr );
     329                        } else if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) {
     330                                return getCalledFunction( addrExpr->get_arg() );
    329331                        }
    330332                        return nullptr;
     
    336338                if ( ! appExpr ) return NULL;
    337339                DeclarationWithType * function = getCalledFunction( appExpr->get_function() );
    338                 assert( function );
     340                assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() );
    339341                // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
    340342                // will call all member dtors, and some members may have a user defined dtor.
     
    386388                } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) {
    387389                        return callArg( untypedExpr, pos );
     390                } else if ( TupleAssignExpr * tupleExpr = dynamic_cast< TupleAssignExpr * > ( callExpr ) ) {
     391                        std::list< Statement * > & stmts = tupleExpr->get_stmtExpr()->get_statements()->get_kids();
     392                        assertf( ! stmts.empty(), "TupleAssignExpr somehow has no statements." );
     393                        ExprStmt * stmt = safe_dynamic_cast< ExprStmt * >( stmts.back() );
     394                        TupleExpr * tuple = safe_dynamic_cast< TupleExpr * >( stmt->get_expr() );
     395                        assertf( ! tuple->get_exprs().empty(), "TupleAssignExpr somehow has empty tuple expr." );
     396                        return getCallArg( tuple->get_exprs().front(), pos );
    388397                } else {
    389                         assertf( false, "Unexpected expression type passed to getCallArg" );
     398                        assertf( false, "Unexpected expression type passed to getCallArg: %s", toString( callExpr ).c_str() );
    390399                }
    391400        }
     
    538547        }
    539548
     549        FunctionDecl * isAssignment( Declaration * decl ) {
     550                return isCopyFunction( decl, "?=?" );
     551        }
     552        FunctionDecl * isDestructor( Declaration * decl ) {
     553                if ( isDestructor( decl->get_name() ) ) {
     554                        return dynamic_cast< FunctionDecl * >( decl );
     555                }
     556                return nullptr;
     557        }
     558        FunctionDecl * isDefaultConstructor( Declaration * decl ) {
     559                if ( isConstructor( decl->get_name() ) ) {
     560                        if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
     561                                if ( func->get_functionType()->get_parameters().size() == 1 ) {
     562                                        return func;
     563                                }
     564                        }
     565                }
     566                return nullptr;
     567        }
    540568        FunctionDecl * isCopyConstructor( Declaration * decl ) {
    541569                return isCopyFunction( decl, "?{}" );
  • src/InitTweak/InitTweak.h

    r6acb935 ra362f97  
    3232        bool isCtorDtorAssign( const std::string & );
    3333
     34        FunctionDecl * isAssignment( Declaration * decl );
     35        FunctionDecl * isDestructor( Declaration * decl );
     36        FunctionDecl * isDefaultConstructor( Declaration * decl );
    3437        FunctionDecl * isCopyConstructor( Declaration * decl );
    3538        FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname );
  • src/Parser/TypeData.cc

    r6acb935 ra362f97  
    5757                aggregate.actuals = nullptr;
    5858                aggregate.fields = nullptr;
     59                aggregate.body = false;
    5960                break;
    6061          case AggregateInst:
  • src/ResolvExpr/Unify.cc

    r6acb935 ra362f97  
    123123        }
    124124
    125         struct CompleteTypeChecker : public Visitor {
    126                 virtual void visit( VoidType *basicType ) { status = false; }
    127                 virtual void visit( BasicType *basicType ) {}
    128                 virtual void visit( PointerType *pointerType ) {}
    129                 virtual void visit( ArrayType *arrayType ) { status = ! arrayType->get_isVarLen(); }
    130                 virtual void visit( FunctionType *functionType ) {}
    131                 virtual void visit( StructInstType *aggregateUseType ) { status = aggregateUseType->get_baseStruct()->has_body(); }
    132                 virtual void visit( UnionInstType *aggregateUseType ) { status = aggregateUseType->get_baseUnion()->has_body(); }
    133                 // xxx - enum inst does not currently contain a pointer to base, this should be fixed.
    134                 virtual void visit( EnumInstType *aggregateUseType ) { /* status = aggregateUseType->get_baseEnum()->hasBody(); */ }
    135                 virtual void visit( TraitInstType *aggregateUseType ) { assert( false ); }
    136                 virtual void visit( TypeInstType *aggregateUseType ) { status = aggregateUseType->get_baseType()->isComplete(); }
    137                 virtual void visit( TupleType *tupleType ) {} // xxx - not sure if this is right, might need to recursively check complete-ness
    138                 virtual void visit( TypeofType *typeofType ) { assert( false ); }
    139                 virtual void visit( AttrType *attrType ) { assert( false ); } // xxx - not sure what to do here
    140                 virtual void visit( VarArgsType *varArgsType ){} // xxx - is this right?
    141                 virtual void visit( ZeroType *zeroType ) {}
    142                 virtual void visit( OneType *oneType ) {}
    143                 bool status = true;
    144         };
    145         bool isComplete( Type * type ) {
    146                 CompleteTypeChecker checker;
    147                 assert( type );
    148                 type->accept( checker );
    149                 return checker.status;
    150         }
    151 
    152125        bool tyVarCompatible( const TypeDecl::Data & data, Type *type, const SymTab::Indexer &indexer ) {
    153126                switch ( data.kind ) {
     
    158131                        // type must also be complete
    159132                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    160                         return ! isFtype( type, indexer ) && (! data.isComplete || isComplete( type ));
     133                        return ! isFtype( type, indexer ) && (! data.isComplete || type->isComplete() );
    161134                  case TypeDecl::Ftype:
    162135                        return isFtype( type, indexer );
    163136                        case TypeDecl::Ttype:
    164137                        // ttype unifies with any tuple type
    165                         return dynamic_cast< TupleType * >( type );
     138                        return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
    166139                } // switch
    167140                return false;
     
    488461        }
    489462
    490         template< typename Iterator >
    491         std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end ) {
     463        template< typename Iterator, typename Func >
     464        std::unique_ptr<Type> combineTypes( Iterator begin, Iterator end, Func & toType ) {
    492465                std::list< Type * > types;
    493466                for ( ; begin != end; ++begin ) {
    494467                        // it's guaranteed that a ttype variable will be bound to a flat tuple, so ensure that this results in a flat tuple
    495                         flatten( (*begin)->get_type(), back_inserter( types ) );
     468                        flatten( toType( *begin ), back_inserter( types ) );
    496469                }
    497470                return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) );
     
    500473        template< typename Iterator1, typename Iterator2 >
    501474        bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {
     475                auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); };
    502476                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    503477                        Type * t1 = (*list1Begin)->get_type();
     
    509483                        if ( isTtype1 && ! isTtype2 ) {
    510484                                // combine all of the things in list2, then unify
    511                                 return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     485                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    512486                        } else if ( isTtype2 && ! isTtype1 ) {
    513487                                // combine all of the things in list1, then unify
    514                                 return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     488                                return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    515489                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    516490                                return false;
     
    522496                        Type * t1 = (*list1Begin)->get_type();
    523497                        if ( Tuples::isTtype( t1 ) ) {
    524                                 return unifyExact( t1, combineTypes( list2Begin, list2End ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     498                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    525499                        } else return false;
    526500                } else if ( list2Begin != list2End ) {
     
    528502                        Type * t2 = (*list2Begin)->get_type();
    529503                        if ( Tuples::isTtype( t2 ) ) {
    530                                 return unifyExact( combineTypes( list1Begin, list1End ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     504                                return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
    531505                        } else return false;
    532506                } else {
     
    665639        template< typename Iterator1, typename Iterator2 >
    666640        bool unifyList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     641                auto get_type = [](Type * t) { return t; };
    667642                for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) {
    668                         Type *commonType = 0;
    669                         if ( ! unifyInexact( *list1Begin, *list2Begin, env, needAssertions, haveAssertions, openVars, widenMode, indexer, commonType ) ) {
     643                        Type * t1 = *list1Begin;
     644                        Type * t2 = *list2Begin;
     645                        bool isTtype1 = Tuples::isTtype( t1 );
     646                        bool isTtype2 = Tuples::isTtype( t2 );
     647                        // xxx - assumes ttype must be last parameter
     648                        // xxx - there may be a nice way to refactor this, but be careful because the argument positioning might matter in some cases.
     649                        if ( isTtype1 && ! isTtype2 ) {
     650                                // combine all of the things in list2, then unify
     651                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     652                        } else if ( isTtype2 && ! isTtype1 ) {
     653                                // combine all of the things in list1, then unify
     654                                return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     655                        } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) {
    670656                                return false;
    671                         }
    672                         delete commonType;
     657                        } // if
     658
    673659                } // for
    674                 if ( list1Begin != list1End || list2Begin != list2End ) {
    675                         return false;
     660                if ( list1Begin != list1End ) {
     661                        // try unifying empty tuple type with ttype
     662                        Type * t1 = *list1Begin;
     663                        if ( Tuples::isTtype( t1 ) ) {
     664                                return unifyExact( t1, combineTypes( list2Begin, list2End, get_type ).get(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     665                        } else return false;
     666                } else if ( list2Begin != list2End ) {
     667                        // try unifying empty tuple type with ttype
     668                        Type * t2 = *list2Begin;
     669                        if ( Tuples::isTtype( t2 ) ) {
     670                                return unifyExact( combineTypes( list1Begin, list1End, get_type ).get(), t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     671                        } else return false;
    676672                } else {
    677673                        return true;
    678                 } //if
     674                } // if
    679675        }
    680676
    681677        void Unify::visit(TupleType *tupleType) {
    682678                if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
    683                         result = unifyList( tupleType->get_types().begin(), tupleType->get_types().end(), otherTuple->get_types().begin(), otherTuple->get_types().end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     679                        std::unique_ptr<TupleType> flat1( tupleType->clone() );
     680                        std::unique_ptr<TupleType> flat2( otherTuple->clone() );
     681                        std::list<Type *> types1, types2;
     682
     683                        TtypeExpander expander( env );
     684                        flat1->acceptMutator( expander );
     685                        flat2->acceptMutator( expander );
     686
     687                        flatten( flat1.get(), back_inserter( types1 ) );
     688                        flatten( flat2.get(), back_inserter( types2 ) );
     689
     690                        result = unifyList( types1.begin(), types1.end(), types2.begin(), types2.end(), env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    684691                } // if
    685692        }
  • src/SymTab/Autogen.cc

    r6acb935 ra362f97  
    2525#include "Autogen.h"
    2626#include "GenPoly/ScopedSet.h"
     27#include "Common/ScopedMap.h"
    2728#include "SymTab/Mangler.h"
    2829#include "GenPoly/DeclMutator.h"
     
    3031namespace SymTab {
    3132        Type * SizeType = 0;
    32 
    33         class AutogenerateRoutines : public Visitor {
     33        typedef ScopedMap< std::string, bool > TypeMap;
     34
     35        /// Data used to generate functions generically. Specifically, the name of the generated function, a function which generates the routine protoype, and a map which contains data to determine whether a function should be generated.
     36        struct FuncData {
     37                typedef FunctionType * (*TypeGen)( Type * );
     38                FuncData( const std::string & fname, const TypeGen & genType, TypeMap & map ) : fname( fname ), genType( genType ), map( map ) {}
     39                std::string fname;
     40                TypeGen genType;
     41                TypeMap & map;
     42        };
     43
     44        class AutogenerateRoutines final : public Visitor {
    3445          public:
    3546                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     
    3748                typedef Visitor Parent;
    3849                using Parent::visit;
     50
     51                AutogenerateRoutines();
    3952
    4053                virtual void visit( EnumDecl *enumDecl );
     
    5770                std::set< std::string > structsDone;
    5871                unsigned int functionNesting = 0;     // current level of nested functions
     72                /// Note: the following maps could be ScopedSets, but it should be easier to work
     73                /// deleted functions in if they are maps, since the value false can be inserted
     74                /// at the current scope without affecting outer scopes or requiring copies.
     75                TypeMap copyable, assignable, constructable, destructable;
     76                std::vector< FuncData > data;
    5977        };
    6078
     
    144162                decl->fixUniqueId();
    145163                return decl;
     164        }
     165
     166        /// inserts base type of first argument into map if pred(funcDecl) is true
     167        void insert( FunctionDecl *funcDecl, TypeMap & map, FunctionDecl * (*pred)(Declaration *) ) {
     168                // insert type into constructable, etc. map if appropriate
     169                if ( pred( funcDecl ) ) {
     170                        FunctionType * ftype = funcDecl->get_functionType();
     171                        assert( ! ftype->get_parameters().empty() );
     172                        Type * t = safe_dynamic_cast< PointerType * >( ftype->get_parameters().front()->get_type() )->get_base();
     173                        map.insert( Mangler::mangleType( t ), true );
     174                }
     175        }
     176
     177        /// using map and t, determines if is constructable, etc.
     178        bool lookup( const TypeMap & map, Type * t ) {
     179                if ( dynamic_cast< PointerType * >( t ) ) {
     180                        // will need more complicated checking if we want this to work with pointer types, since currently
     181                        return true;
     182                } else if ( ArrayType * at = dynamic_cast< ArrayType * >( t ) ) {
     183                        // an array's constructor, etc. is generated on the fly based on the base type's constructor, etc.
     184                        return lookup( map, at->get_base() );
     185                }
     186                TypeMap::const_iterator it = map.find( Mangler::mangleType( t ) );
     187                if ( it != map.end() ) return it->second;
     188                // something that does not appear in the map is by default not constructable, etc.
     189                return false;
     190        }
     191
     192        /// using map and aggr, examines each member to determine if constructor, etc. should be generated
     193        template<typename AggrDecl>
     194        bool shouldGenerate( const TypeMap & map, AggrDecl * aggr ) {
     195                for ( Declaration * dcl : aggr->get_members() ) {
     196                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( dcl ) ) {
     197                                if ( ! lookup( map, dwt->get_type() ) ) return false;
     198                        }
     199                }
     200                return true;
     201        }
     202
     203        /// data structure for abstracting the generation of special functions
     204        template< typename OutputIterator >
     205        struct FuncGenerator {
     206                StructDecl *aggregateDecl;
     207                StructInstType *refType;
     208                unsigned int functionNesting;
     209                const std::list< TypeDecl* > & typeParams;
     210                OutputIterator out;
     211                FuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) : aggregateDecl( aggregateDecl ), refType( refType ), functionNesting( functionNesting ), typeParams( typeParams ), out( out ) {}
     212
     213                /// generates a function (?{}, ?=?, ^?{}) based on the data argument and members. If function is generated, inserts the type into the map.
     214                void gen( const FuncData & data ) {
     215                        if ( ! shouldGenerate( data.map, aggregateDecl ) ) return;
     216                        FunctionType * ftype = data.genType( refType );
     217                        cloneAll( typeParams, ftype->get_forall() );
     218                        *out++ = genFunc( data.fname, ftype, functionNesting );
     219                        data.map.insert( Mangler::mangleType( refType ), true );
     220                }
     221        };
     222
     223        template< typename OutputIterator >
     224        FuncGenerator<OutputIterator> makeFuncGenerator( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, const std::list< TypeDecl* > & typeParams, OutputIterator out ) {
     225                return FuncGenerator<OutputIterator>( aggregateDecl, refType, functionNesting, typeParams, out );
    146226        }
    147227
     
    308388
    309389        /// generates struct constructors, destructor, and assignment functions
    310         void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) {
    311 
     390        void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) {
    312391                // Make function polymorphic in same parameters as generic struct, if applicable
    313392                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    314393                bool isDynamicLayout = hasDynamicLayout( aggregateDecl );  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    315394
    316                 // T ?=?(T *, T);
    317                 FunctionType *assignType = genAssignType( refType );
    318                 cloneAll( typeParams, assignType->get_forall() );
    319 
    320                 // void ?{}(T *); void ^?{}(T *);
    321                 FunctionType *ctorType = genDefaultType( refType );
    322                 cloneAll( typeParams, ctorType->get_forall() );
    323                 FunctionType *dtorType = genDefaultType( refType );
    324                 cloneAll( typeParams, dtorType->get_forall() );
    325 
    326                 // void ?{}(T *, T);
    327                 FunctionType *copyCtorType = genCopyType( refType );
    328                 cloneAll( typeParams, copyCtorType->get_forall() );
    329 
    330                 FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting );
    331                 FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting );
    332                 FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting );
    333                 FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting );
     395                // generate each of the functions based on the supplied FuncData objects
     396                std::list< FunctionDecl * > newFuncs;
     397                auto generator = makeFuncGenerator( aggregateDecl, refType, functionNesting, typeParams, back_inserter( newFuncs ) );
     398                for ( const FuncData & d : data ) {
     399                        generator.gen( d );
     400                }
     401                // field ctors are only generated if default constructor and copy constructor are both generated
     402                unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );
    334403
    335404                if ( functionNesting == 0 ) {
     
    338407                        // Note: this is necessary if we want structs which contain
    339408                        // generic (otype) structs as members.
    340                         addForwardDecl( assignDecl, declsToAdd );
    341                         addForwardDecl( ctorDecl, declsToAdd );
    342                         addForwardDecl( copyCtorDecl, declsToAdd );
    343                         addForwardDecl( dtorDecl, declsToAdd );
     409                        for ( FunctionDecl * dcl : newFuncs ) {
     410                                addForwardDecl( dcl, declsToAdd );
     411                        }
     412                }
     413
     414                for ( FunctionDecl * dcl : newFuncs ) {
     415                        // generate appropriate calls to member ctor, assignment
     416                        // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor
     417                        if ( ! InitTweak::isDestructor( dcl->get_name() ) ) {
     418                                makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl, isDynamicLayout );
     419                        } else {
     420                                makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout, false );
     421                        }
     422                        if ( InitTweak::isAssignment( dcl->get_name() ) ) {
     423                                // assignment needs to return a value
     424                                FunctionType * assignType = dcl->get_functionType();
     425                                assert( assignType->get_parameters().size() == 2 );
     426                                ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() );
     427                                dcl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     428                        }
     429                        declsToAdd.push_back( dcl );
    344430                }
    345431
    346432                // create constructors which take each member type as a parameter.
    347433                // for example, for struct A { int x, y; }; generate
    348                 // void ?{}(A *, int) and void ?{}(A *, int, int)
    349                 std::list<Declaration *> memCtors;
    350                 FunctionType * memCtorType = ctorType->clone();
    351                 for ( std::list<Declaration *>::iterator i = aggregateDecl->get_members().begin(); i != aggregateDecl->get_members().end(); ++i ) {
    352                         DeclarationWithType * member = dynamic_cast<DeclarationWithType *>( *i );
    353                         assert( member );
    354                         if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( member ) ) ) {
    355                                 // don't make a function whose parameter is an unnamed bitfield
    356                                 continue;
    357                         } else if ( member->get_name() == "" ) {
    358                                 // don't assign to anonymous members
    359                                 // xxx - this is a temporary fix. Anonymous members tie into
    360                                 // our inheritance model. I think the correct way to handle this is to
    361                                 // cast the structure to the type of the member and let the resolver
    362                                 // figure out whether it's valid and have a pass afterwards that fixes
    363                                 // the assignment to use pointer arithmetic with the offset of the
    364                                 // member, much like how generic type members are handled.
    365                                 continue;
    366                         }
    367                         memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) );
    368                         FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
    369                         makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, isDynamicLayout );
    370                         memCtors.push_back( ctor );
    371                 }
    372                 delete memCtorType;
    373 
    374                 // generate appropriate calls to member ctor, assignment
    375                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, isDynamicLayout );
    376                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, isDynamicLayout );
    377                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, isDynamicLayout );
    378                 // needs to do everything in reverse, so pass "forward" as false
    379                 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, isDynamicLayout, false );
    380 
    381                 assert( assignType->get_parameters().size() == 2 );
    382                 ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( assignType->get_parameters().back() );
    383                 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    384 
    385                 declsToAdd.push_back( ctorDecl );
    386                 declsToAdd.push_back( copyCtorDecl );
    387                 declsToAdd.push_back( dtorDecl );
    388                 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return
    389                 declsToAdd.splice( declsToAdd.end(), memCtors );
     434                //   void ?{}(A *, int) and void ?{}(A *, int, int)
     435                // Field constructors are only generated if default and copy constructor
     436                // are generated, since they need access to both
     437                if ( numCtors == 2 ) {
     438                        FunctionType * memCtorType = genDefaultType( refType );
     439                        cloneAll( typeParams, memCtorType->get_forall() );
     440                        for ( std::list<Declaration *>::iterator i = aggregateDecl->get_members().begin(); i != aggregateDecl->get_members().end(); ++i ) {
     441                                DeclarationWithType * member = dynamic_cast<DeclarationWithType *>( *i );
     442                                assert( member );
     443                                if ( isUnnamedBitfield( dynamic_cast< ObjectDecl * > ( member ) ) ) {
     444                                        // don't make a function whose parameter is an unnamed bitfield
     445                                        continue;
     446                                } else if ( member->get_name() == "" ) {
     447                                        // don't assign to anonymous members
     448                                        // xxx - this is a temporary fix. Anonymous members tie into
     449                                        // our inheritance model. I think the correct way to handle this is to
     450                                        // cast the structure to the type of the member and let the resolver
     451                                        // figure out whether it's valid and have a pass afterwards that fixes
     452                                        // the assignment to use pointer arithmetic with the offset of the
     453                                        // member, much like how generic type members are handled.
     454                                        continue;
     455                                }
     456                                memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) );
     457                                FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
     458                                makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, isDynamicLayout );
     459                                declsToAdd.push_back( ctor );
     460                        }
     461                        delete memCtorType;
     462                }
    390463        }
    391464
     
    481554        }
    482555
     556        AutogenerateRoutines::AutogenerateRoutines() {
     557                // the order here determines the order that these functions are generated.
     558                // assignment should come last since it uses copy constructor in return.
     559                data.push_back( FuncData( "?{}", genDefaultType, constructable ) );
     560                data.push_back( FuncData( "?{}", genCopyType, copyable ) );
     561                data.push_back( FuncData( "^?{}", genDefaultType, destructable ) );
     562                data.push_back( FuncData( "?=?", genAssignType, assignable ) );
     563        }
     564
    483565        void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
    484566                if ( ! enumDecl->get_members().empty() ) {
     
    491573
    492574        void AutogenerateRoutines::visit( StructDecl *structDecl ) {
    493                 if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
     575                if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    494576                        StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    495577                        for ( TypeDecl * typeDecl : structDecl->get_parameters() ) {
     578                                // need to visit assertions so that they are added to the appropriate maps
     579                                acceptAll( typeDecl->get_assertions(), *this );
    496580                                structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );
    497581                        }
    498582                        structInst.set_baseStruct( structDecl );
    499                         makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd );
     583                        makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd, data );
    500584                        structsDone.insert( structDecl->get_name() );
    501585                } // if
     
    564648
    565649        void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
     650                // record the existence of this function as appropriate
     651                insert( functionDecl, constructable, InitTweak::isDefaultConstructor );
     652                insert( functionDecl, assignable, InitTweak::isAssignment );
     653                insert( functionDecl, copyable, InitTweak::isCopyConstructor );
     654                insert( functionDecl, destructable, InitTweak::isDestructor );
     655
    566656                maybeAccept( functionDecl->get_functionType(), *this );
    567657                acceptAll( functionDecl->get_oldDecls(), *this );
     
    572662
    573663        void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
     664                constructable.beginScope();
     665                assignable.beginScope();
     666                copyable.beginScope();
     667                destructable.beginScope();
    574668                visitStatement( compoundStmt );
     669                constructable.endScope();
     670                assignable.endScope();
     671                copyable.endScope();
     672                destructable.endScope();
    575673        }
    576674
  • src/SymTab/FixFunction.cc

    r6acb935 ra362f97  
    2525
    2626        DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
    27                 ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     27                ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0, functionDecl->get_attributes() );
     28                functionDecl->get_attributes().clear();
    2829                delete functionDecl;
    2930                return pointer;
  • src/SymTab/Validate.cc

    r6acb935 ra362f97  
    114114                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    115115          private:
    116                 using Indexer::visit;
     116                using Parent::visit;
    117117                void visit( StructInstType *structInst ) final;
    118118                void visit( UnionInstType *unionInst ) final;
     
    131131
    132132        /// Replaces array and function types in forall lists by appropriate pointer type
    133         class Pass3 : public Indexer {
     133        class Pass3 final : public Indexer {
    134134                typedef Indexer Parent;
    135135          public:
     136                using Parent::visit;
    136137                Pass3( const Indexer *indexer );
    137138          private:
    138                 virtual void visit( ObjectDecl *object );
    139                 virtual void visit( FunctionDecl *func );
     139                virtual void visit( ObjectDecl *object ) override;
     140                virtual void visit( FunctionDecl *func ) override;
    140141
    141142                const Indexer *indexer;
     
    375376        }
    376377
    377         void LinkReferenceToTypes::visit( TraitInstType *contextInst ) {
    378                 Parent::visit( contextInst );
    379                 if ( contextInst->get_name() == "sized" ) {
     378        void LinkReferenceToTypes::visit( TraitInstType *traitInst ) {
     379                Parent::visit( traitInst );
     380                if ( traitInst->get_name() == "sized" ) {
    380381                        // "sized" is a special trait with no members - just flick the sized status on for the type variable
    381                         if ( contextInst->get_parameters().size() != 1 ) {
    382                                 throw SemanticError( "incorrect number of context parameters: ", contextInst );
     382                        if ( traitInst->get_parameters().size() != 1 ) {
     383                                throw SemanticError( "incorrect number of trait parameters: ", traitInst );
    383384                        }
    384                         TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( contextInst->get_parameters().front() );
     385                        TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() );
    385386                        TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() );
    386387                        TypeDecl * decl = inst->get_baseType();
     
    389390                        return;
    390391                }
    391                 TraitDecl *ctx = indexer->lookupTrait( contextInst->get_name() );
    392                 if ( ! ctx ) {
    393                         throw SemanticError( "use of undeclared context " + contextInst->get_name() );
    394                 } // if
    395                 for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
    396                         for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    397                                 if ( TraitInstType *otherCtx = dynamic_cast< TraitInstType * >(*assert ) ) {
    398                                         cloneAll( otherCtx->get_members(), contextInst->get_members() );
    399                                 } else {
    400                                         contextInst->get_members().push_back( (*assert )->clone() );
    401                                 } // if
     392                TraitDecl *traitDecl = indexer->lookupTrait( traitInst->get_name() );
     393                if ( ! traitDecl ) {
     394                        throw SemanticError( "use of undeclared trait " + traitInst->get_name() );
     395                } // if
     396                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
     397                        throw SemanticError( "incorrect number of trait parameters: ", traitInst );
     398                } // if
     399
     400                for ( TypeDecl * td : traitDecl->get_parameters() ) {
     401                        for ( DeclarationWithType * assert : td->get_assertions() ) {
     402                                traitInst->get_members().push_back( assert->clone() );
    402403                        } // for
    403404                } // for
    404405
    405                 if ( ctx->get_parameters().size() != contextInst->get_parameters().size() ) {
    406                         throw SemanticError( "incorrect number of context parameters: ", contextInst );
    407                 } // if
    408 
    409                 // need to clone members of the context for ownership purposes
     406                // need to clone members of the trait for ownership purposes
    410407                std::list< Declaration * > members;
    411                 std::transform( ctx->get_members().begin(), ctx->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
    412 
    413                 applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( contextInst->get_members() ) );
     408                std::transform( traitDecl->get_members().begin(), traitDecl->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } );
     409
     410                applySubstitution( traitDecl->get_parameters().begin(), traitDecl->get_parameters().end(), traitInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( traitInst->get_members() ) );
     411
     412                // need to carry over the 'sized' status of each decl in the instance
     413                for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
     414                        TypeExpr * expr = safe_dynamic_cast< TypeExpr * >( std::get<1>(p) );
     415                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
     416                                TypeDecl * formalDecl = std::get<0>(p);
     417                                TypeDecl * instDecl = inst->get_baseType();
     418                                if ( formalDecl->get_sized() ) instDecl->set_sized( true );
     419                        }
     420                }
    414421        }
    415422
     
    457464        }
    458465
    459         /// Fix up assertions
    460         void forallFixer( Type *func ) {
    461                 for ( Type::ForallList::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
     466        /// Fix up assertions - flattens assertion lists, removing all trait instances
     467        void forallFixer( Type * func ) {
     468                for ( TypeDecl * type : func->get_forall() ) {
    462469                        std::list< DeclarationWithType * > toBeDone, nextRound;
    463                         toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
     470                        toBeDone.splice( toBeDone.end(), type->get_assertions() );
    464471                        while ( ! toBeDone.empty() ) {
    465                                 for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
    466                                         if ( TraitInstType *ctx = dynamic_cast< TraitInstType * >( (*assertion )->get_type() ) ) {
    467                                                 for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
    468                                                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
    469                                                         assert( dwt );
     472                                for ( DeclarationWithType * assertion : toBeDone ) {
     473                                        if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     474                                                // expand trait instance into all of its members
     475                                                for ( Declaration * member : traitInst->get_members() ) {
     476                                                        DeclarationWithType *dwt = safe_dynamic_cast< DeclarationWithType * >( member );
    470477                                                        nextRound.push_back( dwt->clone() );
    471478                                                }
    472                                                 delete ctx;
     479                                                delete traitInst;
    473480                                        } else {
     481                                                // pass assertion through
    474482                                                FixFunction fixer;
    475                                                 *assertion = (*assertion )->acceptMutator( fixer );
     483                                                assertion = assertion->acceptMutator( fixer );
    476484                                                if ( fixer.get_isVoid() ) {
    477485                                                        throw SemanticError( "invalid type void in assertion of function ", func );
    478486                                                }
    479                                                 (*type )->get_assertions().push_back( *assertion );
     487                                                type->get_assertions().push_back( assertion );
    480488                                        } // if
    481489                                } // for
     
    629637                if ( FunctionType *funtype = dynamic_cast<FunctionType *>( ret->get_type() ) ) {
    630638                        // replace the current object declaration with a function declaration
    631                         return new FunctionDecl( ret->get_name(), ret->get_storageClass(), ret->get_linkage(), funtype, 0, ret->get_isInline(), ret->get_isNoreturn() );
     639                        FunctionDecl * newDecl = new FunctionDecl( ret->get_name(), ret->get_storageClass(), ret->get_linkage(), funtype, 0, ret->get_isInline(), ret->get_isNoreturn(), objDecl->get_attributes() );
     640                        objDecl->get_attributes().clear();
     641                        delete objDecl;
     642                        return newDecl;
    632643                } else if ( objDecl->get_isInline() || objDecl->get_isNoreturn() ) {
    633644                        throw SemanticError( "invalid inline or _Noreturn specification in declaration of ", objDecl );
  • src/SynTree/AggregateDecl.cc

    r6acb935 ra362f97  
    6969std::string EnumDecl::typeString() const { return "enum"; }
    7070
    71 std::string TraitDecl::typeString() const { return "context"; }
     71std::string TraitDecl::typeString() const { return "trait"; }
    7272
    7373// Local Variables: //
  • src/SynTree/ReferenceToType.cc

    r6acb935 ra362f97  
    6464}
    6565
     66bool StructInstType::isComplete() const { return baseStruct->has_body(); }
     67
    6668void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    6769        assert( baseStruct );
     
    9092}
    9193
     94bool UnionInstType::isComplete() const { return baseUnion->has_body(); }
     95
    9296void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const {
    9397        assert( baseUnion );
     
    111115std::string EnumInstType::typeString() const { return "enum"; }
    112116
    113 std::string TraitInstType::typeString() const { return "context"; }
     117std::string TraitInstType::typeString() const { return "trait"; }
    114118
    115119TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) {
     
    120124        deleteAll( members );
    121125}
     126
     127bool TraitInstType::isComplete() const { assert( false ); }
    122128
    123129TypeInstType::TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType ) : Parent( tq, name ) {
     
    143149std::string TypeInstType::typeString() const { return "type"; }
    144150
     151bool TypeInstType::isComplete() const { return baseType->isComplete(); }
     152
    145153void TypeInstType::print( std::ostream &os, int indent ) const {
    146154        using std::endl;
  • src/SynTree/Type.h

    r6acb935 ra362f97  
    7474        virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; }
    7575
     76        virtual bool isComplete() const { return true; }
     77
    7678        virtual Type *clone() const = 0;
    7779        virtual void accept( Visitor &v ) = 0;
     
    9092
    9193        virtual unsigned size() const { return 0; };
     94        virtual bool isComplete() const { return false; }
    9295
    9396        virtual VoidType *clone() const { return new VoidType( *this ); }
     
    185188        void set_isStatic( bool newValue ) { isStatic = newValue; }
    186189
     190        virtual bool isComplete() const { return ! isVarLen; }
     191
    187192        virtual ArrayType *clone() const { return new ArrayType( *this ); }
    188193        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    258263        std::list<TypeDecl*> * get_baseParameters();
    259264
     265        virtual bool isComplete() const;
     266
    260267        /// Looks up the members of this struct named "name" and places them into "foundDecls".
    261268        /// Clones declarations into "foundDecls", caller responsible for freeing
     
    287294        std::list<TypeDecl*> * get_baseParameters();
    288295
     296        virtual bool isComplete() const;
     297
    289298        /// looks up the members of this union named "name" and places them into "foundDecls"
    290299        /// Clones declarations into "foundDecls", caller responsible for freeing
     
    310319        EnumInstType( const EnumInstType &other ) : Parent( other ) {}
    311320
     321        // xxx - enum inst does not currently contain a pointer to base, this should be fixed.
     322        // virtual bool isComplete() const { return baseEnum()->hasBody(); }
     323
    312324        virtual EnumInstType *clone() const { return new EnumInstType( *this ); }
    313325        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    325337
    326338        std::list< Declaration* >& get_members() { return members; }
     339
     340        virtual bool isComplete() const;
    327341
    328342        virtual TraitInstType *clone() const { return new TraitInstType( *this ); }
     
    349363        bool get_isFtype() const { return isFtype; }
    350364        void set_isFtype( bool newValue ) { isFtype = newValue; }
     365
     366        virtual bool isComplete() const;
    351367
    352368        virtual TypeInstType *clone() const { return new TypeInstType( *this ); }
     
    382398        }
    383399
     400        // virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness
     401
    384402        virtual TupleType *clone() const { return new TupleType( *this ); }
    385403        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    398416        Expression *get_expr() const { return expr; }
    399417        void set_expr( Expression *newValue ) { expr = newValue; }
     418
     419        virtual bool isComplete() const { assert( false ); return false; }
    400420
    401421        virtual TypeofType *clone() const { return new TypeofType( *this ); }
     
    423443        void set_isType( bool newValue ) { isType = newValue; }
    424444
     445        virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here
     446
    425447        virtual AttrType *clone() const { return new AttrType( *this ); }
    426448        virtual void accept( Visitor &v ) { v.visit( this ); }
     
    439461        VarArgsType();
    440462        VarArgsType( Type::Qualifiers tq );
     463
     464        virtual bool isComplete() const{ return true; } // xxx - is this right?
    441465
    442466        virtual VarArgsType *clone() const { return new VarArgsType( *this ); }
  • src/driver/cfa.cc

    r6acb935 ra362f97  
    267267                }
    268268                nargs += 1;
     269                args[nargs] = "-lpthread";
     270                nargs += 1;
    269271        } // if
    270272#endif //HAVE_LIBCFA
  • src/examples/thread.c

    r6acb935 ra362f97  
     1#include <fstream>
    12#include <kernel>
    23#include <stdlib>
     
    45
    56// Start coroutine routines
    6 extern "C" {
    7       forall(dtype T | is_coroutine(T))
    8       void CtxInvokeCoroutine(T * this);
    9 
    10       forall(dtype T | is_coroutine(T))
    11       void CtxStart(T * this, void ( *invoke)(T *));
    12 
    13         forall(dtype T | is_coroutine(T))
    14       void CtxInvokeThread(T * this);
    15 }
    16 
    177struct MyThread {
    18         thread_h t;
     8        thread t;
    199        unsigned id;
    2010        unsigned count;
    2111};
    2212
     13DECL_THREAD(MyThread)
     14
    2315void ?{}( MyThread * this ) {
    24         this->id = 0;
    25         this->count = 10;
    2616}
    2717
     
    3121}
    3222
    33 void ^?{}( MyThread * this ) {}
    34 
    3523void main(MyThread* this) {
    36         printf("Main called with %p\n", this);
    37         printf("Thread %d : Suspending %d times\n", this->id, this->count);
     24        sout | "Thread" | this->id | " : Suspending" | this->count | "times" | endl;
     25        yield();
    3826
    3927        for(int i = 0; i < this->count; i++) {
    40                 printf("Thread %d : Suspend No. %d\n", this->id, i + 1);
    41                 printf("Back to %p\n", &this->t.c);
    42                 suspend();
     28                sout | "Thread" | this->id | " : Suspend No." | i + 1 | endl;
     29                yield();
    4330        }
    4431}
    4532
    46 thread_h* get_thread(MyThread* this) {
    47         return &this->t;
    48 }
     33int main(int argc, char* argv[]) {
    4934
    50 coroutine* get_coroutine(MyThread* this) {
    51         return &this->t.c;
    52 }
     35        unsigned itterations = 10u;
     36        if(argc == 2) {
     37                int val = ato(argv[1]);
     38                assert(val >= 0);
     39                itterations = val;
     40        }
    5341
    54 int main() {
     42        sout | "User main begin" | endl;
    5543
    56         thread(MyThread) thread1;
    57         thread(MyThread) thread2;
     44        {
     45                processor p;
     46                {
     47                        scoped(MyThread) thread1 = { 1u, itterations };
     48                        scoped(MyThread) thread2 = { 2u, itterations };
     49                }
     50        }
    5851
    59         thread2.handle.id = 1;
    60 
    61         printf("\n\nMain is %p\n", this_coroutine());
    62 
    63         kernel_run();
    64 
    65         printf("Kernel terminated correctly\n");
     52        sout | "User main end" | endl;
    6653
    6754        return 0;
  • src/libcfa/concurrency/CtxSwitch-i386.S

    r6acb935 ra362f97  
    8686        ret
    8787
     88.text
     89        .align 2
     90.globl  CtxGet
     91CtxGet:
     92        movl %esp,SP_OFFSET(%eax)
     93        movl %ebp,FP_OFFSET(%eax)
     94
     95        ret
     96
    8897// Local Variables: //
    8998// compile-command: "make install" //
  • src/libcfa/concurrency/CtxSwitch-x86_64.S

    r6acb935 ra362f97  
    8484        jmp *%r12
    8585
     86.text
     87        .align 2
     88.globl  CtxGet
     89CtxGet:
     90        movq %rsp,SP_OFFSET(%rdi)
     91        movq %rbp,FP_OFFSET(%rdi)
     92
     93        ret
     94
    8695// Local Variables: //
    8796// mode: c //
  • src/libcfa/concurrency/coroutines

    r6acb935 ra362f97  
    6262
    6363// Get current coroutine
    64 extern coroutine * current_coroutine; //PRIVATE, never use directly
    65 static inline coroutine * this_coroutine(void) {
    66         return current_coroutine;
    67 }
     64coroutine * this_coroutine(void);
    6865
    6966// Private wrappers for context switch and stack creation
     
    7673
    7774        assertf( src->last != 0,
    78                 "Attempt to suspend coroutine %.256s (%p) that has never been resumed.\n"
     75                "Attempt to suspend coroutine \"%.256s\" (%p) that has never been resumed.\n"
    7976                "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.",
    8077                src->name, src );
    8178        assertf( src->last->notHalted,
    82                 "Attempt by coroutine %.256s (%p) to suspend back to terminated coroutine %.256s (%p).\n"
     79                "Attempt by coroutine \"%.256s\" (%p) to suspend back to terminated coroutine \"%.256s\" (%p).\n"
    8380                "Possible cause is terminated coroutine's main routine has already returned.",
    8481                src->name, src, src->last->name, src->last );
  • src/libcfa/concurrency/coroutines.c

    r6acb935 ra362f97  
     1//                              -*- Mode: CFA -*-
    12//
    23// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     
    1415//
    1516
     17#include "coroutines"
     18
    1619extern "C" {
    1720#include <stddef.h>
     
    2326}
    2427
    25 #include "coroutines"
     28#include "kernel"
    2629#include "libhdr.h"
    2730
    2831#define __CFA_INVOKE_PRIVATE__
    2932#include "invoke.h"
     33
     34extern processor * get_this_processor();
    3035
    3136//-----------------------------------------------------------------------------
     
    3540#define MinStackSize 1000
    3641static size_t pageSize = 0;                             // architecture pagesize HACK, should go in proper runtime singleton
    37 
    38 //Extra private desctructor for the main
    39 //FIXME the main should not actually allocate a stack
    40 //Since the main is never resumed the extra stack does not cause
    41 //any problem but it is wasted memory
    42 void ?{}(coStack_t* this, size_t size);
    43 void ?{}(coroutine* this, size_t size);
    44 
    45 //Main coroutine
    46 //FIXME do not construct a stack for the main
    47 coroutine main_coroutine = { 1000 };
    48 
    49 //Current coroutine
    50 //Will need to be in TLS when multi-threading is added
    51 coroutine* current_coroutine = &main_coroutine;
    5242
    5343//-----------------------------------------------------------------------------
     
    111101// is not inline (We can't inline Cforall in C)
    112102void suspend_no_inline(void) {
    113         LIB_DEBUG_PRINTF("Suspending back : to %p from %p\n", this_coroutine(), this_coroutine() ? this_coroutine()->last : (void*)-1);
    114 
    115103        suspend();
    116104}
     
    123111
    124112        // set new coroutine that task is executing
    125         current_coroutine = dst;                       
     113        get_this_processor()->current_coroutine = dst;                 
    126114
    127115        // context switch to specified coroutine
  • src/libcfa/concurrency/invoke.c

    r6acb935 ra362f97  
     1//                              -*- Mode: C -*-
     2//
     3// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     4//
     5// The contents of this file are covered under the licence agreement in the
     6// file "LICENCE" distributed with Cforall.
     7//
     8// invoke.c --
     9//
     10// Author           : Thierry Delisle
     11// Created On       : Tue Jan 17 12:27:26 2016
     12// Last Modified By : Thierry Delisle
     13// Last Modified On : --
     14// Update Count     : 0
     15//
    116
    217#include <stdbool.h>
     
    1429
    1530extern void __suspend_no_inline__F___1(void);
    16 extern void __scheduler_remove__F_P9sthread_h__1(struct thread_h*);
     31extern void __signal_termination__F_P7sthread__1(struct thread*);
    1732
    1833void CtxInvokeCoroutine(
     
    3348      main( this );
    3449
     50      cor->state = Halt;
     51      cor->notHalted = false;
     52
    3553      //Final suspend, should never return
    3654      __suspend_no_inline__F___1();
     
    4058void CtxInvokeThread(
    4159      void (*main)(void *),
    42       struct thread_h *(*get_thread)(void *),
     60      struct thread *(*get_thread)(void *),
    4361      void *this
    4462) {
     
    4765      __suspend_no_inline__F___1();
    4866
    49       struct thread_h* thrd = get_thread( this );
     67      struct thread* thrd = get_thread( this );
    5068      struct coroutine* cor = &thrd->c;
    5169      cor->state = Active;
     
    5472      main( this );
    5573
    56       __scheduler_remove__F_P9sthread_h__1(thrd);
     74      __signal_termination__F_P7sthread__1(thrd);
    5775
    5876      //Final suspend, should never return
  • src/libcfa/concurrency/invoke.h

    r6acb935 ra362f97  
     1//                              -*- Mode: C -*-
     2//
     3// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     4//
     5// The contents of this file are covered under the licence agreement in the
     6// file "LICENCE" distributed with Cforall.
     7//
     8// invoke.h --
     9//
     10// Author           : Thierry Delisle
     11// Created On       : Tue Jan 17 12:27:26 2016
     12// Last Modified By : Thierry Delisle
     13// Last Modified On : --
     14// Update Count     : 0
     15//
     16
    117#include <stdbool.h>
    218#include <stdint.h>
     
    1127
    1228      #define unlikely(x)    __builtin_expect(!!(x), 0)
     29      #define thread_local _Thread_local
     30      #define SCHEDULER_CAPACITY 10
     31
     32      struct simple_thread_list {
     33            struct thread * head;
     34            struct thread ** tail;
     35      };
     36
     37      #ifdef __CFORALL__
     38      extern "Cforall" {
     39            void ?{}( struct simple_thread_list * );
     40            void append( struct simple_thread_list *, struct thread * );
     41            struct thread * pop_head( struct simple_thread_list * );
     42      }
     43      #endif
    1344
    1445      struct coStack_t {
     
    3566      };
    3667
    37       struct thread_h {
     68      struct simple_lock {
     69        struct simple_thread_list blocked;
     70      };
     71
     72      struct thread {
    3873            struct coroutine c;
     74            struct simple_lock lock;
     75            struct thread * next;
    3976      };
    4077
     
    5289      // assembler routines that performs the context switch
    5390      extern void CtxInvokeStub( void );
    54       void CtxSwitch( void *from, void *to ) asm ("CtxSwitch");
     91      void CtxSwitch( void * from, void * to ) asm ("CtxSwitch");
     92      void CtxGet( void * this ) asm ("CtxGet");
    5593
    5694#endif //_INVOKE_PRIVATE_H_
  • src/libcfa/concurrency/kernel

    r6acb935 ra362f97  
    2020#include <stdbool.h>
    2121
     22#include "invoke.h"
     23
     24extern "C" {
     25#include <pthread.h>
     26}
     27
     28//-----------------------------------------------------------------------------
     29// Cluster
     30struct cluster {
     31        simple_thread_list ready_queue;
     32        pthread_spinlock_t lock;
     33};
     34
     35void ?{}(cluster * this);
     36void ^?{}(cluster * this);
     37
     38//-----------------------------------------------------------------------------
     39// Processor
    2240struct processor {
    23         struct proc_coroutine * cor;
    24         unsigned int thread_index;
    25         unsigned int thread_count;
    26         struct thread_h * threads[10];
    27         bool terminated;
     41        struct processorCtx_t * ctx;
     42        cluster * cltr;
     43        coroutine * current_coroutine;
     44        thread * current_thread;
     45        pthread_t kernel_thread;
     46        simple_lock lock;
     47        volatile bool terminated;
    2848};
    2949
    3050void ?{}(processor * this);
     51void ?{}(processor * this, cluster * cltr);
    3152void ^?{}(processor * this);
    3253
    33 void scheduler_add( struct thread_h * thrd );
    34 void scheduler_remove( struct thread_h * thrd );
    35 void kernel_run( void );
     54
     55//-----------------------------------------------------------------------------
     56// Locks
     57
     58void ?{}(simple_lock * this);
     59void ^?{}(simple_lock * this);
     60
     61void lock( simple_lock * );
     62void unlock( simple_lock * );
     63
     64struct pthread_spinlock_guard {
     65        pthread_spinlock_t * lock;
     66};
     67
     68static inline void ?{}( pthread_spinlock_guard * this, pthread_spinlock_t * lock ) {
     69        this->lock = lock;
     70        pthread_spin_lock( this->lock );
     71}
     72
     73static inline void ^?{}( pthread_spinlock_guard * this ) {
     74        pthread_spin_unlock( this->lock );
     75}
     76
     77// //Simple spinlock implementation from
     78// //http://stackoverflow.com/questions/1383363/is-my-spin-lock-implementation-correct-and-optimal
     79// //Not optimal but correct
     80// #define VOL
     81
     82// struct simple_spinlock {
     83//      VOL int lock;
     84// };
     85
     86// extern VOL int __sync_lock_test_and_set( VOL int *, VOL int);
     87// extern void __sync_synchronize();
     88
     89// static inline void lock( simple_spinlock * this ) {
     90//     while (__sync_lock_test_and_set(&this->lock, 1)) {
     91//         // Do nothing. This GCC builtin instruction
     92//         // ensures memory barrier.
     93//     }
     94// }
     95
     96// static inline void unlock( simple_spinlock * this ) {
     97//     __sync_synchronize(); // Memory barrier.
     98//     this->lock = 0;
     99// }
    36100
    37101#endif //KERNEL_H
  • src/libcfa/concurrency/kernel.c

    r6acb935 ra362f97  
    2020//C Includes
    2121#include <stddef.h>
     22extern "C" {
     23#include <sys/resource.h>
     24}
    2225
    2326//CFA Includes
     
    2932#include "invoke.h"
    3033
    31 processor systemProcessorStorage = {};
    32 processor * systemProcessor = &systemProcessorStorage;
    33 
    34 void ?{}(processor * this) {
    35         this->cor = NULL;
    36         this->thread_index = 0;
    37         this->thread_count = 10;
    38         this->terminated = false;
    39 
    40         for(int i = 0; i < 10; i++) {
    41                 this->threads[i] = NULL;
    42         }
    43 
    44         LIB_DEBUG_PRINTF("Processor : ctor for core %p (core spots %d)\n", this, this->thread_count);
    45 }
    46 
    47 void ^?{}(processor * this) {
    48 
    49 }
    50 
    51 //-----------------------------------------------------------------------------
    52 // Processor coroutine
    53 struct proc_coroutine {
     34//-----------------------------------------------------------------------------
     35// Kernel storage
     36struct processorCtx_t {
    5437        processor * proc;
    5538        coroutine c;
    5639};
    5740
    58 void ?{}(coroutine * this, processor * proc) {
    59         this{};
    60 }
    61 
    62 DECL_COROUTINE(proc_coroutine)
    63 
    64 void ?{}(proc_coroutine * this, processor * proc) {
    65         (&this->c){proc};
     41DECL_COROUTINE(processorCtx_t)
     42
     43#define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)]
     44
     45KERNEL_STORAGE(processorCtx_t, systemProcessorCtx);
     46KERNEL_STORAGE(cluster, systemCluster);
     47KERNEL_STORAGE(processor, systemProcessor);
     48KERNEL_STORAGE(thread, mainThread);
     49KERNEL_STORAGE(machine_context_t, mainThread_context);
     50
     51cluster * systemCluster;
     52processor * systemProcessor;
     53thread * mainThread;
     54
     55void kernel_startup(void)  __attribute__((constructor(101)));
     56void kernel_shutdown(void) __attribute__((destructor(101)));
     57
     58//-----------------------------------------------------------------------------
     59// Global state
     60
     61thread_local processor * this_processor;
     62
     63processor * get_this_processor() {
     64        return this_processor;
     65}
     66
     67coroutine * this_coroutine(void) {
     68        return this_processor->current_coroutine;
     69}
     70
     71thread * this_thread(void) {
     72        return this_processor->current_thread;
     73}
     74
     75//-----------------------------------------------------------------------------
     76// Main thread construction
     77struct current_stack_info_t {
     78        machine_context_t ctx; 
     79        unsigned int size;              // size of stack
     80        void *base;                             // base of stack
     81        void *storage;                  // pointer to stack
     82        void *limit;                    // stack grows towards stack limit
     83        void *context;                  // address of cfa_context_t
     84        void *top;                              // address of top of storage
     85};
     86
     87void ?{}( current_stack_info_t * this ) {
     88        CtxGet( &this->ctx );
     89        this->base = this->ctx.FP;
     90        this->storage = this->ctx.SP;
     91
     92        rlimit r;
     93        int ret = getrlimit( RLIMIT_STACK, &r);
     94        this->size = r.rlim_cur;
     95
     96        this->limit = (void *)(((intptr_t)this->base) - this->size);
     97        this->context = &mainThread_context_storage;
     98        this->top = this->base;
     99}
     100
     101void ?{}( coStack_t * this, current_stack_info_t * info) {
     102        this->size = info->size;
     103        this->storage = info->storage;
     104        this->limit = info->limit;
     105        this->base = info->base;
     106        this->context = info->context;
     107        this->top = info->top;
     108        this->userStack = true;
     109}
     110
     111void ?{}( coroutine * this, current_stack_info_t * info) {
     112        (&this->stack){ info };
     113        this->name = "Main Thread";
     114        this->errno_ = 0;
     115        this->state = Inactive;
     116        this->notHalted = true;
     117}
     118
     119void ?{}( thread * this, current_stack_info_t * info) {
     120        (&this->c){ info };
     121}
     122
     123//-----------------------------------------------------------------------------
     124// Processor coroutine
     125void ?{}(processorCtx_t * this, processor * proc) {
     126        (&this->c){};
    66127        this->proc = proc;
    67         proc->cor = this;
    68 }
    69 
    70 void ^?{}(proc_coroutine * this) {
    71         ^(&this->c){};
    72 }
    73 
    74 void CtxInvokeProcessor(processor * proc) {
    75         proc_coroutine proc_cor_storage = {proc};
    76         resume( &proc_cor_storage );
     128        proc->ctx = this;
     129}
     130
     131void ?{}(processorCtx_t * this, processor * proc, current_stack_info_t * info) {
     132        (&this->c){ info };
     133        this->proc = proc;
     134        proc->ctx = this;
     135}
     136
     137void start(processor * this);
     138
     139void ?{}(processor * this) {
     140        this{ systemCluster };
     141}
     142
     143void ?{}(processor * this, cluster * cltr) {
     144        this->cltr = cltr;
     145        this->current_coroutine = NULL;
     146        this->current_thread = NULL;
     147        (&this->lock){};
     148        this->terminated = false;
     149
     150        start( this );
     151}
     152
     153void ?{}(processor * this, cluster * cltr, processorCtx_t * ctx) {
     154        this->cltr = cltr;
     155        this->current_coroutine = NULL;
     156        this->current_thread = NULL;
     157        (&this->lock){};
     158        this->terminated = false;
     159
     160        this->ctx = ctx;
     161        LIB_DEBUG_PRINTF("Kernel : constructing processor context %p\n", ctx);
     162        ctx{ this };
     163}
     164
     165void ^?{}(processor * this) {
     166        if( ! this->terminated ) {
     167                LIB_DEBUG_PRINTF("Kernel : core %p signaling termination\n", this);
     168                this->terminated = true;
     169                lock( &this->lock );
     170        }
     171}
     172
     173void ?{}(cluster * this) {
     174        ( &this->ready_queue ){};
     175        pthread_spin_init( &this->lock, PTHREAD_PROCESS_PRIVATE );
     176}
     177
     178void ^?{}(cluster * this) {
     179        pthread_spin_destroy( &this->lock );
    77180}
    78181
    79182//-----------------------------------------------------------------------------
    80183// Processor running routines
    81 void main(proc_coroutine * cor);
    82 thread_h * nextThread(processor * this);
    83 void runThread(processor * this, thread_h * dst);
     184void main(processorCtx_t * ctx);
     185thread * nextThread(cluster * this);
     186void runThread(processor * this, thread * dst);
    84187void spin(processor * this, unsigned int * spin_count);
    85188
    86 void main(proc_coroutine * cor) {
    87         processor * this;
    88         this = cor->proc;
    89 
    90         thread_h * readyThread = NULL;
     189void main(processorCtx_t * ctx) {
     190        processor * this = ctx->proc;
     191        LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this);
     192
     193        thread * readyThread = NULL;
    91194        for( unsigned int spin_count = 0; ! this->terminated; spin_count++ ) {
    92195               
    93                 readyThread = nextThread(this);
     196                readyThread = nextThread( this->cltr );
    94197
    95198                if(readyThread) {
     
    101204        }
    102205
     206        LIB_DEBUG_PRINTF("Kernel : core %p unlocking thread\n", this);
     207        unlock( &this->lock );
    103208        LIB_DEBUG_PRINTF("Kernel : core %p terminated\n", this);
    104209}
    105210
    106 thread_h * nextThread(processor * this) {
    107         for(int i = 0; i < this->thread_count; i++) {
    108                 this->thread_index = (this->thread_index + 1) % this->thread_count;     
    109                
    110                 thread_h * thrd = this->threads[this->thread_index];
    111                 if(thrd) return thrd;
    112         }
    113 
    114         return NULL;
    115 }
    116 
    117 void runThread(processor * this, thread_h * dst) {
    118         coroutine * proc_ctx = get_coroutine(this->cor);
     211void runThread(processor * this, thread * dst) {
     212        coroutine * proc_ctx = get_coroutine(this->ctx);
    119213        coroutine * thrd_ctx = get_coroutine(dst);
    120214        thrd_ctx->last = proc_ctx;
     
    122216        // context switch to specified coroutine
    123217        // Which is now the current_coroutine
    124         LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
    125         current_coroutine = thrd_ctx;
     218        // LIB_DEBUG_PRINTF("Kernel : switching to ctx %p (from %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
     219        this->current_thread = dst;
     220        this->current_coroutine = thrd_ctx;
    126221        CtxSwitch( proc_ctx->stack.context, thrd_ctx->stack.context );
    127         current_coroutine = proc_ctx;
    128         LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
     222        this->current_coroutine = proc_ctx;
     223        // LIB_DEBUG_PRINTF("Kernel : returned from ctx %p (to %p, current %p)\n", thrd_ctx, proc_ctx, current_coroutine);
    129224
    130225        // when CtxSwitch returns we are back in the processor coroutine
     
    135230}
    136231
    137 //-----------------------------------------------------------------------------
    138 // Kernel runner (Temporary)
    139 
    140 void scheduler_add( struct thread_h * thrd ) {
    141         LIB_DEBUG_PRINTF("Kernel : scheduling %p on core %p (%d spots)\n", thrd, systemProcessor, systemProcessor->thread_count);
    142         for(int i = 0; i < systemProcessor->thread_count; i++) {
    143                 if(systemProcessor->threads[i] == NULL) {
    144                         systemProcessor->threads[i] = thrd;
    145                         return;
     232void * CtxInvokeProcessor(void * arg) {
     233        processor * proc = (processor *) arg;
     234        this_processor = proc;
     235        // SKULLDUGGERY: We want to create a context for the processor coroutine
     236        // which is needed for the 2-step context switch. However, there is no reason
     237        // to waste the perfectly valid stack create by pthread.
     238        current_stack_info_t info;
     239        machine_context_t ctx;
     240        info.context = &ctx;
     241        processorCtx_t proc_cor_storage = { proc, &info };
     242
     243        proc->current_coroutine = &proc->ctx->c;
     244        proc->current_thread = NULL;
     245
     246        LIB_DEBUG_PRINTF("Kernel : core %p created (%p)\n", proc, proc->ctx);
     247
     248        // LIB_DEBUG_PRINTF("Kernel : core    base : %p \n", info.base );
     249        // LIB_DEBUG_PRINTF("Kernel : core storage : %p \n", info.storage );
     250        // LIB_DEBUG_PRINTF("Kernel : core    size : %x \n", info.size );
     251        // LIB_DEBUG_PRINTF("Kernel : core   limit : %p \n", info.limit );
     252        // LIB_DEBUG_PRINTF("Kernel : core context : %p \n", info.context );
     253        // LIB_DEBUG_PRINTF("Kernel : core     top : %p \n", info.top );
     254
     255        //We now have a proper context from which to schedule threads
     256
     257        // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
     258        // resume it to start it like it normally would, it will just context switch
     259        // back to here. Instead directly call the main since we already are on the
     260        // appropriate stack.
     261        proc_cor_storage.c.state = Active;
     262      main( &proc_cor_storage );
     263      proc_cor_storage.c.state = Halt;
     264      proc_cor_storage.c.notHalted = false;
     265
     266        LIB_DEBUG_PRINTF("Kernel : core %p main ended (%p)\n", proc, proc->ctx);       
     267
     268        return NULL;
     269}
     270
     271void start(processor * this) {
     272        LIB_DEBUG_PRINTF("Kernel : Starting core %p\n", this);
     273       
     274        pthread_attr_t attributes;
     275        pthread_attr_init( &attributes );
     276
     277        pthread_create( &this->kernel_thread, &attributes, CtxInvokeProcessor, (void*)this );
     278
     279        pthread_attr_destroy( &attributes );
     280
     281        LIB_DEBUG_PRINTF("Kernel : core %p started\n", this);   
     282}
     283
     284//-----------------------------------------------------------------------------
     285// Scheduler routines
     286void thread_schedule( thread * thrd ) {
     287        assertf( thrd->next == NULL, "Expected null got %p", thrd->next );
     288       
     289        pthread_spinlock_guard guard = { &systemProcessor->cltr->lock };
     290        append( &systemProcessor->cltr->ready_queue, thrd );
     291}
     292
     293thread * nextThread(cluster * this) {
     294        pthread_spinlock_guard guard = { &this->lock };
     295        return pop_head( &this->ready_queue );
     296}
     297
     298//-----------------------------------------------------------------------------
     299// Kernel boot procedures
     300void kernel_startup(void) {
     301
     302        // SKULLDUGGERY: the mainThread steals the process main thread
     303        // which will then be scheduled by the systemProcessor normally
     304        LIB_DEBUG_PRINTF("Kernel : Starting\n");       
     305
     306        current_stack_info_t info;
     307
     308        // LIB_DEBUG_PRINTF("Kernel : core    base : %p \n", info.base );
     309        // LIB_DEBUG_PRINTF("Kernel : core storage : %p \n", info.storage );
     310        // LIB_DEBUG_PRINTF("Kernel : core    size : %x \n", info.size );
     311        // LIB_DEBUG_PRINTF("Kernel : core   limit : %p \n", info.limit );
     312        // LIB_DEBUG_PRINTF("Kernel : core context : %p \n", info.context );
     313        // LIB_DEBUG_PRINTF("Kernel : core     top : %p \n", info.top );
     314
     315        // Start by initializing the main thread
     316        mainThread = (thread *)&mainThread_storage;
     317        mainThread{ &info };
     318
     319        // Initialize the system cluster
     320        systemCluster = (cluster *)&systemCluster_storage;
     321        systemCluster{};
     322
     323        // Initialize the system processor and the system processor ctx
     324        // (the coroutine that contains the processing control flow)
     325        systemProcessor = (processor *)&systemProcessor_storage;
     326        systemProcessor{ systemCluster, (processorCtx_t *)&systemProcessorCtx_storage };
     327
     328        // Add the main thread to the ready queue
     329        // once resume is called on systemProcessor->ctx the mainThread needs to be scheduled like any normal thread
     330        thread_schedule(mainThread);
     331
     332        //initialize the global state variables
     333        this_processor = systemProcessor;
     334        this_processor->current_thread = mainThread;
     335        this_processor->current_coroutine = &mainThread->c;
     336
     337        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
     338        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
     339        // mainThread is on the ready queue when this call is made.
     340        resume(systemProcessor->ctx);
     341
     342
     343
     344        // THE SYSTEM IS NOW COMPLETELY RUNNING
     345
     346
     347
     348        LIB_DEBUG_PRINTF("Kernel : Started\n--------------------------------------------------\n\n");
     349}
     350
     351void kernel_shutdown(void) {
     352        LIB_DEBUG_PRINTF("\n--------------------------------------------------\nKernel : Shutting down\n");
     353
     354        // SKULLDUGGERY: Notify the systemProcessor it needs to terminates.
     355        // When its coroutine terminates, it return control to the mainThread
     356        // which is currently here
     357        systemProcessor->terminated = true;
     358        suspend();
     359
     360        // THE SYSTEM IS NOW COMPLETELY STOPPED
     361
     362        // Destroy the system processor and its context in reverse order of construction
     363        // These were manually constructed so we need manually destroy them
     364        ^(systemProcessor->ctx){};
     365        ^(systemProcessor){};
     366
     367        // Final step, destroy the main thread since it is no longer needed
     368        // Since we provided a stack to this taxk it will not destroy anything
     369        ^(mainThread){};
     370
     371        LIB_DEBUG_PRINTF("Kernel : Shutdown complete\n");       
     372}
     373
     374//-----------------------------------------------------------------------------
     375// Locks
     376void ?{}( simple_lock * this ) {
     377        ( &this->blocked ){};
     378}
     379
     380void ^?{}( simple_lock * this ) {
     381
     382}
     383
     384void lock( simple_lock * this ) {
     385        {
     386                pthread_spinlock_guard guard = { &systemCluster->lock };        //HUGE TEMP HACK which only works if we have a single cluster and is stupid
     387                append( &this->blocked, this_thread() );
     388        }
     389        suspend();
     390}
     391
     392void unlock( simple_lock * this ) {
     393        thread * it;
     394        while( it = pop_head( &this->blocked) ) {
     395                thread_schedule( it );
     396        }
     397}
     398
     399//-----------------------------------------------------------------------------
     400// Queues
     401void ?{}( simple_thread_list * this ) {
     402        this->head = NULL;
     403        this->tail = &this->head;
     404}
     405
     406void append( simple_thread_list * this, thread * t ) {
     407        assert( t->next == NULL );
     408        *this->tail = t;
     409        this->tail = &t->next;
     410}
     411
     412thread * pop_head( simple_thread_list * this ) {
     413        thread * head = this->head;
     414        if( head ) {
     415                this->head = head->next;
     416                if( !head->next ) {
     417                        this->tail = &this->head;
    146418                }
    147         }
    148         assert(false);
    149 }
    150 
    151 void scheduler_remove( struct thread_h * thrd ) {
    152         LIB_DEBUG_PRINTF("Kernel : unscheduling %p from core %p\n", thrd, systemProcessor);
    153         for(int i = 0; i < systemProcessor->thread_count; i++) {
    154                 if(systemProcessor->threads[i] == thrd) {
    155                         systemProcessor->threads[i] = NULL;
    156                         break;
    157                 }
    158         }
    159         for(int i = 0; i < systemProcessor->thread_count; i++) {
    160                 if(systemProcessor->threads[i] != NULL) {
    161                         return;
    162                 }
    163         }
    164         LIB_DEBUG_PRINTF("Kernel : terminating core %p\n\n\n", systemProcessor);       
    165         systemProcessor->terminated = true;
    166 }
    167 
    168 void kernel_run( void ) {
    169         CtxInvokeProcessor(systemProcessor);
    170 }
    171 
     419                head->next = NULL;
     420        }       
     421       
     422        return head;
     423}
    172424// Local Variables: //
    173425// mode: c //
  • src/libcfa/concurrency/threads

    r6acb935 ra362f97  
    2727// Anything that implements this trait can be resumed.
    2828// Anything that is resumed is a coroutine.
    29 trait is_thread(dtype T /*| sized(T)*/) {
     29trait is_thread(dtype T | sized(T)) {
    3030      void main(T* this);
    31       thread_h* get_thread(T* this);
    32         /*void ?{}(T*);
    33         void ^?{}(T*);*/
     31      thread* get_thread(T* this);
    3432};
    3533
    36 forall(otype T | is_thread(T) )
     34#define DECL_THREAD(X) static inline thread* get_thread(X* this) { return &this->t; } void main(X* this);
     35
     36forall( dtype T | sized(T) | is_thread(T) )
    3737static inline coroutine* get_coroutine(T* this) {
    3838        return &get_thread(this)->c;
    3939}
    4040
    41 static inline coroutine* get_coroutine(thread_h* this) {
     41static inline coroutine* get_coroutine(thread* this) {
    4242        return &this->c;
    4343}
    4444
     45thread * this_thread(void);
     46
    4547//-----------------------------------------------------------------------------
    4648// Ctors and dtors
    47 void ?{}(thread_h* this);
    48 void ^?{}(thread_h* this);
     49void ?{}(thread* this);
     50void ^?{}(thread* this);
    4951
    5052//-----------------------------------------------------------------------------
    5153// thread runner
    5254// Structure that actually start and stop threads
    53 forall(otype T | is_thread(T) )
    54 struct thread {
     55forall( dtype T | sized(T) | is_thread(T) )
     56struct scoped {
    5557        T handle;
    5658};
    5759
    58 forall(otype T | is_thread(T) )
    59 void ?{}( thread(T)* this );
     60forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T*); } )
     61void ?{}( scoped(T)* this );
    6062
    61 forall(otype T, ttype P | is_thread(T) | { void ?{}(T*, P); } )
    62 void ?{}( thread(T)* this, P params );
     63forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T*, P); } )
     64void ?{}( scoped(T)* this, P params );
    6365
    64 forall(otype T | is_thread(T) )
    65 void ^?{}( thread(T)* this );
     66forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } )
     67void ^?{}( scoped(T)* this );
    6668
    67 //-----------------------------------------------------------------------------
    68 // PRIVATE exposed because of inline
     69void yield();
    6970
    7071#endif //THREADS_H
  • src/libcfa/concurrency/threads.c

    r6acb935 ra362f97  
    2323#include "invoke.h"
    2424
    25 #include <stdlib>
     25extern "C" {
     26        #include <stddef.h>
     27}
     28
     29extern processor * get_this_processor();
    2630
    2731//-----------------------------------------------------------------------------
    2832// Forward declarations
    29 forall(otype T | is_thread(T) )
    30 void start( thread(T)* this );
     33forall( dtype T | sized(T) | is_thread(T) )
     34void start( T* this );
    3135
    32 forall(otype T | is_thread(T) )
    33 void stop( thread(T)* this );
     36forall( dtype T | sized(T) | is_thread(T) )
     37void stop( T* this );
    3438
    3539//-----------------------------------------------------------------------------
    3640// Thread ctors and dtors
    3741
    38 void ?{}(thread_h* this) {
     42void ?{}(thread* this) {
    3943        (&this->c){};
     44        this->c.name = "Anonymous Coroutine";
     45        (&this->lock){};
     46        this->next = NULL;
    4047}
    4148
    42 void ^?{}(thread_h* this) {
     49void ^?{}(thread* this) {
    4350        ^(&this->c){};
    4451}
    4552
    46 forall(otype T | is_thread(T) )
    47 void ?{}( thread(T)* this ) {
    48         printf("thread() ctor\n");
     53forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T*); } )
     54void ?{}( scoped(T)* this ) {
    4955        (&this->handle){};
    50         start(this);
     56        start(&this->handle);
    5157}
    5258
    53 forall(otype T, ttype P | is_thread(T) | { void ?{}(T*, P); } )
    54 void ?{}( thread(T)* this, P params ) {
     59forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T*, P); } )
     60void ?{}( scoped(T)* this, P params ) {
    5561        (&this->handle){ params };
    56         start(this);
     62        start(&this->handle);
    5763}
    5864
    59 forall(otype T | is_thread(T) )
    60 void ^?{}( thread(T)* this ) {
    61         stop(this);
     65forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } )
     66void ^?{}( scoped(T)* this ) {
     67        stop(&this->handle);
    6268        ^(&this->handle){};
    6369}
     
    7076}
    7177
    72 forall(otype T | is_thread(T))
    73 void start( thread(T)* this ) {
    74         T* handle  = &this->handle;
    75         coroutine* thrd_c = get_coroutine(handle);
    76         thread_h*  thrd_h = get_thread   (handle);
     78extern void thread_schedule( thread * );
     79
     80forall( dtype T | sized(T) | is_thread(T) )
     81void start( T* this ) {
     82        coroutine* thrd_c = get_coroutine(this);
     83        thread*  thrd_h = get_thread   (this);
    7784        thrd_c->last = this_coroutine();
    78         current_coroutine = thrd_c;
     85        get_this_processor()->current_coroutine = thrd_c;
    7986
    8087        // LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", handle, thrd_c, thrd_h);
    8188
    8289        create_stack(&thrd_c->stack, thrd_c->stack.size);
    83         CtxStart(handle, CtxInvokeThread);
     90        CtxStart(this, CtxInvokeThread);
    8491        CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context );
    8592
    86         scheduler_add(thrd_h);
     93        thread_schedule(thrd_h);
    8794}
    8895
    89 forall(otype T | is_thread(T) )
    90 void stop( thread(T)* this ) {
     96forall( dtype T | sized(T) | is_thread(T) )
     97void stop( T* this ) {
     98        thread*  thrd = get_thread(this);
     99        if( thrd->c.notHalted ) {
     100                lock( &thrd->lock );
     101        }
     102}
    91103
     104void signal_termination( thread * this ) {
     105        this->c.state = Halt;
     106      this->c.notHalted = false;
     107        unlock( &this->lock );
     108}
     109
     110void yield( void ) {
     111        thread_schedule( this_thread() );
     112        suspend();
    92113}
    93114
  • src/tests/.expect/32/declarationSpecifier.txt

    r6acb935 ra362f97  
    1 extern void *malloc(unsigned int __size);
    2 extern void free(void *__ptr);
    3 extern void abort(void);
    4 extern int atexit(void (*__func)(void));
    5 extern void exit(int __status);
     1__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
     2__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
     3__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
     4__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
     5__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
    66extern int printf(const char *__restrict __format, ...);
    77volatile const short __x1__CVs_1;
     
    1616    int __i__i_1;
    1717};
    18 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
    1918static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
    2019static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
    2120static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
     21static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
    2222static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){
    2323    ((void)((*((int *)(&(*___dst__P13s__anonymous0_1).__i__i_1)))) /* ?{} */);
     
    4040    int __i__i_1;
    4141};
    42 static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
    4342static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1);
    4443static inline void ___constructor__F_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
    4544static inline void ___destructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1);
     45static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
    4646static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1){
    4747    ((void)((*((int *)(&(*___dst__P13s__anonymous1_1).__i__i_1)))) /* ?{} */);
     
    6464    int __i__i_1;
    6565};
    66 static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
    6766static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1);
    6867static inline void ___constructor__F_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
    6968static inline void ___destructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1);
     69static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
    7070static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1){
    7171    ((void)((*((int *)(&(*___dst__P13s__anonymous2_1).__i__i_1)))) /* ?{} */);
     
    8888    int __i__i_1;
    8989};
    90 static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
    9190static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1);
    9291static inline void ___constructor__F_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
    9392static inline void ___destructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1);
     93static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
    9494static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1){
    9595    ((void)((*((int *)(&(*___dst__P13s__anonymous3_1).__i__i_1)))) /* ?{} */);
     
    112112    int __i__i_1;
    113113};
    114 static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
    115114static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1);
    116115static inline void ___constructor__F_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
    117116static inline void ___destructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1);
     117static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
    118118static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1){
    119119    ((void)((*((int *)(&(*___dst__P13s__anonymous4_1).__i__i_1)))) /* ?{} */);
     
    136136    int __i__i_1;
    137137};
    138 static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
    139138static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1);
    140139static inline void ___constructor__F_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
    141140static inline void ___destructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1);
     141static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
    142142static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1){
    143143    ((void)((*((int *)(&(*___dst__P13s__anonymous5_1).__i__i_1)))) /* ?{} */);
     
    160160    int __i__i_1;
    161161};
    162 static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
    163162static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1);
    164163static inline void ___constructor__F_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
    165164static inline void ___destructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1);
     165static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
    166166static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1){
    167167    ((void)((*((int *)(&(*___dst__P13s__anonymous6_1).__i__i_1)))) /* ?{} */);
     
    184184    int __i__i_1;
    185185};
    186 static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
    187186static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1);
    188187static inline void ___constructor__F_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
    189188static inline void ___destructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1);
     189static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
    190190static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1){
    191191    ((void)((*((int *)(&(*___dst__P13s__anonymous7_1).__i__i_1)))) /* ?{} */);
     
    216216    short __i__s_1;
    217217};
    218 static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
    219218static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1);
    220219static inline void ___constructor__F_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
    221220static inline void ___destructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1);
     221static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
    222222static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1){
    223223    ((void)((*((short *)(&(*___dst__P13s__anonymous8_1).__i__s_1)))) /* ?{} */);
     
    240240    short __i__s_1;
    241241};
    242 static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
    243242static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1);
    244243static inline void ___constructor__F_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
    245244static inline void ___destructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1);
     245static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
    246246static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1){
    247247    ((void)((*((short *)(&(*___dst__P13s__anonymous9_1).__i__s_1)))) /* ?{} */);
     
    264264    short __i__s_1;
    265265};
    266 static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
    267266static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1);
    268267static inline void ___constructor__F_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
    269268static inline void ___destructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1);
     269static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
    270270static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1){
    271271    ((void)((*((short *)(&(*___dst__P14s__anonymous10_1).__i__s_1)))) /* ?{} */);
     
    288288    short __i__s_1;
    289289};
    290 static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
    291290static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1);
    292291static inline void ___constructor__F_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
    293292static inline void ___destructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1);
     293static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
    294294static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1){
    295295    ((void)((*((short *)(&(*___dst__P14s__anonymous11_1).__i__s_1)))) /* ?{} */);
     
    312312    short __i__s_1;
    313313};
    314 static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
    315314static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1);
    316315static inline void ___constructor__F_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
    317316static inline void ___destructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1);
     317static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
    318318static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1){
    319319    ((void)((*((short *)(&(*___dst__P14s__anonymous12_1).__i__s_1)))) /* ?{} */);
     
    336336    short __i__s_1;
    337337};
    338 static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
    339338static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1);
    340339static inline void ___constructor__F_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
    341340static inline void ___destructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1);
     341static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
    342342static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1){
    343343    ((void)((*((short *)(&(*___dst__P14s__anonymous13_1).__i__s_1)))) /* ?{} */);
     
    360360    short __i__s_1;
    361361};
    362 static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
    363362static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1);
    364363static inline void ___constructor__F_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
    365364static inline void ___destructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1);
     365static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
    366366static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1){
    367367    ((void)((*((short *)(&(*___dst__P14s__anonymous14_1).__i__s_1)))) /* ?{} */);
     
    384384    short __i__s_1;
    385385};
    386 static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
    387386static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1);
    388387static inline void ___constructor__F_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
    389388static inline void ___destructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1);
     389static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
    390390static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1){
    391391    ((void)((*((short *)(&(*___dst__P14s__anonymous15_1).__i__s_1)))) /* ?{} */);
     
    424424    int __i__i_1;
    425425};
    426 static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
    427426static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1);
    428427static inline void ___constructor__F_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
    429428static inline void ___destructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1);
     429static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
    430430static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1){
    431431    ((void)((*((int *)(&(*___dst__P14s__anonymous16_1).__i__i_1)))) /* ?{} */);
     
    448448    int __i__i_1;
    449449};
    450 static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
    451450static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1);
    452451static inline void ___constructor__F_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
    453452static inline void ___destructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1);
     453static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
    454454static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1){
    455455    ((void)((*((int *)(&(*___dst__P14s__anonymous17_1).__i__i_1)))) /* ?{} */);
     
    472472    int __i__i_1;
    473473};
    474 static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
    475474static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1);
    476475static inline void ___constructor__F_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
    477476static inline void ___destructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1);
     477static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
    478478static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1){
    479479    ((void)((*((int *)(&(*___dst__P14s__anonymous18_1).__i__i_1)))) /* ?{} */);
     
    496496    int __i__i_1;
    497497};
    498 static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
    499498static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1);
    500499static inline void ___constructor__F_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
    501500static inline void ___destructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1);
     501static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
    502502static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1){
    503503    ((void)((*((int *)(&(*___dst__P14s__anonymous19_1).__i__i_1)))) /* ?{} */);
     
    520520    int __i__i_1;
    521521};
    522 static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
    523522static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1);
    524523static inline void ___constructor__F_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
    525524static inline void ___destructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1);
     525static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
    526526static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1){
    527527    ((void)((*((int *)(&(*___dst__P14s__anonymous20_1).__i__i_1)))) /* ?{} */);
     
    544544    int __i__i_1;
    545545};
    546 static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
    547546static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1);
    548547static inline void ___constructor__F_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
    549548static inline void ___destructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1);
     549static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
    550550static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1){
    551551    ((void)((*((int *)(&(*___dst__P14s__anonymous21_1).__i__i_1)))) /* ?{} */);
     
    568568    int __i__i_1;
    569569};
    570 static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
    571570static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1);
    572571static inline void ___constructor__F_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
    573572static inline void ___destructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1);
     573static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
    574574static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1){
    575575    ((void)((*((int *)(&(*___dst__P14s__anonymous22_1).__i__i_1)))) /* ?{} */);
     
    592592    int __i__i_1;
    593593};
    594 static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
    595594static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1);
    596595static inline void ___constructor__F_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
    597596static inline void ___destructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1);
     597static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
    598598static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1){
    599599    ((void)((*((int *)(&(*___dst__P14s__anonymous23_1).__i__i_1)))) /* ?{} */);
     
    629629}
    630630static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); }
    631 extern void *malloc(unsigned int __size);
    632 extern void free(void *__ptr);
    633 extern void abort(void);
    634 extern int atexit(void (*__func)(void));
    635 extern void exit(int __status);
     631__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
     632__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
     633__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
     634__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
     635__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
    636636extern int printf(const char *__restrict __format, ...);
    637637static inline int invoke_main(int argc, char **argv, char **envp);
     
    640640    int _tmp_cp_ret0;
    641641    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
    642     ((void)(_tmp_cp_ret0) /* ^?{} */);
     642    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    643643    return ((int )___retval_main__i_1);
    644644}
  • src/tests/.expect/32/extension.txt

    r6acb935 ra362f97  
    1 extern void *malloc(unsigned int __size);
    2 extern void free(void *__ptr);
    3 extern void abort(void);
    4 extern int atexit(void (*__func)(void));
    5 extern void exit(int __status);
     1__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
     2__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
     3__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
     4__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
     5__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
    66extern int printf(const char *__restrict __format, ...);
    77__extension__ int __a__i_1;
     
    1313    __extension__ int __c__i_1;
    1414};
    15 static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
    1615static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1);
    1716static inline void ___constructor__F_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
    1817static inline void ___destructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1);
     18static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
    1919static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1){
    2020    ((void)((*((int *)(&(*___dst__P2sS_1).__a__i_1)))) /* ?{} */);
     
    9393    int _tmp_cp_ret0;
    9494    ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0));
    95     ((void)(_tmp_cp_ret0) /* ^?{} */);
     95    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    9696    ((void)__extension__ sizeof(3));
    9797    ((void)__extension__ (((int )(3!=((int )0))) || ((int )(4!=((int )0)))));
  • src/tests/.expect/32/gccExtensions.txt

    r6acb935 ra362f97  
    1 extern void *malloc(unsigned int __size);
    2 extern void free(void *__ptr);
    3 extern void abort(void);
    4 extern int atexit(void (*__func)(void));
    5 extern void exit(int __status);
     1__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
     2__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
     3__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
     4__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
     5__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
    66extern int printf(const char *__restrict __format, ...);
    77extern int __x__i_1 asm ( "xx" );
     
    166166}
    167167static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); }
    168 extern void *malloc(unsigned int __size);
    169 extern void free(void *__ptr);
    170 extern void abort(void);
    171 extern int atexit(void (*__func)(void));
    172 extern void exit(int __status);
     168__attribute__ ((__malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);
     169__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
     170__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void abort(void);
     171__attribute__ ((__nonnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));
     172__attribute__ ((__noreturn__,__nothrow__,__leaf__)) extern void exit(int __status);
    173173extern int printf(const char *__restrict __format, ...);
    174174static inline int invoke_main(int argc, char **argv, char **envp);
     
    177177    int _tmp_cp_ret0;
    178178    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
    179     ((void)(_tmp_cp_ret0) /* ^?{} */);
     179    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    180180    return ((int )___retval_main__i_1);
    181181}
  • src/tests/.expect/64/declarationSpecifier.txt

    r6acb935 ra362f97  
    1616    int __i__i_1;
    1717};
    18 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
    1918static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
    2019static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
    2120static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
     21static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
    2222static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){
    2323    ((void)((*((int *)(&(*___dst__P13s__anonymous0_1).__i__i_1)))) /* ?{} */);
     
    4040    int __i__i_1;
    4141};
    42 static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
    4342static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1);
    4443static inline void ___constructor__F_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
    4544static inline void ___destructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1);
     45static inline struct __anonymous1 ___operator_assign__F13s__anonymous1_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1);
    4646static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1){
    4747    ((void)((*((int *)(&(*___dst__P13s__anonymous1_1).__i__i_1)))) /* ?{} */);
     
    6464    int __i__i_1;
    6565};
    66 static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
    6766static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1);
    6867static inline void ___constructor__F_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
    6968static inline void ___destructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1);
     69static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
    7070static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1){
    7171    ((void)((*((int *)(&(*___dst__P13s__anonymous2_1).__i__i_1)))) /* ?{} */);
     
    8888    int __i__i_1;
    8989};
    90 static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
    9190static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1);
    9291static inline void ___constructor__F_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
    9392static inline void ___destructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1);
     93static inline struct __anonymous3 ___operator_assign__F13s__anonymous3_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1);
    9494static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1){
    9595    ((void)((*((int *)(&(*___dst__P13s__anonymous3_1).__i__i_1)))) /* ?{} */);
     
    112112    int __i__i_1;
    113113};
    114 static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
    115114static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1);
    116115static inline void ___constructor__F_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
    117116static inline void ___destructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1);
     117static inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1);
    118118static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1){
    119119    ((void)((*((int *)(&(*___dst__P13s__anonymous4_1).__i__i_1)))) /* ?{} */);
     
    136136    int __i__i_1;
    137137};
    138 static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
    139138static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1);
    140139static inline void ___constructor__F_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
    141140static inline void ___destructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1);
     141static inline struct __anonymous5 ___operator_assign__F13s__anonymous5_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1);
    142142static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1){
    143143    ((void)((*((int *)(&(*___dst__P13s__anonymous5_1).__i__i_1)))) /* ?{} */);
     
    160160    int __i__i_1;
    161161};
    162 static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
    163162static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1);
    164163static inline void ___constructor__F_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
    165164static inline void ___destructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1);
     165static inline struct __anonymous6 ___operator_assign__F13s__anonymous6_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1);
    166166static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1){
    167167    ((void)((*((int *)(&(*___dst__P13s__anonymous6_1).__i__i_1)))) /* ?{} */);
     
    184184    int __i__i_1;
    185185};
    186 static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
    187186static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1);
    188187static inline void ___constructor__F_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
    189188static inline void ___destructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1);
     189static inline struct __anonymous7 ___operator_assign__F13s__anonymous7_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1);
    190190static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1){
    191191    ((void)((*((int *)(&(*___dst__P13s__anonymous7_1).__i__i_1)))) /* ?{} */);
     
    216216    short __i__s_1;
    217217};
    218 static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
    219218static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1);
    220219static inline void ___constructor__F_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
    221220static inline void ___destructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1);
     221static inline struct __anonymous8 ___operator_assign__F13s__anonymous8_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1);
    222222static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1){
    223223    ((void)((*((short *)(&(*___dst__P13s__anonymous8_1).__i__s_1)))) /* ?{} */);
     
    240240    short __i__s_1;
    241241};
    242 static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
    243242static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1);
    244243static inline void ___constructor__F_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
    245244static inline void ___destructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1);
     245static inline struct __anonymous9 ___operator_assign__F13s__anonymous9_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1);
    246246static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1){
    247247    ((void)((*((short *)(&(*___dst__P13s__anonymous9_1).__i__s_1)))) /* ?{} */);
     
    264264    short __i__s_1;
    265265};
    266 static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
    267266static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1);
    268267static inline void ___constructor__F_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
    269268static inline void ___destructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1);
     269static inline struct __anonymous10 ___operator_assign__F14s__anonymous10_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1);
    270270static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1){
    271271    ((void)((*((short *)(&(*___dst__P14s__anonymous10_1).__i__s_1)))) /* ?{} */);
     
    288288    short __i__s_1;
    289289};
    290 static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
    291290static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1);
    292291static inline void ___constructor__F_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
    293292static inline void ___destructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1);
     293static inline struct __anonymous11 ___operator_assign__F14s__anonymous11_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1);
    294294static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1){
    295295    ((void)((*((short *)(&(*___dst__P14s__anonymous11_1).__i__s_1)))) /* ?{} */);
     
    312312    short __i__s_1;
    313313};
    314 static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
    315314static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1);
    316315static inline void ___constructor__F_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
    317316static inline void ___destructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1);
     317static inline struct __anonymous12 ___operator_assign__F14s__anonymous12_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1);
    318318static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1){
    319319    ((void)((*((short *)(&(*___dst__P14s__anonymous12_1).__i__s_1)))) /* ?{} */);
     
    336336    short __i__s_1;
    337337};
    338 static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
    339338static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1);
    340339static inline void ___constructor__F_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
    341340static inline void ___destructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1);
     341static inline struct __anonymous13 ___operator_assign__F14s__anonymous13_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1);
    342342static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1){
    343343    ((void)((*((short *)(&(*___dst__P14s__anonymous13_1).__i__s_1)))) /* ?{} */);
     
    360360    short __i__s_1;
    361361};
    362 static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
    363362static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1);
    364363static inline void ___constructor__F_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
    365364static inline void ___destructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1);
     365static inline struct __anonymous14 ___operator_assign__F14s__anonymous14_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1);
    366366static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1){
    367367    ((void)((*((short *)(&(*___dst__P14s__anonymous14_1).__i__s_1)))) /* ?{} */);
     
    384384    short __i__s_1;
    385385};
    386 static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
    387386static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1);
    388387static inline void ___constructor__F_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
    389388static inline void ___destructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1);
     389static inline struct __anonymous15 ___operator_assign__F14s__anonymous15_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1);
    390390static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1){
    391391    ((void)((*((short *)(&(*___dst__P14s__anonymous15_1).__i__s_1)))) /* ?{} */);
     
    424424    int __i__i_1;
    425425};
    426 static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
    427426static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1);
    428427static inline void ___constructor__F_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
    429428static inline void ___destructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1);
     429static inline struct __anonymous16 ___operator_assign__F14s__anonymous16_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1);
    430430static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1){
    431431    ((void)((*((int *)(&(*___dst__P14s__anonymous16_1).__i__i_1)))) /* ?{} */);
     
    448448    int __i__i_1;
    449449};
    450 static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
    451450static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1);
    452451static inline void ___constructor__F_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
    453452static inline void ___destructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1);
     453static inline struct __anonymous17 ___operator_assign__F14s__anonymous17_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1);
    454454static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1){
    455455    ((void)((*((int *)(&(*___dst__P14s__anonymous17_1).__i__i_1)))) /* ?{} */);
     
    472472    int __i__i_1;
    473473};
    474 static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
    475474static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1);
    476475static inline void ___constructor__F_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
    477476static inline void ___destructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1);
     477static inline struct __anonymous18 ___operator_assign__F14s__anonymous18_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1);
    478478static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1){
    479479    ((void)((*((int *)(&(*___dst__P14s__anonymous18_1).__i__i_1)))) /* ?{} */);
     
    496496    int __i__i_1;
    497497};
    498 static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
    499498static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1);
    500499static inline void ___constructor__F_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
    501500static inline void ___destructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1);
     501static inline struct __anonymous19 ___operator_assign__F14s__anonymous19_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1);
    502502static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1){
    503503    ((void)((*((int *)(&(*___dst__P14s__anonymous19_1).__i__i_1)))) /* ?{} */);
     
    520520    int __i__i_1;
    521521};
    522 static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
    523522static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1);
    524523static inline void ___constructor__F_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
    525524static inline void ___destructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1);
     525static inline struct __anonymous20 ___operator_assign__F14s__anonymous20_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1);
    526526static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1){
    527527    ((void)((*((int *)(&(*___dst__P14s__anonymous20_1).__i__i_1)))) /* ?{} */);
     
    544544    int __i__i_1;
    545545};
    546 static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
    547546static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1);
    548547static inline void ___constructor__F_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
    549548static inline void ___destructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1);
     549static inline struct __anonymous21 ___operator_assign__F14s__anonymous21_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1);
    550550static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1){
    551551    ((void)((*((int *)(&(*___dst__P14s__anonymous21_1).__i__i_1)))) /* ?{} */);
     
    568568    int __i__i_1;
    569569};
    570 static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
    571570static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1);
    572571static inline void ___constructor__F_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
    573572static inline void ___destructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1);
     573static inline struct __anonymous22 ___operator_assign__F14s__anonymous22_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1);
    574574static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1){
    575575    ((void)((*((int *)(&(*___dst__P14s__anonymous22_1).__i__i_1)))) /* ?{} */);
     
    592592    int __i__i_1;
    593593};
    594 static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
    595594static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1);
    596595static inline void ___constructor__F_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
    597596static inline void ___destructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1);
     597static inline struct __anonymous23 ___operator_assign__F14s__anonymous23_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1);
    598598static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1){
    599599    ((void)((*((int *)(&(*___dst__P14s__anonymous23_1).__i__i_1)))) /* ?{} */);
     
    640640    int _tmp_cp_ret0;
    641641    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
    642     ((void)(_tmp_cp_ret0) /* ^?{} */);
     642    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    643643    return ((int )___retval_main__i_1);
    644644}
  • src/tests/.expect/64/extension.txt

    r6acb935 ra362f97  
    1313    __extension__ int __c__i_1;
    1414};
    15 static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
    1615static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1);
    1716static inline void ___constructor__F_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
    1817static inline void ___destructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1);
     18static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);
    1919static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1){
    2020    ((void)((*((int *)(&(*___dst__P2sS_1).__a__i_1)))) /* ?{} */);
     
    9393    int _tmp_cp_ret0;
    9494    ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0));
    95     ((void)(_tmp_cp_ret0) /* ^?{} */);
     95    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    9696    ((void)__extension__ sizeof(3));
    9797    ((void)__extension__ (((int )(3!=((int )0))) || ((int )(4!=((int )0)))));
  • src/tests/.expect/64/gccExtensions.txt

    r6acb935 ra362f97  
    177177    int _tmp_cp_ret0;
    178178    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
    179     ((void)(_tmp_cp_ret0) /* ^?{} */);
     179    ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */);
    180180    return ((int )___retval_main__i_1);
    181181}
  • src/tests/Makefile.am

    r6acb935 ra362f97  
    3030
    3131all-local :
    32         @+python test.py vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once
     32        @+python test.py vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once coroutine
    3333
    3434all-tests :
  • src/tests/Makefile.in

    r6acb935 ra362f97  
    651651
    652652all-local :
    653         @+python test.py vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once
     653        @+python test.py vector_test avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once coroutine
    654654
    655655all-tests :
  • src/tests/vector/array.c

    r6acb935 ra362f97  
    1616#include "array.h"
    1717
    18 /// forall( otype array_type, elt_type | bounded_array( array_type, elt_type ) )
    19 /// [ array_iterator begin, array_iterator end ]
    20 /// get_iterators( array_type array )
    21 /// {
    22 ///   begin = 0;
    23 ///   end = last( array );
    24 /// }
     18forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
     19[ elt_type * begin, elt_type * end ] get_iterators( array_type * array ) {
     20        return [ begin( array ), end( array ) ];
     21}
    2522
    2623// The first element is always at index 0.
  • src/tests/vector/array.h

    r6acb935 ra362f97  
    3232// implement iterator_for
    3333
    34 typedef int array_iterator;
    35 
    36 /// forall( otype array_type, elt_type | bounded_array( array_type, elt_type ) )
    37 /// [ array_iterator begin, array_iterator end ] get_iterators( array_type );
     34forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
     35[ elt_type * begin, elt_type * end ] get_iterators( array_type * );
    3836
    3937
Note: See TracChangeset for help on using the changeset viewer.