Changeset a362f97
- Timestamp:
- Jan 27, 2017, 3:27:34 PM (8 years ago)
- 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. - Files:
-
- 5 added
- 40 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/proposals/concurrency/thePlan.md
r6acb935 ra362f97 1 1 _Phase 1_ : Prototype 2 Threads and Processors. 3 Main needs to call process 2 done - Threads. 3 done - Main thread is a cfa thread. 4 done - SimpleBlockingLock. 5 done - Synchronisation points in thread destructors. 6 done - Processors & SpinLock. 4 7 5 8 _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. 9 Monitor type and enter/leave mutex member routines 10 Monitors as a language feature (not calling enter/leave by hand) 11 Internal scheduling 10 12 11 13 _Phase 3_ : Kernel features 12 Threads features ex: detach 13 Internal scheduling 14 Clusters 14 Detach thread 15 Cluster migration 16 Preemption 15 17 16 18 _Phase 4_ : Monitor features -
src/Common/utility.h
r6acb935 ra362f97 252 252 253 253 template< typename T > 254 struct reverse Iterate_t {254 struct reverse_iterate_t { 255 255 T& ref; 256 256 257 reverse Iterate_t( T & ref ) : ref(ref) {}257 reverse_iterate_t( T & ref ) : ref(ref) {} 258 258 259 259 typedef typename T::reverse_iterator iterator; … … 263 263 264 264 template< typename T > 265 reverseIterate_t< T > reverseIterate( T & ref ) { 266 return reverseIterate_t< T >( ref ); 267 } 268 265 reverse_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 275 template< typename T1, typename T2 > 276 struct 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 297 private: 298 std::tuple<T1, T2> args; 299 }; 300 301 template< typename... Args > 302 group_iterate_t<Args...> group_iterate( const Args &... args ) { 303 return group_iterate_t<Args...>(args...); 304 } 269 305 #endif // _UTILITY_H 270 306 -
src/GenPoly/InstantiateGeneric.cc
r6acb935 ra362f97 220 220 assert(paramType && "Aggregate parameters should be type expressions"); 221 221 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 225 224 out.push_back( paramType->clone() ); 226 225 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; 240 241 } 241 242 } -
src/GenPoly/Specialize.cc
r6acb935 ra362f97 35 35 36 36 namespace GenPoly { 37 class Specializer;38 37 class Specialize final : public PolyMutator { 39 friend class Specializer;40 38 public: 41 39 using PolyMutator::mutate; … … 47 45 // virtual Expression * mutate( CommaExpr *commaExpr ); 48 46 49 Specializer * specializer = nullptr;50 47 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"; 51 52 }; 52 53 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 conversion68 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 conversion76 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 83 54 /// 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 ) { 85 56 if ( env ) { 86 57 using namespace ResolvExpr; … … 106 77 } 107 78 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 ) { 166 91 assertf( actual->has_result(), "attempting to specialize an untyped expression" ); 167 92 if ( needsSpecialization( formalType, actual->get_result(), env ) ) { … … 185 110 } 186 111 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 194 112 /// restructures arg to match the structure of a single formal parameter. Assumes that atomic types are compatible (as the Resolver should have ensured this) 195 113 template< typename OutIterator > … … 207 125 208 126 /// 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. 211 129 template< typename Iterator, typename OutIterator > 212 130 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" ); 226 149 227 150 FunctionType *newType = funType->clone(); … … 253 176 std::list< DeclarationWithType * >::iterator formalEnd = funType->get_parameters().end(); 254 177 255 Expression * last = nullptr;256 178 for ( DeclarationWithType* param : thunkFunc->get_functionType()->get_parameters() ) { 257 179 // 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. … … 259 181 assertf( formalBegin != formalEnd, "Reached end of formal parameters before finding ttype parameter" ); 260 182 if ( Tuples::isTtype((*formalBegin)->get_type()) ) { 261 last = new VariableExpr( param);183 fixLastArg( new VariableExpr( param ), actualBegin, actualEnd, back_inserter( appExpr->get_args() ) ); 262 184 break; 263 185 } … … 268 190 appExpr->get_args().push_back( new VariableExpr( param ) ); 269 191 } // for 270 assert( last );271 fixLastArg( last, actualBegin, actualEnd, back_inserter( appExpr->get_args() ) );272 192 appExpr->set_env( maybeClone( env ) ); 273 193 if ( inferParams ) { … … 281 201 std::list< Statement* > oldStmts; 282 202 oldStmts.splice( oldStmts.end(), stmtsToAdd ); 283 spec.mutate( appExpr );203 mutate( appExpr ); 284 204 paramPrefix = oldParamPrefix; 285 205 // write any statements added for recursive specializations into the thunk body … … 311 231 std::list< Expression* >::iterator actual; 312 232 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() ); 314 234 } 315 235 } … … 322 242 // create thunks for the inferred parameters 323 243 // 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 ); 324 247 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() ); 326 249 } 327 handleExplicitParams( appExpr );328 250 } 329 251 return appExpr; … … 333 255 addrExpr->get_arg()->acceptMutator( *this ); 334 256 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() ) ); 336 258 return addrExpr; 337 259 } … … 343 265 return castExpr; 344 266 } 345 Expression *specialized = specializer->doSpecialization( castExpr->get_result(), castExpr->get_arg() );267 Expression *specialized = doSpecialization( castExpr->get_result(), castExpr->get_arg() ); 346 268 if ( specialized != castExpr->get_arg() ) { 347 269 // assume here that the specialization incorporates the cast … … 370 292 void convertSpecializations( std::list< Declaration* >& translationUnit ) { 371 293 Specialize spec; 372 373 TupleSpecializer tupleSpec( spec );374 spec.specializer = &tupleSpec;375 mutateAll( translationUnit, spec );376 377 PolySpecializer polySpec( spec );378 spec.specializer = &polySpec;379 294 mutateAll( translationUnit, spec ); 380 295 } -
src/InitTweak/FixGlobalInit.cc
r6acb935 ra362f97 84 84 // for library code are run before constructors and destructors for user code, 85 85 // specify a priority when building the library. Priorities 0-100 are reserved by gcc. 86 ctorParameters.push_back( new ConstantExpr( Constant::from_int( 10 1) ) );87 dtorParameters.push_back( new ConstantExpr( Constant::from_int( 10 1) ) );86 ctorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) ); 87 dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) ); 88 88 } 89 89 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 21 21 #include <unordered_set> 22 22 #include "InitTweak.h" 23 #include "GenInit.h" 23 24 #include "FixInit.h" 24 25 #include "FixGlobalInit.h" … … 86 87 /// create and resolve ctor/dtor expression: fname(var, [cpArg]) 87 88 Expression * makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg = NULL ); 88 Expression * makeCtorDtor( const std::string & fname, Expression * thisArg, Expression * cpArg = NULL );89 89 /// true if type does not need to be copy constructed to ensure correctness 90 90 bool skipCopyConstruct( Type * type ); 91 91 void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr ); 92 void destructRet( Expression* ret, ImplicitCopyCtorExpr * impCpCtorExpr );92 void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ); 93 93 94 94 TypeSubstitution * env; … … 398 398 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) { 399 399 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(); 408 404 409 405 // resolve copy constructor … … 420 416 } // if 421 417 422 delete untyped;418 delete stmt; 423 419 return resolved; 424 420 } … … 456 452 } 457 453 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 ) ); 460 456 } 461 457 … … 487 483 if ( ! result->get_isLvalue() ) { 488 484 // 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 ); 490 486 } 491 487 } // for … … 515 511 last->set_expr( makeCtorDtor( "?{}", ret, last->get_expr() ) ); 516 512 517 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", new AddressExpr( new VariableExpr( ret ) )) );513 stmtExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) ); 518 514 } // if 519 515 -
src/InitTweak/GenInit.cc
r6acb935 ra362f97 247 247 managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) ); 248 248 } 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; 249 259 } 250 260 -
src/InitTweak/GenInit.h
r6acb935 ra362f97 28 28 void genInit( std::list< Declaration * > & translationUnit ); 29 29 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 30 33 /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer 31 34 ConstructorInit * genCtorInit( ObjectDecl * objDecl ); -
src/InitTweak/InitTweak.cc
r6acb935 ra362f97 327 327 } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) { 328 328 return handleDerefCalledFunction( appExpr ); 329 } else if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( expr ) ) { 330 return getCalledFunction( addrExpr->get_arg() ); 329 331 } 330 332 return nullptr; … … 336 338 if ( ! appExpr ) return NULL; 337 339 DeclarationWithType * function = getCalledFunction( appExpr->get_function() ); 338 assert ( function);340 assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() ); 339 341 // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor 340 342 // will call all member dtors, and some members may have a user defined dtor. … … 386 388 } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) { 387 389 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 ); 388 397 } else { 389 assertf( false, "Unexpected expression type passed to getCallArg ");398 assertf( false, "Unexpected expression type passed to getCallArg: %s", toString( callExpr ).c_str() ); 390 399 } 391 400 } … … 538 547 } 539 548 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 } 540 568 FunctionDecl * isCopyConstructor( Declaration * decl ) { 541 569 return isCopyFunction( decl, "?{}" ); -
src/InitTweak/InitTweak.h
r6acb935 ra362f97 32 32 bool isCtorDtorAssign( const std::string & ); 33 33 34 FunctionDecl * isAssignment( Declaration * decl ); 35 FunctionDecl * isDestructor( Declaration * decl ); 36 FunctionDecl * isDefaultConstructor( Declaration * decl ); 34 37 FunctionDecl * isCopyConstructor( Declaration * decl ); 35 38 FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ); -
src/Parser/TypeData.cc
r6acb935 ra362f97 57 57 aggregate.actuals = nullptr; 58 58 aggregate.fields = nullptr; 59 aggregate.body = false; 59 60 break; 60 61 case AggregateInst: -
src/ResolvExpr/Unify.cc
r6acb935 ra362f97 123 123 } 124 124 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-ness138 virtual void visit( TypeofType *typeofType ) { assert( false ); }139 virtual void visit( AttrType *attrType ) { assert( false ); } // xxx - not sure what to do here140 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 152 125 bool tyVarCompatible( const TypeDecl::Data & data, Type *type, const SymTab::Indexer &indexer ) { 153 126 switch ( data.kind ) { … … 158 131 // type must also be complete 159 132 // 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() ); 161 134 case TypeDecl::Ftype: 162 135 return isFtype( type, indexer ); 163 136 case TypeDecl::Ttype: 164 137 // ttype unifies with any tuple type 165 return dynamic_cast< TupleType * >( type ) ;138 return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type ); 166 139 } // switch 167 140 return false; … … 488 461 } 489 462 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 ) { 492 465 std::list< Type * > types; 493 466 for ( ; begin != end; ++begin ) { 494 467 // 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 ) ); 496 469 } 497 470 return std::unique_ptr<Type>( new TupleType( Type::Qualifiers(), types ) ); … … 500 473 template< typename Iterator1, typename Iterator2 > 501 474 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(); }; 502 476 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { 503 477 Type * t1 = (*list1Begin)->get_type(); … … 509 483 if ( isTtype1 && ! isTtype2 ) { 510 484 // 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 ); 512 486 } else if ( isTtype2 && ! isTtype1 ) { 513 487 // 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 ); 515 489 } else if ( ! unifyExact( t1, t2, env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ) ) { 516 490 return false; … … 522 496 Type * t1 = (*list1Begin)->get_type(); 523 497 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 ); 525 499 } else return false; 526 500 } else if ( list2Begin != list2End ) { … … 528 502 Type * t2 = (*list2Begin)->get_type(); 529 503 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 ); 531 505 } else return false; 532 506 } else { … … 665 639 template< typename Iterator1, typename Iterator2 > 666 640 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; }; 667 642 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 ) ) { 670 656 return false; 671 } 672 delete commonType; 657 } // if 658 673 659 } // 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; 676 672 } else { 677 673 return true; 678 } // if674 } // if 679 675 } 680 676 681 677 void Unify::visit(TupleType *tupleType) { 682 678 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 ); 684 691 } // if 685 692 } -
src/SymTab/Autogen.cc
r6acb935 ra362f97 25 25 #include "Autogen.h" 26 26 #include "GenPoly/ScopedSet.h" 27 #include "Common/ScopedMap.h" 27 28 #include "SymTab/Mangler.h" 28 29 #include "GenPoly/DeclMutator.h" … … 30 31 namespace SymTab { 31 32 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 { 34 45 public: 35 46 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } … … 37 48 typedef Visitor Parent; 38 49 using Parent::visit; 50 51 AutogenerateRoutines(); 39 52 40 53 virtual void visit( EnumDecl *enumDecl ); … … 57 70 std::set< std::string > structsDone; 58 71 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; 59 77 }; 60 78 … … 144 162 decl->fixUniqueId(); 145 163 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 ); 146 226 } 147 227 … … 308 388 309 389 /// 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 ) { 312 391 // Make function polymorphic in same parameters as generic struct, if applicable 313 392 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 314 393 bool isDynamicLayout = hasDynamicLayout( aggregateDecl ); // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union) 315 394 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() ); } ); 334 403 335 404 if ( functionNesting == 0 ) { … … 338 407 // Note: this is necessary if we want structs which contain 339 408 // 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 ); 344 430 } 345 431 346 432 // create constructors which take each member type as a parameter. 347 433 // 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 } 390 463 } 391 464 … … 481 554 } 482 555 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 483 565 void AutogenerateRoutines::visit( EnumDecl *enumDecl ) { 484 566 if ( ! enumDecl->get_members().empty() ) { … … 491 573 492 574 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() ) { 494 576 StructInstType structInst( Type::Qualifiers(), structDecl->get_name() ); 495 577 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 ); 496 580 structInst.get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) ); 497 581 } 498 582 structInst.set_baseStruct( structDecl ); 499 makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd );583 makeStructFunctions( structDecl, &structInst, functionNesting, declsToAdd, data ); 500 584 structsDone.insert( structDecl->get_name() ); 501 585 } // if … … 564 648 565 649 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 566 656 maybeAccept( functionDecl->get_functionType(), *this ); 567 657 acceptAll( functionDecl->get_oldDecls(), *this ); … … 572 662 573 663 void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) { 664 constructable.beginScope(); 665 assignable.beginScope(); 666 copyable.beginScope(); 667 destructable.beginScope(); 574 668 visitStatement( compoundStmt ); 669 constructable.endScope(); 670 assignable.endScope(); 671 copyable.endScope(); 672 destructable.endScope(); 575 673 } 576 674 -
src/SymTab/FixFunction.cc
r6acb935 ra362f97 25 25 26 26 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(); 28 29 delete functionDecl; 29 30 return pointer; -
src/SymTab/Validate.cc
r6acb935 ra362f97 114 114 LinkReferenceToTypes( bool doDebug, const Indexer *indexer ); 115 115 private: 116 using Indexer::visit;116 using Parent::visit; 117 117 void visit( StructInstType *structInst ) final; 118 118 void visit( UnionInstType *unionInst ) final; … … 131 131 132 132 /// Replaces array and function types in forall lists by appropriate pointer type 133 class Pass3 : public Indexer {133 class Pass3 final : public Indexer { 134 134 typedef Indexer Parent; 135 135 public: 136 using Parent::visit; 136 137 Pass3( const Indexer *indexer ); 137 138 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; 140 141 141 142 const Indexer *indexer; … … 375 376 } 376 377 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" ) { 380 381 // "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 ); 383 384 } 384 TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( contextInst->get_parameters().front() );385 TypeExpr * param = safe_dynamic_cast< TypeExpr * > ( traitInst->get_parameters().front() ); 385 386 TypeInstType * inst = safe_dynamic_cast< TypeInstType * > ( param->get_type() ); 386 387 TypeDecl * decl = inst->get_baseType(); … … 389 390 return; 390 391 } 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 } // if392 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() ); 402 403 } // for 403 404 } // for 404 405 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 410 407 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 } 414 421 } 415 422 … … 457 464 } 458 465 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() ) { 462 469 std::list< DeclarationWithType * > toBeDone, nextRound; 463 toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );470 toBeDone.splice( toBeDone.end(), type->get_assertions() ); 464 471 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 ); 470 477 nextRound.push_back( dwt->clone() ); 471 478 } 472 delete ctx;479 delete traitInst; 473 480 } else { 481 // pass assertion through 474 482 FixFunction fixer; 475 *assertion = (*assertion )->acceptMutator( fixer );483 assertion = assertion->acceptMutator( fixer ); 476 484 if ( fixer.get_isVoid() ) { 477 485 throw SemanticError( "invalid type void in assertion of function ", func ); 478 486 } 479 (*type )->get_assertions().push_back( *assertion );487 type->get_assertions().push_back( assertion ); 480 488 } // if 481 489 } // for … … 629 637 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( ret->get_type() ) ) { 630 638 // 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; 632 643 } else if ( objDecl->get_isInline() || objDecl->get_isNoreturn() ) { 633 644 throw SemanticError( "invalid inline or _Noreturn specification in declaration of ", objDecl ); -
src/SynTree/AggregateDecl.cc
r6acb935 ra362f97 69 69 std::string EnumDecl::typeString() const { return "enum"; } 70 70 71 std::string TraitDecl::typeString() const { return " context"; }71 std::string TraitDecl::typeString() const { return "trait"; } 72 72 73 73 // Local Variables: // -
src/SynTree/ReferenceToType.cc
r6acb935 ra362f97 64 64 } 65 65 66 bool StructInstType::isComplete() const { return baseStruct->has_body(); } 67 66 68 void StructInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const { 67 69 assert( baseStruct ); … … 90 92 } 91 93 94 bool UnionInstType::isComplete() const { return baseUnion->has_body(); } 95 92 96 void UnionInstType::lookup( const std::string &name, std::list< Declaration* > &foundDecls ) const { 93 97 assert( baseUnion ); … … 111 115 std::string EnumInstType::typeString() const { return "enum"; } 112 116 113 std::string TraitInstType::typeString() const { return " context"; }117 std::string TraitInstType::typeString() const { return "trait"; } 114 118 115 119 TraitInstType::TraitInstType( const TraitInstType &other ) : Parent( other ) { … … 120 124 deleteAll( members ); 121 125 } 126 127 bool TraitInstType::isComplete() const { assert( false ); } 122 128 123 129 TypeInstType::TypeInstType( const Type::Qualifiers &tq, const std::string &name, TypeDecl *baseType ) : Parent( tq, name ) { … … 143 149 std::string TypeInstType::typeString() const { return "type"; } 144 150 151 bool TypeInstType::isComplete() const { return baseType->isComplete(); } 152 145 153 void TypeInstType::print( std::ostream &os, int indent ) const { 146 154 using std::endl; -
src/SynTree/Type.h
r6acb935 ra362f97 74 74 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; } 75 75 76 virtual bool isComplete() const { return true; } 77 76 78 virtual Type *clone() const = 0; 77 79 virtual void accept( Visitor &v ) = 0; … … 90 92 91 93 virtual unsigned size() const { return 0; }; 94 virtual bool isComplete() const { return false; } 92 95 93 96 virtual VoidType *clone() const { return new VoidType( *this ); } … … 185 188 void set_isStatic( bool newValue ) { isStatic = newValue; } 186 189 190 virtual bool isComplete() const { return ! isVarLen; } 191 187 192 virtual ArrayType *clone() const { return new ArrayType( *this ); } 188 193 virtual void accept( Visitor &v ) { v.visit( this ); } … … 258 263 std::list<TypeDecl*> * get_baseParameters(); 259 264 265 virtual bool isComplete() const; 266 260 267 /// Looks up the members of this struct named "name" and places them into "foundDecls". 261 268 /// Clones declarations into "foundDecls", caller responsible for freeing … … 287 294 std::list<TypeDecl*> * get_baseParameters(); 288 295 296 virtual bool isComplete() const; 297 289 298 /// looks up the members of this union named "name" and places them into "foundDecls" 290 299 /// Clones declarations into "foundDecls", caller responsible for freeing … … 310 319 EnumInstType( const EnumInstType &other ) : Parent( other ) {} 311 320 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 312 324 virtual EnumInstType *clone() const { return new EnumInstType( *this ); } 313 325 virtual void accept( Visitor &v ) { v.visit( this ); } … … 325 337 326 338 std::list< Declaration* >& get_members() { return members; } 339 340 virtual bool isComplete() const; 327 341 328 342 virtual TraitInstType *clone() const { return new TraitInstType( *this ); } … … 349 363 bool get_isFtype() const { return isFtype; } 350 364 void set_isFtype( bool newValue ) { isFtype = newValue; } 365 366 virtual bool isComplete() const; 351 367 352 368 virtual TypeInstType *clone() const { return new TypeInstType( *this ); } … … 382 398 } 383 399 400 // virtual bool isComplete() const { return true; } // xxx - not sure if this is right, might need to recursively check complete-ness 401 384 402 virtual TupleType *clone() const { return new TupleType( *this ); } 385 403 virtual void accept( Visitor &v ) { v.visit( this ); } … … 398 416 Expression *get_expr() const { return expr; } 399 417 void set_expr( Expression *newValue ) { expr = newValue; } 418 419 virtual bool isComplete() const { assert( false ); return false; } 400 420 401 421 virtual TypeofType *clone() const { return new TypeofType( *this ); } … … 423 443 void set_isType( bool newValue ) { isType = newValue; } 424 444 445 virtual bool isComplete() const { assert( false ); } // xxx - not sure what to do here 446 425 447 virtual AttrType *clone() const { return new AttrType( *this ); } 426 448 virtual void accept( Visitor &v ) { v.visit( this ); } … … 439 461 VarArgsType(); 440 462 VarArgsType( Type::Qualifiers tq ); 463 464 virtual bool isComplete() const{ return true; } // xxx - is this right? 441 465 442 466 virtual VarArgsType *clone() const { return new VarArgsType( *this ); } -
src/driver/cfa.cc
r6acb935 ra362f97 267 267 } 268 268 nargs += 1; 269 args[nargs] = "-lpthread"; 270 nargs += 1; 269 271 } // if 270 272 #endif //HAVE_LIBCFA -
src/examples/thread.c
r6acb935 ra362f97 1 #include <fstream> 1 2 #include <kernel> 2 3 #include <stdlib> … … 4 5 5 6 // 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 17 7 struct MyThread { 18 thread _ht;8 thread t; 19 9 unsigned id; 20 10 unsigned count; 21 11 }; 22 12 13 DECL_THREAD(MyThread) 14 23 15 void ?{}( MyThread * this ) { 24 this->id = 0;25 this->count = 10;26 16 } 27 17 … … 31 21 } 32 22 33 void ^?{}( MyThread * this ) {}34 35 23 void 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(); 38 26 39 27 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(); 43 30 } 44 31 } 45 32 46 thread_h* get_thread(MyThread* this) { 47 return &this->t; 48 } 33 int main(int argc, char* argv[]) { 49 34 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 } 53 41 54 int main() { 42 sout | "User main begin" | endl; 55 43 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 } 58 51 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; 66 53 67 54 return 0; -
src/libcfa/concurrency/CtxSwitch-i386.S
r6acb935 ra362f97 86 86 ret 87 87 88 .text 89 .align 2 90 .globl CtxGet 91 CtxGet: 92 movl %esp,SP_OFFSET(%eax) 93 movl %ebp,FP_OFFSET(%eax) 94 95 ret 96 88 97 // Local Variables: // 89 98 // compile-command: "make install" // -
src/libcfa/concurrency/CtxSwitch-x86_64.S
r6acb935 ra362f97 84 84 jmp *%r12 85 85 86 .text 87 .align 2 88 .globl CtxGet 89 CtxGet: 90 movq %rsp,SP_OFFSET(%rdi) 91 movq %rbp,FP_OFFSET(%rdi) 92 93 ret 94 86 95 // Local Variables: // 87 96 // mode: c // -
src/libcfa/concurrency/coroutines
r6acb935 ra362f97 62 62 63 63 // Get current coroutine 64 extern coroutine * current_coroutine; //PRIVATE, never use directly 65 static inline coroutine * this_coroutine(void) { 66 return current_coroutine; 67 } 64 coroutine * this_coroutine(void); 68 65 69 66 // Private wrappers for context switch and stack creation … … 76 73 77 74 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" 79 76 "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.", 80 77 src->name, src ); 81 78 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" 83 80 "Possible cause is terminated coroutine's main routine has already returned.", 84 81 src->name, src, src->last->name, src->last ); -
src/libcfa/concurrency/coroutines.c
r6acb935 ra362f97 1 // -*- Mode: CFA -*- 1 2 // 2 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo … … 14 15 // 15 16 17 #include "coroutines" 18 16 19 extern "C" { 17 20 #include <stddef.h> … … 23 26 } 24 27 25 #include " coroutines"28 #include "kernel" 26 29 #include "libhdr.h" 27 30 28 31 #define __CFA_INVOKE_PRIVATE__ 29 32 #include "invoke.h" 33 34 extern processor * get_this_processor(); 30 35 31 36 //----------------------------------------------------------------------------- … … 35 40 #define MinStackSize 1000 36 41 static size_t pageSize = 0; // architecture pagesize HACK, should go in proper runtime singleton 37 38 //Extra private desctructor for the main39 //FIXME the main should not actually allocate a stack40 //Since the main is never resumed the extra stack does not cause41 //any problem but it is wasted memory42 void ?{}(coStack_t* this, size_t size);43 void ?{}(coroutine* this, size_t size);44 45 //Main coroutine46 //FIXME do not construct a stack for the main47 coroutine main_coroutine = { 1000 };48 49 //Current coroutine50 //Will need to be in TLS when multi-threading is added51 coroutine* current_coroutine = &main_coroutine;52 42 53 43 //----------------------------------------------------------------------------- … … 111 101 // is not inline (We can't inline Cforall in C) 112 102 void 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 115 103 suspend(); 116 104 } … … 123 111 124 112 // set new coroutine that task is executing 125 current_coroutine = dst;113 get_this_processor()->current_coroutine = dst; 126 114 127 115 // 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 // 1 16 2 17 #include <stdbool.h> … … 14 29 15 30 extern void __suspend_no_inline__F___1(void); 16 extern void __s cheduler_remove__F_P9sthread_h__1(struct thread_h*);31 extern void __signal_termination__F_P7sthread__1(struct thread*); 17 32 18 33 void CtxInvokeCoroutine( … … 33 48 main( this ); 34 49 50 cor->state = Halt; 51 cor->notHalted = false; 52 35 53 //Final suspend, should never return 36 54 __suspend_no_inline__F___1(); … … 40 58 void CtxInvokeThread( 41 59 void (*main)(void *), 42 struct thread _h*(*get_thread)(void *),60 struct thread *(*get_thread)(void *), 43 61 void *this 44 62 ) { … … 47 65 __suspend_no_inline__F___1(); 48 66 49 struct thread _h* thrd = get_thread( this );67 struct thread* thrd = get_thread( this ); 50 68 struct coroutine* cor = &thrd->c; 51 69 cor->state = Active; … … 54 72 main( this ); 55 73 56 __s cheduler_remove__F_P9sthread_h__1(thrd);74 __signal_termination__F_P7sthread__1(thrd); 57 75 58 76 //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 1 17 #include <stdbool.h> 2 18 #include <stdint.h> … … 11 27 12 28 #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 13 44 14 45 struct coStack_t { … … 35 66 }; 36 67 37 struct thread_h { 68 struct simple_lock { 69 struct simple_thread_list blocked; 70 }; 71 72 struct thread { 38 73 struct coroutine c; 74 struct simple_lock lock; 75 struct thread * next; 39 76 }; 40 77 … … 52 89 // assembler routines that performs the context switch 53 90 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"); 55 93 56 94 #endif //_INVOKE_PRIVATE_H_ -
src/libcfa/concurrency/kernel
r6acb935 ra362f97 20 20 #include <stdbool.h> 21 21 22 #include "invoke.h" 23 24 extern "C" { 25 #include <pthread.h> 26 } 27 28 //----------------------------------------------------------------------------- 29 // Cluster 30 struct cluster { 31 simple_thread_list ready_queue; 32 pthread_spinlock_t lock; 33 }; 34 35 void ?{}(cluster * this); 36 void ^?{}(cluster * this); 37 38 //----------------------------------------------------------------------------- 39 // Processor 22 40 struct 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; 28 48 }; 29 49 30 50 void ?{}(processor * this); 51 void ?{}(processor * this, cluster * cltr); 31 52 void ^?{}(processor * this); 32 53 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 58 void ?{}(simple_lock * this); 59 void ^?{}(simple_lock * this); 60 61 void lock( simple_lock * ); 62 void unlock( simple_lock * ); 63 64 struct pthread_spinlock_guard { 65 pthread_spinlock_t * lock; 66 }; 67 68 static inline void ?{}( pthread_spinlock_guard * this, pthread_spinlock_t * lock ) { 69 this->lock = lock; 70 pthread_spin_lock( this->lock ); 71 } 72 73 static 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 // } 36 100 37 101 #endif //KERNEL_H -
src/libcfa/concurrency/kernel.c
r6acb935 ra362f97 20 20 //C Includes 21 21 #include <stddef.h> 22 extern "C" { 23 #include <sys/resource.h> 24 } 22 25 23 26 //CFA Includes … … 29 32 #include "invoke.h" 30 33 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 36 struct processorCtx_t { 54 37 processor * proc; 55 38 coroutine c; 56 39 }; 57 40 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}; 41 DECL_COROUTINE(processorCtx_t) 42 43 #define KERNEL_STORAGE(T,X) static char X##_storage[sizeof(T)] 44 45 KERNEL_STORAGE(processorCtx_t, systemProcessorCtx); 46 KERNEL_STORAGE(cluster, systemCluster); 47 KERNEL_STORAGE(processor, systemProcessor); 48 KERNEL_STORAGE(thread, mainThread); 49 KERNEL_STORAGE(machine_context_t, mainThread_context); 50 51 cluster * systemCluster; 52 processor * systemProcessor; 53 thread * mainThread; 54 55 void kernel_startup(void) __attribute__((constructor(101))); 56 void kernel_shutdown(void) __attribute__((destructor(101))); 57 58 //----------------------------------------------------------------------------- 59 // Global state 60 61 thread_local processor * this_processor; 62 63 processor * get_this_processor() { 64 return this_processor; 65 } 66 67 coroutine * this_coroutine(void) { 68 return this_processor->current_coroutine; 69 } 70 71 thread * this_thread(void) { 72 return this_processor->current_thread; 73 } 74 75 //----------------------------------------------------------------------------- 76 // Main thread construction 77 struct 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 87 void ?{}( 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 101 void ?{}( 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 111 void ?{}( 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 119 void ?{}( thread * this, current_stack_info_t * info) { 120 (&this->c){ info }; 121 } 122 123 //----------------------------------------------------------------------------- 124 // Processor coroutine 125 void ?{}(processorCtx_t * this, processor * proc) { 126 (&this->c){}; 66 127 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 131 void ?{}(processorCtx_t * this, processor * proc, current_stack_info_t * info) { 132 (&this->c){ info }; 133 this->proc = proc; 134 proc->ctx = this; 135 } 136 137 void start(processor * this); 138 139 void ?{}(processor * this) { 140 this{ systemCluster }; 141 } 142 143 void ?{}(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 153 void ?{}(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 165 void ^?{}(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 173 void ?{}(cluster * this) { 174 ( &this->ready_queue ){}; 175 pthread_spin_init( &this->lock, PTHREAD_PROCESS_PRIVATE ); 176 } 177 178 void ^?{}(cluster * this) { 179 pthread_spin_destroy( &this->lock ); 77 180 } 78 181 79 182 //----------------------------------------------------------------------------- 80 183 // Processor running routines 81 void main(proc _coroutine * cor);82 thread _h * nextThread(processor * this);83 void runThread(processor * this, thread _h* dst);184 void main(processorCtx_t * ctx); 185 thread * nextThread(cluster * this); 186 void runThread(processor * this, thread * dst); 84 187 void spin(processor * this, unsigned int * spin_count); 85 188 86 void main(proc _coroutine * cor) {87 processor * this ;88 this = cor->proc;89 90 thread _h* readyThread = NULL;189 void main(processorCtx_t * ctx) { 190 processor * this = ctx->proc; 191 LIB_DEBUG_PRINTF("Kernel : core %p starting\n", this); 192 193 thread * readyThread = NULL; 91 194 for( unsigned int spin_count = 0; ! this->terminated; spin_count++ ) { 92 195 93 readyThread = nextThread( this);196 readyThread = nextThread( this->cltr ); 94 197 95 198 if(readyThread) { … … 101 204 } 102 205 206 LIB_DEBUG_PRINTF("Kernel : core %p unlocking thread\n", this); 207 unlock( &this->lock ); 103 208 LIB_DEBUG_PRINTF("Kernel : core %p terminated\n", this); 104 209 } 105 210 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); 211 void runThread(processor * this, thread * dst) { 212 coroutine * proc_ctx = get_coroutine(this->ctx); 119 213 coroutine * thrd_ctx = get_coroutine(dst); 120 214 thrd_ctx->last = proc_ctx; … … 122 216 // context switch to specified coroutine 123 217 // 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; 126 221 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); 129 224 130 225 // when CtxSwitch returns we are back in the processor coroutine … … 135 230 } 136 231 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; 232 void * 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 271 void 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 286 void 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 293 thread * nextThread(cluster * this) { 294 pthread_spinlock_guard guard = { &this->lock }; 295 return pop_head( &this->ready_queue ); 296 } 297 298 //----------------------------------------------------------------------------- 299 // Kernel boot procedures 300 void 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 351 void 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 376 void ?{}( simple_lock * this ) { 377 ( &this->blocked ){}; 378 } 379 380 void ^?{}( simple_lock * this ) { 381 382 } 383 384 void 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 392 void unlock( simple_lock * this ) { 393 thread * it; 394 while( it = pop_head( &this->blocked) ) { 395 thread_schedule( it ); 396 } 397 } 398 399 //----------------------------------------------------------------------------- 400 // Queues 401 void ?{}( simple_thread_list * this ) { 402 this->head = NULL; 403 this->tail = &this->head; 404 } 405 406 void append( simple_thread_list * this, thread * t ) { 407 assert( t->next == NULL ); 408 *this->tail = t; 409 this->tail = &t->next; 410 } 411 412 thread * 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; 146 418 } 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 } 172 424 // Local Variables: // 173 425 // mode: c // -
src/libcfa/concurrency/threads
r6acb935 ra362f97 27 27 // Anything that implements this trait can be resumed. 28 28 // Anything that is resumed is a coroutine. 29 trait is_thread(dtype T /*| sized(T)*/) {29 trait is_thread(dtype T | sized(T)) { 30 30 void main(T* this); 31 thread_h* get_thread(T* this); 32 /*void ?{}(T*); 33 void ^?{}(T*);*/ 31 thread* get_thread(T* this); 34 32 }; 35 33 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 36 forall( dtype T | sized(T) | is_thread(T) ) 37 37 static inline coroutine* get_coroutine(T* this) { 38 38 return &get_thread(this)->c; 39 39 } 40 40 41 static inline coroutine* get_coroutine(thread _h* this) {41 static inline coroutine* get_coroutine(thread* this) { 42 42 return &this->c; 43 43 } 44 44 45 thread * this_thread(void); 46 45 47 //----------------------------------------------------------------------------- 46 48 // Ctors and dtors 47 void ?{}(thread _h* this);48 void ^?{}(thread _h* this);49 void ?{}(thread* this); 50 void ^?{}(thread* this); 49 51 50 52 //----------------------------------------------------------------------------- 51 53 // thread runner 52 54 // Structure that actually start and stop threads 53 forall( otype T| is_thread(T) )54 struct thread {55 forall( dtype T | sized(T) | is_thread(T) ) 56 struct scoped { 55 57 T handle; 56 58 }; 57 59 58 forall( otype T | is_thread(T))59 void ?{}( thread(T)* this );60 forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T*); } ) 61 void ?{}( scoped(T)* this ); 60 62 61 forall( otype T, ttype P| is_thread(T) | { void ?{}(T*, P); } )62 void ?{}( thread(T)* this, P params );63 forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T*, P); } ) 64 void ?{}( scoped(T)* this, P params ); 63 65 64 forall( otype T | is_thread(T))65 void ^?{}( thread(T)* this );66 forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } ) 67 void ^?{}( scoped(T)* this ); 66 68 67 //----------------------------------------------------------------------------- 68 // PRIVATE exposed because of inline 69 void yield(); 69 70 70 71 #endif //THREADS_H -
src/libcfa/concurrency/threads.c
r6acb935 ra362f97 23 23 #include "invoke.h" 24 24 25 #include <stdlib> 25 extern "C" { 26 #include <stddef.h> 27 } 28 29 extern processor * get_this_processor(); 26 30 27 31 //----------------------------------------------------------------------------- 28 32 // Forward declarations 29 forall( otype T| is_thread(T) )30 void start( thread(T)* this );33 forall( dtype T | sized(T) | is_thread(T) ) 34 void start( T* this ); 31 35 32 forall( otype T| is_thread(T) )33 void stop( thread(T)* this );36 forall( dtype T | sized(T) | is_thread(T) ) 37 void stop( T* this ); 34 38 35 39 //----------------------------------------------------------------------------- 36 40 // Thread ctors and dtors 37 41 38 void ?{}(thread _h* this) {42 void ?{}(thread* this) { 39 43 (&this->c){}; 44 this->c.name = "Anonymous Coroutine"; 45 (&this->lock){}; 46 this->next = NULL; 40 47 } 41 48 42 void ^?{}(thread _h* this) {49 void ^?{}(thread* this) { 43 50 ^(&this->c){}; 44 51 } 45 52 46 forall(otype T | is_thread(T) ) 47 void ?{}( thread(T)* this ) { 48 printf("thread() ctor\n"); 53 forall( dtype T | sized(T) | is_thread(T) | { void ?{}(T*); } ) 54 void ?{}( scoped(T)* this ) { 49 55 (&this->handle){}; 50 start( this);56 start(&this->handle); 51 57 } 52 58 53 forall( otype T, ttype P| is_thread(T) | { void ?{}(T*, P); } )54 void ?{}( thread(T)* this, P params ) {59 forall( dtype T, ttype P | sized(T) | is_thread(T) | { void ?{}(T*, P); } ) 60 void ?{}( scoped(T)* this, P params ) { 55 61 (&this->handle){ params }; 56 start( this);62 start(&this->handle); 57 63 } 58 64 59 forall( otype T | is_thread(T))60 void ^?{}( thread(T)* this ) {61 stop( this);65 forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } ) 66 void ^?{}( scoped(T)* this ) { 67 stop(&this->handle); 62 68 ^(&this->handle){}; 63 69 } … … 70 76 } 71 77 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); 78 extern void thread_schedule( thread * ); 79 80 forall( dtype T | sized(T) | is_thread(T) ) 81 void start( T* this ) { 82 coroutine* thrd_c = get_coroutine(this); 83 thread* thrd_h = get_thread (this); 77 84 thrd_c->last = this_coroutine(); 78 current_coroutine = thrd_c;85 get_this_processor()->current_coroutine = thrd_c; 79 86 80 87 // LIB_DEBUG_PRINTF("Thread start : %p (t %p, c %p)\n", handle, thrd_c, thrd_h); 81 88 82 89 create_stack(&thrd_c->stack, thrd_c->stack.size); 83 CtxStart( handle, CtxInvokeThread);90 CtxStart(this, CtxInvokeThread); 84 91 CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context ); 85 92 86 scheduler_add(thrd_h);93 thread_schedule(thrd_h); 87 94 } 88 95 89 forall(otype T | is_thread(T) ) 90 void stop( thread(T)* this ) { 96 forall( dtype T | sized(T) | is_thread(T) ) 97 void stop( T* this ) { 98 thread* thrd = get_thread(this); 99 if( thrd->c.notHalted ) { 100 lock( &thrd->lock ); 101 } 102 } 91 103 104 void signal_termination( thread * this ) { 105 this->c.state = Halt; 106 this->c.notHalted = false; 107 unlock( &this->lock ); 108 } 109 110 void yield( void ) { 111 thread_schedule( this_thread() ); 112 suspend(); 92 113 } 93 114 -
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); 6 6 extern int printf(const char *__restrict __format, ...); 7 7 volatile const short __x1__CVs_1; … … 16 16 int __i__i_1; 17 17 }; 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);19 18 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1); 20 19 static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1); 21 20 static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1); 21 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); 22 22 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){ 23 23 ((void)((*((int *)(&(*___dst__P13s__anonymous0_1).__i__i_1)))) /* ?{} */); … … 40 40 int __i__i_1; 41 41 }; 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);43 42 static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1); 44 43 static inline void ___constructor__F_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1); 45 44 static inline void ___destructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1); 45 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); 46 46 static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1){ 47 47 ((void)((*((int *)(&(*___dst__P13s__anonymous1_1).__i__i_1)))) /* ?{} */); … … 64 64 int __i__i_1; 65 65 }; 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);67 66 static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1); 68 67 static inline void ___constructor__F_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1); 69 68 static inline void ___destructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1); 69 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); 70 70 static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1){ 71 71 ((void)((*((int *)(&(*___dst__P13s__anonymous2_1).__i__i_1)))) /* ?{} */); … … 88 88 int __i__i_1; 89 89 }; 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);91 90 static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1); 92 91 static inline void ___constructor__F_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1); 93 92 static inline void ___destructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1); 93 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); 94 94 static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1){ 95 95 ((void)((*((int *)(&(*___dst__P13s__anonymous3_1).__i__i_1)))) /* ?{} */); … … 112 112 int __i__i_1; 113 113 }; 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);115 114 static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1); 116 115 static inline void ___constructor__F_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1); 117 116 static inline void ___destructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1); 117 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); 118 118 static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1){ 119 119 ((void)((*((int *)(&(*___dst__P13s__anonymous4_1).__i__i_1)))) /* ?{} */); … … 136 136 int __i__i_1; 137 137 }; 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);139 138 static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1); 140 139 static inline void ___constructor__F_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1); 141 140 static inline void ___destructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1); 141 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); 142 142 static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1){ 143 143 ((void)((*((int *)(&(*___dst__P13s__anonymous5_1).__i__i_1)))) /* ?{} */); … … 160 160 int __i__i_1; 161 161 }; 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);163 162 static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1); 164 163 static inline void ___constructor__F_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1); 165 164 static inline void ___destructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1); 165 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); 166 166 static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1){ 167 167 ((void)((*((int *)(&(*___dst__P13s__anonymous6_1).__i__i_1)))) /* ?{} */); … … 184 184 int __i__i_1; 185 185 }; 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);187 186 static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1); 188 187 static inline void ___constructor__F_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1); 189 188 static inline void ___destructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1); 189 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); 190 190 static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1){ 191 191 ((void)((*((int *)(&(*___dst__P13s__anonymous7_1).__i__i_1)))) /* ?{} */); … … 216 216 short __i__s_1; 217 217 }; 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);219 218 static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1); 220 219 static inline void ___constructor__F_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1); 221 220 static inline void ___destructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1); 221 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); 222 222 static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1){ 223 223 ((void)((*((short *)(&(*___dst__P13s__anonymous8_1).__i__s_1)))) /* ?{} */); … … 240 240 short __i__s_1; 241 241 }; 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);243 242 static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1); 244 243 static inline void ___constructor__F_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1); 245 244 static inline void ___destructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1); 245 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); 246 246 static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1){ 247 247 ((void)((*((short *)(&(*___dst__P13s__anonymous9_1).__i__s_1)))) /* ?{} */); … … 264 264 short __i__s_1; 265 265 }; 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);267 266 static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1); 268 267 static inline void ___constructor__F_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1); 269 268 static inline void ___destructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1); 269 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); 270 270 static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1){ 271 271 ((void)((*((short *)(&(*___dst__P14s__anonymous10_1).__i__s_1)))) /* ?{} */); … … 288 288 short __i__s_1; 289 289 }; 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);291 290 static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1); 292 291 static inline void ___constructor__F_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1); 293 292 static inline void ___destructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1); 293 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); 294 294 static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1){ 295 295 ((void)((*((short *)(&(*___dst__P14s__anonymous11_1).__i__s_1)))) /* ?{} */); … … 312 312 short __i__s_1; 313 313 }; 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);315 314 static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1); 316 315 static inline void ___constructor__F_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1); 317 316 static inline void ___destructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1); 317 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); 318 318 static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1){ 319 319 ((void)((*((short *)(&(*___dst__P14s__anonymous12_1).__i__s_1)))) /* ?{} */); … … 336 336 short __i__s_1; 337 337 }; 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);339 338 static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1); 340 339 static inline void ___constructor__F_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1); 341 340 static inline void ___destructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1); 341 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); 342 342 static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1){ 343 343 ((void)((*((short *)(&(*___dst__P14s__anonymous13_1).__i__s_1)))) /* ?{} */); … … 360 360 short __i__s_1; 361 361 }; 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);363 362 static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1); 364 363 static inline void ___constructor__F_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1); 365 364 static inline void ___destructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1); 365 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); 366 366 static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1){ 367 367 ((void)((*((short *)(&(*___dst__P14s__anonymous14_1).__i__s_1)))) /* ?{} */); … … 384 384 short __i__s_1; 385 385 }; 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);387 386 static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1); 388 387 static inline void ___constructor__F_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1); 389 388 static inline void ___destructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1); 389 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); 390 390 static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1){ 391 391 ((void)((*((short *)(&(*___dst__P14s__anonymous15_1).__i__s_1)))) /* ?{} */); … … 424 424 int __i__i_1; 425 425 }; 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);427 426 static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1); 428 427 static inline void ___constructor__F_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1); 429 428 static inline void ___destructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1); 429 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); 430 430 static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1){ 431 431 ((void)((*((int *)(&(*___dst__P14s__anonymous16_1).__i__i_1)))) /* ?{} */); … … 448 448 int __i__i_1; 449 449 }; 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);451 450 static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1); 452 451 static inline void ___constructor__F_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1); 453 452 static inline void ___destructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1); 453 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); 454 454 static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1){ 455 455 ((void)((*((int *)(&(*___dst__P14s__anonymous17_1).__i__i_1)))) /* ?{} */); … … 472 472 int __i__i_1; 473 473 }; 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);475 474 static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1); 476 475 static inline void ___constructor__F_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1); 477 476 static inline void ___destructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1); 477 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); 478 478 static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1){ 479 479 ((void)((*((int *)(&(*___dst__P14s__anonymous18_1).__i__i_1)))) /* ?{} */); … … 496 496 int __i__i_1; 497 497 }; 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);499 498 static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1); 500 499 static inline void ___constructor__F_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1); 501 500 static inline void ___destructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1); 501 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); 502 502 static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1){ 503 503 ((void)((*((int *)(&(*___dst__P14s__anonymous19_1).__i__i_1)))) /* ?{} */); … … 520 520 int __i__i_1; 521 521 }; 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);523 522 static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1); 524 523 static inline void ___constructor__F_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1); 525 524 static inline void ___destructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1); 525 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); 526 526 static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1){ 527 527 ((void)((*((int *)(&(*___dst__P14s__anonymous20_1).__i__i_1)))) /* ?{} */); … … 544 544 int __i__i_1; 545 545 }; 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);547 546 static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1); 548 547 static inline void ___constructor__F_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1); 549 548 static inline void ___destructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1); 549 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); 550 550 static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1){ 551 551 ((void)((*((int *)(&(*___dst__P14s__anonymous21_1).__i__i_1)))) /* ?{} */); … … 568 568 int __i__i_1; 569 569 }; 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);571 570 static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1); 572 571 static inline void ___constructor__F_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1); 573 572 static inline void ___destructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1); 573 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); 574 574 static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1){ 575 575 ((void)((*((int *)(&(*___dst__P14s__anonymous22_1).__i__i_1)))) /* ?{} */); … … 592 592 int __i__i_1; 593 593 }; 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);595 594 static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1); 596 595 static inline void ___constructor__F_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1); 597 596 static inline void ___destructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1); 597 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); 598 598 static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1){ 599 599 ((void)((*((int *)(&(*___dst__P14s__anonymous23_1).__i__i_1)))) /* ?{} */); … … 629 629 } 630 630 static 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); 636 636 extern int printf(const char *__restrict __format, ...); 637 637 static inline int invoke_main(int argc, char **argv, char **envp); … … 640 640 int _tmp_cp_ret0; 641 641 ((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)))) /* ^?{} */); 643 643 return ((int )___retval_main__i_1); 644 644 } -
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); 6 6 extern int printf(const char *__restrict __format, ...); 7 7 __extension__ int __a__i_1; … … 13 13 __extension__ int __c__i_1; 14 14 }; 15 static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);16 15 static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1); 17 16 static inline void ___constructor__F_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1); 18 17 static inline void ___destructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1); 18 static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1); 19 19 static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1){ 20 20 ((void)((*((int *)(&(*___dst__P2sS_1).__a__i_1)))) /* ?{} */); … … 93 93 int _tmp_cp_ret0; 94 94 ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0)); 95 ((void)( _tmp_cp_ret0) /* ^?{} */);95 ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */); 96 96 ((void)__extension__ sizeof(3)); 97 97 ((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); 6 6 extern int printf(const char *__restrict __format, ...); 7 7 extern int __x__i_1 asm ( "xx" ); … … 166 166 } 167 167 static 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); 173 173 extern int printf(const char *__restrict __format, ...); 174 174 static inline int invoke_main(int argc, char **argv, char **envp); … … 177 177 int _tmp_cp_ret0; 178 178 ((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)))) /* ^?{} */); 180 180 return ((int )___retval_main__i_1); 181 181 } -
src/tests/.expect/64/declarationSpecifier.txt
r6acb935 ra362f97 16 16 int __i__i_1; 17 17 }; 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);19 18 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1); 20 19 static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1); 21 20 static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1); 21 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); 22 22 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){ 23 23 ((void)((*((int *)(&(*___dst__P13s__anonymous0_1).__i__i_1)))) /* ?{} */); … … 40 40 int __i__i_1; 41 41 }; 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);43 42 static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1); 44 43 static inline void ___constructor__F_P13s__anonymous113s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1, struct __anonymous1 ___src__13s__anonymous1_1); 45 44 static inline void ___destructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1); 45 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); 46 46 static inline void ___constructor__F_P13s__anonymous1_autogen___1(struct __anonymous1 *___dst__P13s__anonymous1_1){ 47 47 ((void)((*((int *)(&(*___dst__P13s__anonymous1_1).__i__i_1)))) /* ?{} */); … … 64 64 int __i__i_1; 65 65 }; 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);67 66 static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1); 68 67 static inline void ___constructor__F_P13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1); 69 68 static inline void ___destructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1); 69 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); 70 70 static inline void ___constructor__F_P13s__anonymous2_autogen___1(struct __anonymous2 *___dst__P13s__anonymous2_1){ 71 71 ((void)((*((int *)(&(*___dst__P13s__anonymous2_1).__i__i_1)))) /* ?{} */); … … 88 88 int __i__i_1; 89 89 }; 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);91 90 static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1); 92 91 static inline void ___constructor__F_P13s__anonymous313s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1, struct __anonymous3 ___src__13s__anonymous3_1); 93 92 static inline void ___destructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1); 93 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); 94 94 static inline void ___constructor__F_P13s__anonymous3_autogen___1(struct __anonymous3 *___dst__P13s__anonymous3_1){ 95 95 ((void)((*((int *)(&(*___dst__P13s__anonymous3_1).__i__i_1)))) /* ?{} */); … … 112 112 int __i__i_1; 113 113 }; 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);115 114 static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1); 116 115 static inline void ___constructor__F_P13s__anonymous413s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1, struct __anonymous4 ___src__13s__anonymous4_1); 117 116 static inline void ___destructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1); 117 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); 118 118 static inline void ___constructor__F_P13s__anonymous4_autogen___1(struct __anonymous4 *___dst__P13s__anonymous4_1){ 119 119 ((void)((*((int *)(&(*___dst__P13s__anonymous4_1).__i__i_1)))) /* ?{} */); … … 136 136 int __i__i_1; 137 137 }; 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);139 138 static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1); 140 139 static inline void ___constructor__F_P13s__anonymous513s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1, struct __anonymous5 ___src__13s__anonymous5_1); 141 140 static inline void ___destructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1); 141 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); 142 142 static inline void ___constructor__F_P13s__anonymous5_autogen___1(struct __anonymous5 *___dst__P13s__anonymous5_1){ 143 143 ((void)((*((int *)(&(*___dst__P13s__anonymous5_1).__i__i_1)))) /* ?{} */); … … 160 160 int __i__i_1; 161 161 }; 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);163 162 static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1); 164 163 static inline void ___constructor__F_P13s__anonymous613s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1, struct __anonymous6 ___src__13s__anonymous6_1); 165 164 static inline void ___destructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1); 165 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); 166 166 static inline void ___constructor__F_P13s__anonymous6_autogen___1(struct __anonymous6 *___dst__P13s__anonymous6_1){ 167 167 ((void)((*((int *)(&(*___dst__P13s__anonymous6_1).__i__i_1)))) /* ?{} */); … … 184 184 int __i__i_1; 185 185 }; 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);187 186 static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1); 188 187 static inline void ___constructor__F_P13s__anonymous713s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1, struct __anonymous7 ___src__13s__anonymous7_1); 189 188 static inline void ___destructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1); 189 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); 190 190 static inline void ___constructor__F_P13s__anonymous7_autogen___1(struct __anonymous7 *___dst__P13s__anonymous7_1){ 191 191 ((void)((*((int *)(&(*___dst__P13s__anonymous7_1).__i__i_1)))) /* ?{} */); … … 216 216 short __i__s_1; 217 217 }; 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);219 218 static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1); 220 219 static inline void ___constructor__F_P13s__anonymous813s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1, struct __anonymous8 ___src__13s__anonymous8_1); 221 220 static inline void ___destructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1); 221 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); 222 222 static inline void ___constructor__F_P13s__anonymous8_autogen___1(struct __anonymous8 *___dst__P13s__anonymous8_1){ 223 223 ((void)((*((short *)(&(*___dst__P13s__anonymous8_1).__i__s_1)))) /* ?{} */); … … 240 240 short __i__s_1; 241 241 }; 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);243 242 static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1); 244 243 static inline void ___constructor__F_P13s__anonymous913s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1, struct __anonymous9 ___src__13s__anonymous9_1); 245 244 static inline void ___destructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1); 245 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); 246 246 static inline void ___constructor__F_P13s__anonymous9_autogen___1(struct __anonymous9 *___dst__P13s__anonymous9_1){ 247 247 ((void)((*((short *)(&(*___dst__P13s__anonymous9_1).__i__s_1)))) /* ?{} */); … … 264 264 short __i__s_1; 265 265 }; 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);267 266 static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1); 268 267 static inline void ___constructor__F_P14s__anonymous1014s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1, struct __anonymous10 ___src__14s__anonymous10_1); 269 268 static inline void ___destructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1); 269 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); 270 270 static inline void ___constructor__F_P14s__anonymous10_autogen___1(struct __anonymous10 *___dst__P14s__anonymous10_1){ 271 271 ((void)((*((short *)(&(*___dst__P14s__anonymous10_1).__i__s_1)))) /* ?{} */); … … 288 288 short __i__s_1; 289 289 }; 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);291 290 static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1); 292 291 static inline void ___constructor__F_P14s__anonymous1114s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1, struct __anonymous11 ___src__14s__anonymous11_1); 293 292 static inline void ___destructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1); 293 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); 294 294 static inline void ___constructor__F_P14s__anonymous11_autogen___1(struct __anonymous11 *___dst__P14s__anonymous11_1){ 295 295 ((void)((*((short *)(&(*___dst__P14s__anonymous11_1).__i__s_1)))) /* ?{} */); … … 312 312 short __i__s_1; 313 313 }; 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);315 314 static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1); 316 315 static inline void ___constructor__F_P14s__anonymous1214s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1, struct __anonymous12 ___src__14s__anonymous12_1); 317 316 static inline void ___destructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1); 317 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); 318 318 static inline void ___constructor__F_P14s__anonymous12_autogen___1(struct __anonymous12 *___dst__P14s__anonymous12_1){ 319 319 ((void)((*((short *)(&(*___dst__P14s__anonymous12_1).__i__s_1)))) /* ?{} */); … … 336 336 short __i__s_1; 337 337 }; 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);339 338 static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1); 340 339 static inline void ___constructor__F_P14s__anonymous1314s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1, struct __anonymous13 ___src__14s__anonymous13_1); 341 340 static inline void ___destructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1); 341 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); 342 342 static inline void ___constructor__F_P14s__anonymous13_autogen___1(struct __anonymous13 *___dst__P14s__anonymous13_1){ 343 343 ((void)((*((short *)(&(*___dst__P14s__anonymous13_1).__i__s_1)))) /* ?{} */); … … 360 360 short __i__s_1; 361 361 }; 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);363 362 static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1); 364 363 static inline void ___constructor__F_P14s__anonymous1414s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1, struct __anonymous14 ___src__14s__anonymous14_1); 365 364 static inline void ___destructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1); 365 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); 366 366 static inline void ___constructor__F_P14s__anonymous14_autogen___1(struct __anonymous14 *___dst__P14s__anonymous14_1){ 367 367 ((void)((*((short *)(&(*___dst__P14s__anonymous14_1).__i__s_1)))) /* ?{} */); … … 384 384 short __i__s_1; 385 385 }; 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);387 386 static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1); 388 387 static inline void ___constructor__F_P14s__anonymous1514s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1, struct __anonymous15 ___src__14s__anonymous15_1); 389 388 static inline void ___destructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1); 389 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); 390 390 static inline void ___constructor__F_P14s__anonymous15_autogen___1(struct __anonymous15 *___dst__P14s__anonymous15_1){ 391 391 ((void)((*((short *)(&(*___dst__P14s__anonymous15_1).__i__s_1)))) /* ?{} */); … … 424 424 int __i__i_1; 425 425 }; 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);427 426 static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1); 428 427 static inline void ___constructor__F_P14s__anonymous1614s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1, struct __anonymous16 ___src__14s__anonymous16_1); 429 428 static inline void ___destructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1); 429 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); 430 430 static inline void ___constructor__F_P14s__anonymous16_autogen___1(struct __anonymous16 *___dst__P14s__anonymous16_1){ 431 431 ((void)((*((int *)(&(*___dst__P14s__anonymous16_1).__i__i_1)))) /* ?{} */); … … 448 448 int __i__i_1; 449 449 }; 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);451 450 static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1); 452 451 static inline void ___constructor__F_P14s__anonymous1714s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1, struct __anonymous17 ___src__14s__anonymous17_1); 453 452 static inline void ___destructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1); 453 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); 454 454 static inline void ___constructor__F_P14s__anonymous17_autogen___1(struct __anonymous17 *___dst__P14s__anonymous17_1){ 455 455 ((void)((*((int *)(&(*___dst__P14s__anonymous17_1).__i__i_1)))) /* ?{} */); … … 472 472 int __i__i_1; 473 473 }; 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);475 474 static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1); 476 475 static inline void ___constructor__F_P14s__anonymous1814s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1, struct __anonymous18 ___src__14s__anonymous18_1); 477 476 static inline void ___destructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1); 477 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); 478 478 static inline void ___constructor__F_P14s__anonymous18_autogen___1(struct __anonymous18 *___dst__P14s__anonymous18_1){ 479 479 ((void)((*((int *)(&(*___dst__P14s__anonymous18_1).__i__i_1)))) /* ?{} */); … … 496 496 int __i__i_1; 497 497 }; 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);499 498 static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1); 500 499 static inline void ___constructor__F_P14s__anonymous1914s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1, struct __anonymous19 ___src__14s__anonymous19_1); 501 500 static inline void ___destructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1); 501 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); 502 502 static inline void ___constructor__F_P14s__anonymous19_autogen___1(struct __anonymous19 *___dst__P14s__anonymous19_1){ 503 503 ((void)((*((int *)(&(*___dst__P14s__anonymous19_1).__i__i_1)))) /* ?{} */); … … 520 520 int __i__i_1; 521 521 }; 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);523 522 static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1); 524 523 static inline void ___constructor__F_P14s__anonymous2014s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1, struct __anonymous20 ___src__14s__anonymous20_1); 525 524 static inline void ___destructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1); 525 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); 526 526 static inline void ___constructor__F_P14s__anonymous20_autogen___1(struct __anonymous20 *___dst__P14s__anonymous20_1){ 527 527 ((void)((*((int *)(&(*___dst__P14s__anonymous20_1).__i__i_1)))) /* ?{} */); … … 544 544 int __i__i_1; 545 545 }; 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);547 546 static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1); 548 547 static inline void ___constructor__F_P14s__anonymous2114s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1, struct __anonymous21 ___src__14s__anonymous21_1); 549 548 static inline void ___destructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1); 549 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); 550 550 static inline void ___constructor__F_P14s__anonymous21_autogen___1(struct __anonymous21 *___dst__P14s__anonymous21_1){ 551 551 ((void)((*((int *)(&(*___dst__P14s__anonymous21_1).__i__i_1)))) /* ?{} */); … … 568 568 int __i__i_1; 569 569 }; 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);571 570 static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1); 572 571 static inline void ___constructor__F_P14s__anonymous2214s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1, struct __anonymous22 ___src__14s__anonymous22_1); 573 572 static inline void ___destructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1); 573 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); 574 574 static inline void ___constructor__F_P14s__anonymous22_autogen___1(struct __anonymous22 *___dst__P14s__anonymous22_1){ 575 575 ((void)((*((int *)(&(*___dst__P14s__anonymous22_1).__i__i_1)))) /* ?{} */); … … 592 592 int __i__i_1; 593 593 }; 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);595 594 static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1); 596 595 static inline void ___constructor__F_P14s__anonymous2314s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1, struct __anonymous23 ___src__14s__anonymous23_1); 597 596 static inline void ___destructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1); 597 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); 598 598 static inline void ___constructor__F_P14s__anonymous23_autogen___1(struct __anonymous23 *___dst__P14s__anonymous23_1){ 599 599 ((void)((*((int *)(&(*___dst__P14s__anonymous23_1).__i__i_1)))) /* ?{} */); … … 640 640 int _tmp_cp_ret0; 641 641 ((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)))) /* ^?{} */); 643 643 return ((int )___retval_main__i_1); 644 644 } -
src/tests/.expect/64/extension.txt
r6acb935 ra362f97 13 13 __extension__ int __c__i_1; 14 14 }; 15 static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1);16 15 static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1); 17 16 static inline void ___constructor__F_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1); 18 17 static inline void ___destructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1); 18 static inline struct S ___operator_assign__F2sS_P2sS2sS_autogen___1(struct S *___dst__P2sS_1, struct S ___src__2sS_1); 19 19 static inline void ___constructor__F_P2sS_autogen___1(struct S *___dst__P2sS_1){ 20 20 ((void)((*((int *)(&(*___dst__P2sS_1).__a__i_1)))) /* ?{} */); … … 93 93 int _tmp_cp_ret0; 94 94 ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0)); 95 ((void)( _tmp_cp_ret0) /* ^?{} */);95 ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */); 96 96 ((void)__extension__ sizeof(3)); 97 97 ((void)__extension__ (((int )(3!=((int )0))) || ((int )(4!=((int )0))))); -
src/tests/.expect/64/gccExtensions.txt
r6acb935 ra362f97 177 177 int _tmp_cp_ret0; 178 178 ((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)))) /* ^?{} */); 180 180 return ((int )___retval_main__i_1); 181 181 } -
src/tests/Makefile.am
r6acb935 ra362f97 30 30 31 31 all-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 33 33 34 34 all-tests : -
src/tests/Makefile.in
r6acb935 ra362f97 651 651 652 652 all-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 654 654 655 655 all-tests : -
src/tests/vector/array.c
r6acb935 ra362f97 16 16 #include "array.h" 17 17 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 /// } 18 forall( 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 } 25 22 26 23 // The first element is always at index 0. -
src/tests/vector/array.h
r6acb935 ra362f97 32 32 // implement iterator_for 33 33 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 ); 34 forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) ) 35 [ elt_type * begin, elt_type * end ] get_iterators( array_type * ); 38 36 39 37
Note: See TracChangeset
for help on using the changeset viewer.