- Timestamp:
- Nov 25, 2017, 3:22:18 PM (8 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- c6e2c18
- Parents:
- 9d06142 (diff), 3de176d (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. - Location:
- src
- Files:
-
- 7 added
- 2 deleted
- 72 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/Debug.h
r9d06142 rc0d00b6 24 24 #include "SynTree/Declaration.h" 25 25 26 /// debug codegen a translation unit 27 static inline void debugCodeGen( const std::list< Declaration * > & translationUnit, const std::string & label ) { 28 std::list< Declaration * > decls; 26 #define DEBUG 29 27 30 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), []( Declaration * decl ) { 31 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); 32 }); 28 namespace Debug { 29 /// debug codegen a translation unit 30 static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label ) { 31 #ifdef DEBUG 32 std::list< Declaration * > decls; 33 33 34 std::cerr << "======" << label << "======" << std::endl; 35 CodeGen::generate( decls, std::cerr, false, true ); 36 } // dump 34 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), []( Declaration * decl ) { 35 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); 36 }); 37 38 std::cerr << "======" << label << "======" << std::endl; 39 CodeGen::generate( decls, std::cerr, false, true ); 40 #endif 41 } // dump 42 43 static inline void treeDump( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label ) { 44 #ifdef DEBUG 45 std::list< Declaration * > decls; 46 47 filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), []( Declaration * decl ) { 48 return ! LinkageSpec::isBuiltin( decl->get_linkage() ); 49 }); 50 51 std::cerr << "======" << label << "======" << std::endl; 52 printAll( decls, std::cerr ); 53 #endif 54 } // dump 55 } 37 56 38 57 // Local Variables: // -
src/Concurrency/Keywords.cc
r9d06142 rc0d00b6 553 553 ), 554 554 new ListInit( 555 map_range < std::list<Initializer*> > ( args, [ this](DeclarationWithType * var ){555 map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){ 556 556 Type * type = var->get_type()->clone(); 557 557 type->set_mutex( false ); -
src/GenPoly/Box.cc
r9d06142 rc0d00b6 167 167 Expression *postmutate( OffsetofExpr *offsetofExpr ); 168 168 Expression *postmutate( OffsetPackExpr *offsetPackExpr ); 169 void premutate( StructDecl * ); 170 void premutate( UnionDecl * ); 169 171 170 172 void beginScope(); … … 178 180 /// adds type parameters to the layout call; will generate the appropriate parameters if needed 179 181 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ); 182 /// change the type of generic aggregate members to char[] 183 void mutateMembers( AggregateDecl * aggrDecl ); 180 184 181 185 /// Enters a new scope for type-variables, adding the type variables from ty … … 1414 1418 1415 1419 void PolyGenericCalculator::premutate( TypedefDecl *typedefDecl ) { 1420 assert(false); 1416 1421 beginTypeScope( typedefDecl->get_base() ); 1417 1422 } … … 1460 1465 } 1461 1466 1467 /// converts polymorphic type T into a suitable monomorphic representation, currently: __attribute__((aligned(8)) char[size_T] 1468 Type * polyToMonoType( Type * declType ) { 1469 Type * charType = new BasicType( Type::Qualifiers(), BasicType::Kind::Char); 1470 Expression * size = new NameExpr( sizeofName( mangleType(declType) ) ); 1471 Attribute * aligned = new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ); 1472 return new ArrayType( Type::Qualifiers(), charType, size, 1473 true, false, std::list<Attribute *>{ aligned } ); 1474 } 1475 1476 void PolyGenericCalculator::mutateMembers( AggregateDecl * aggrDecl ) { 1477 std::set< std::string > genericParams; 1478 for ( TypeDecl * td : aggrDecl->parameters ) { 1479 genericParams.insert( td->name ); 1480 } 1481 for ( Declaration * decl : aggrDecl->members ) { 1482 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( decl ) ) { 1483 Type * ty = replaceTypeInst( field->type, env ); 1484 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 1485 // do not try to monomorphize generic parameters 1486 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() && ! genericParams.count( typeInst->name ) ) { 1487 // polymorphic aggregate members should be converted into monomorphic members. 1488 // Using char[size_T] here respects the expected sizing rules of an aggregate type. 1489 Type * newType = polyToMonoType( field->type ); 1490 delete field->type; 1491 field->type = newType; 1492 } 1493 } 1494 } 1495 } 1496 } 1497 1498 void PolyGenericCalculator::premutate( StructDecl * structDecl ) { 1499 mutateMembers( structDecl ); 1500 } 1501 1502 void PolyGenericCalculator::premutate( UnionDecl * unionDecl ) { 1503 mutateMembers( unionDecl ); 1504 } 1505 1462 1506 void PolyGenericCalculator::premutate( DeclStmt *declStmt ) { 1463 1507 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { … … 1465 1509 // change initialization of a polymorphic value object to allocate via a VLA 1466 1510 // (alloca was previously used, but can't be safely used in loops) 1467 Type *declType = objectDecl->get_type(); 1468 ObjectDecl *newBuf = new ObjectDecl( bufNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, 1469 new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::Kind::Char), new NameExpr( sizeofName( mangleType(declType) ) ), 1470 true, false, std::list<Attribute*>{ new Attribute( "aligned", std::list<Expression*>{ new ConstantExpr( Constant::from_int(8) ) } ) } ), 0 ); 1511 ObjectDecl *newBuf = ObjectDecl::newObject( bufNamer.newName(), polyToMonoType( objectDecl->type ), nullptr ); 1471 1512 stmtsToAddBefore.push_back( new DeclStmt( noLabels, newBuf ) ); 1472 1513 -
src/GenPoly/InstantiateGeneric.cc
r9d06142 rc0d00b6 27 27 #include "Common/utility.h" // for deleteAll, cloneAll 28 28 #include "GenPoly.h" // for isPolyType, typesPolyCompatible 29 #include "ResolvExpr/typeops.h" 29 30 #include "ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 30 31 #include "ScrubTyVars.h" // for ScrubTyVars … … 151 152 return gt; 152 153 } 154 155 /// Add cast to dtype-static member expressions so that type information is not lost in GenericInstantiator 156 struct FixDtypeStatic final { 157 Expression * postmutate( MemberExpr * memberExpr ); 158 159 template<typename AggrInst> 160 Expression * fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ); 161 }; 153 162 154 163 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately … … 198 207 199 208 void instantiateGeneric( std::list< Declaration* > &translationUnit ) { 209 PassVisitor<FixDtypeStatic> fixer; 200 210 PassVisitor<GenericInstantiator> instantiator; 211 212 mutateAll( translationUnit, fixer ); 201 213 mutateAll( translationUnit, instantiator ); 214 } 215 216 bool isDtypeStatic( const std::list< TypeDecl* >& baseParams ) { 217 return std::all_of( baseParams.begin(), baseParams.end(), []( TypeDecl * td ) { return ! td->isComplete(); } ); 202 218 } 203 219 … … 479 495 } 480 496 497 template< typename AggrInst > 498 Expression * FixDtypeStatic::fixMemberExpr( AggrInst * inst, MemberExpr * memberExpr ) { 499 // need to cast dtype-static member expressions to their actual type before that type is erased. 500 auto & baseParams = *inst->get_baseParameters(); 501 if ( isDtypeStatic( baseParams ) ) { 502 if ( ! ResolvExpr::typesCompatible( memberExpr->result, memberExpr->member->get_type(), SymTab::Indexer() ) ) { 503 // type of member and type of expression differ, so add cast to actual type 504 return new CastExpr( memberExpr, memberExpr->result->clone() ); 505 } 506 } 507 return memberExpr; 508 } 509 510 Expression * FixDtypeStatic::postmutate( MemberExpr * memberExpr ) { 511 Type * aggrType = memberExpr->aggregate->result; 512 if ( isGenericType( aggrType ) ) { 513 if ( StructInstType * inst = dynamic_cast< StructInstType * >( aggrType ) ) { 514 return fixMemberExpr( inst, memberExpr ); 515 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( aggrType ) ) { 516 return fixMemberExpr( inst, memberExpr ); 517 } 518 } 519 return memberExpr; 520 } 521 481 522 } // namespace GenPoly 482 523 -
src/InitTweak/FixInit.cc
r9d06142 rc0d00b6 396 396 if ( skipCopyConstruct( result ) ) return; // skip certain non-copyable types 397 397 398 // type may involve type variables, so apply type substitution to get temporary variable's actual type. 398 // type may involve type variables, so apply type substitution to get temporary variable's actual type, 399 // since result type may not be substituted (e.g., if the type does not appear in the parameter list) 399 400 // Use applyFree so that types bound in function pointers are not substituted, e.g. in forall(dtype T) void (*)(T). 400 result = result->clone();401 401 env->applyFree( result ); 402 402 ObjectDecl * tmp = ObjectDecl::newObject( "__tmp", result, nullptr ); … … 573 573 574 574 if ( returnDecl ) { 575 UntypedExpr * assign = new UntypedExpr( new NameExpr( "?=?" ) ); 576 assign->get_args().push_back( new VariableExpr( returnDecl ) ); 577 assign->get_args().push_back( callExpr ); 578 // know the result type of the assignment is the type of the LHS (minus the pointer), so 579 // add that onto the assignment expression so that later steps have the necessary information 580 assign->set_result( returnDecl->get_type()->clone() ); 581 575 ApplicationExpr * assign = createBitwiseAssignment( new VariableExpr( returnDecl ), callExpr ); 582 576 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) ); 583 577 // move env from callExpr to retExpr … … 937 931 } 938 932 939 void addIds( SymTab::Indexer & indexer, const std::list< DeclarationWithType * > & decls ) {940 for ( auto d : decls ) {941 indexer.addId( d );942 }943 }944 945 void addTypes( SymTab::Indexer & indexer, const std::list< TypeDecl * > & tds ) {946 for ( auto td : tds ) {947 indexer.addType( td );948 addIds( indexer, td->assertions );949 }950 }951 952 933 void GenStructMemberCalls::previsit( StructDecl * structDecl ) { 953 934 if ( ! dtorStruct && structDecl->name == "__Destructor" ) { … … 1018 999 // need to explicitly re-add function parameters to the indexer in order to resolve copy constructors 1019 1000 auto guard = makeFuncGuard( [this]() { indexer.enterScope(); }, [this]() { indexer.leaveScope(); } ); 1020 addTypes( indexer, function->type->forall ); 1021 addIds( indexer, function->type->returnVals ); 1022 addIds( indexer, function->type->parameters ); 1001 indexer.addFunctionType( function->type ); 1023 1002 1024 1003 // need to iterate through members in reverse in order for … … 1035 1014 // insert and resolve default/copy constructor call for each field that's unhandled 1036 1015 std::list< Statement * > stmt; 1037 Expression * arg2 = 0;1016 Expression * arg2 = nullptr; 1038 1017 if ( isCopyConstructor( function ) ) { 1039 1018 // if copy ctor, need to pass second-param-of-this-function.field … … 1188 1167 assert( ctorExpr->result && ctorExpr->get_result()->size() == 1 ); 1189 1168 1190 // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary.1191 ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), ctorExpr->get_result()->clone(), nullptr );1192 declsToAddBefore.push_back( tmp );1193 1194 1169 // xxx - this can be TupleAssignExpr now. Need to properly handle this case. 1195 1170 ApplicationExpr * callExpr = strict_dynamic_cast< ApplicationExpr * > ( ctorExpr->get_callExpr() ); … … 1197 1172 ctorExpr->set_callExpr( nullptr ); 1198 1173 ctorExpr->set_env( nullptr ); 1174 1175 // xxx - ideally we would reuse the temporary generated from the copy constructor passes from within firstArg if it exists and not generate a temporary if it's unnecessary. 1176 ObjectDecl * tmp = ObjectDecl::newObject( tempNamer.newName(), callExpr->args.front()->result->clone(), nullptr ); 1177 declsToAddBefore.push_back( tmp ); 1199 1178 delete ctorExpr; 1200 1179 -
src/InitTweak/InitTweak.cc
r9d06142 rc0d00b6 12 12 #include "Parser/LinkageSpec.h" // for Spec, isBuiltin, Intrinsic 13 13 #include "ResolvExpr/typeops.h" // for typesCompatibleIgnoreQualifiers 14 #include "SymTab/Autogen.h" 14 15 #include "SymTab/Indexer.h" // for Indexer 15 16 #include "SynTree/Attribute.h" // for Attribute … … 98 99 class InitExpander::ExpanderImpl { 99 100 public: 101 virtual ~ExpanderImpl() = default; 100 102 virtual std::list< Expression * > next( std::list< Expression * > & indices ) = 0; 101 103 virtual Statement * buildListInit( UntypedExpr * callExpr, std::list< Expression * > & indices ) = 0; … … 105 107 public: 106 108 InitImpl( Initializer * init ) : init( init ) {} 109 virtual ~InitImpl() = default; 107 110 108 111 virtual std::list< Expression * > next( __attribute((unused)) std::list< Expression * > & indices ) { … … 121 124 public: 122 125 ExprImpl( Expression * expr ) : arg( expr ) {} 123 124 ~ExprImpl() { delete arg; } 126 virtual ~ExprImpl() { delete arg; } 125 127 126 128 virtual std::list< Expression * > next( std::list< Expression * > & indices ) { … … 523 525 } 524 526 527 ApplicationExpr * createBitwiseAssignment( Expression * dst, Expression * src ) { 528 static FunctionDecl * assign = nullptr; 529 if ( ! assign ) { 530 // temporary? Generate a fake assignment operator to represent bitwise assignments. 531 // This operator could easily exist as a real function, but it's tricky because nothing should resolve to this function. 532 TypeDecl * td = new TypeDecl( "T", noStorageClasses, nullptr, TypeDecl::Dtype, true ); 533 assign = new FunctionDecl( "?=?", noStorageClasses, LinkageSpec::Intrinsic, SymTab::genAssignType( new TypeInstType( noQualifiers, td->name, td ) ), nullptr ); 534 } 535 if ( dynamic_cast< ReferenceType * >( dst->result ) ) { 536 dst = new AddressExpr( dst ); 537 } else { 538 dst = new CastExpr( dst, new ReferenceType( noQualifiers, dst->result->clone() ) ); 539 } 540 if ( dynamic_cast< ReferenceType * >( src->result ) ) { 541 src = new CastExpr( src, new ReferenceType( noQualifiers, src->result->stripReferences()->clone() ) ); 542 } 543 return new ApplicationExpr( VariableExpr::functionPointer( assign ), { dst, src } ); 544 } 545 525 546 class ConstExprChecker : public Visitor { 526 547 public: -
src/InitTweak/InitTweak.h
r9d06142 rc0d00b6 35 35 /// returns the first parameter of a constructor/destructor/assignment function 36 36 ObjectDecl * getParamThis( FunctionType * ftype ); 37 38 /// generate a bitwise assignment operation. 39 ApplicationExpr * createBitwiseAssignment( Expression * dst, Expression * src ); 37 40 38 41 /// transform Initializer into an argument list that can be passed to a call expression -
src/Makefile.in
r9d06142 rc0d00b6 210 210 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \ 211 211 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \ 212 ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT) \ 212 213 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \ 213 214 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \ … … 511 512 ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \ 512 513 ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \ 513 ResolvExpr/CurrentObject.cc SymTab/Indexer.cc \ 514 SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \ 515 SymTab/ImplementationType.cc SymTab/TypeEquality.cc \ 516 SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \ 517 SynTree/BasicType.cc SynTree/PointerType.cc \ 518 SynTree/ArrayType.cc SynTree/ReferenceType.cc \ 519 SynTree/FunctionType.cc SynTree/ReferenceToType.cc \ 520 SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \ 514 ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \ 515 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \ 516 SymTab/FixFunction.cc SymTab/ImplementationType.cc \ 517 SymTab/TypeEquality.cc SymTab/Autogen.cc SynTree/Type.cc \ 518 SynTree/VoidType.cc SynTree/BasicType.cc \ 519 SynTree/PointerType.cc SynTree/ArrayType.cc \ 520 SynTree/ReferenceType.cc SynTree/FunctionType.cc \ 521 SynTree/ReferenceToType.cc SynTree/TupleType.cc \ 522 SynTree/TypeofType.cc SynTree/AttrType.cc \ 521 523 SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \ 522 524 SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 825 827 ResolvExpr/$(am__dirstamp) \ 826 828 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 829 ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT): \ 830 ResolvExpr/$(am__dirstamp) \ 831 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 827 832 SymTab/$(am__dirstamp): 828 833 @$(MKDIR_P) SymTab … … 1022 1027 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@ 1023 1028 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@ 1029 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po@am__quote@ 1024 1030 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@ 1025 1031 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@ … … 1964 1970 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi` 1965 1971 1972 ResolvExpr/driver_cfa_cpp-ExplodedActual.o: ResolvExpr/ExplodedActual.cc 1973 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc 1974 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po 1975 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.o' libtool=no @AMDEPBACKSLASH@ 1976 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1977 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc 1978 1979 ResolvExpr/driver_cfa_cpp-ExplodedActual.obj: ResolvExpr/ExplodedActual.cc 1980 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi` 1981 @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po 1982 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.obj' libtool=no @AMDEPBACKSLASH@ 1983 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1984 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi` 1985 1966 1986 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc 1967 1987 @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc -
src/Parser/DeclarationNode.cc
r9d06142 rc0d00b6 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Sep 23 18:16:48201713 // Update Count : 10 2412 // Last Modified On : Mon Nov 20 09:21:52 2017 13 // Update Count : 1031 14 14 // 15 15 … … 509 509 510 510 DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) { 511 if ( ! q ) { delete q; return this; } 511 if ( ! q ) { delete q; return this; } // empty qualifier 512 512 513 513 checkSpecifiers( q ); 514 514 copySpecifiers( q ); 515 515 516 if ( ! q->type ) { 517 delete q; 518 return this; 519 } // if 516 if ( ! q->type ) { delete q; return this; } 520 517 521 518 if ( ! type ) { 522 type = q->type; // reuse thisstructure519 type = q->type; // reuse structure 523 520 q->type = nullptr; 524 521 delete q; … … 526 523 } // if 527 524 528 if ( q->type->forall ) { 529 if ( type->forall ) { 530 type->forall->appendList( q->type->forall ); 525 if ( q->type->forall ) { // forall qualifier ? 526 if ( type->forall ) { // polymorphic routine ? 527 type->forall->appendList( q->type->forall ); // augment forall qualifier 531 528 } else { 532 if ( type->kind == TypeData::Aggregate ) { 533 type->aggregate.params = q->type->forall; 534 // change implicit typedef from TYPEDEFname to TYPEGENname 535 typedefTable.changeKind( *type->aggregate.name, TypedefTable::TG ); 536 } else { 537 type->forall = q->type->forall; 529 if ( type->kind == TypeData::Aggregate ) { // struct/union ? 530 if ( type->aggregate.params ) { // polymorphic ? 531 type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier 532 } else { // not polymorphic 533 type->aggregate.params = q->type->forall; // make polymorphic type 534 // change implicit typedef from TYPEDEFname to TYPEGENname 535 typedefTable.changeKind( *type->aggregate.name, TypedefTable::TG ); 536 } // if 537 } else { // not polymorphic 538 type->forall = q->type->forall; // make polymorphic routine 538 539 } // if 539 540 } // if 540 q->type->forall = nullptr; 541 q->type->forall = nullptr; // forall qualifier moved 541 542 } // if 542 543 -
src/Parser/parser.yy
r9d06142 rc0d00b6 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Oct 25 12:28:54201713 // Update Count : 2 89312 // Last Modified On : Mon Nov 20 09:45:36 2017 13 // Update Count : 2945 14 14 // 15 15 … … 114 114 } // for 115 115 } // distExt 116 117 // There is an ambiguity for inline generic-routine return-types and generic routines. 118 // forall( otype T ) struct S { int i; } bar( T ) {} 119 // Does the forall bind to the struct or the routine, and how would it be possible to explicitly specify the binding. 120 // forall( otype T ) struct S { int T; } forall( otype W ) bar( W ) {} 121 122 void rebindForall( DeclarationNode * declSpec, DeclarationNode * funcDecl ) { 123 if ( declSpec->type->kind == TypeData::Aggregate ) { // return is aggregate definition 124 funcDecl->type->forall = declSpec->type->aggregate.params; // move forall from aggregate to function type 125 declSpec->type->aggregate.params = nullptr; 126 } // if 127 } // rebindForall 116 128 117 129 bool forall = false; // aggregate have one or more forall qualifiers ? … … 348 360 349 361 350 // Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string 351 // is ambiguous: 352 // .---------. matches IF '(' comma_expression ')' statement . (reduce) 353 // if ( C ) S1 else S2 354 // `-----------------' matches IF '(' comma_expression ')' statement . (shift) ELSE statement */ 362 // Handle shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string is ambiguous: 363 // .---------. matches IF '(' comma_expression ')' statement . (reduce) 364 // if ( C ) S1 else S2 365 // `-----------------' matches IF '(' comma_expression ')' statement . (shift) ELSE statement */ 355 366 // Similar issues exit with the waitfor statement. 356 367 … … 361 372 %precedence TIMEOUT // token precedence for start of TIMEOUT in WAITFOR statement 362 373 %precedence ELSE // token precedence for start of else clause in IF/WAITFOR statement 374 375 // Handle shift/reduce conflict for generic type by shifting the '(' token. For example, this string is ambiguous: 376 // forall( otype T ) struct Foo { T v; }; 377 // .-----. matches pointer to function returning a generic (which is impossible without a type) 378 // Foo ( *fp )( int ); 379 // `---' matches start of TYPEGENname '(' 380 // Must be: 381 // Foo( int ) ( *fp )( int ); 382 383 // Order of these lines matters (low-to-high precedence). 384 %precedence TYPEGENname 385 %precedence '(' 363 386 364 387 %locations // support location tracking for error messages … … 1765 1788 1766 1789 typegen_name: // CFA 1767 TYPEGENname '(' ')' 1790 TYPEGENname 1791 { $$ = DeclarationNode::newFromTypeGen( $1, nullptr ); } 1792 | TYPEGENname '(' ')' 1768 1793 { $$ = DeclarationNode::newFromTypeGen( $1, nullptr ); } 1769 1794 | TYPEGENname '(' type_list ')' … … 1809 1834 } 1810 1835 | aggregate_key attribute_list_opt typegen_name // CFA 1811 { $$ = $3->addQualifiers( $2 ); } 1836 { 1837 // Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is 1838 // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and 1839 // delete newFromTypeGen. 1840 $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $3->type->symbolic.actuals, nullptr, false )->addQualifiers( $2 ); 1841 $3->type->symbolic.name = nullptr; 1842 $3->type->symbolic.actuals = nullptr; 1843 delete $3; 1844 } 1812 1845 ; 1813 1846 … … 2380 2413 | declaration_specifier function_declarator with_clause_opt compound_statement 2381 2414 { 2415 rebindForall( $1, $2 ); 2382 2416 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2383 2417 typedefTable.leaveScope(); … … 2406 2440 | declaration_specifier KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement 2407 2441 { 2442 rebindForall( $1, $2 ); 2408 2443 typedefTable.addToEnclosingScope( TypedefTable::ID ); 2409 2444 typedefTable.leaveScope(); -
src/ResolvExpr/Alternative.cc
r9d06142 rc0d00b6 18 18 #include <ostream> // for operator<<, ostream, basic_o... 19 19 #include <string> // for operator<<, char_traits, string 20 #include <utility> // for move 20 21 21 22 #include "Common/utility.h" // for maybeClone … … 81 82 os << std::endl; 82 83 } 84 85 void splice( AltList& dst, AltList& src ) { 86 dst.reserve( dst.size() + src.size() ); 87 for ( Alternative& alt : src ) { 88 dst.push_back( std::move(alt) ); 89 } 90 src.clear(); 91 } 92 93 void spliceBegin( AltList& dst, AltList& src ) { 94 splice( src, dst ); 95 dst.swap( src ); 96 } 97 83 98 } // namespace ResolvExpr 84 99 -
src/ResolvExpr/Alternative.h
r9d06142 rc0d00b6 17 17 18 18 #include <iosfwd> // for ostream 19 #include < list> // for list19 #include <vector> // for vector 20 20 21 21 #include "Cost.h" // for Cost … … 25 25 26 26 namespace ResolvExpr { 27 struct Alternative;28 29 typedef std::list< Alternative > AltList;30 31 27 struct Alternative { 32 28 Alternative(); … … 41 37 void print( std::ostream &os, Indenter indent = {} ) const; 42 38 39 /// Returns the stored expression, but released from management of this Alternative 40 Expression* release_expr() { 41 Expression* tmp = expr; 42 expr = nullptr; 43 return tmp; 44 } 45 43 46 Cost cost; 44 47 Cost cvtCost; … … 46 49 TypeEnvironment env; 47 50 }; 51 52 typedef std::vector< Alternative > AltList; 53 54 /// Moves all elements from src to the end of dst 55 void splice( AltList& dst, AltList& src ); 56 57 /// Moves all elements from src to the beginning of dst 58 void spliceBegin( AltList& dst, AltList& src ); 48 59 } // namespace ResolvExpr 49 60 -
src/ResolvExpr/AlternativeFinder.cc
r9d06142 rc0d00b6 16 16 #include <algorithm> // for copy 17 17 #include <cassert> // for strict_dynamic_cast, assert, assertf 18 #include <cstddef> // for size_t 18 19 #include <iostream> // for operator<<, cerr, ostream, endl 19 20 #include <iterator> // for back_insert_iterator, back_inserter 20 21 #include <list> // for _List_iterator, list, _List_const_... 21 22 #include <map> // for _Rb_tree_iterator, map, _Rb_tree_c... 22 #include <memory> // for allocator_traits<>::value_type 23 #include <memory> // for allocator_traits<>::value_type, unique_ptr 23 24 #include <utility> // for pair 25 #include <vector> // for vector 24 26 25 27 #include "Alternative.h" // for AltList, Alternative … … 28 30 #include "Common/utility.h" // for deleteAll, printAll, CodeLocation 29 31 #include "Cost.h" // for Cost, Cost::zero, operator<<, Cost... 32 #include "ExplodedActual.h" // for ExplodedActual 30 33 #include "InitTweak/InitTweak.h" // for getFunctionName 31 34 #include "RenameVars.h" // for RenameVars, global_renamer … … 49 52 #define PRINT( text ) if ( resolvep ) { text } 50 53 //#define DEBUG_COST 54 55 using std::move; 56 57 /// copies any copyable type 58 template<typename T> 59 T copy(const T& x) { return x; } 51 60 52 61 namespace ResolvExpr { … … 178 187 expr->accept( *this ); 179 188 if ( failFast && alternatives.empty() ) { 189 PRINT( 190 std::cerr << "No reasonable alternatives for expression " << expr << std::endl; 191 ) 180 192 throw SemanticError( "No reasonable alternatives for expression ", expr ); 181 193 } … … 186 198 printAlts( alternatives, std::cerr ); 187 199 ) 188 AltList ::iterator oldBegin = alternatives.begin();189 pruneAlternatives( alternatives.begin(), alternatives.end(), front_inserter( alternatives) );190 if ( failFast && alternatives.begin() == oldBegin) {200 AltList pruned; 201 pruneAlternatives( alternatives.begin(), alternatives.end(), back_inserter( pruned ) ); 202 if ( failFast && pruned.empty() ) { 191 203 std::ostringstream stream; 192 204 AltList winners; … … 198 210 throw SemanticError( stream.str() ); 199 211 } 200 alternatives .erase( oldBegin, alternatives.end());212 alternatives = move(pruned); 201 213 PRINT( 202 214 std::cerr << "there are " << oldsize << " alternatives before elimination" << std::endl; … … 333 345 tmpCost.incPoly( -tmpCost.get_polyCost() ); 334 346 if ( tmpCost != Cost::zero ) { 335 // if ( convCost != Cost::zero ) {336 347 Type *newType = formalType->clone(); 337 348 env.apply( newType ); … … 405 416 /// needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() ); 406 417 } 407 }408 409 /// instantiate a single argument by matching actuals from [actualIt, actualEnd) against formalType,410 /// producing expression(s) in out and their total cost in cost.411 template< typename AltIterator, typename OutputIterator >412 bool instantiateArgument( Type * formalType, Initializer * defaultValue, AltIterator & actualIt, AltIterator actualEnd, OpenVarSet & openVars, TypeEnvironment & resultEnv, AssertionSet & resultNeed, AssertionSet & resultHave, const SymTab::Indexer & indexer, Cost & cost, OutputIterator out ) {413 if ( TupleType * tupleType = dynamic_cast< TupleType * >( formalType ) ) {414 // formalType is a TupleType - group actuals into a TupleExpr whose type unifies with the TupleType415 std::list< Expression * > exprs;416 for ( Type * type : *tupleType ) {417 if ( ! instantiateArgument( type, defaultValue, actualIt, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( exprs ) ) ) {418 deleteAll( exprs );419 return false;420 }421 }422 *out++ = new TupleExpr( exprs );423 } else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {424 // xxx - mixing default arguments with variadic??425 std::list< Expression * > exprs;426 for ( ; actualIt != actualEnd; ++actualIt ) {427 exprs.push_back( actualIt->expr->clone() );428 cost += actualIt->cost;429 }430 Expression * arg = nullptr;431 if ( exprs.size() == 1 && Tuples::isTtype( exprs.front()->get_result() ) ) {432 // the case where a ttype value is passed directly is special, e.g. for argument forwarding purposes433 // xxx - what if passing multiple arguments, last of which is ttype?434 // xxx - what would happen if unify was changed so that unifying tuple types flattened both before unifying lists? then pass in TupleType(ttype) below.435 arg = exprs.front();436 } else {437 arg = new TupleExpr( exprs );438 }439 assert( arg && arg->get_result() );440 if ( ! unify( ttype, arg->get_result(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {441 return false;442 }443 *out++ = arg;444 } else if ( actualIt != actualEnd ) {445 // both actualType and formalType are atomic (non-tuple) types - if they unify446 // then accept actual as an argument, otherwise return false (fail to instantiate argument)447 Expression * actual = actualIt->expr;448 Type * actualType = actual->get_result();449 450 PRINT(451 std::cerr << "formal type is ";452 formalType->print( std::cerr );453 std::cerr << std::endl << "actual type is ";454 actualType->print( std::cerr );455 std::cerr << std::endl;456 )457 if ( ! unify( formalType, actualType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) {458 // std::cerr << "unify failed" << std::endl;459 return false;460 }461 // move the expression from the alternative to the output iterator462 *out++ = actual;463 actualIt->expr = nullptr;464 cost += actualIt->cost;465 ++actualIt;466 } else {467 // End of actuals - Handle default values468 if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) {469 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( si->get_value() ) ) {470 // so far, only constant expressions are accepted as default values471 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( castExpr->get_arg() ) ) {472 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) {473 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) {474 *out++ = cnstexpr->clone();475 return true;476 } // if477 } // if478 } // if479 }480 } // if481 return false;482 } // if483 return true;484 }485 486 bool AlternativeFinder::instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ) {487 simpleCombineEnvironments( actuals.begin(), actuals.end(), resultEnv );488 // make sure we don't widen any existing bindings489 for ( TypeEnvironment::iterator i = resultEnv.begin(); i != resultEnv.end(); ++i ) {490 i->allowWidening = false;491 }492 resultEnv.extractOpenVars( openVars );493 494 // flatten actuals so that each actual has an atomic (non-tuple) type495 AltList exploded;496 Tuples::explode( actuals, indexer, back_inserter( exploded ) );497 498 AltList::iterator actualExpr = exploded.begin();499 AltList::iterator actualEnd = exploded.end();500 for ( DeclarationWithType * formal : formals ) {501 // match flattened actuals with formal parameters - actuals will be grouped to match502 // with formals as appropriate503 Cost cost = Cost::zero;504 std::list< Expression * > newExprs;505 ObjectDecl * obj = strict_dynamic_cast< ObjectDecl * >( formal );506 if ( ! instantiateArgument( obj->get_type(), obj->get_init(), actualExpr, actualEnd, openVars, resultEnv, resultNeed, resultHave, indexer, cost, back_inserter( newExprs ) ) ) {507 deleteAll( newExprs );508 return false;509 }510 // success - produce argument as a new alternative511 assert( newExprs.size() == 1 );512 out.push_back( Alternative( newExprs.front(), resultEnv, cost ) );513 }514 if ( actualExpr != actualEnd ) {515 // there are still actuals remaining, but we've run out of formal parameters to match against516 // this is okay only if the function is variadic517 if ( ! isVarArgs ) {518 return false;519 }520 out.splice( out.end(), exploded, actualExpr, actualEnd );521 }522 return true;523 418 } 524 419 … … 675 570 } 676 571 677 template< typename OutputIterator > 678 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ) { 679 OpenVarSet openVars; 680 AssertionSet resultNeed, resultHave; 681 TypeEnvironment resultEnv( func.env ); 682 makeUnifiableVars( funcType, openVars, resultNeed ); 683 resultEnv.add( funcType->get_forall() ); // add all type variables as open variables now so that those not used in the parameter list are still considered open 684 AltList instantiatedActuals; // filled by instantiate function 572 /// Gets a default value from an initializer, nullptr if not present 573 ConstantExpr* getDefaultValue( Initializer* init ) { 574 if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) { 575 if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) { 576 return dynamic_cast<ConstantExpr*>( ce->get_arg() ); 577 } 578 } 579 return nullptr; 580 } 581 582 /// State to iteratively build a match of parameter expressions to arguments 583 struct ArgPack { 584 std::size_t parent; ///< Index of parent pack 585 std::unique_ptr<Expression> expr; ///< The argument stored here 586 Cost cost; ///< The cost of this argument 587 TypeEnvironment env; ///< Environment for this pack 588 AssertionSet need; ///< Assertions outstanding for this pack 589 AssertionSet have; ///< Assertions found for this pack 590 OpenVarSet openVars; ///< Open variables for this pack 591 unsigned nextArg; ///< Index of next argument in arguments list 592 unsigned tupleStart; ///< Number of tuples that start at this index 593 unsigned nextExpl; ///< Index of next exploded element 594 unsigned explAlt; ///< Index of alternative for nextExpl > 0 595 596 ArgPack() 597 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 598 599 tupleStart(0), nextExpl(0), explAlt(0) {} 600 601 ArgPack(const TypeEnvironment& env, const AssertionSet& need, const AssertionSet& have, 602 const OpenVarSet& openVars) 603 : parent(0), expr(), cost(Cost::zero), env(env), need(need), have(have), 604 openVars(openVars), nextArg(0), tupleStart(0), nextExpl(0), explAlt(0) {} 605 606 ArgPack(std::size_t parent, Expression* expr, TypeEnvironment&& env, AssertionSet&& need, 607 AssertionSet&& have, OpenVarSet&& openVars, unsigned nextArg, 608 unsigned tupleStart = 0, Cost cost = Cost::zero, unsigned nextExpl = 0, 609 unsigned explAlt = 0 ) 610 : parent(parent), expr(expr->clone()), cost(cost), env(move(env)), need(move(need)), 611 have(move(have)), openVars(move(openVars)), nextArg(nextArg), tupleStart(tupleStart), 612 nextExpl(nextExpl), explAlt(explAlt) {} 613 614 ArgPack(const ArgPack& o, TypeEnvironment&& env, AssertionSet&& need, AssertionSet&& have, 615 OpenVarSet&& openVars, unsigned nextArg, Cost added ) 616 : parent(o.parent), expr(o.expr ? o.expr->clone() : nullptr), cost(o.cost + added), 617 env(move(env)), need(move(need)), have(move(have)), openVars(move(openVars)), 618 nextArg(nextArg), tupleStart(o.tupleStart), nextExpl(0), explAlt(0) {} 619 620 /// true iff this pack is in the middle of an exploded argument 621 bool hasExpl() const { return nextExpl > 0; } 622 623 /// Gets the list of exploded alternatives for this pack 624 const ExplodedActual& getExpl( const ExplodedArgs& args ) const { 625 return args[nextArg-1][explAlt]; 626 } 627 628 /// Ends a tuple expression, consolidating the appropriate actuals 629 void endTuple( const std::vector<ArgPack>& packs ) { 630 // add all expressions in tuple to list, summing cost 631 std::list<Expression*> exprs; 632 const ArgPack* pack = this; 633 if ( expr ) { exprs.push_front( expr.release() ); } 634 while ( pack->tupleStart == 0 ) { 635 pack = &packs[pack->parent]; 636 exprs.push_front( pack->expr->clone() ); 637 cost += pack->cost; 638 } 639 // reset pack to appropriate tuple 640 expr.reset( new TupleExpr( exprs ) ); 641 tupleStart = pack->tupleStart - 1; 642 parent = pack->parent; 643 } 644 }; 645 646 /// Instantiates an argument to match a formal, returns false if no results left 647 bool instantiateArgument( Type* formalType, Initializer* initializer, 648 const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart, 649 const SymTab::Indexer& indexer, unsigned nTuples = 0 ) { 650 if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) { 651 // formalType is a TupleType - group actuals into a TupleExpr 652 ++nTuples; 653 for ( Type* type : *tupleType ) { 654 // xxx - dropping initializer changes behaviour from previous, but seems correct 655 if ( ! instantiateArgument( 656 type, nullptr, args, results, genStart, indexer, nTuples ) ) 657 return false; 658 nTuples = 0; 659 } 660 // re-consititute tuples for final generation 661 for ( auto i = genStart; i < results.size(); ++i ) { 662 results[i].endTuple( results ); 663 } 664 return true; 665 } else if ( TypeInstType* ttype = Tuples::isTtype( formalType ) ) { 666 // formalType is a ttype, consumes all remaining arguments 667 // xxx - mixing default arguments with variadic?? 668 669 // completed tuples; will be spliced to end of results to finish 670 std::vector<ArgPack> finalResults{}; 671 672 // iterate until all results completed 673 std::size_t genEnd; 674 ++nTuples; 675 do { 676 genEnd = results.size(); 677 678 // add another argument to results 679 for ( std::size_t i = genStart; i < genEnd; ++i ) { 680 auto nextArg = results[i].nextArg; 681 682 // use next element of exploded tuple if present 683 if ( results[i].hasExpl() ) { 684 const ExplodedActual& expl = results[i].getExpl( args ); 685 686 unsigned nextExpl = results[i].nextExpl + 1; 687 if ( nextExpl == expl.exprs.size() ) { 688 nextExpl = 0; 689 } 690 691 results.emplace_back( 692 i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env), 693 copy(results[i].need), copy(results[i].have), 694 copy(results[i].openVars), nextArg, nTuples, Cost::zero, nextExpl, 695 results[i].explAlt ); 696 697 continue; 698 } 699 700 // finish result when out of arguments 701 if ( nextArg >= args.size() ) { 702 ArgPack newResult{ 703 results[i].env, results[i].need, results[i].have, 704 results[i].openVars }; 705 newResult.nextArg = nextArg; 706 Type* argType; 707 708 if ( nTuples > 0 ) { 709 // first iteration, push empty tuple expression 710 newResult.parent = i; 711 std::list<Expression*> emptyList; 712 newResult.expr.reset( new TupleExpr( emptyList ) ); 713 argType = newResult.expr->get_result(); 714 } else { 715 // clone result to collect tuple 716 newResult.parent = results[i].parent; 717 newResult.cost = results[i].cost; 718 newResult.tupleStart = results[i].tupleStart; 719 newResult.expr.reset( results[i].expr->clone() ); 720 argType = newResult.expr->get_result(); 721 722 if ( results[i].tupleStart > 0 && Tuples::isTtype( argType ) ) { 723 // the case where a ttype value is passed directly is special, 724 // e.g. for argument forwarding purposes 725 // xxx - what if passing multiple arguments, last of which is 726 // ttype? 727 // xxx - what would happen if unify was changed so that unifying 728 // tuple 729 // types flattened both before unifying lists? then pass in 730 // TupleType (ttype) below. 731 --newResult.tupleStart; 732 } else { 733 // collapse leftover arguments into tuple 734 newResult.endTuple( results ); 735 argType = newResult.expr->get_result(); 736 } 737 } 738 739 // check unification for ttype before adding to final 740 if ( unify( ttype, argType, newResult.env, newResult.need, newResult.have, 741 newResult.openVars, indexer ) ) { 742 finalResults.push_back( move(newResult) ); 743 } 744 745 continue; 746 } 747 748 // add each possible next argument 749 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 750 const ExplodedActual& expl = args[nextArg][j]; 751 752 // fresh copies of parent parameters for this iteration 753 TypeEnvironment env = results[i].env; 754 OpenVarSet openVars = results[i].openVars; 755 756 env.addActual( expl.env, openVars ); 757 758 // skip empty tuple arguments by (near-)cloning parent into next gen 759 if ( expl.exprs.empty() ) { 760 results.emplace_back( 761 results[i], move(env), copy(results[i].need), 762 copy(results[i].have), move(openVars), nextArg + 1, expl.cost ); 763 764 continue; 765 } 766 767 // add new result 768 results.emplace_back( 769 i, expl.exprs.front().get(), move(env), copy(results[i].need), 770 copy(results[i].have), move(openVars), nextArg + 1, 771 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 772 } 773 } 774 775 // reset for next round 776 genStart = genEnd; 777 nTuples = 0; 778 } while ( genEnd != results.size() ); 779 780 // splice final results onto results 781 for ( std::size_t i = 0; i < finalResults.size(); ++i ) { 782 results.push_back( move(finalResults[i]) ); 783 } 784 return ! finalResults.empty(); 785 } 786 787 // iterate each current subresult 788 std::size_t genEnd = results.size(); 789 for ( std::size_t i = genStart; i < genEnd; ++i ) { 790 auto nextArg = results[i].nextArg; 791 792 // use remainder of exploded tuple if present 793 if ( results[i].hasExpl() ) { 794 const ExplodedActual& expl = results[i].getExpl( args ); 795 Expression* expr = expl.exprs[results[i].nextExpl].get(); 796 797 TypeEnvironment env = results[i].env; 798 AssertionSet need = results[i].need, have = results[i].have; 799 OpenVarSet openVars = results[i].openVars; 800 801 Type* actualType = expr->get_result(); 802 803 PRINT( 804 std::cerr << "formal type is "; 805 formalType->print( std::cerr ); 806 std::cerr << std::endl << "actual type is "; 807 actualType->print( std::cerr ); 808 std::cerr << std::endl; 809 ) 810 811 if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) { 812 unsigned nextExpl = results[i].nextExpl + 1; 813 if ( nextExpl == expl.exprs.size() ) { 814 nextExpl = 0; 815 } 816 817 results.emplace_back( 818 i, expr, move(env), move(need), move(have), move(openVars), nextArg, 819 nTuples, Cost::zero, nextExpl, results[i].explAlt ); 820 } 821 822 continue; 823 } 824 825 // use default initializers if out of arguments 826 if ( nextArg >= args.size() ) { 827 if ( ConstantExpr* cnstExpr = getDefaultValue( initializer ) ) { 828 if ( Constant* cnst = dynamic_cast<Constant*>( cnstExpr->get_constant() ) ) { 829 TypeEnvironment env = results[i].env; 830 AssertionSet need = results[i].need, have = results[i].have; 831 OpenVarSet openVars = results[i].openVars; 832 833 if ( unify( formalType, cnst->get_type(), env, need, have, openVars, 834 indexer ) ) { 835 results.emplace_back( 836 i, cnstExpr, move(env), move(need), move(have), 837 move(openVars), nextArg, nTuples ); 838 } 839 } 840 } 841 842 continue; 843 } 844 845 // Check each possible next argument 846 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 847 const ExplodedActual& expl = args[nextArg][j]; 848 849 // fresh copies of parent parameters for this iteration 850 TypeEnvironment env = results[i].env; 851 AssertionSet need = results[i].need, have = results[i].have; 852 OpenVarSet openVars = results[i].openVars; 853 854 env.addActual( expl.env, openVars ); 855 856 // skip empty tuple arguments by (near-)cloning parent into next gen 857 if ( expl.exprs.empty() ) { 858 results.emplace_back( 859 results[i], move(env), move(need), move(have), move(openVars), 860 nextArg + 1, expl.cost ); 861 862 continue; 863 } 864 865 // consider only first exploded actual 866 Expression* expr = expl.exprs.front().get(); 867 Type* actualType = expr->get_result()->clone(); 868 869 PRINT( 870 std::cerr << "formal type is "; 871 formalType->print( std::cerr ); 872 std::cerr << std::endl << "actual type is "; 873 actualType->print( std::cerr ); 874 std::cerr << std::endl; 875 ) 876 877 // attempt to unify types 878 if ( unify( formalType, actualType, env, need, have, openVars, indexer ) ) { 879 // add new result 880 results.emplace_back( 881 i, expr, move(env), move(need), move(have), move(openVars), nextArg + 1, 882 nTuples, expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 883 } 884 } 885 } 886 887 // reset for next parameter 888 genStart = genEnd; 889 890 return genEnd != results.size(); 891 } 892 893 template<typename OutputIterator> 894 void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 895 const std::vector<ArgPack>& results, OutputIterator out ) { 896 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 897 // sum cost and accumulate actuals 898 std::list<Expression*>& args = appExpr->get_args(); 899 Cost cost = Cost::zero; 900 const ArgPack* pack = &result; 901 while ( pack->expr ) { 902 args.push_front( pack->expr->clone() ); 903 cost += pack->cost; 904 pack = &results[pack->parent]; 905 } 906 // build and validate new alternative 907 Alternative newAlt( appExpr, result.env, cost ); 908 PRINT( 909 std::cerr << "instantiate function success: " << appExpr << std::endl; 910 std::cerr << "need assertions:" << std::endl; 911 printAssertionSet( result.need, std::cerr, 8 ); 912 ) 913 inferParameters( result.need, result.have, newAlt, result.openVars, out ); 914 } 915 916 template<typename OutputIterator> 917 void AlternativeFinder::makeFunctionAlternatives( const Alternative &func, 918 FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) { 919 OpenVarSet funcOpenVars; 920 AssertionSet funcNeed, funcHave; 921 TypeEnvironment funcEnv( func.env ); 922 makeUnifiableVars( funcType, funcOpenVars, funcNeed ); 923 // add all type variables as open variables now so that those not used in the parameter 924 // list are still considered open. 925 funcEnv.add( funcType->get_forall() ); 926 685 927 if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) { 686 928 // attempt to narrow based on expected target type 687 929 Type * returnType = funcType->get_returnVals().front()->get_type(); 688 if ( ! unify( returnType, targetType, resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 689 // unification failed, don't pursue this alternative 930 if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars, 931 indexer ) ) { 932 // unification failed, don't pursue this function alternative 690 933 return; 691 934 } 692 935 } 693 936 694 if ( instantiateFunction( funcType->get_parameters(), actualAlt, funcType->get_isVarArgs(), openVars, resultEnv, resultNeed, resultHave, instantiatedActuals ) ) { 695 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); 696 Alternative newAlt( appExpr, resultEnv, sumCost( instantiatedActuals ) ); 697 makeExprList( instantiatedActuals, appExpr->get_args() ); 698 PRINT( 699 std::cerr << "instantiate function success: " << appExpr << std::endl; 700 std::cerr << "need assertions:" << std::endl; 701 printAssertionSet( resultNeed, std::cerr, 8 ); 702 ) 703 inferParameters( resultNeed, resultHave, newAlt, openVars, out ); 937 // iteratively build matches, one parameter at a time 938 std::vector<ArgPack> results; 939 results.push_back( ArgPack{ funcEnv, funcNeed, funcHave, funcOpenVars } ); 940 std::size_t genStart = 0; 941 942 for ( DeclarationWithType* formal : funcType->get_parameters() ) { 943 ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal ); 944 if ( ! instantiateArgument( 945 obj->get_type(), obj->get_init(), args, results, genStart, indexer ) ) 946 return; 947 } 948 949 if ( funcType->get_isVarArgs() ) { 950 // append any unused arguments to vararg pack 951 std::size_t genEnd; 952 do { 953 genEnd = results.size(); 954 955 // iterate results 956 for ( std::size_t i = genStart; i < genEnd; ++i ) { 957 auto nextArg = results[i].nextArg; 958 959 // use remainder of exploded tuple if present 960 if ( results[i].hasExpl() ) { 961 const ExplodedActual& expl = results[i].getExpl( args ); 962 963 unsigned nextExpl = results[i].nextExpl + 1; 964 if ( nextExpl == expl.exprs.size() ) { 965 nextExpl = 0; 966 } 967 968 results.emplace_back( 969 i, expl.exprs[results[i].nextExpl].get(), copy(results[i].env), 970 copy(results[i].need), copy(results[i].have), 971 copy(results[i].openVars), nextArg, 0, Cost::zero, nextExpl, 972 results[i].explAlt ); 973 974 continue; 975 } 976 977 // finish result when out of arguments 978 if ( nextArg >= args.size() ) { 979 validateFunctionAlternative( func, results[i], results, out ); 980 981 continue; 982 } 983 984 // add each possible next argument 985 for ( std::size_t j = 0; j < args[nextArg].size(); ++j ) { 986 const ExplodedActual& expl = args[nextArg][j]; 987 988 // fresh copies of parent parameters for this iteration 989 TypeEnvironment env = results[i].env; 990 OpenVarSet openVars = results[i].openVars; 991 992 env.addActual( expl.env, openVars ); 993 994 // skip empty tuple arguments by (near-)cloning parent into next gen 995 if ( expl.exprs.empty() ) { 996 results.emplace_back( 997 results[i], move(env), copy(results[i].need), 998 copy(results[i].have), move(openVars), nextArg + 1, expl.cost ); 999 1000 continue; 1001 } 1002 1003 // add new result 1004 results.emplace_back( 1005 i, expl.exprs.front().get(), move(env), copy(results[i].need), 1006 copy(results[i].have), move(openVars), nextArg + 1, 0, 1007 expl.cost, expl.exprs.size() == 1 ? 0 : 1, j ); 1008 } 1009 } 1010 1011 genStart = genEnd; 1012 } while ( genEnd != results.size() ); 1013 } else { 1014 // filter out results that don't use all the arguments 1015 for ( std::size_t i = genStart; i < results.size(); ++i ) { 1016 ArgPack& result = results[i]; 1017 if ( ! result.hasExpl() && result.nextArg >= args.size() ) { 1018 validateFunctionAlternative( func, result, results, out ); 1019 } 1020 } 704 1021 } 705 1022 } … … 711 1028 if ( funcFinder.alternatives.empty() ) return; 712 1029 713 std::list< AlternativeFinder > argAlternatives; 714 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), back_inserter( argAlternatives ) ); 715 716 std::list< AltList > possibilities; 717 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 1030 std::vector< AlternativeFinder > argAlternatives; 1031 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), 1032 back_inserter( argAlternatives ) ); 718 1033 719 1034 // take care of possible tuple assignments 720 1035 // if not tuple assignment, assignment is taken care of as a normal function call 721 Tuples::handleTupleAssignment( *this, untypedExpr, possibilities );1036 Tuples::handleTupleAssignment( *this, untypedExpr, argAlternatives ); 722 1037 723 1038 // find function operators … … 730 1045 printAlts( funcOpFinder.alternatives, std::cerr, 1 ); 731 1046 ) 1047 1048 // pre-explode arguments 1049 ExplodedArgs argExpansions; 1050 argExpansions.reserve( argAlternatives.size() ); 1051 1052 for ( const AlternativeFinder& arg : argAlternatives ) { 1053 argExpansions.emplace_back(); 1054 auto& argE = argExpansions.back(); 1055 argE.reserve( arg.alternatives.size() ); 1056 1057 for ( const Alternative& actual : arg ) { 1058 argE.emplace_back( actual, indexer ); 1059 } 1060 } 732 1061 733 1062 AltList candidates; … … 744 1073 Alternative newFunc( *func ); 745 1074 referenceToRvalueConversion( newFunc.expr ); 746 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 747 // XXX 748 //Designators::check_alternative( function, *actualAlt ); 749 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) ); 750 } 1075 makeFunctionAlternatives( newFunc, function, argExpansions, 1076 std::back_inserter( candidates ) ); 751 1077 } 752 1078 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer) … … 756 1082 Alternative newFunc( *func ); 757 1083 referenceToRvalueConversion( newFunc.expr ); 758 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 759 makeFunctionAlternatives( newFunc, function, *actualAlt, std::back_inserter( candidates ) ); 760 } // for 1084 makeFunctionAlternatives( newFunc, function, argExpansions, 1085 std::back_inserter( candidates ) ); 761 1086 } // if 762 1087 } // if 763 1088 } 764 765 // try each function operator ?() with the current function alternative and each of the argument combinations 766 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); funcOp != funcOpFinder.alternatives.end(); ++funcOp ) { 767 // check if the type is pointer to function 768 if ( PointerType *pointer = dynamic_cast< PointerType* >( funcOp->expr->get_result()->stripReferences() ) ) { 769 if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) { 1089 } catch ( SemanticError &e ) { 1090 errors.append( e ); 1091 } 1092 } // for 1093 1094 // try each function operator ?() with each function alternative 1095 if ( ! funcOpFinder.alternatives.empty() ) { 1096 // add exploded function alternatives to front of argument list 1097 std::vector<ExplodedActual> funcE; 1098 funcE.reserve( funcFinder.alternatives.size() ); 1099 for ( const Alternative& actual : funcFinder ) { 1100 funcE.emplace_back( actual, indexer ); 1101 } 1102 argExpansions.insert( argExpansions.begin(), move(funcE) ); 1103 1104 for ( AltList::iterator funcOp = funcOpFinder.alternatives.begin(); 1105 funcOp != funcOpFinder.alternatives.end(); ++funcOp ) { 1106 try { 1107 // check if type is a pointer to function 1108 if ( PointerType* pointer = dynamic_cast<PointerType*>( 1109 funcOp->expr->get_result()->stripReferences() ) ) { 1110 if ( FunctionType* function = 1111 dynamic_cast<FunctionType*>( pointer->get_base() ) ) { 770 1112 Alternative newFunc( *funcOp ); 771 1113 referenceToRvalueConversion( newFunc.expr ); 772 for ( std::list< AltList >::iterator actualAlt = possibilities.begin(); actualAlt != possibilities.end(); ++actualAlt ) { 773 AltList currentAlt; 774 currentAlt.push_back( *func ); 775 currentAlt.insert( currentAlt.end(), actualAlt->begin(), actualAlt->end() ); 776 makeFunctionAlternatives( newFunc, function, currentAlt, std::back_inserter( candidates ) ); 777 } // for 778 } // if 779 } // if 780 } // for 781 } catch ( SemanticError &e ) { 782 errors.append( e ); 783 } 784 } // for 1114 makeFunctionAlternatives( newFunc, function, argExpansions, 1115 std::back_inserter( candidates ) ); 1116 } 1117 } 1118 } catch ( SemanticError &e ) { 1119 errors.append( e ); 1120 } 1121 } 1122 } 785 1123 786 1124 // Implement SFINAE; resolution errors are only errors if there aren't any non-erroneous resolutions … … 788 1126 789 1127 // compute conversionsion costs 790 for ( Alt List::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc) {791 Cost cvtCost = computeApplicationConversionCost( *withFunc, indexer );1128 for ( Alternative& withFunc : candidates ) { 1129 Cost cvtCost = computeApplicationConversionCost( withFunc, indexer ); 792 1130 793 1131 PRINT( 794 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc ->expr );1132 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr ); 795 1133 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() ); 796 1134 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() ); … … 801 1139 printAll( appExpr->get_args(), std::cerr, 8 ); 802 1140 std::cerr << "bindings are:" << std::endl; 803 withFunc ->env.print( std::cerr, 8 );1141 withFunc.env.print( std::cerr, 8 ); 804 1142 std::cerr << "cost of conversion is:" << cvtCost << std::endl; 805 1143 ) 806 1144 if ( cvtCost != Cost::infinity ) { 807 withFunc ->cvtCost = cvtCost;808 alternatives.push_back( *withFunc );1145 withFunc.cvtCost = cvtCost; 1146 alternatives.push_back( withFunc ); 809 1147 } // if 810 1148 } // for 811 1149 812 candidates.clear(); 813 candidates.splice( candidates.end(), alternatives ); 814 815 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) ); 816 817 // function may return struct or union value, in which case we need to add alternatives for implicit 818 // conversions to each of the anonymous members, must happen after findMinCost since anon conversions 819 // are never the cheapest expression 820 for ( const Alternative & alt : alternatives ) { 1150 candidates = move(alternatives); 1151 1152 // use a new list so that alternatives are not examined by addAnonConversions twice. 1153 AltList winners; 1154 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( winners ) ); 1155 1156 // function may return struct or union value, in which case we need to add alternatives 1157 // for implicitconversions to each of the anonymous members, must happen after findMinCost 1158 // since anon conversions are never the cheapest expression 1159 for ( const Alternative & alt : winners ) { 821 1160 addAnonConversions( alt ); 822 1161 } 1162 spliceBegin( alternatives, winners ); 823 1163 824 1164 if ( alternatives.empty() && targetType && ! targetType->isVoid() ) { … … 844 1184 AlternativeFinder finder( indexer, env ); 845 1185 finder.find( addressExpr->get_arg() ); 846 for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i ) { 847 if ( isLvalue( i->expr ) ) { 848 alternatives.push_back( Alternative( new AddressExpr( i->expr->clone() ), i->env, i->cost ) ); 1186 for ( Alternative& alt : finder.alternatives ) { 1187 if ( isLvalue( alt.expr ) ) { 1188 alternatives.push_back( 1189 Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } ); 849 1190 } // if 850 1191 } // for … … 852 1193 853 1194 void AlternativeFinder::visit( LabelAddressExpr * expr ) { 854 alternatives.push_back( Alternative ( expr->clone(), env, Cost::zero));1195 alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } ); 855 1196 } 856 1197 … … 894 1235 895 1236 AltList candidates; 896 for ( std::list< Alternative >::iterator i = finder.alternatives.begin(); i != finder.alternatives.end(); ++i) {1237 for ( Alternative & alt : finder.alternatives ) { 897 1238 AssertionSet needAssertions, haveAssertions; 898 1239 OpenVarSet openVars; … … 902 1243 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 903 1244 // to. 904 int discardedValues = i->expr->get_result()->size() - castExpr->get_result()->size();1245 int discardedValues = alt.expr->get_result()->size() - castExpr->get_result()->size(); 905 1246 if ( discardedValues < 0 ) continue; 906 1247 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 907 1248 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 908 1249 // unification run for side-effects 909 unify( castExpr->get_result(), i->expr->get_result(), i->env, needAssertions, haveAssertions, openVars, indexer ); 910 Cost thisCost = castCost( i->expr->get_result(), castExpr->get_result(), indexer, i->env ); 1250 unify( castExpr->get_result(), alt.expr->get_result(), alt.env, needAssertions, 1251 haveAssertions, openVars, indexer ); 1252 Cost thisCost = castCost( alt.expr->get_result(), castExpr->get_result(), indexer, 1253 alt.env ); 1254 PRINT( 1255 std::cerr << "working on cast with result: " << castExpr->result << std::endl; 1256 std::cerr << "and expr type: " << alt.expr->result << std::endl; 1257 std::cerr << "env: " << alt.env << std::endl; 1258 ) 911 1259 if ( thisCost != Cost::infinity ) { 1260 PRINT( 1261 std::cerr << "has finite cost." << std::endl; 1262 ) 912 1263 // count one safe conversion for each value that is thrown away 913 1264 thisCost.incSafe( discardedValues ); 914 Alternative newAlt( restructureCast( i->expr->clone(), toType ), i->env, i->cost, thisCost ); 915 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 1265 Alternative newAlt( restructureCast( alt.expr->clone(), toType ), alt.env, 1266 alt.cost, thisCost ); 1267 inferParameters( needAssertions, haveAssertions, newAlt, openVars, 1268 back_inserter( candidates ) ); 916 1269 } // if 917 1270 } // for … … 1200 1553 1201 1554 void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) { 1202 std::list< AlternativeFinder > subExprAlternatives; 1203 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), back_inserter( subExprAlternatives ) ); 1204 std::list< AltList > possibilities; 1205 combos( subExprAlternatives.begin(), subExprAlternatives.end(), back_inserter( possibilities ) ); 1206 for ( std::list< AltList >::const_iterator i = possibilities.begin(); i != possibilities.end(); ++i ) { 1555 std::vector< AlternativeFinder > subExprAlternatives; 1556 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 1557 back_inserter( subExprAlternatives ) ); 1558 std::vector< AltList > possibilities; 1559 combos( subExprAlternatives.begin(), subExprAlternatives.end(), 1560 back_inserter( possibilities ) ); 1561 for ( const AltList& alts : possibilities ) { 1207 1562 std::list< Expression * > exprs; 1208 makeExprList( *i, exprs );1563 makeExprList( alts, exprs ); 1209 1564 1210 1565 TypeEnvironment compositeEnv; 1211 simpleCombineEnvironments( i->begin(), i->end(), compositeEnv ); 1212 alternatives.push_back( Alternative( new TupleExpr( exprs ) , compositeEnv, sumCost( *i ) ) ); 1566 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 1567 alternatives.push_back( 1568 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } ); 1213 1569 } // for 1214 1570 } -
src/ResolvExpr/AlternativeFinder.h
r9d06142 rc0d00b6 21 21 22 22 #include "Alternative.h" // for AltList, Alternative 23 #include "ExplodedActual.h" // for ExplodedActual 23 24 #include "ResolvExpr/Cost.h" // for Cost, Cost::infinity 24 25 #include "ResolvExpr/TypeEnvironment.h" // for AssertionSet, OpenVarSet … … 31 32 32 33 namespace ResolvExpr { 34 struct ArgPack; 35 36 /// First index is which argument, second index is which alternative for that argument, 37 /// third index is which exploded element of that alternative 38 using ExplodedArgs = std::vector< std::vector< ExplodedActual > >; 39 33 40 class AlternativeFinder : public Visitor { 34 41 public: 35 42 AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env ); 43 44 AlternativeFinder( const AlternativeFinder& o ) 45 : indexer(o.indexer), alternatives(o.alternatives), env(o.env), 46 targetType(o.targetType) {} 47 48 AlternativeFinder( AlternativeFinder&& o ) 49 : indexer(o.indexer), alternatives(std::move(o.alternatives)), env(o.env), 50 targetType(o.targetType) {} 51 52 AlternativeFinder& operator= ( const AlternativeFinder& o ) { 53 if (&o == this) return *this; 54 55 // horrific nasty hack to rebind references... 56 alternatives.~AltList(); 57 new(this) AlternativeFinder(o); 58 return *this; 59 } 60 61 AlternativeFinder& operator= ( AlternativeFinder&& o ) { 62 if (&o == this) return *this; 63 64 // horrific nasty hack to rebind references... 65 alternatives.~AltList(); 66 new(this) AlternativeFinder(std::move(o)); 67 return *this; 68 } 69 36 70 void find( Expression *expr, bool adjust = false, bool prune = true, bool failFast = true ); 37 71 /// Calls find with the adjust flag set; adjustment turns array and function types into equivalent pointer types … … 99 133 /// Adds alternatives for offsetof expressions, given the base type and name of the member 100 134 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 101 bool instantiateFunction( std::list< DeclarationWithType* >& formals, const AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave, AltList & out ); 102 template< typename OutputIterator > 103 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const AltList &actualAlt, OutputIterator out ); 135 /// Takes a final result and checks if its assertions can be satisfied 136 template<typename OutputIterator> 137 void validateFunctionAlternative( const Alternative &func, ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out ); 138 /// Finds matching alternatives for a function, given a set of arguments 139 template<typename OutputIterator> 140 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out ); 141 /// Checks if assertion parameters match for a new alternative 104 142 template< typename OutputIterator > 105 143 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); -
src/ResolvExpr/PtrsAssignable.cc
r9d06142 rc0d00b6 68 68 69 69 void PtrsAssignable::visit( __attribute((unused)) VoidType *voidType ) { 70 if ( ! dynamic_cast< FunctionType* >( dest ) ) { 71 // T * = void * is safe for any T that is not a function type. 72 // xxx - this should be unsafe... 73 result = 1; 74 } // if 70 // T * = void * is disallowed - this is a change from C, where any 71 // void * can be assigned or passed to a non-void pointer without a cast. 75 72 } 76 73 -
src/ResolvExpr/RenameVars.cc
r9d06142 rc0d00b6 29 29 RenameVars global_renamer; 30 30 31 RenameVars::RenameVars() : level( 0 ) {31 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 32 32 mapStack.push_front( std::map< std::string, std::string >() ); 33 33 } … … 35 35 void RenameVars::reset() { 36 36 level = 0; 37 resetCount++; 37 38 } 38 39 … … 130 131 for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 131 132 std::ostringstream output; 132 output << "_" << level << "_" << (*i)->get_name();133 output << "_" << resetCount << "_" << level << "_" << (*i)->get_name(); 133 134 std::string newname( output.str() ); 134 135 mapStack.front()[ (*i)->get_name() ] = newname; -
src/ResolvExpr/RenameVars.h
r9d06142 rc0d00b6 48 48 void typeBefore( Type *type ); 49 49 void typeAfter( Type *type ); 50 int level ;50 int level, resetCount; 51 51 std::list< std::map< std::string, std::string > > mapStack; 52 52 }; -
src/ResolvExpr/Resolver.cc
r9d06142 rc0d00b6 18 18 #include <memory> // for allocator, allocator_traits<... 19 19 #include <tuple> // for get 20 #include <vector> 20 21 21 22 #include "Alternative.h" // for Alternative, AltList … … 411 412 412 413 // Find all alternatives for all arguments in canonical form 413 std:: list< AlternativeFinder > argAlternatives;414 std::vector< AlternativeFinder > argAlternatives; 414 415 funcFinder.findSubExprs( clause.target.arguments.begin(), clause.target.arguments.end(), back_inserter( argAlternatives ) ); 415 416 416 417 // List all combinations of arguments 417 std:: list< AltList > possibilities;418 std::vector< AltList > possibilities; 418 419 combos( argAlternatives.begin(), argAlternatives.end(), back_inserter( possibilities ) ); 419 420 -
src/ResolvExpr/TypeEnvironment.cc
r9d06142 rc0d00b6 201 201 } 202 202 203 void TypeEnvironment::addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ) { 204 for ( const EqvClass& c : actualEnv ) { 205 EqvClass c2 = c; 206 c2.allowWidening = false; 207 for ( const std::string& var : c2.vars ) { 208 openVars[ var ] = c2.data; 209 } 210 env.push_back( std::move(c2) ); 211 } 212 } 213 214 std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ) { 215 env.print( out ); 216 return out; 217 } 203 218 } // namespace ResolvExpr 204 219 -
src/ResolvExpr/TypeEnvironment.h
r9d06142 rc0d00b6 86 86 TypeEnvironment *clone() const { return new TypeEnvironment( *this ); } 87 87 88 /// Iteratively adds the environment of a new actual (with allowWidening = false), 89 /// and extracts open variables. 90 void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars ); 91 88 92 typedef std::list< EqvClass >::iterator iterator; 89 93 iterator begin() { return env.begin(); } … … 110 114 return sub.applyFree( type ); 111 115 } 116 117 std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ); 112 118 } // namespace ResolvExpr 113 119 -
src/ResolvExpr/module.mk
r9d06142 rc0d00b6 32 32 ResolvExpr/Occurs.cc \ 33 33 ResolvExpr/TypeEnvironment.cc \ 34 ResolvExpr/CurrentObject.cc 34 ResolvExpr/CurrentObject.cc \ 35 ResolvExpr/ExplodedActual.cc -
src/ResolvExpr/typeops.h
r9d06142 rc0d00b6 16 16 #pragma once 17 17 18 #include <vector> 19 18 20 #include "SynTree/SynTree.h" 19 21 #include "SynTree/Type.h" … … 28 30 void combos( InputIterator begin, InputIterator end, OutputIterator out ) { 29 31 typedef typename InputIterator::value_type SetType; 30 typedef typename std:: list< typename SetType::value_type > ListType;32 typedef typename std::vector< typename SetType::value_type > ListType; 31 33 32 34 if ( begin == end ) { … … 38 40 begin++; 39 41 40 std:: list< ListType > recursiveResult;42 std::vector< ListType > recursiveResult; 41 43 combos( begin, end, back_inserter( recursiveResult ) ); 42 44 43 for ( typename std::list< ListType >::const_iterator i = recursiveResult.begin(); i != recursiveResult.end(); ++i ) { 44 for ( typename ListType::const_iterator j = current->begin(); j != current->end(); ++j ) { 45 ListType result; 46 std::back_insert_iterator< ListType > inserter = back_inserter( result ); 47 *inserter++ = *j; 48 std::copy( i->begin(), i->end(), inserter ); 49 *out++ = result; 50 } // for 51 } // for 45 for ( const auto& i : recursiveResult ) for ( const auto& j : *current ) { 46 ListType result; 47 std::back_insert_iterator< ListType > inserter = back_inserter( result ); 48 *inserter++ = j; 49 std::copy( i.begin(), i.end(), inserter ); 50 *out++ = result; 51 } 52 52 } 53 53 -
src/SymTab/Autogen.cc
r9d06142 rc0d00b6 62 62 void previsit( FunctionDecl * functionDecl ); 63 63 64 void previsit( FunctionType * ftype );65 void previsit( PointerType * ptype );66 67 64 void previsit( CompoundStmt * compoundStmt ); 68 65 … … 72 69 unsigned int functionNesting = 0; // current level of nested functions 73 70 74 InitTweak::ManagedTypes managedTypes;75 71 std::vector< FuncData > data; 76 72 }; … … 625 621 // generate ctor/dtors/assign for typedecls, e.g., otype T = int *; 626 622 void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) { 627 visit_children = false;628 623 if ( ! typeDecl->base ) return; 629 624 … … 631 626 TypeFuncGenerator gen( typeDecl, &refType, data, functionNesting, indexer ); 632 627 generateFunctions( gen, declsToAddAfter ); 633 } 634 635 void AutogenerateRoutines::previsit( FunctionType *) { 636 // ensure that we don't add assignment ops for types defined as part of the function 637 visit_children = false; 638 } 639 640 void AutogenerateRoutines::previsit( PointerType *) { 641 // ensure that we don't add assignment ops for types defined as part of the pointer 642 visit_children = false; 628 643 629 } 644 630 … … 648 634 } 649 635 650 void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) { 651 visit_children = false; 652 // record the existence of this function as appropriate 653 managedTypes.handleDWT( functionDecl ); 654 655 maybeAccept( functionDecl->type, *visitor ); 636 void AutogenerateRoutines::previsit( FunctionDecl * ) { 637 // Track whether we're currently in a function. 638 // Can ignore function type idiosyncrasies, because function type can never 639 // declare a new type. 656 640 functionNesting += 1; 657 maybeAccept( functionDecl->statements, *visitor ); 658 functionNesting -= 1; 641 GuardAction( [this]() { functionNesting -= 1; } ); 659 642 } 660 643 661 644 void AutogenerateRoutines::previsit( CompoundStmt * ) { 662 GuardScope( managedTypes );663 645 GuardScope( structsDone ); 664 646 } -
src/SymTab/Autogen.h
r9d06142 rc0d00b6 59 59 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 60 60 template< typename OutputIterator > 61 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true );61 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true ); 62 62 63 63 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 64 64 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 65 65 template< typename OutputIterator > 66 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, bool addCast = false) {66 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) { 67 67 bool isReferenceCtorDtor = false; 68 68 if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { … … 71 71 fname = "?=?"; 72 72 dstParam = new AddressExpr( dstParam ); 73 addCast = false;73 addCast = nullptr; 74 74 isReferenceCtorDtor = true; 75 75 } … … 86 86 // remove lvalue as a qualifier, this can change to 87 87 // type->get_qualifiers() = Type::Qualifiers(); 88 assert( type ); 89 Type * castType = type->clone(); 88 Type * castType = addCast->clone(); 90 89 castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 91 90 // castType->set_lvalue( true ); // xxx - might not need this … … 118 117 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 119 118 template< typename OutputIterator > 120 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {119 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) { 121 120 static UniqueName indexName( "_index" ); 122 121 123 122 // for a flexible array member nothing is done -- user must define own assignment 124 if ( ! array->get_dimension() ) return ; 123 if ( ! array->get_dimension() ) return; 124 125 if ( addCast ) { 126 // peel off array layer from cast 127 ArrayType * at = strict_dynamic_cast< ArrayType * >( addCast ); 128 addCast = at->base; 129 } 125 130 126 131 Expression * begin, * end, * update, * cmp; … … 174 179 175 180 template< typename OutputIterator > 176 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, booladdCast, bool forward ) {181 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) { 177 182 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 178 183 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); … … 194 199 if ( isUnnamedBitfield( obj ) ) return; 195 200 196 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ); 201 Type * addCast = nullptr; 202 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && ! obj->get_bitfieldWidth() ) ) ) { 203 assert( dstParam->result ); 204 addCast = dstParam->result; 205 } 197 206 std::list< Statement * > stmts; 198 207 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->type, addCast, forward ); -
src/SymTab/Indexer.cc
r9d06142 rc0d00b6 567 567 } 568 568 569 void Indexer::addIds( const std::list< DeclarationWithType * > & decls ) { 570 for ( auto d : decls ) { 571 addId( d ); 572 } 573 } 574 575 void Indexer::addTypes( const std::list< TypeDecl * > & tds ) { 576 for ( auto td : tds ) { 577 addType( td ); 578 addIds( td->assertions ); 579 } 580 } 581 582 void Indexer::addFunctionType( FunctionType * ftype ) { 583 addTypes( ftype->forall ); 584 addIds( ftype->returnVals ); 585 addIds( ftype->parameters ); 586 } 587 569 588 void Indexer::enterScope() { 570 589 ++scope; -
src/SymTab/Indexer.h
r9d06142 rc0d00b6 76 76 void addTrait( TraitDecl *decl ); 77 77 78 /// convenience function for adding a list of Ids to the indexer 79 void addIds( const std::list< DeclarationWithType * > & decls ); 80 81 /// convenience function for adding a list of forall parameters to the indexer 82 void addTypes( const std::list< TypeDecl * > & tds ); 83 84 /// convenience function for adding all of the declarations in a function type to the indexer 85 void addFunctionType( FunctionType * ftype ); 86 78 87 bool doDebug = false; ///< Display debugging trace? 79 88 private: -
src/SymTab/Validate.cc
r9d06142 rc0d00b6 124 124 125 125 /// Associates forward declarations of aggregates with their definitions 126 struct LinkReferenceToTypes final : public WithIndexer {126 struct LinkReferenceToTypes final : public WithIndexer, public WithGuards { 127 127 LinkReferenceToTypes( const Indexer *indexer ); 128 128 void postvisit( TypeInstType *typeInst ); … … 137 137 void postvisit( UnionDecl *unionDecl ); 138 138 void postvisit( TraitDecl * traitDecl ); 139 140 void previsit( StructDecl *structDecl ); 141 void previsit( UnionDecl *unionDecl ); 142 143 void renameGenericParams( std::list< TypeDecl * > & params ); 139 144 140 145 private: … … 147 152 ForwardStructsType forwardStructs; 148 153 ForwardUnionsType forwardUnions; 154 /// true if currently in a generic type body, so that type parameter instances can be renamed appropriately 155 bool inGeneric = false; 149 156 }; 150 157 … … 423 430 } 424 431 432 void checkGenericParameters( ReferenceToType * inst ) { 433 for ( Expression * param : inst->parameters ) { 434 if ( ! dynamic_cast< TypeExpr * >( param ) ) { 435 throw SemanticError( "Expression parameters for generic types are currently unsupported: ", inst ); 436 } 437 } 438 } 439 425 440 void LinkReferenceToTypes::postvisit( StructInstType *structInst ) { 426 441 StructDecl *st = local_indexer->lookupStruct( structInst->get_name() ); … … 434 449 forwardStructs[ structInst->get_name() ].push_back( structInst ); 435 450 } // if 451 checkGenericParameters( structInst ); 436 452 } 437 453 … … 446 462 forwardUnions[ unionInst->get_name() ].push_back( unionInst ); 447 463 } // if 464 checkGenericParameters( unionInst ); 448 465 } 449 466 … … 525 542 // need to carry over the 'sized' status of each decl in the instance 526 543 for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) { 527 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( std::get<1>(p) ); 544 TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) ); 545 if ( ! expr ) { 546 throw SemanticError( "Expression parameters for trait instances are currently unsupported: ", std::get<1>(p) ); 547 } 528 548 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) { 529 549 TypeDecl * formalDecl = std::get<0>(p); … … 546 566 } // if 547 567 } // if 568 } 569 570 void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) { 571 // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g. 572 // forall(otype T) 573 // struct Box { 574 // T x; 575 // }; 576 // forall(otype T) 577 // void f(Box(T) b) { 578 // ... 579 // } 580 // The T in Box and the T in f are different, so internally the naming must reflect that. 581 GuardValue( inGeneric ); 582 inGeneric = ! params.empty(); 583 for ( TypeDecl * td : params ) { 584 td->name = "__" + td->name + "_generic_"; 585 } 586 } 587 588 void LinkReferenceToTypes::previsit( StructDecl * structDecl ) { 589 renameGenericParams( structDecl->parameters ); 590 } 591 592 void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) { 593 renameGenericParams( unionDecl->parameters ); 548 594 } 549 595 … … 575 621 576 622 void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) { 623 // ensure generic parameter instances are renamed like the base type 624 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 577 625 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) { 578 626 if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) { -
src/SynTree/Expression.cc
r9d06142 rc0d00b6 88 88 Type * type = var->get_type()->clone(); 89 89 type->set_lvalue( true ); 90 91 // xxx - doesn't quite work yet - get different alternatives with the same cost 92 93 // // enumerators are not lvalues 94 // if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( var->get_type() ) ) { 95 // assert( inst->baseEnum ); 96 // EnumDecl * decl = inst->baseEnum; 97 // for ( Declaration * member : decl->members ) { 98 // if ( member == _var ) { 99 // type->set_lvalue( false ); 100 // } 101 // } 102 // } 103 90 104 set_result( type ); 91 105 } … … 324 338 return makeSub( refType->get_base() ); 325 339 } else if ( StructInstType * aggInst = dynamic_cast< StructInstType * >( t ) ) { 326 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst-> get_parameters().begin() );340 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->parameters.begin() ); 327 341 } else if ( UnionInstType * aggInst = dynamic_cast< UnionInstType * >( t ) ) { 328 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst-> get_parameters().begin() );342 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->parameters.begin() ); 329 343 } else { 330 344 assertf( false, "makeSub expects struct or union type for aggregate, but got: %s", toString( t ).c_str() ); -
src/Tuples/Explode.h
r9d06142 rc0d00b6 16 16 #pragma once 17 17 18 #include <iterator> // for back_inserter, back_insert_iterator 18 #include <iterator> // for back_inserter, back_insert_iterator 19 #include <utility> // for forward 19 20 20 #include "ResolvExpr/Alternative.h" // for Alternative, AltList 21 #include "SynTree/Expression.h" // for Expression, UniqueExpr, AddressExpr 22 #include "SynTree/Type.h" // for TupleType, Type 23 #include "Tuples.h" // for maybeImpure 21 #include "ResolvExpr/Alternative.h" // for Alternative, AltList 22 #include "ResolvExpr/ExplodedActual.h" // for ExplodedActual 23 #include "SynTree/Expression.h" // for Expression, UniqueExpr, AddressExpr 24 #include "SynTree/Type.h" // for TupleType, Type 25 #include "Tuples.h" // for maybeImpure 24 26 25 27 namespace SymTab { … … 39 41 } 40 42 43 /// Append alternative to an OutputIterator of Alternatives 44 template<typename OutputIterator> 45 void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 46 const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) { 47 *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost }; 48 } 49 50 /// Append alternative to an ExplodedActual 51 static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 52 const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 53 ea.exprs.emplace_back( expr ); 54 /// xxx -- merge environment, cost? 55 } 56 41 57 /// helper function used by explode 42 template< typename OutputIterator > 43 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign ) { 58 template< typename Output > 59 void explodeUnique( Expression * expr, const ResolvExpr::Alternative & alt, 60 const SymTab::Indexer & indexer, Output&& out, bool isTupleAssign ) { 44 61 if ( isTupleAssign ) { 45 62 // tuple assignment needs CastExprs to be recursively exploded to easily get at all of the components 46 63 if ( CastExpr * castExpr = isReferenceCast( expr ) ) { 47 64 ResolvExpr::AltList alts; 48 explodeUnique( castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); 65 explodeUnique( 66 castExpr->get_arg(), alt, indexer, back_inserter( alts ), isTupleAssign ); 49 67 for ( ResolvExpr::Alternative & alt : alts ) { 50 68 // distribute reference cast over all components 51 a lt.expr = distributeReference( alt.expr );52 *out++ = alt;69 append( std::forward<Output>(out), distributeReference( alt.release_expr() ), 70 alt.env, alt.cost, alt.cvtCost ); 53 71 } 54 72 // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives) … … 61 79 // can open tuple expr and dump its exploded components 62 80 for ( Expression * expr : tupleExpr->get_exprs() ) { 63 explodeUnique( expr, alt, indexer, out, isTupleAssign );81 explodeUnique( expr, alt, indexer, std::forward<Output>(out), isTupleAssign ); 64 82 } 65 83 } else { … … 77 95 for ( unsigned int i = 0; i < tupleType->size(); i++ ) { 78 96 TupleIndexExpr * idx = new TupleIndexExpr( arg->clone(), i ); 79 explodeUnique( idx, alt, indexer, out, isTupleAssign );97 explodeUnique( idx, alt, indexer, std::forward<Output>(out), isTupleAssign ); 80 98 delete idx; 81 99 } … … 84 102 } else { 85 103 // atomic (non-tuple) type - output a clone of the expression in a new alternative 86 *out++ = ResolvExpr::Alternative(expr->clone(), alt.env, alt.cost, alt.cvtCost );104 append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost ); 87 105 } 88 106 } 89 107 90 108 /// expands a tuple-valued alternative into multiple alternatives, each with a non-tuple-type 91 template< typename OutputIterator > 92 void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) { 93 explodeUnique( alt.expr, alt, indexer, out, isTupleAssign ); 109 template< typename Output > 110 void explode( const ResolvExpr::Alternative &alt, const SymTab::Indexer & indexer, 111 Output&& out, bool isTupleAssign = false ) { 112 explodeUnique( alt.expr, alt, indexer, std::forward<Output>(out), isTupleAssign ); 94 113 } 95 114 96 115 // explode list of alternatives 97 template< typename AltIterator, typename OutputIterator > 98 void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) { 116 template< typename AltIterator, typename Output > 117 void explode( AltIterator altBegin, AltIterator altEnd, const SymTab::Indexer & indexer, 118 Output&& out, bool isTupleAssign = false ) { 99 119 for ( ; altBegin != altEnd; ++altBegin ) { 100 explode( *altBegin, indexer, out, isTupleAssign );120 explode( *altBegin, indexer, std::forward<Output>(out), isTupleAssign ); 101 121 } 102 122 } 103 123 104 template< typename OutputIterator > 105 void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, OutputIterator out, bool isTupleAssign = false ) { 106 explode( alts.begin(), alts.end(), indexer, out, isTupleAssign ); 124 template< typename Output > 125 void explode( const ResolvExpr::AltList & alts, const SymTab::Indexer & indexer, Output&& out, 126 bool isTupleAssign = false ) { 127 explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign ); 107 128 } 108 129 } // namespace Tuples -
src/Tuples/TupleAssignment.cc
r9d06142 rc0d00b6 20 20 #include <memory> // for unique_ptr, allocator_trai... 21 21 #include <string> // for string 22 #include <vector> 22 23 23 24 #include "CodeGen/OperatorTable.h" … … 33 34 #include "ResolvExpr/Resolver.h" // for resolveCtorInit 34 35 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 36 #include "ResolvExpr/typeops.h" // for combos 35 37 #include "SynTree/Declaration.h" // for ObjectDecl 36 38 #include "SynTree/Expression.h" // for Expression, CastExpr, Name... … … 52 54 // dispatcher for Tuple (multiple and mass) assignment operations 53 55 TupleAssignSpotter( ResolvExpr::AlternativeFinder & ); 54 void spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities );56 void spot( UntypedExpr * expr, std::vector<ResolvExpr::AlternativeFinder> &args ); 55 57 56 58 private: … … 59 61 struct Matcher { 60 62 public: 61 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ); 63 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const 64 ResolvExpr::AltList& rhs ); 62 65 virtual ~Matcher() {} 63 66 virtual void match( std::list< Expression * > &out ) = 0; … … 72 75 struct MassAssignMatcher : public Matcher { 73 76 public: 74 MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ); 77 MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 78 const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {} 75 79 virtual void match( std::list< Expression * > &out ); 76 80 }; … … 78 82 struct MultipleAssignMatcher : public Matcher { 79 83 public: 80 MultipleAssignMatcher( TupleAssignSpotter &spot, const ResolvExpr::AltList & alts ); 84 MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 85 const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {} 81 86 virtual void match( std::list< Expression * > &out ); 82 87 }; … … 114 119 } 115 120 116 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) { 121 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr, 122 std::vector<ResolvExpr::AlternativeFinder> &args ) { 117 123 TupleAssignSpotter spotter( currentFinder ); 118 spotter.spot( expr, possibilities );124 spotter.spot( expr, args ); 119 125 } 120 126 … … 122 128 : currentFinder(f) {} 123 129 124 void TupleAssignSpotter::spot( UntypedExpr * expr, const std::list<ResolvExpr::AltList> &possibilities ) { 130 void TupleAssignSpotter::spot( UntypedExpr * expr, 131 std::vector<ResolvExpr::AlternativeFinder> &args ) { 125 132 if ( NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) { 126 133 if ( CodeGen::isCtorDtorAssign( op->get_name() ) ) { 127 fname = op->get_name(); 128 PRINT( std::cerr << "TupleAssignment: " << fname << std::endl; ) 129 for ( std::list<ResolvExpr::AltList>::const_iterator ali = possibilities.begin(); ali != possibilities.end(); ++ali ) { 130 if ( ali->size() == 0 ) continue; // AlternativeFinder will natrually handle this case, if it's legal 131 if ( ali->size() <= 1 && CodeGen::isAssignment( op->get_name() ) ) { 132 // what does it mean if an assignment takes 1 argument? maybe someone defined such a function, in which case AlternativeFinder will naturally handle it 133 continue; 134 fname = op->get_name(); 135 136 // AlternativeFinder will naturally handle this case case, if it's legal 137 if ( args.size() == 0 ) return; 138 139 // if an assignment only takes 1 argument, that's odd, but maybe someone wrote 140 // the function, in which case AlternativeFinder will handle it normally 141 if ( args.size() == 1 && CodeGen::isAssignment( fname ) ) return; 142 143 // look over all possible left-hand-sides 144 for ( ResolvExpr::Alternative& lhsAlt : args[0] ) { 145 // skip non-tuple LHS 146 if ( ! refToTuple(lhsAlt.expr) ) continue; 147 148 // explode is aware of casts - ensure every LHS expression is sent into explode 149 // with a reference cast 150 // xxx - this seems to change the alternatives before the normal 151 // AlternativeFinder flow; maybe this is desired? 152 if ( ! dynamic_cast<CastExpr*>( lhsAlt.expr ) ) { 153 lhsAlt.expr = new CastExpr( lhsAlt.expr, 154 new ReferenceType( Type::Qualifiers(), 155 lhsAlt.expr->get_result()->clone() ) ); 134 156 } 135 157 136 assert( ! ali->empty() ); 137 // grab args 2-N and group into a TupleExpr 138 const ResolvExpr::Alternative & alt1 = ali->front(); 139 auto begin = std::next(ali->begin(), 1), end = ali->end(); 140 PRINT( std::cerr << "alt1 is " << alt1.expr << std::endl; ) 141 if ( refToTuple(alt1.expr) ) { 142 PRINT( std::cerr << "and is reference to tuple" << std::endl; ) 143 if ( isMultAssign( begin, end ) ) { 144 PRINT( std::cerr << "possible multiple assignment" << std::endl; ) 145 matcher.reset( new MultipleAssignMatcher( *this, *ali ) ); 146 } else { 147 // mass assignment 148 PRINT( std::cerr << "possible mass assignment" << std::endl; ) 149 matcher.reset( new MassAssignMatcher( *this, *ali ) ); 158 // explode the LHS so that each field of a tuple-valued-expr is assigned 159 ResolvExpr::AltList lhs; 160 explode( lhsAlt, currentFinder.get_indexer(), back_inserter(lhs), true ); 161 for ( ResolvExpr::Alternative& alt : lhs ) { 162 // each LHS value must be a reference - some come in with a cast expression, 163 // if not just cast to reference here 164 if ( ! dynamic_cast<ReferenceType*>( alt.expr->get_result() ) ) { 165 alt.expr = new CastExpr( alt.expr, 166 new ReferenceType( Type::Qualifiers(), 167 alt.expr->get_result()->clone() ) ); 150 168 } 169 } 170 171 if ( args.size() == 1 ) { 172 // mass default-initialization/destruction 173 ResolvExpr::AltList rhs{}; 174 matcher.reset( new MassAssignMatcher( *this, lhs, rhs ) ); 151 175 match(); 176 } else if ( args.size() > 2 ) { 177 // expand all possible RHS possibilities 178 // TODO build iterative version of this instead of using combos 179 std::vector< ResolvExpr::AltList > rhsAlts; 180 combos( std::next(args.begin(), 1), args.end(), 181 std::back_inserter( rhsAlts ) ); 182 for ( const ResolvExpr::AltList& rhsAlt : rhsAlts ) { 183 // multiple assignment 184 ResolvExpr::AltList rhs; 185 explode( rhsAlt, currentFinder.get_indexer(), 186 std::back_inserter(rhs), true ); 187 matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) ); 188 match(); 189 } 190 } else { 191 for ( const ResolvExpr::Alternative& rhsAlt : args[1] ) { 192 ResolvExpr::AltList rhs; 193 if ( isTuple(rhsAlt.expr) ) { 194 // multiple assignment 195 explode( rhsAlt, currentFinder.get_indexer(), 196 std::back_inserter(rhs), true ); 197 matcher.reset( new MultipleAssignMatcher( *this, lhs, rhs ) ); 198 } else { 199 // mass assignment 200 rhs.push_back( rhsAlt ); 201 matcher.reset( new MassAssignMatcher( *this, lhs, rhs ) ); 202 } 203 match(); 204 } 152 205 } 153 206 } … … 169 222 ResolvExpr::AltList current; 170 223 // now resolve new assignments 171 for ( std::list< Expression * >::iterator i = new_assigns.begin(); i != new_assigns.end(); ++i ) { 224 for ( std::list< Expression * >::iterator i = new_assigns.begin(); 225 i != new_assigns.end(); ++i ) { 172 226 PRINT( 173 227 std::cerr << "== resolving tuple assign ==" << std::endl; … … 175 229 ) 176 230 177 ResolvExpr::AlternativeFinder finder( currentFinder.get_indexer(), currentFinder.get_environ() ); 231 ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(), 232 currentFinder.get_environ() }; 178 233 try { 179 234 finder.findWithAdjustment(*i); … … 196 251 // combine assignment environments into combined expression environment 197 252 simpleCombineEnvironments( current.begin(), current.end(), matcher->compositeEnv ); 198 currentFinder.get_alternatives().push_front( ResolvExpr::Alternative(new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, ResolvExpr::sumCost( current ) + matcher->baseCost ) ); 199 } 200 201 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList &alts ) : spotter(spotter), baseCost( ResolvExpr::sumCost( alts ) ) { 202 assert( ! alts.empty() ); 203 // combine argument environments into combined expression environment 204 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 205 206 ResolvExpr::Alternative lhsAlt = alts.front(); 207 // explode is aware of casts - ensure every LHS expression is sent into explode with a reference cast 208 if ( ! dynamic_cast< CastExpr * >( lhsAlt.expr ) ) { 209 lhsAlt.expr = new CastExpr( lhsAlt.expr, new ReferenceType( Type::Qualifiers(), lhsAlt.expr->get_result()->clone() ) ); 210 } 211 212 // explode the lhs so that each field of the tuple-valued-expr is assigned. 213 explode( lhsAlt, spotter.currentFinder.get_indexer(), back_inserter(lhs), true ); 214 215 for ( ResolvExpr::Alternative & alt : lhs ) { 216 // every LHS value must be a reference - some come in with a cast expression, if it doesn't just cast to reference here. 217 if ( ! dynamic_cast< ReferenceType * >( alt.expr->get_result() ) ) { 218 alt.expr = new CastExpr( alt.expr, new ReferenceType( Type::Qualifiers(), alt.expr->get_result()->clone() ) ); 219 } 220 } 221 } 222 223 TupleAssignSpotter::MassAssignMatcher::MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) { 224 assert( alts.size() == 1 || alts.size() == 2 ); 225 if ( alts.size() == 2 ) { 226 rhs.push_back( alts.back() ); 227 } 228 } 229 230 TupleAssignSpotter::MultipleAssignMatcher::MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList & alts ) : Matcher( spotter, alts ) { 231 // explode the rhs so that each field of the tuple-valued-expr is assigned. 232 explode( std::next(alts.begin(), 1), alts.end(), spotter.currentFinder.get_indexer(), back_inserter(rhs), true ); 253 // xxx -- was push_front 254 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative( 255 new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 256 ResolvExpr::sumCost( current ) + matcher->baseCost ) ); 257 } 258 259 TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter, 260 const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs ) 261 : lhs(lhs), rhs(rhs), spotter(spotter), 262 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) { 263 simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv ); 264 simpleCombineEnvironments( rhs.begin(), rhs.end(), compositeEnv ); 233 265 } 234 266 -
src/Tuples/Tuples.h
r9d06142 rc0d00b6 17 17 18 18 #include <string> 19 #include <vector> 19 20 20 21 #include "SynTree/Expression.h" … … 26 27 namespace Tuples { 27 28 // TupleAssignment.cc 28 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, const std::list<ResolvExpr::AltList> & possibilities ); 29 29 void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, 30 std::vector< ResolvExpr::AlternativeFinder >& args ); 31 30 32 // TupleExpansion.cc 31 33 /// expands z.[a, b.[x, y], c] into [z.a, z.b.x, z.b.y, z.c], inserting UniqueExprs as appropriate -
src/benchmark/Makefile.am
r9d06142 rc0d00b6 23 23 STATS = ${TOOLSDIR}stat.py 24 24 repeats = 30 25 TIME_FORMAT = "%E" 26 PRINT_FORMAT = %20s: #Comments needed for spacing 25 27 26 28 .NOTPARALLEL: … … 29 31 30 32 all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT) 31 32 bench$(EXEEXT) :33 @for ccflags in "-debug" "-nodebug"; do \34 echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\35 ${CC} ${AM_CFLAGS} ${CFLAGS} $${ccflags} -lrt bench.c;\36 ./a.out ; \37 done ; \38 rm -f ./a.out ;39 40 csv-data$(EXEEXT):41 @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=50000000 csv-data.c42 @./a.out43 @rm -f ./a.out44 45 ## =========================================================================================================46 ctxswitch$(EXEEXT): \47 ctxswitch-pthread.run \48 ctxswitch-cfa_coroutine.run \49 ctxswitch-cfa_thread.run \50 ctxswitch-upp_coroutine.run \51 ctxswitch-upp_thread.run52 53 ctxswitch-cfa_coroutine$(EXEEXT):54 ${CC} ctxswitch/cfa_cor.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}55 56 ctxswitch-cfa_thread$(EXEEXT):57 ${CC} ctxswitch/cfa_thrd.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}58 59 ctxswitch-upp_coroutine$(EXEEXT):60 u++ ctxswitch/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}61 62 ctxswitch-upp_thread$(EXEEXT):63 u++ ctxswitch/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}64 65 ctxswitch-pthread$(EXEEXT):66 @BACKEND_CC@ ctxswitch/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}67 68 ## =========================================================================================================69 mutex$(EXEEXT) :\70 mutex-function.run \71 mutex-pthread_lock.run \72 mutex-upp.run \73 mutex-cfa1.run \74 mutex-cfa2.run \75 mutex-cfa4.run76 77 mutex-function$(EXEEXT):78 @BACKEND_CC@ mutex/function.c -DBENCH_N=500000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}79 80 mutex-pthread_lock$(EXEEXT):81 @BACKEND_CC@ mutex/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}82 83 mutex-upp$(EXEEXT):84 u++ mutex/upp.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}85 86 mutex-cfa1$(EXEEXT):87 ${CC} mutex/cfa1.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}88 89 mutex-cfa2$(EXEEXT):90 ${CC} mutex/cfa2.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}91 92 mutex-cfa4$(EXEEXT):93 ${CC} mutex/cfa4.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}94 95 ## =========================================================================================================96 signal$(EXEEXT) :\97 signal-upp.run \98 signal-cfa1.run \99 signal-cfa2.run \100 signal-cfa4.run101 102 signal-upp$(EXEEXT):103 u++ schedint/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}104 105 signal-cfa1$(EXEEXT):106 ${CC} schedint/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}107 108 signal-cfa2$(EXEEXT):109 ${CC} schedint/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}110 111 signal-cfa4$(EXEEXT):112 ${CC} schedint/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}113 114 ## =========================================================================================================115 waitfor$(EXEEXT) :\116 waitfor-upp.run \117 waitfor-cfa1.run \118 waitfor-cfa2.run \119 waitfor-cfa4.run120 121 waitfor-upp$(EXEEXT):122 u++ schedext/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}123 124 waitfor-cfa1$(EXEEXT):125 ${CC} schedext/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}126 127 waitfor-cfa2$(EXEEXT):128 ${CC} schedext/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}129 130 waitfor-cfa4$(EXEEXT):131 ${CC} schedext/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}132 133 ## =========================================================================================================134 creation$(EXEEXT) :\135 creation-pthread.run \136 creation-cfa_coroutine.run \137 creation-cfa_thread.run \138 creation-upp_coroutine.run \139 creation-upp_thread.run140 141 creation-cfa_coroutine$(EXEEXT):142 ${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}143 144 creation-cfa_thread$(EXEEXT):145 ${CC} creation/cfa_thrd.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}146 147 creation-upp_coroutine$(EXEEXT):148 u++ creation/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}149 150 creation-upp_thread$(EXEEXT):151 u++ creation/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}152 153 creation-pthread$(EXEEXT):154 @BACKEND_CC@ creation/pthreads.c -DBENCH_N=250000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}155 156 ## =========================================================================================================157 33 158 34 %.run : %$(EXEEXT) ${REPEAT} … … 165 41 @rm -f a.out .result.log 166 42 43 %.runquiet : 44 @+make $(basename $@) 45 @./a.out 46 @rm -f a.out 47 48 %.make : 49 @printf "${PRINT_FORMAT}" $(basename $(subst compile-,,$@)) 50 @+/usr/bin/time -f ${TIME_FORMAT} make $(basename $@) 2>&1 51 167 52 ${REPEAT} : 168 53 @+make -C ${TOOLSDIR} repeat 54 55 ## ========================================================================================================= 56 57 jenkins$(EXEEXT): 58 @echo "{" 59 @echo -e '\t"githash": "'${githash}'",' 60 @echo -e '\t"arch": "' ${arch} '",' 61 @echo -e '\t"compile": {' 62 @+make compile TIME_FORMAT='%e,' PRINT_FORMAT='\t\t\"%s\" :' 63 @echo -e '\t\t"dummy" : {}' 64 @echo -e '\t},' 65 @echo -e '\t"ctxswitch": {' 66 @echo -en '\t\t"coroutine":' 67 @+make ctxswitch-cfa_coroutine.runquiet 68 @echo -en '\t\t,"thread":' 69 @+make ctxswitch-cfa_thread.runquiet 70 @echo -e '\t},' 71 @echo -e '\t"mutex": [' 72 @echo -en '\t\t' 73 @+make mutex-cfa1.runquiet 74 @echo -en '\t\t,' 75 @+make mutex-cfa2.runquiet 76 @echo -e '\t],' 77 @echo -e '\t"scheduling": [' 78 @echo -en '\t\t' 79 @+make signal-cfa1.runquiet 80 @echo -en '\t\t,' 81 @+make signal-cfa2.runquiet 82 @echo -en '\t\t,' 83 @+make waitfor-cfa1.runquiet 84 @echo -en '\t\t,' 85 @+make waitfor-cfa2.runquiet 86 @echo -e '\n\t],' 87 @echo -e '\t"epoch": ' $(shell date +%s) 88 @echo "}" 89 90 ## ========================================================================================================= 91 ctxswitch$(EXEEXT): \ 92 ctxswitch-pthread.run \ 93 ctxswitch-cfa_coroutine.run \ 94 ctxswitch-cfa_thread.run \ 95 ctxswitch-upp_coroutine.run \ 96 ctxswitch-upp_thread.run 97 98 ctxswitch-cfa_coroutine$(EXEEXT): 99 @${CC} ctxswitch/cfa_cor.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 100 101 ctxswitch-cfa_thread$(EXEEXT): 102 @${CC} ctxswitch/cfa_thrd.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 103 104 ctxswitch-upp_coroutine$(EXEEXT): 105 @u++ ctxswitch/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 106 107 ctxswitch-upp_thread$(EXEEXT): 108 @u++ ctxswitch/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 109 110 ctxswitch-pthread$(EXEEXT): 111 @@BACKEND_CC@ ctxswitch/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 112 113 ## ========================================================================================================= 114 mutex$(EXEEXT) :\ 115 mutex-function.run \ 116 mutex-pthread_lock.run \ 117 mutex-upp.run \ 118 mutex-cfa1.run \ 119 mutex-cfa2.run \ 120 mutex-cfa4.run 121 122 mutex-function$(EXEEXT): 123 @@BACKEND_CC@ mutex/function.c -DBENCH_N=500000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 124 125 mutex-pthread_lock$(EXEEXT): 126 @@BACKEND_CC@ mutex/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 127 128 mutex-upp$(EXEEXT): 129 @u++ mutex/upp.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 130 131 mutex-cfa1$(EXEEXT): 132 @${CC} mutex/cfa1.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 133 134 mutex-cfa2$(EXEEXT): 135 @${CC} mutex/cfa2.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 136 137 mutex-cfa4$(EXEEXT): 138 @${CC} mutex/cfa4.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 139 140 ## ========================================================================================================= 141 signal$(EXEEXT) :\ 142 signal-upp.run \ 143 signal-cfa1.run \ 144 signal-cfa2.run \ 145 signal-cfa4.run 146 147 signal-upp$(EXEEXT): 148 @u++ schedint/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 149 150 signal-cfa1$(EXEEXT): 151 @${CC} schedint/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 152 153 signal-cfa2$(EXEEXT): 154 @${CC} schedint/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 155 156 signal-cfa4$(EXEEXT): 157 @${CC} schedint/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 158 159 ## ========================================================================================================= 160 waitfor$(EXEEXT) :\ 161 waitfor-upp.run \ 162 waitfor-cfa1.run \ 163 waitfor-cfa2.run \ 164 waitfor-cfa4.run 165 166 waitfor-upp$(EXEEXT): 167 @u++ schedext/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 168 169 waitfor-cfa1$(EXEEXT): 170 @${CC} schedext/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 171 172 waitfor-cfa2$(EXEEXT): 173 @${CC} schedext/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 174 175 waitfor-cfa4$(EXEEXT): 176 @${CC} schedext/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 177 178 ## ========================================================================================================= 179 creation$(EXEEXT) :\ 180 creation-pthread.run \ 181 creation-cfa_coroutine.run \ 182 creation-cfa_coroutine_eager.run \ 183 creation-cfa_thread.run \ 184 creation-upp_coroutine.run \ 185 creation-upp_thread.run 186 187 creation-cfa_coroutine$(EXEEXT): 188 @${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 189 190 creation-cfa_coroutine_eager$(EXEEXT): 191 @${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} -DEAGER 192 193 creation-cfa_thread$(EXEEXT): 194 @${CC} creation/cfa_thrd.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 195 196 creation-upp_coroutine$(EXEEXT): 197 @u++ creation/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 198 199 creation-upp_thread$(EXEEXT): 200 @u++ creation/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 201 202 creation-pthread$(EXEEXT): 203 @@BACKEND_CC@ creation/pthreads.c -DBENCH_N=250000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 204 205 ## ========================================================================================================= 206 207 compile$(EXEEXT) :\ 208 compile-array.make \ 209 compile-attributes.make \ 210 compile-empty.make \ 211 compile-expression.make \ 212 compile-io.make \ 213 compile-monitor.make \ 214 compile-operators.make \ 215 compile-typeof.make 216 217 218 compile-array$(EXEEXT): 219 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/array.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 220 221 compile-attributes$(EXEEXT): 222 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/attributes.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 223 224 compile-empty$(EXEEXT): 225 @${CC} -nodebug -quiet -fsyntax-only -w compile/empty.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 226 227 compile-expression$(EXEEXT): 228 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/expression.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 229 230 compile-io$(EXEEXT): 231 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/io.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 232 233 compile-monitor$(EXEEXT): 234 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/monitor.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 235 236 compile-operators$(EXEEXT): 237 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/operators.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 238 239 compile-thread$(EXEEXT): 240 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/thread.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 241 242 compile-typeof$(EXEEXT): 243 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/typeof.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 244 -
src/benchmark/Makefile.in
r9d06142 rc0d00b6 124 124 esac 125 125 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 126 am__DIST_COMMON = $(srcdir)/Makefile.in 126 am__DIST_COMMON = $(srcdir)/Makefile.in compile 127 127 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 128 128 ACLOCAL = @ACLOCAL@ … … 253 253 STATS = ${TOOLSDIR}stat.py 254 254 repeats = 30 255 TIME_FORMAT = "%E" 256 PRINT_FORMAT = %20s: #Comments needed for spacing 255 257 all: all-am 256 258 … … 446 448 all : ctxswitch$(EXEEXT) mutex$(EXEEXT) signal$(EXEEXT) waitfor$(EXEEXT) creation$(EXEEXT) 447 449 448 bench$(EXEEXT) :449 @for ccflags in "-debug" "-nodebug"; do \450 echo ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -lrt bench.c;\451 ${CC} ${AM_CFLAGS} ${CFLAGS} $${ccflags} -lrt bench.c;\452 ./a.out ; \453 done ; \454 rm -f ./a.out ;455 456 csv-data$(EXEEXT):457 @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=50000000 csv-data.c458 @./a.out459 @rm -f ./a.out460 461 ctxswitch$(EXEEXT): \462 ctxswitch-pthread.run \463 ctxswitch-cfa_coroutine.run \464 ctxswitch-cfa_thread.run \465 ctxswitch-upp_coroutine.run \466 ctxswitch-upp_thread.run467 468 ctxswitch-cfa_coroutine$(EXEEXT):469 ${CC} ctxswitch/cfa_cor.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}470 471 ctxswitch-cfa_thread$(EXEEXT):472 ${CC} ctxswitch/cfa_thrd.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}473 474 ctxswitch-upp_coroutine$(EXEEXT):475 u++ ctxswitch/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}476 477 ctxswitch-upp_thread$(EXEEXT):478 u++ ctxswitch/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}479 480 ctxswitch-pthread$(EXEEXT):481 @BACKEND_CC@ ctxswitch/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}482 483 mutex$(EXEEXT) :\484 mutex-function.run \485 mutex-pthread_lock.run \486 mutex-upp.run \487 mutex-cfa1.run \488 mutex-cfa2.run \489 mutex-cfa4.run490 491 mutex-function$(EXEEXT):492 @BACKEND_CC@ mutex/function.c -DBENCH_N=500000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}493 494 mutex-pthread_lock$(EXEEXT):495 @BACKEND_CC@ mutex/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}496 497 mutex-upp$(EXEEXT):498 u++ mutex/upp.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}499 500 mutex-cfa1$(EXEEXT):501 ${CC} mutex/cfa1.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}502 503 mutex-cfa2$(EXEEXT):504 ${CC} mutex/cfa2.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}505 506 mutex-cfa4$(EXEEXT):507 ${CC} mutex/cfa4.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}508 509 signal$(EXEEXT) :\510 signal-upp.run \511 signal-cfa1.run \512 signal-cfa2.run \513 signal-cfa4.run514 515 signal-upp$(EXEEXT):516 u++ schedint/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}517 518 signal-cfa1$(EXEEXT):519 ${CC} schedint/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}520 521 signal-cfa2$(EXEEXT):522 ${CC} schedint/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}523 524 signal-cfa4$(EXEEXT):525 ${CC} schedint/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}526 527 waitfor$(EXEEXT) :\528 waitfor-upp.run \529 waitfor-cfa1.run \530 waitfor-cfa2.run \531 waitfor-cfa4.run532 533 waitfor-upp$(EXEEXT):534 u++ schedext/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}535 536 waitfor-cfa1$(EXEEXT):537 ${CC} schedext/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}538 539 waitfor-cfa2$(EXEEXT):540 ${CC} schedext/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}541 542 waitfor-cfa4$(EXEEXT):543 ${CC} schedext/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}544 545 creation$(EXEEXT) :\546 creation-pthread.run \547 creation-cfa_coroutine.run \548 creation-cfa_thread.run \549 creation-upp_coroutine.run \550 creation-upp_thread.run551 552 creation-cfa_coroutine$(EXEEXT):553 ${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}554 555 creation-cfa_thread$(EXEEXT):556 ${CC} creation/cfa_thrd.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags}557 558 creation-upp_coroutine$(EXEEXT):559 u++ creation/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}560 561 creation-upp_thread$(EXEEXT):562 u++ creation/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags}563 564 creation-pthread$(EXEEXT):565 @BACKEND_CC@ creation/pthreads.c -DBENCH_N=250000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags}566 567 450 %.run : %$(EXEEXT) ${REPEAT} 568 451 @rm -f .result.log … … 574 457 @rm -f a.out .result.log 575 458 459 %.runquiet : 460 @+make $(basename $@) 461 @./a.out 462 @rm -f a.out 463 464 %.make : 465 @printf "${PRINT_FORMAT}" $(basename $(subst compile-,,$@)) 466 @+/usr/bin/time -f ${TIME_FORMAT} make $(basename $@) 2>&1 467 576 468 ${REPEAT} : 577 469 @+make -C ${TOOLSDIR} repeat 470 471 jenkins$(EXEEXT): 472 @echo "{" 473 @echo -e '\t"githash": "'${githash}'",' 474 @echo -e '\t"arch": "' ${arch} '",' 475 @echo -e '\t"compile": {' 476 @+make compile TIME_FORMAT='%e,' PRINT_FORMAT='\t\t\"%s\" :' 477 @echo -e '\t\t"dummy" : {}' 478 @echo -e '\t},' 479 @echo -e '\t"ctxswitch": {' 480 @echo -en '\t\t"coroutine":' 481 @+make ctxswitch-cfa_coroutine.runquiet 482 @echo -en '\t\t,"thread":' 483 @+make ctxswitch-cfa_thread.runquiet 484 @echo -e '\t},' 485 @echo -e '\t"mutex": [' 486 @echo -en '\t\t' 487 @+make mutex-cfa1.runquiet 488 @echo -en '\t\t,' 489 @+make mutex-cfa2.runquiet 490 @echo -e '\t],' 491 @echo -e '\t"scheduling": [' 492 @echo -en '\t\t' 493 @+make signal-cfa1.runquiet 494 @echo -en '\t\t,' 495 @+make signal-cfa2.runquiet 496 @echo -en '\t\t,' 497 @+make waitfor-cfa1.runquiet 498 @echo -en '\t\t,' 499 @+make waitfor-cfa2.runquiet 500 @echo -e '\n\t],' 501 @echo -e '\t"epoch": ' $(shell date +%s) 502 @echo "}" 503 504 ctxswitch$(EXEEXT): \ 505 ctxswitch-pthread.run \ 506 ctxswitch-cfa_coroutine.run \ 507 ctxswitch-cfa_thread.run \ 508 ctxswitch-upp_coroutine.run \ 509 ctxswitch-upp_thread.run 510 511 ctxswitch-cfa_coroutine$(EXEEXT): 512 @${CC} ctxswitch/cfa_cor.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 513 514 ctxswitch-cfa_thread$(EXEEXT): 515 @${CC} ctxswitch/cfa_thrd.c -DBENCH_N=50000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 516 517 ctxswitch-upp_coroutine$(EXEEXT): 518 @u++ ctxswitch/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 519 520 ctxswitch-upp_thread$(EXEEXT): 521 @u++ ctxswitch/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 522 523 ctxswitch-pthread$(EXEEXT): 524 @@BACKEND_CC@ ctxswitch/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 525 526 mutex$(EXEEXT) :\ 527 mutex-function.run \ 528 mutex-pthread_lock.run \ 529 mutex-upp.run \ 530 mutex-cfa1.run \ 531 mutex-cfa2.run \ 532 mutex-cfa4.run 533 534 mutex-function$(EXEEXT): 535 @@BACKEND_CC@ mutex/function.c -DBENCH_N=500000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 536 537 mutex-pthread_lock$(EXEEXT): 538 @@BACKEND_CC@ mutex/pthreads.c -DBENCH_N=50000000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 539 540 mutex-upp$(EXEEXT): 541 @u++ mutex/upp.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 542 543 mutex-cfa1$(EXEEXT): 544 @${CC} mutex/cfa1.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 545 546 mutex-cfa2$(EXEEXT): 547 @${CC} mutex/cfa2.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 548 549 mutex-cfa4$(EXEEXT): 550 @${CC} mutex/cfa4.c -DBENCH_N=5000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 551 552 signal$(EXEEXT) :\ 553 signal-upp.run \ 554 signal-cfa1.run \ 555 signal-cfa2.run \ 556 signal-cfa4.run 557 558 signal-upp$(EXEEXT): 559 @u++ schedint/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 560 561 signal-cfa1$(EXEEXT): 562 @${CC} schedint/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 563 564 signal-cfa2$(EXEEXT): 565 @${CC} schedint/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 566 567 signal-cfa4$(EXEEXT): 568 @${CC} schedint/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 569 570 waitfor$(EXEEXT) :\ 571 waitfor-upp.run \ 572 waitfor-cfa1.run \ 573 waitfor-cfa2.run \ 574 waitfor-cfa4.run 575 576 waitfor-upp$(EXEEXT): 577 @u++ schedext/upp.cc -DBENCH_N=5000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 578 579 waitfor-cfa1$(EXEEXT): 580 @${CC} schedext/cfa1.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 581 582 waitfor-cfa2$(EXEEXT): 583 @${CC} schedext/cfa2.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 584 585 waitfor-cfa4$(EXEEXT): 586 @${CC} schedext/cfa4.c -DBENCH_N=500000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 587 588 creation$(EXEEXT) :\ 589 creation-pthread.run \ 590 creation-cfa_coroutine.run \ 591 creation-cfa_coroutine_eager.run \ 592 creation-cfa_thread.run \ 593 creation-upp_coroutine.run \ 594 creation-upp_thread.run 595 596 creation-cfa_coroutine$(EXEEXT): 597 @${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 598 599 creation-cfa_coroutine_eager$(EXEEXT): 600 @${CC} creation/cfa_cor.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} -DEAGER 601 602 creation-cfa_thread$(EXEEXT): 603 @${CC} creation/cfa_thrd.c -DBENCH_N=10000000 -I. -nodebug -lrt -quiet @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 604 605 creation-upp_coroutine$(EXEEXT): 606 @u++ creation/upp_cor.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 607 608 creation-upp_thread$(EXEEXT): 609 @u++ creation/upp_thrd.cc -DBENCH_N=50000000 -I. -nodebug -lrt -quiet ${AM_CFLAGS} ${CFLAGS} ${ccflags} 610 611 creation-pthread$(EXEEXT): 612 @@BACKEND_CC@ creation/pthreads.c -DBENCH_N=250000 -I. -lrt -pthread ${AM_CFLAGS} ${CFLAGS} ${ccflags} 613 614 compile$(EXEEXT) :\ 615 compile-array.make \ 616 compile-attributes.make \ 617 compile-empty.make \ 618 compile-expression.make \ 619 compile-io.make \ 620 compile-monitor.make \ 621 compile-operators.make \ 622 compile-typeof.make 623 624 compile-array$(EXEEXT): 625 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/array.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 626 627 compile-attributes$(EXEEXT): 628 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/attributes.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 629 630 compile-empty$(EXEEXT): 631 @${CC} -nodebug -quiet -fsyntax-only -w compile/empty.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 632 633 compile-expression$(EXEEXT): 634 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/expression.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 635 636 compile-io$(EXEEXT): 637 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/io.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 638 639 compile-monitor$(EXEEXT): 640 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/monitor.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 641 642 compile-operators$(EXEEXT): 643 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/operators.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 644 645 compile-thread$(EXEEXT): 646 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/thread.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 647 648 compile-typeof$(EXEEXT): 649 @${CC} -nodebug -quiet -fsyntax-only -w ../tests/typeof.c @CFA_FLAGS@ ${AM_CFLAGS} ${CFLAGS} ${ccflags} 578 650 579 651 # Tell versions [3.59,3.63) of GNU make to not export all variables. -
src/benchmark/creation/cfa_cor.c
r9d06142 rc0d00b6 5 5 6 6 coroutine MyCoroutine {}; 7 void ?{} (MyCoroutine & this) { prime(this); } 7 void ?{} (MyCoroutine & this) { 8 #ifdef EAGER 9 prime(this); 10 #endif 11 } 8 12 void main(MyCoroutine & this) {} 9 13 -
src/libcfa/Makefile.am
r9d06142 rc0d00b6 95 95 96 96 cfa_includedir = $(CFA_INCDIR) 97 nobase_cfa_include_HEADERS = ${headers} ${stdhdr} math gmp concurrency/invoke.h 97 nobase_cfa_include_HEADERS = \ 98 ${headers} \ 99 ${stdhdr} \ 100 math \ 101 gmp \ 102 bits/defs.h \ 103 bits/locks.h \ 104 concurrency/invoke.h \ 105 libhdr.h \ 106 libhdr/libalign.h \ 107 libhdr/libdebug.h \ 108 libhdr/libtools.h 98 109 99 110 CLEANFILES = libcfa-prelude.c -
src/libcfa/Makefile.in
r9d06142 rc0d00b6 264 264 containers/result containers/vector concurrency/coroutine \ 265 265 concurrency/thread concurrency/kernel concurrency/monitor \ 266 ${shell echo stdhdr/*} math gmp concurrency/invoke.h 266 ${shell echo stdhdr/*} math gmp bits/defs.h bits/locks.h \ 267 concurrency/invoke.h libhdr.h libhdr/libalign.h \ 268 libhdr/libdebug.h libhdr/libtools.h 267 269 HEADERS = $(nobase_cfa_include_HEADERS) 268 270 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 430 432 stdhdr = ${shell echo stdhdr/*} 431 433 cfa_includedir = $(CFA_INCDIR) 432 nobase_cfa_include_HEADERS = ${headers} ${stdhdr} math gmp concurrency/invoke.h 434 nobase_cfa_include_HEADERS = \ 435 ${headers} \ 436 ${stdhdr} \ 437 math \ 438 gmp \ 439 bits/defs.h \ 440 bits/locks.h \ 441 concurrency/invoke.h \ 442 libhdr.h \ 443 libhdr/libalign.h \ 444 libhdr/libdebug.h \ 445 libhdr/libtools.h 446 433 447 CLEANFILES = libcfa-prelude.c 434 448 all: all-am -
src/libcfa/concurrency/alarm.c
r9d06142 rc0d00b6 186 186 187 187 disable_interrupts(); 188 lock( &event_kernel->lock DEBUG_CTX2 );188 lock( event_kernel->lock DEBUG_CTX2 ); 189 189 { 190 190 verify( validate( alarms ) ); … … 196 196 } 197 197 } 198 unlock( &event_kernel->lock );198 unlock( event_kernel->lock ); 199 199 this->set = true; 200 200 enable_interrupts( DEBUG_CTX ); … … 203 203 void unregister_self( alarm_node_t * this ) { 204 204 disable_interrupts(); 205 lock( &event_kernel->lock DEBUG_CTX2 );205 lock( event_kernel->lock DEBUG_CTX2 ); 206 206 { 207 207 verify( validate( &event_kernel->alarms ) ); 208 208 remove( &event_kernel->alarms, this ); 209 209 } 210 unlock( &event_kernel->lock );210 unlock( event_kernel->lock ); 211 211 enable_interrupts( DEBUG_CTX ); 212 212 this->set = false; -
src/libcfa/concurrency/invoke.h
r9d06142 rc0d00b6 14 14 // 15 15 16 #include <stdbool.h>17 #include <stdint.h>16 #include "bits/defs.h" 17 #include "bits/locks.h" 18 18 19 19 #ifdef __CFORALL__ … … 25 25 #define _INVOKE_H_ 26 26 27 #define unlikely(x) __builtin_expect(!!(x), 0)28 #define thread_local _Thread_local29 30 27 typedef void (*fptr_t)(); 31 28 typedef int_fast16_t __lock_size_t; 32 33 struct spinlock {34 volatile int lock;35 #ifdef __CFA_DEBUG__36 const char * prev_name;37 void* prev_thrd;38 #endif39 };40 29 41 30 struct __thread_queue_t { … … 58 47 void push( struct __condition_stack_t &, struct __condition_criterion_t * ); 59 48 struct __condition_criterion_t * pop( struct __condition_stack_t & ); 60 61 void ?{}(spinlock & this);62 void ^?{}(spinlock & this);63 49 } 64 50 #endif … … 122 108 struct monitor_desc { 123 109 // spinlock to protect internal data 124 struct spinlocklock;110 struct __spinlock_t lock; 125 111 126 112 // current owner of the monitor -
src/libcfa/concurrency/kernel
r9d06142 rc0d00b6 26 26 //----------------------------------------------------------------------------- 27 27 // Locks 28 // Lock the spinlock, spin if already acquired29 void lock ( spinlock * DEBUG_CTX_PARAM2 );28 // // Lock the spinlock, spin if already acquired 29 // void lock ( spinlock * DEBUG_CTX_PARAM2 ); 30 30 31 // Lock the spinlock, yield repeatedly if already acquired32 void lock_yield( spinlock * DEBUG_CTX_PARAM2 );31 // // Lock the spinlock, yield repeatedly if already acquired 32 // void lock_yield( spinlock * DEBUG_CTX_PARAM2 ); 33 33 34 // Lock the spinlock, return false if already acquired35 bool try_lock ( spinlock * DEBUG_CTX_PARAM2 );34 // // Lock the spinlock, return false if already acquired 35 // bool try_lock ( spinlock * DEBUG_CTX_PARAM2 ); 36 36 37 // Unlock the spinlock38 void unlock ( spinlock * );37 // // Unlock the spinlock 38 // void unlock ( spinlock * ); 39 39 40 40 struct semaphore { 41 spinlocklock;41 __spinlock_t lock; 42 42 int count; 43 43 __thread_queue_t waiting; … … 54 54 struct cluster { 55 55 // Ready queue locks 56 spinlockready_queue_lock;56 __spinlock_t ready_queue_lock; 57 57 58 58 // Ready queue for threads … … 74 74 FinishOpCode action_code; 75 75 thread_desc * thrd; 76 spinlock* lock;77 spinlock** locks;76 __spinlock_t * lock; 77 __spinlock_t ** locks; 78 78 unsigned short lock_count; 79 79 thread_desc ** thrds; … … 120 120 #ifdef __CFA_DEBUG__ 121 121 // Last function to enable preemption on this processor 122 c har * last_enable;122 const char * last_enable; 123 123 #endif 124 124 }; -
src/libcfa/concurrency/kernel.c
r9d06142 rc0d00b6 242 242 void finishRunning(processor * this) { 243 243 if( this->finish.action_code == Release ) { 244 unlock( this->finish.lock );244 unlock( *this->finish.lock ); 245 245 } 246 246 else if( this->finish.action_code == Schedule ) { … … 248 248 } 249 249 else if( this->finish.action_code == Release_Schedule ) { 250 unlock( this->finish.lock );250 unlock( *this->finish.lock ); 251 251 ScheduleThread( this->finish.thrd ); 252 252 } 253 253 else if( this->finish.action_code == Release_Multi ) { 254 254 for(int i = 0; i < this->finish.lock_count; i++) { 255 unlock( this->finish.locks[i] );255 unlock( *this->finish.locks[i] ); 256 256 } 257 257 } 258 258 else if( this->finish.action_code == Release_Multi_Schedule ) { 259 259 for(int i = 0; i < this->finish.lock_count; i++) { 260 unlock( this->finish.locks[i] );260 unlock( *this->finish.locks[i] ); 261 261 } 262 262 for(int i = 0; i < this->finish.thrd_count; i++) { … … 334 334 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 335 335 336 lock( &this_processor->cltr->ready_queue_lock DEBUG_CTX2 );336 lock( this_processor->cltr->ready_queue_lock DEBUG_CTX2 ); 337 337 append( this_processor->cltr->ready_queue, thrd ); 338 unlock( &this_processor->cltr->ready_queue_lock );338 unlock( this_processor->cltr->ready_queue_lock ); 339 339 340 340 verify( disable_preempt_count > 0 ); … … 343 343 thread_desc * nextThread(cluster * this) { 344 344 verify( disable_preempt_count > 0 ); 345 lock( &this->ready_queue_lock DEBUG_CTX2 );345 lock( this->ready_queue_lock DEBUG_CTX2 ); 346 346 thread_desc * head = pop_head( this->ready_queue ); 347 unlock( &this->ready_queue_lock );347 unlock( this->ready_queue_lock ); 348 348 verify( disable_preempt_count > 0 ); 349 349 return head; … … 358 358 } 359 359 360 void BlockInternal( spinlock* lock ) {360 void BlockInternal( __spinlock_t * lock ) { 361 361 disable_interrupts(); 362 362 this_processor->finish.action_code = Release; … … 384 384 } 385 385 386 void BlockInternal( spinlock* lock, thread_desc * thrd ) {386 void BlockInternal( __spinlock_t * lock, thread_desc * thrd ) { 387 387 assert(thrd); 388 388 disable_interrupts(); … … 398 398 } 399 399 400 void BlockInternal( spinlock* locks [], unsigned short count) {400 void BlockInternal(__spinlock_t * locks [], unsigned short count) { 401 401 disable_interrupts(); 402 402 this_processor->finish.action_code = Release_Multi; … … 411 411 } 412 412 413 void BlockInternal( spinlock* locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {413 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 414 414 disable_interrupts(); 415 415 this_processor->finish.action_code = Release_Multi_Schedule; … … 426 426 } 427 427 428 void LeaveThread( spinlock* lock, thread_desc * thrd) {428 void LeaveThread(__spinlock_t * lock, thread_desc * thrd) { 429 429 verify( disable_preempt_count > 0 ); 430 430 this_processor->finish.action_code = thrd ? Release_Schedule : Release; … … 516 516 } 517 517 518 static spinlockkernel_abort_lock;519 static spinlockkernel_debug_lock;518 static __spinlock_t kernel_abort_lock; 519 static __spinlock_t kernel_debug_lock; 520 520 static bool kernel_abort_called = false; 521 521 … … 523 523 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 524 524 // the globalAbort flag is true. 525 lock( &kernel_abort_lock DEBUG_CTX2 );525 lock( kernel_abort_lock DEBUG_CTX2 ); 526 526 527 527 // first task to abort ? 528 528 if ( !kernel_abort_called ) { // not first task to abort ? 529 529 kernel_abort_called = true; 530 unlock( &kernel_abort_lock );530 unlock( kernel_abort_lock ); 531 531 } 532 532 else { 533 unlock( &kernel_abort_lock );533 unlock( kernel_abort_lock ); 534 534 535 535 sigset_t mask; … … 561 561 extern "C" { 562 562 void __lib_debug_acquire() { 563 lock( &kernel_debug_lock DEBUG_CTX2 );563 lock( kernel_debug_lock DEBUG_CTX2 ); 564 564 } 565 565 566 566 void __lib_debug_release() { 567 unlock( &kernel_debug_lock );567 unlock( kernel_debug_lock ); 568 568 } 569 569 } … … 574 574 //----------------------------------------------------------------------------- 575 575 // Locks 576 void ?{}( spinlock & this ) {577 this.lock = 0;578 }579 void ^?{}( spinlock & this ) {580 581 }582 583 bool try_lock( spinlock * this DEBUG_CTX_PARAM2 ) {584 return this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0;585 }586 587 void lock( spinlock * this DEBUG_CTX_PARAM2 ) {588 for ( unsigned int i = 1;; i += 1 ) {589 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }590 }591 LIB_DEBUG_DO(592 this->prev_name = caller;593 this->prev_thrd = this_thread;594 )595 }596 597 void lock_yield( spinlock * this DEBUG_CTX_PARAM2 ) {598 for ( unsigned int i = 1;; i += 1 ) {599 if ( this->lock == 0 && __sync_lock_test_and_set_4( &this->lock, 1 ) == 0 ) { break; }600 yield();601 }602 LIB_DEBUG_DO(603 this->prev_name = caller;604 this->prev_thrd = this_thread;605 )606 }607 608 609 void unlock( spinlock * this ) {610 __sync_lock_release_4( &this->lock );611 }612 613 576 void ?{}( semaphore & this, int count = 1 ) { 614 577 (this.lock){}; … … 619 582 620 583 void P(semaphore & this) { 621 lock( &this.lock DEBUG_CTX2 );584 lock( this.lock DEBUG_CTX2 ); 622 585 this.count -= 1; 623 586 if ( this.count < 0 ) { … … 629 592 } 630 593 else { 631 unlock( &this.lock );594 unlock( this.lock ); 632 595 } 633 596 } … … 635 598 void V(semaphore & this) { 636 599 thread_desc * thrd = NULL; 637 lock( &this.lock DEBUG_CTX2 );600 lock( this.lock DEBUG_CTX2 ); 638 601 this.count += 1; 639 602 if ( this.count <= 0 ) { … … 642 605 } 643 606 644 unlock( &this.lock );607 unlock( this.lock ); 645 608 646 609 // make new owner -
src/libcfa/concurrency/kernel_private.h
r9d06142 rc0d00b6 45 45 //Block current thread and release/wake-up the following resources 46 46 void BlockInternal(void); 47 void BlockInternal( spinlock* lock);47 void BlockInternal(__spinlock_t * lock); 48 48 void BlockInternal(thread_desc * thrd); 49 void BlockInternal( spinlock* lock, thread_desc * thrd);50 void BlockInternal( spinlock* locks [], unsigned short count);51 void BlockInternal( spinlock* locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count);52 void LeaveThread( spinlock* lock, thread_desc * thrd);49 void BlockInternal(__spinlock_t * lock, thread_desc * thrd); 50 void BlockInternal(__spinlock_t * locks [], unsigned short count); 51 void BlockInternal(__spinlock_t * locks [], unsigned short count, thread_desc * thrds [], unsigned short thrd_count); 52 void LeaveThread(__spinlock_t * lock, thread_desc * thrd); 53 53 54 54 //----------------------------------------------------------------------------- … … 66 66 struct event_kernel_t { 67 67 alarm_list_t alarms; 68 spinlocklock;68 __spinlock_t lock; 69 69 }; 70 70 -
src/libcfa/concurrency/monitor.c
r9d06142 rc0d00b6 34 34 static inline bool is_accepted( monitor_desc * this, const __monitor_group_t & monitors ); 35 35 36 static inline void lock_all ( spinlock* locks [], __lock_size_t count );37 static inline void lock_all ( monitor_desc * source [], spinlock* /*out*/ locks [], __lock_size_t count );38 static inline void unlock_all( spinlock* locks [], __lock_size_t count );36 static inline void lock_all ( __spinlock_t * locks [], __lock_size_t count ); 37 static inline void lock_all ( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count ); 38 static inline void unlock_all( __spinlock_t * locks [], __lock_size_t count ); 39 39 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ); 40 40 41 static inline void save ( monitor_desc * ctx [], __lock_size_t count, spinlock* locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] );42 static inline void restore( monitor_desc * ctx [], __lock_size_t count, spinlock* locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] );41 static inline void save ( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*out*/ recursions [], __waitfor_mask_t /*out*/ masks [] ); 42 static inline void restore( monitor_desc * ctx [], __lock_size_t count, __spinlock_t * locks [], unsigned int /*in */ recursions [], __waitfor_mask_t /*in */ masks [] ); 43 43 44 44 static inline void init ( __lock_size_t count, monitor_desc * monitors [], __condition_node_t & waiter, __condition_criterion_t criteria [] ); … … 53 53 static inline __lock_size_t count_max ( const __waitfor_mask_t & mask ); 54 54 static inline __lock_size_t aggregate ( monitor_desc * storage [], const __waitfor_mask_t & mask ); 55 56 #ifndef __CFA_LOCK_NO_YIELD 57 #define DO_LOCK lock_yield 58 #else 59 #define DO_LOCK lock 60 #endif 55 61 56 62 //----------------------------------------------------------------------------- … … 71 77 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \ 72 78 __waitfor_mask_t masks [ count ]; /* Save the current waitfor masks to restore them later */ \ 73 spinlock * locks[ count ]; /* We need to pass-in an array of locks to BlockInternal */ \79 __spinlock_t * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \ 74 80 75 81 #define monitor_save save ( monitors, count, locks, recursions, masks ) … … 84 90 // Enter single monitor 85 91 static void __enter_monitor_desc( monitor_desc * this, const __monitor_group_t & group ) { 86 // Lock the monitor spinlock , lock_yield to reduce contention87 lock_yield( &this->lock DEBUG_CTX2 );92 // Lock the monitor spinlock 93 DO_LOCK( this->lock DEBUG_CTX2 ); 88 94 thread_desc * thrd = this_thread; 89 95 … … 127 133 128 134 // Release the lock and leave 129 unlock( &this->lock );135 unlock( this->lock ); 130 136 return; 131 137 } 132 138 133 139 static void __enter_monitor_dtor( monitor_desc * this, fptr_t func ) { 134 // Lock the monitor spinlock , lock_yield to reduce contention135 lock_yield( &this->lock DEBUG_CTX2 );140 // Lock the monitor spinlock 141 DO_LOCK( this->lock DEBUG_CTX2 ); 136 142 thread_desc * thrd = this_thread; 137 143 … … 145 151 set_owner( this, thrd ); 146 152 147 unlock( &this->lock );153 unlock( this->lock ); 148 154 return; 149 155 } … … 196 202 // Leave single monitor 197 203 void __leave_monitor_desc( monitor_desc * this ) { 198 // Lock the monitor spinlock, lock_yieldto reduce contention199 lock_yield( &this->lock DEBUG_CTX2 );204 // Lock the monitor spinlock, DO_LOCK to reduce contention 205 DO_LOCK( this->lock DEBUG_CTX2 ); 200 206 201 207 LIB_DEBUG_PRINT_SAFE("Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner); … … 210 216 if( this->recursion != 0) { 211 217 LIB_DEBUG_PRINT_SAFE("Kernel : recursion still %d\n", this->recursion); 212 unlock( &this->lock );218 unlock( this->lock ); 213 219 return; 214 220 } … … 218 224 219 225 // We can now let other threads in safely 220 unlock( &this->lock );226 unlock( this->lock ); 221 227 222 228 //We need to wake-up the thread … … 243 249 244 250 // Lock the monitor now 245 lock_yield( &this->lock DEBUG_CTX2 );251 DO_LOCK( this->lock DEBUG_CTX2 ); 246 252 247 253 disable_interrupts(); … … 730 736 } 731 737 732 static inline void lock_all( spinlock* locks [], __lock_size_t count ) {738 static inline void lock_all( __spinlock_t * locks [], __lock_size_t count ) { 733 739 for( __lock_size_t i = 0; i < count; i++ ) { 734 lock_yield(locks[i] DEBUG_CTX2 );735 } 736 } 737 738 static inline void lock_all( monitor_desc * source [], spinlock* /*out*/ locks [], __lock_size_t count ) {740 DO_LOCK( *locks[i] DEBUG_CTX2 ); 741 } 742 } 743 744 static inline void lock_all( monitor_desc * source [], __spinlock_t * /*out*/ locks [], __lock_size_t count ) { 739 745 for( __lock_size_t i = 0; i < count; i++ ) { 740 spinlock* l = &source[i]->lock;741 lock_yield(l DEBUG_CTX2 );746 __spinlock_t * l = &source[i]->lock; 747 DO_LOCK( *l DEBUG_CTX2 ); 742 748 if(locks) locks[i] = l; 743 749 } 744 750 } 745 751 746 static inline void unlock_all( spinlock* locks [], __lock_size_t count ) {752 static inline void unlock_all( __spinlock_t * locks [], __lock_size_t count ) { 747 753 for( __lock_size_t i = 0; i < count; i++ ) { 748 unlock( locks[i] );754 unlock( *locks[i] ); 749 755 } 750 756 } … … 752 758 static inline void unlock_all( monitor_desc * locks [], __lock_size_t count ) { 753 759 for( __lock_size_t i = 0; i < count; i++ ) { 754 unlock( &locks[i]->lock );760 unlock( locks[i]->lock ); 755 761 } 756 762 } … … 759 765 monitor_desc * ctx [], 760 766 __lock_size_t count, 761 __attribute((unused)) spinlock* locks [],767 __attribute((unused)) __spinlock_t * locks [], 762 768 unsigned int /*out*/ recursions [], 763 769 __waitfor_mask_t /*out*/ masks [] … … 772 778 monitor_desc * ctx [], 773 779 __lock_size_t count, 774 spinlock* locks [],780 __spinlock_t * locks [], 775 781 unsigned int /*out*/ recursions [], 776 782 __waitfor_mask_t /*out*/ masks [] … … 817 823 this.monitor_count = thrd->monitors.size; 818 824 819 this.monitors = malloc( this.monitor_count * sizeof( *this.monitors ) );825 this.monitors = (monitor_desc **)malloc( this.monitor_count * sizeof( *this.monitors ) ); 820 826 for( int i = 0; i < this.monitor_count; i++ ) { 821 827 this.monitors[i] = thrd->monitors.list[i]; -
src/libcfa/concurrency/preemption.c
r9d06142 rc0d00b6 355 355 case SI_KERNEL: 356 356 // LIB_DEBUG_PRINT_SAFE("Kernel : Preemption thread tick\n"); 357 lock( &event_kernel->lock DEBUG_CTX2 );357 lock( event_kernel->lock DEBUG_CTX2 ); 358 358 tick_preemption(); 359 unlock( &event_kernel->lock );359 unlock( event_kernel->lock ); 360 360 break; 361 361 // Signal was not sent by the kernel but by an other thread -
src/libcfa/stdhdr/stddef.h
r9d06142 rc0d00b6 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 // 7 // stddef.h -- 8 // 6 // 7 // stddef.h -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Mon Jul 4 23:25:26 2016 … … 12 12 // Last Modified On : Tue Jul 5 20:40:01 2016 13 13 // Update Count : 12 14 // 14 // 15 15 16 16 extern "C" { 17 #include_next <stddef.h> // has internal check for multiple expansion 17 #include_next <stddef.h> // has internal check for multiple expansion 18 #undef NULL 19 #define NULL 0 // define NULL as 0 rather than (void*)0 to take advantage of zero_t 18 20 } // extern "C" 19 21 -
src/libcfa/stdlib
r9d06142 rc0d00b6 77 77 //printf( "X8\n" ); 78 78 T * ptr = (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc 79 return memset( ptr, (int)fill, sizeof(T) ); // initial with fill value79 return (T *)memset( ptr, (int)fill, sizeof(T) ); // initial with fill value 80 80 } // alloc 81 81 … … 87 87 //printf( "X10\n" ); 88 88 T * ptr = (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc 89 return memset( ptr, (int)fill, dim * sizeof(T) );89 return (T *)memset( ptr, (int)fill, dim * sizeof(T) ); 90 90 } // alloc 91 91 92 92 static inline forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim ) { 93 93 //printf( "X11\n" ); 94 return ( void *)realloc( (void *)ptr, dim * (size_t)sizeof(T) ); // C realloc94 return (T *)(void *)realloc( (void *)ptr, dim * (size_t)sizeof(T) ); // C realloc 95 95 } // alloc 96 96 forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim, char fill ); … … 103 103 //printf( "X14\n" ); 104 104 T * ptr = (T *)memalign( align, sizeof(T) ); 105 return memset( ptr, (int)fill, sizeof(T) );105 return (T *)memset( ptr, (int)fill, sizeof(T) ); 106 106 } // align_alloc 107 107 … … 113 113 //printf( "X16\n" ); 114 114 T * ptr = (T *)memalign( align, dim * sizeof(T) ); 115 return memset( ptr, (int)fill, dim * sizeof(T) );115 return (T *)memset( ptr, (int)fill, dim * sizeof(T) ); 116 116 } // align_alloc 117 117 … … 120 120 static inline forall( dtype T | sized(T) ) T * memset( T * dest, char c ) { 121 121 //printf( "X17\n" ); 122 return memset( dest, c, sizeof(T) );122 return (T *)memset( dest, c, sizeof(T) ); 123 123 } // memset 124 124 extern "C" { void * memcpy( void * dest, const void * src, size_t size ); } // use default C routine for void * 125 125 static inline forall( dtype T | sized(T) ) T * memcpy( T * dest, const T * src ) { 126 126 //printf( "X18\n" ); 127 return memcpy( dest, src, sizeof(T) );127 return (T *)memcpy( dest, src, sizeof(T) ); 128 128 } // memcpy 129 129 … … 131 131 static inline forall( dtype T | sized(T) ) T * memset( T dest[], size_t dim, char c ) { 132 132 //printf( "X19\n" ); 133 return ( void *)memset( dest, c, dim * sizeof(T) ); // C memset133 return (T *)(void *)memset( dest, c, dim * sizeof(T) ); // C memset 134 134 } // memset 135 135 static inline forall( dtype T | sized(T) ) T * memcpy( T dest[], const T src[], size_t dim ) { 136 136 //printf( "X20\n" ); 137 return ( void *)memcpy( dest, src, dim * sizeof(T) ); // C memcpy137 return (T *)(void *)memcpy( dest, src, dim * sizeof(T) ); // C memcpy 138 138 } // memcpy 139 139 -
src/main.cc
r9d06142 rc0d00b6 206 206 FILE * extras = fopen( libcfap | treep ? "../prelude/extras.cf" : CFA_LIBDIR "/extras.cf", "r" ); 207 207 assertf( extras, "cannot open extras.cf\n" ); 208 parse( extras, LinkageSpec:: C );208 parse( extras, LinkageSpec::BuiltinC ); 209 209 210 210 if ( ! libcfap ) { -
src/prelude/builtins.c
r9d06142 rc0d00b6 80 80 } // ?\? 81 81 82 static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); double ?/?( double, T ); } ) 83 double ?\?( T x, signed long int y ) { 84 if ( y >= 0 ) return (double)(x \ (unsigned long int)y); 85 else return 1.0 / x \ (unsigned long int)(-y); 86 } // ?\? 82 // FIXME (x \ (unsigned long int)y) relies on X ?\?(T, unsigned long) a function that is neither 83 // defined, nor passed as an assertion parameter. Without user-defined conversions, cannot specify 84 // X as a type that casts to double, yet it doesn't make sense to write functions with that type 85 // signature where X is double. 86 87 // static inline forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); double ?/?( double, T ); } ) 88 // double ?\?( T x, signed long int y ) { 89 // if ( y >= 0 ) return (double)(x \ (unsigned long int)y); 90 // else return 1.0 / x \ (unsigned long int)(-y); 91 // } // ?\? 87 92 88 93 static inline long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; } -
src/prelude/prelude.cf
r9d06142 rc0d00b6 403 403 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * volatile &, const volatile DT * ); 404 404 405 forall( dtype DT ) DT * ?=?( DT * &, void * );406 forall( dtype DT ) DT * ?=?( DT * volatile &, void * );407 forall( dtype DT ) const DT * ?=?( const DT * &, void * );408 forall( dtype DT ) const DT * ?=?( const DT * volatile &, void * );409 forall( dtype DT ) const DT * ?=?( const DT * &, const void * );410 forall( dtype DT ) const DT * ?=?( const DT * volatile &, const void * );411 forall( dtype DT ) volatile DT * ?=?( volatile DT * &, void * );412 forall( dtype DT ) volatile DT * ?=?( volatile DT * volatile &, void * );413 forall( dtype DT ) volatile DT * ?=?( volatile DT * &, volatile void * );414 forall( dtype DT ) volatile DT * ?=?( volatile DT * volatile &, volatile void * );415 416 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * &, void * );417 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * volatile &, void * );418 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * &, const void * );419 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * volatile &, const void * );420 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * &, volatile void * );421 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * volatile &, volatile void * );422 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * &, const volatile void * );423 forall( dtype DT ) const volatile DT * ?=?( const volatile DT * volatile &, const volatile void * );424 425 405 forall( dtype DT ) void * ?=?( void * &, DT * ); 426 406 forall( dtype DT ) void * ?=?( void * volatile &, DT * ); … … 441 421 forall( dtype DT ) const volatile void * ?=?( const volatile void * &, const volatile DT * ); 442 422 forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &, const volatile DT * ); 443 444 void * ?=?( void * &, void * );445 void * ?=?( void * volatile &, void * );446 const void * ?=?( const void * &, void * );447 const void * ?=?( const void * volatile &, void * );448 const void * ?=?( const void * &, const void * );449 const void * ?=?( const void * volatile &, const void * );450 volatile void * ?=?( volatile void * &, void * );451 volatile void * ?=?( volatile void * volatile &, void * );452 volatile void * ?=?( volatile void * &, volatile void * );453 volatile void * ?=?( volatile void * volatile &, volatile void * );454 const volatile void * ?=?( const volatile void * &, void * );455 const volatile void * ?=?( const volatile void * volatile &, void * );456 const volatile void * ?=?( const volatile void * &, const void * );457 const volatile void * ?=?( const volatile void * volatile &, const void * );458 const volatile void * ?=?( const volatile void * &, volatile void * );459 const volatile void * ?=?( const volatile void * volatile &, volatile void * );460 const volatile void * ?=?( const volatile void * &, const volatile void * );461 const volatile void * ?=?( const volatile void * volatile &, const volatile void * );462 423 463 424 //forall( dtype DT ) DT * ?=?( DT * &, zero_t ); … … 781 742 forall( dtype DT ) void ?{}( const volatile DT * &, const volatile DT * ); 782 743 783 forall( dtype DT ) void ?{}( DT * &, void * );784 forall( dtype DT ) void ?{}( const DT * &, void * );785 forall( dtype DT ) void ?{}( const DT * &, const void * );786 forall( dtype DT ) void ?{}( volatile DT * &, void * );787 forall( dtype DT ) void ?{}( volatile DT * &, volatile void * );788 789 forall( dtype DT ) void ?{}( const volatile DT * &, void * );790 forall( dtype DT ) void ?{}( const volatile DT * &, const void * );791 forall( dtype DT ) void ?{}( const volatile DT * &, volatile void * );792 forall( dtype DT ) void ?{}( const volatile DT * &, const volatile void * );793 794 744 forall( dtype DT ) void ?{}( void * &, DT * ); 795 745 forall( dtype DT ) void ?{}( const void * &, DT * ); … … 802 752 forall( dtype DT ) void ?{}( const volatile void * &, const volatile DT * ); 803 753 804 void ?{}( void * &, void * );805 void ?{}( const void * &, void * );806 void ?{}( const void * &, const void * );807 void ?{}( volatile void * &, void * );808 void ?{}( volatile void * &, volatile void * );809 void ?{}( const volatile void * &, void * );810 void ?{}( const volatile void * &, const void * );811 void ?{}( const volatile void * &, volatile void * );812 void ?{}( const volatile void * &, const volatile void * );813 814 754 //forall( dtype DT ) void ?{}( DT * &, zero_t ); 815 755 //forall( dtype DT ) void ?{}( DT * volatile &, zero_t ); -
src/tests/.expect/32/KRfunctions.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 signed int __f0__Fi_iPCii__1(signed int __a__i_1, const signed int *__b__PCi_1, signed int __c__i_1){ 8 2 __attribute__ ((unused)) signed int ___retval_f0__i_1; -
src/tests/.expect/32/attributes.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 signed int __la__Fi___1(){ 8 2 __attribute__ ((unused)) signed int ___retval_la__i_1; -
src/tests/.expect/32/declarationSpecifier.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 volatile const signed short int __x1__CVs_1; 8 2 static volatile const signed short int __x2__CVs_1; … … 701 695 } 702 696 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 703 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);704 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);705 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);706 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));707 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);708 extern signed int printf(const char *__restrict __format, ...);709 697 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 710 698 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/32/extension.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 __extension__ signed int __a__i_1; 8 2 __extension__ signed int __b__i_1; -
src/tests/.expect/32/gccExtensions.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 extern signed int __x__i_1 asm ( "xx" ); 8 2 signed int __main__Fi_iPPCc__1(signed int __argc__i_1, const char **__argv__PPCc_1){ … … 174 168 } 175 169 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 176 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);177 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);178 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);179 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));180 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);181 extern signed int printf(const char *__restrict __format, ...);182 170 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 183 171 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/32/literals.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 void __for_each__A0_2_0_0____operator_assign__PFd0_Rd0d0____constructor__PF_Rd0____constructor__PF_Rd0d0____destructor__PF_Rd0____operator_assign__PFd1_Rd1d1____constructor__PF_Rd1____constructor__PF_Rd1d1____destructor__PF_Rd1____operator_preincr__PFd0_Rd0____operator_predecr__PFd0_Rd0____operator_equal__PFi_d0d0____operator_notequal__PFi_d0d0____operator_deref__PFRd1_d0__F_d0d0PF_d1___1(__attribute__ ((unused)) void (*_adapterF_9telt_type__P)(void (*__anonymous_object0)(), void *__anonymous_object1), __attribute__ ((unused)) void *(*_adapterFP9telt_type_14titerator_type_M_P)(void (*__anonymous_object2)(), void *__anonymous_object3), __attribute__ ((unused)) signed int (*_adapterFi_14titerator_type14titerator_type_M_PP)(void (*__anonymous_object4)(), void *__anonymous_object5, void *__anonymous_object6), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type_P_M)(void (*__anonymous_object7)(), __attribute__ ((unused)) void *___retval__operator_preincr__14titerator_type_1, void *__anonymous_object8), __attribute__ ((unused)) void (*_adapterF_P9telt_type9telt_type__MP)(void (*__anonymous_object9)(), void *__anonymous_object10, void *__anonymous_object11), __attribute__ ((unused)) void (*_adapterF9telt_type_P9telt_type9telt_type_P_MP)(void (*__anonymous_object12)(), __attribute__ ((unused)) void *___retval__operator_assign__9telt_type_1, void *__anonymous_object13, void *__anonymous_object14), __attribute__ ((unused)) void (*_adapterF_P14titerator_type14titerator_type__MP)(void (*__anonymous_object15)(), void *__anonymous_object16, void *__anonymous_object17), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type14titerator_type_P_MP)(void (*__anonymous_object18)(), __attribute__ ((unused)) void *___retval__operator_assign__14titerator_type_1, void *__anonymous_object19, void *__anonymous_object20), __attribute__ ((unused)) unsigned long int _sizeof_14titerator_type, __attribute__ ((unused)) unsigned long int _alignof_14titerator_type, __attribute__ ((unused)) unsigned long int _sizeof_9telt_type, __attribute__ ((unused)) unsigned long int _alignof_9telt_type, __attribute__ ((unused)) void *(*___operator_assign__PF14titerator_type_R14titerator_type14titerator_type__1)(void *__anonymous_object21, void *__anonymous_object22), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type__1)(void *__anonymous_object23), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type14titerator_type__1)(void *__anonymous_object24, void *__anonymous_object25), __attribute__ ((unused)) void (*___destructor__PF_R14titerator_type__1)(void *__anonymous_object26), __attribute__ ((unused)) void *(*___operator_assign__PF9telt_type_R9telt_type9telt_type__1)(void *__anonymous_object27, void *__anonymous_object28), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type__1)(void *__anonymous_object29), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type9telt_type__1)(void *__anonymous_object30, void *__anonymous_object31), __attribute__ ((unused)) void (*___destructor__PF_R9telt_type__1)(void *__anonymous_object32), __attribute__ ((unused)) void *(*___operator_preincr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object33), __attribute__ ((unused)) void *(*___operator_predecr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object34), __attribute__ ((unused)) signed int (*___operator_equal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object35, void *__anonymous_object36), __attribute__ ((unused)) signed int (*___operator_notequal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object37, void *__anonymous_object38), __attribute__ ((unused)) void *(*___operator_deref__PFR9telt_type_14titerator_type__1)(void *__anonymous_object39), void *__begin__14titerator_type_1, void *__end__14titerator_type_1, void (*__func__PF_9telt_type__1)(void *__anonymous_object40)); 8 2 void __for_each_reverse__A0_2_0_0____operator_assign__PFd0_Rd0d0____constructor__PF_Rd0____constructor__PF_Rd0d0____destructor__PF_Rd0____operator_assign__PFd1_Rd1d1____constructor__PF_Rd1____constructor__PF_Rd1d1____destructor__PF_Rd1____operator_preincr__PFd0_Rd0____operator_predecr__PFd0_Rd0____operator_equal__PFi_d0d0____operator_notequal__PFi_d0d0____operator_deref__PFRd1_d0__F_d0d0PF_d1___1(__attribute__ ((unused)) void (*_adapterF_9telt_type__P)(void (*__anonymous_object41)(), void *__anonymous_object42), __attribute__ ((unused)) void *(*_adapterFP9telt_type_14titerator_type_M_P)(void (*__anonymous_object43)(), void *__anonymous_object44), __attribute__ ((unused)) signed int (*_adapterFi_14titerator_type14titerator_type_M_PP)(void (*__anonymous_object45)(), void *__anonymous_object46, void *__anonymous_object47), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type_P_M)(void (*__anonymous_object48)(), __attribute__ ((unused)) void *___retval__operator_preincr__14titerator_type_1, void *__anonymous_object49), __attribute__ ((unused)) void (*_adapterF_P9telt_type9telt_type__MP)(void (*__anonymous_object50)(), void *__anonymous_object51, void *__anonymous_object52), __attribute__ ((unused)) void (*_adapterF9telt_type_P9telt_type9telt_type_P_MP)(void (*__anonymous_object53)(), __attribute__ ((unused)) void *___retval__operator_assign__9telt_type_1, void *__anonymous_object54, void *__anonymous_object55), __attribute__ ((unused)) void (*_adapterF_P14titerator_type14titerator_type__MP)(void (*__anonymous_object56)(), void *__anonymous_object57, void *__anonymous_object58), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type14titerator_type_P_MP)(void (*__anonymous_object59)(), __attribute__ ((unused)) void *___retval__operator_assign__14titerator_type_1, void *__anonymous_object60, void *__anonymous_object61), __attribute__ ((unused)) unsigned long int _sizeof_14titerator_type, __attribute__ ((unused)) unsigned long int _alignof_14titerator_type, __attribute__ ((unused)) unsigned long int _sizeof_9telt_type, __attribute__ ((unused)) unsigned long int _alignof_9telt_type, __attribute__ ((unused)) void *(*___operator_assign__PF14titerator_type_R14titerator_type14titerator_type__1)(void *__anonymous_object62, void *__anonymous_object63), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type__1)(void *__anonymous_object64), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type14titerator_type__1)(void *__anonymous_object65, void *__anonymous_object66), __attribute__ ((unused)) void (*___destructor__PF_R14titerator_type__1)(void *__anonymous_object67), __attribute__ ((unused)) void *(*___operator_assign__PF9telt_type_R9telt_type9telt_type__1)(void *__anonymous_object68, void *__anonymous_object69), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type__1)(void *__anonymous_object70), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type9telt_type__1)(void *__anonymous_object71, void *__anonymous_object72), __attribute__ ((unused)) void (*___destructor__PF_R9telt_type__1)(void *__anonymous_object73), __attribute__ ((unused)) void *(*___operator_preincr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object74), __attribute__ ((unused)) void *(*___operator_predecr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object75), __attribute__ ((unused)) signed int (*___operator_equal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object76, void *__anonymous_object77), __attribute__ ((unused)) signed int (*___operator_notequal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object78, void *__anonymous_object79), __attribute__ ((unused)) void *(*___operator_deref__PFR9telt_type_14titerator_type__1)(void *__anonymous_object80), void *__begin__14titerator_type_1, void *__end__14titerator_type_1, void (*__func__PF_9telt_type__1)(void *__anonymous_object81)); … … 1377 1371 } 1378 1372 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); } 1379 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);1380 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);1381 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);1382 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));1383 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);1384 extern signed int printf(const char *__restrict __format, ...);1385 1373 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 1386 1374 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/64/KRfunctions.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 signed int __f0__Fi_iPCii__1(signed int __a__i_1, const signed int *__b__PCi_1, signed int __c__i_1){ 8 2 __attribute__ ((unused)) signed int ___retval_f0__i_1; -
src/tests/.expect/64/attributes.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 signed int __la__Fi___1(){ 8 2 __attribute__ ((unused)) signed int ___retval_la__i_1; -
src/tests/.expect/64/declarationSpecifier.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 volatile const signed short int __x1__CVs_1; 8 2 static volatile const signed short int __x2__CVs_1; … … 701 695 } 702 696 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 703 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);704 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);705 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);706 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));707 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);708 extern signed int printf(const char *__restrict __format, ...);709 697 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 710 698 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/64/extension.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 __extension__ signed int __a__i_1; 8 2 __extension__ signed int __b__i_1; -
src/tests/.expect/64/gccExtensions.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 extern signed int __x__i_1 asm ( "xx" ); 8 2 signed int __main__Fi_iPPCc__1(signed int __argc__i_1, const char **__argv__PPCc_1){ … … 174 168 } 175 169 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 176 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);177 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);178 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);179 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));180 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);181 extern signed int printf(const char *__restrict __format, ...);182 170 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 183 171 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/64/literals.txt
r9d06142 rc0d00b6 1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);6 extern signed int printf(const char *__restrict __format, ...);7 1 void __for_each__A0_2_0_0____operator_assign__PFd0_Rd0d0____constructor__PF_Rd0____constructor__PF_Rd0d0____destructor__PF_Rd0____operator_assign__PFd1_Rd1d1____constructor__PF_Rd1____constructor__PF_Rd1d1____destructor__PF_Rd1____operator_preincr__PFd0_Rd0____operator_predecr__PFd0_Rd0____operator_equal__PFi_d0d0____operator_notequal__PFi_d0d0____operator_deref__PFRd1_d0__F_d0d0PF_d1___1(__attribute__ ((unused)) void (*_adapterF_9telt_type__P)(void (*__anonymous_object0)(), void *__anonymous_object1), __attribute__ ((unused)) void *(*_adapterFP9telt_type_14titerator_type_M_P)(void (*__anonymous_object2)(), void *__anonymous_object3), __attribute__ ((unused)) signed int (*_adapterFi_14titerator_type14titerator_type_M_PP)(void (*__anonymous_object4)(), void *__anonymous_object5, void *__anonymous_object6), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type_P_M)(void (*__anonymous_object7)(), __attribute__ ((unused)) void *___retval__operator_preincr__14titerator_type_1, void *__anonymous_object8), __attribute__ ((unused)) void (*_adapterF_P9telt_type9telt_type__MP)(void (*__anonymous_object9)(), void *__anonymous_object10, void *__anonymous_object11), __attribute__ ((unused)) void (*_adapterF9telt_type_P9telt_type9telt_type_P_MP)(void (*__anonymous_object12)(), __attribute__ ((unused)) void *___retval__operator_assign__9telt_type_1, void *__anonymous_object13, void *__anonymous_object14), __attribute__ ((unused)) void (*_adapterF_P14titerator_type14titerator_type__MP)(void (*__anonymous_object15)(), void *__anonymous_object16, void *__anonymous_object17), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type14titerator_type_P_MP)(void (*__anonymous_object18)(), __attribute__ ((unused)) void *___retval__operator_assign__14titerator_type_1, void *__anonymous_object19, void *__anonymous_object20), __attribute__ ((unused)) unsigned long int _sizeof_14titerator_type, __attribute__ ((unused)) unsigned long int _alignof_14titerator_type, __attribute__ ((unused)) unsigned long int _sizeof_9telt_type, __attribute__ ((unused)) unsigned long int _alignof_9telt_type, __attribute__ ((unused)) void *(*___operator_assign__PF14titerator_type_R14titerator_type14titerator_type__1)(void *__anonymous_object21, void *__anonymous_object22), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type__1)(void *__anonymous_object23), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type14titerator_type__1)(void *__anonymous_object24, void *__anonymous_object25), __attribute__ ((unused)) void (*___destructor__PF_R14titerator_type__1)(void *__anonymous_object26), __attribute__ ((unused)) void *(*___operator_assign__PF9telt_type_R9telt_type9telt_type__1)(void *__anonymous_object27, void *__anonymous_object28), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type__1)(void *__anonymous_object29), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type9telt_type__1)(void *__anonymous_object30, void *__anonymous_object31), __attribute__ ((unused)) void (*___destructor__PF_R9telt_type__1)(void *__anonymous_object32), __attribute__ ((unused)) void *(*___operator_preincr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object33), __attribute__ ((unused)) void *(*___operator_predecr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object34), __attribute__ ((unused)) signed int (*___operator_equal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object35, void *__anonymous_object36), __attribute__ ((unused)) signed int (*___operator_notequal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object37, void *__anonymous_object38), __attribute__ ((unused)) void *(*___operator_deref__PFR9telt_type_14titerator_type__1)(void *__anonymous_object39), void *__begin__14titerator_type_1, void *__end__14titerator_type_1, void (*__func__PF_9telt_type__1)(void *__anonymous_object40)); 8 2 void __for_each_reverse__A0_2_0_0____operator_assign__PFd0_Rd0d0____constructor__PF_Rd0____constructor__PF_Rd0d0____destructor__PF_Rd0____operator_assign__PFd1_Rd1d1____constructor__PF_Rd1____constructor__PF_Rd1d1____destructor__PF_Rd1____operator_preincr__PFd0_Rd0____operator_predecr__PFd0_Rd0____operator_equal__PFi_d0d0____operator_notequal__PFi_d0d0____operator_deref__PFRd1_d0__F_d0d0PF_d1___1(__attribute__ ((unused)) void (*_adapterF_9telt_type__P)(void (*__anonymous_object41)(), void *__anonymous_object42), __attribute__ ((unused)) void *(*_adapterFP9telt_type_14titerator_type_M_P)(void (*__anonymous_object43)(), void *__anonymous_object44), __attribute__ ((unused)) signed int (*_adapterFi_14titerator_type14titerator_type_M_PP)(void (*__anonymous_object45)(), void *__anonymous_object46, void *__anonymous_object47), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type_P_M)(void (*__anonymous_object48)(), __attribute__ ((unused)) void *___retval__operator_preincr__14titerator_type_1, void *__anonymous_object49), __attribute__ ((unused)) void (*_adapterF_P9telt_type9telt_type__MP)(void (*__anonymous_object50)(), void *__anonymous_object51, void *__anonymous_object52), __attribute__ ((unused)) void (*_adapterF9telt_type_P9telt_type9telt_type_P_MP)(void (*__anonymous_object53)(), __attribute__ ((unused)) void *___retval__operator_assign__9telt_type_1, void *__anonymous_object54, void *__anonymous_object55), __attribute__ ((unused)) void (*_adapterF_P14titerator_type14titerator_type__MP)(void (*__anonymous_object56)(), void *__anonymous_object57, void *__anonymous_object58), __attribute__ ((unused)) void (*_adapterF14titerator_type_P14titerator_type14titerator_type_P_MP)(void (*__anonymous_object59)(), __attribute__ ((unused)) void *___retval__operator_assign__14titerator_type_1, void *__anonymous_object60, void *__anonymous_object61), __attribute__ ((unused)) unsigned long int _sizeof_14titerator_type, __attribute__ ((unused)) unsigned long int _alignof_14titerator_type, __attribute__ ((unused)) unsigned long int _sizeof_9telt_type, __attribute__ ((unused)) unsigned long int _alignof_9telt_type, __attribute__ ((unused)) void *(*___operator_assign__PF14titerator_type_R14titerator_type14titerator_type__1)(void *__anonymous_object62, void *__anonymous_object63), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type__1)(void *__anonymous_object64), __attribute__ ((unused)) void (*___constructor__PF_R14titerator_type14titerator_type__1)(void *__anonymous_object65, void *__anonymous_object66), __attribute__ ((unused)) void (*___destructor__PF_R14titerator_type__1)(void *__anonymous_object67), __attribute__ ((unused)) void *(*___operator_assign__PF9telt_type_R9telt_type9telt_type__1)(void *__anonymous_object68, void *__anonymous_object69), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type__1)(void *__anonymous_object70), __attribute__ ((unused)) void (*___constructor__PF_R9telt_type9telt_type__1)(void *__anonymous_object71, void *__anonymous_object72), __attribute__ ((unused)) void (*___destructor__PF_R9telt_type__1)(void *__anonymous_object73), __attribute__ ((unused)) void *(*___operator_preincr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object74), __attribute__ ((unused)) void *(*___operator_predecr__PF14titerator_type_R14titerator_type__1)(void *__anonymous_object75), __attribute__ ((unused)) signed int (*___operator_equal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object76, void *__anonymous_object77), __attribute__ ((unused)) signed int (*___operator_notequal__PFi_14titerator_type14titerator_type__1)(void *__anonymous_object78, void *__anonymous_object79), __attribute__ ((unused)) void *(*___operator_deref__PFR9telt_type_14titerator_type__1)(void *__anonymous_object80), void *__begin__14titerator_type_1, void *__end__14titerator_type_1, void (*__func__PF_9telt_type__1)(void *__anonymous_object81)); … … 1377 1371 } 1378 1372 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi___1(); } 1379 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned long int __size);1380 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);1381 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);1382 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern signed int atexit(void (*__func)(void));1383 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(signed int __status);1384 extern signed int printf(const char *__restrict __format, ...);1385 1373 static inline signed int invoke_main(signed int argc, char **argv, char **envp); 1386 1374 signed int main(signed int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){ -
src/tests/.expect/castError.txt
r9d06142 rc0d00b6 5 5 charAlternatives are: 6 6 Cost ( 1, 0, 0, 0 ): Cast of: 7 Variable Expression: f: signed int 7 Variable Expression: f: function 8 accepting unspecified arguments 9 ... returning nothing 10 8 11 ... to: 9 12 char … … 23 26 24 27 Cost ( 1, 0, 0, 0 ): Cast of: 25 Variable Expression: f: function 26 accepting unspecified arguments 27 ... returning nothing 28 28 Variable Expression: f: signed int 29 29 ... to: 30 30 char -
src/tests/.expect/completeTypeError.txt
r9d06142 rc0d00b6 1 completeTypeError.c:3 4:1 error: No reasonable alternatives for expression Applying untyped:1 completeTypeError.c:33:1 error: No reasonable alternatives for expression Applying untyped: 2 2 Name: *? 3 3 ...to: 4 4 Name: v 5 5 6 completeTypeError.c:34:1 error: No reasonable alternatives for expression Applying untyped: 7 Name: *? 8 ...to: 9 Name: y 10 11 completeTypeError.c:35:1 error: No reasonable alternatives for expression Applying untyped: 12 Name: foo 13 ...to: 14 Name: v 6 15 7 16 completeTypeError.c:36:1 error: No reasonable alternatives for expression Applying untyped: … … 10 19 Name: v 11 20 12 13 21 completeTypeError.c:37:1 error: No reasonable alternatives for expression Applying untyped: 14 22 Name: quux 15 23 ...to: 16 24 Name: v 17 18 25 19 26 completeTypeError.c:58:1 error: No reasonable alternatives for expression Applying untyped: … … 22 29 Name: y 23 30 24 25 31 completeTypeError.c:59:1 error: No reasonable alternatives for expression Applying untyped: 26 32 Name: quux 27 33 ...to: 28 34 Name: y 29 30 35 31 36 completeTypeError.c:60:1 error: No reasonable alternatives for expression Applying untyped: … … 34 39 Name: y 35 40 36 37 41 completeTypeError.c:72:1 error: No reasonable alternatives for expression Applying untyped: 38 42 Name: baz … … 40 44 Name: z 41 45 42 -
src/tests/Makefile.am
r9d06142 rc0d00b6 141 141 typedefRedef-ERR1: typedefRedef.c @CFA_BINDIR@/@CFA_NAME@ 142 142 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 143 144 alloc-ERROR: alloc.c @CFA_BINDIR@/@CFA_NAME@ 145 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} -
src/tests/Makefile.in
r9d06142 rc0d00b6 895 895 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 896 896 897 alloc-ERROR: alloc.c @CFA_BINDIR@/@CFA_NAME@ 898 ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@} 899 897 900 # Tell versions [3.59,3.63) of GNU make to not export all variables. 898 901 # Otherwise a system limit (for SysV at least) may be exceeded. -
src/tests/alloc.c
r9d06142 rc0d00b6 32 32 // allocation, non-array types 33 33 34 p = ( void *)malloc( sizeof(*p) ); // C malloc, type unsafe34 p = (int *)(void *)malloc( sizeof(*p) ); // C malloc, type unsafe 35 35 *p = 0xdeadbeef; 36 36 printf( "C malloc %#x\n", *p ); … … 54 54 printf( "\n" ); 55 55 56 p = calloc( dim, sizeof( *p ) ); // C array calloc, type unsafe56 p = (int *)calloc( dim, sizeof( *p ) ); // C array calloc, type unsafe 57 57 printf( "C array calloc, fill 0\n" ); 58 58 for ( int i = 0; i < dim; i += 1 ) { printf( "%#x ", p[i] ); } … … 83 83 printf( "\n" ); 84 84 85 p = ( void *)realloc( p, dim * sizeof(*p) ); // C realloc85 p = (int *)(void *)realloc( p, dim * sizeof(*p) ); // C realloc 86 86 for ( int i = 0; i < dim; i += 1 ) { p[i] = 0xdeadbeef; } 87 87 printf( "C realloc\n" ); … … 256 256 stp = malloc(); 257 257 printf( "\nSHOULD FAIL\n" ); 258 #ifdef ERR1 258 259 p = alloc( stp, dim * sizeof(*stp) ); 259 260 p = memset( stp, 10 ); 260 261 p = memcpy( &st1, &st ); 262 #endif 261 263 } // main 262 264 -
src/tests/completeTypeError.c
r9d06142 rc0d00b6 12 12 void *v; 13 13 14 //A * x;15 //A * y;16 //B * x;17 //B * z;14 A * x; 15 A * y; 16 B * x; 17 B * z; 18 18 19 19 // okay 20 20 *i; 21 //*x; // picks B22 //*z;21 *x; // picks B 22 *z; 23 23 foo(i); 24 24 bar(i); … … 29 29 bar(v); 30 30 qux(v); 31 foo(v); // questionable, but works at the moment for C compatibility32 31 33 32 // bad 34 33 *v; 35 // *y; 34 *y; 35 foo(v); 36 36 baz(v); 37 37 quux(v); -
src/tests/dtor-early-exit.c
r9d06142 rc0d00b6 22 22 23 23 struct A { 24 c har * name;24 const char * name; 25 25 int * x; 26 26 }; -
src/tests/init_once.c
r9d06142 rc0d00b6 72 72 insert( &constructed, &x ); 73 73 74 x.x = malloc(sizeof(int));74 x.x = (int *)malloc(sizeof(int)); 75 75 } 76 76 -
src/tests/multiDimension.c
r9d06142 rc0d00b6 7 7 printf("default constructing\n"); 8 8 (this.a){ 123 }; 9 this.ptr = malloc(sizeof(int));9 this.ptr = (int *)malloc(sizeof(int)); 10 10 } 11 11 … … 13 13 printf("copy constructing\n"); 14 14 (this.a){ other.a }; 15 this.ptr = malloc(sizeof(int));15 this.ptr = (int *)malloc(sizeof(int)); 16 16 } 17 17 … … 19 19 printf("constructing with %d\n", a); 20 20 (this.a){ a }; 21 this.ptr = malloc(sizeof(int));21 this.ptr = (int *)malloc(sizeof(int)); 22 22 } 23 23 -
src/tests/polymorphism.c
r9d06142 rc0d00b6 14 14 // 15 15 16 #include <assert.h> 17 #include <inttypes.h> 18 16 19 forall(otype T) 17 20 T f(T x, T y) { … … 24 27 } 25 28 29 forall( otype T, otype U ) 30 size_t struct_size( T i, U j ) { 31 struct S { T i; U j; }; 32 return sizeof(S); 33 } 34 35 forall( otype T, otype U ) 36 size_t union_size( T i, U j ) { 37 union B { T i; U j; }; 38 return sizeof(B); 39 } 40 41 // perform some simple operations on aggregates of T and U 42 forall( otype T | { void print(T); int ?==?(T, T); }, otype U | { void print(U); U ?=?(U&, zero_t); } ) 43 U foo(T i, U j) { 44 struct S { T i; U j; }; 45 union B { T i; U j; }; 46 47 S s; 48 s.i = i; 49 assert(s.i == i); 50 51 B b; 52 b.j = 0; 53 b.i = s.i; 54 return b.j; 55 } 56 26 57 int main() { 27 // ensure that x is not changed by the invocation of a polymorphic function 28 int x = 123; 29 int y = 456; 30 int z = f(x, y); 31 printf("%d %d %d\n", x, y, z); 58 { 59 // ensure that x is not changed by the invocation of a polymorphic function 60 int x = 123; 61 int y = 456; 62 int z = f(x, y); 63 printf("%d %d %d\n", x, y, z); 64 } 32 65 33 // explicitly specialize function 34 int (*f)(int) = ident; 35 ((int(*)(int))ident); 36 printf("%d %d\n", f(5), ((int(*)(int))ident)(5)); 66 { 67 // explicitly specialize function 68 int (*f)(int) = ident; 69 ((int(*)(int))ident); 70 printf("%d %d\n", f(5), ((int(*)(int))ident)(5)); 71 } 72 73 { 74 // test aggregates with polymorphic members 75 typedef uint32_t x_type; 76 typedef uint64_t y_type; 77 78 x_type x = 3; 79 y_type y = 3; 80 81 struct S { 82 x_type f1; 83 y_type f2; 84 }; 85 union U { 86 x_type f1; 87 y_type f2; 88 }; 89 // ensure that the size of aggregates with polymorphic members 90 // matches the size of the aggregates in a monomorphic context 91 assert( struct_size(x, y) == sizeof(S) ); 92 assert( union_size(x, y) == sizeof(U) ); 93 94 y_type ?=?(y_type & this, zero_t) { 95 this = (int)0; 96 return this; 97 } 98 99 void print(x_type x) { 100 printf("%"PRIu32"\n", x); 101 } 102 103 void print(y_type y) { 104 printf("%"PRIu64"\n", y); 105 } 106 107 y_type ret = foo(x, y); 108 109 // duplicate logic from inside of foo to ensure the same results 110 U u; 111 u.f2 = 0; 112 u.f1 = x; 113 assert(ret == u.f2); 114 } 37 115 } 38 116 -
src/tests/tupleVariadic.c
r9d06142 rc0d00b6 73 73 [a0, a1, a2, a3] = args; 74 74 a.size = 4; 75 a.data = malloc(sizeof(int)*a.size);75 a.data = (int *)malloc(sizeof(int)*a.size); 76 76 a.data[0] = a0; 77 77 a.data[1] = a1; -
src/tests/vector/vector_int.c
r9d06142 rc0d00b6 27 27 vec.last = -1; 28 28 vec.capacity = reserve; 29 vec.data = malloc( sizeof( int ) * reserve );29 vec.data = (int *)malloc( sizeof( int ) * reserve ); 30 30 } 31 31 … … 33 33 vec.last = other.last; 34 34 vec.capacity = other.capacity; 35 vec.data = malloc( sizeof( int ) * other.capacity );35 vec.data = (int *)malloc( sizeof( int ) * other.capacity ); 36 36 for (int i = 0; i < vec.last; i++) { 37 37 vec.data[i] = other.data[i]; … … 45 45 void reserve( vector_int *vec, int reserve ) { 46 46 if ( reserve > vec->capacity ) { 47 vec->data = realloc( vec->data, sizeof( int ) * reserve );47 vec->data = (int *)realloc( vec->data, sizeof( int ) * reserve ); 48 48 vec->capacity = reserve; 49 49 } … … 54 54 if ( vec->last == vec->capacity ) { 55 55 vec->capacity *= 2; 56 vec->data = realloc( vec->data, sizeof( int ) * vec->capacity );56 vec->data = (int *)realloc( vec->data, sizeof( int ) * vec->capacity ); 57 57 } 58 58 vec->data[ vec->last ] = element;
Note:
See TracChangeset
for help on using the changeset viewer.