Changes in src/GenPoly/Box.cc [aa19ccf:c2ad3c9]
- File:
-
- 1 edited
-
src/GenPoly/Box.cc (modified) (46 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/GenPoly/Box.cc
raa19ccf rc2ad3c9 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Feb 5 16:45:07201613 // Update Count : 2 8611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 13 14:51:21 2016 13 // Update Count : 295 14 14 // 15 15 … … 133 133 Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const { 134 134 TypeList typeList( params ); 135 135 136 136 // scan scopes for matches to the key 137 137 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) { … … 160 160 virtual Declaration *mutate( UnionDecl *unionDecl ); 161 161 }; 162 162 163 163 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 164 164 class Pass1 : public PolyMutator { … … 197 197 void addInferredParams( ApplicationExpr *appExpr, FunctionType *functionType, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ); 198 198 /// Stores assignment operators from assertion list in local map of assignment operations 199 void find AssignOps( const std::list< TypeDecl *> &forall );199 void findTypeOps( const std::list< TypeDecl *> &forall ); 200 200 void passAdapters( ApplicationExpr *appExpr, FunctionType *functionType, const TyVarMap &exprTyVars ); 201 201 FunctionDecl *makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ); … … 205 205 ObjectDecl *makeTemporary( Type *type ); 206 206 207 ScopedMap< std::string, DeclarationWithType *> assignOps; ///< Currently known type variable assignment operators 207 ScopedMap< std::string, DeclarationWithType* > assignOps; ///< Currently known type variable assignment operators 208 ScopedMap< std::string, DeclarationWithType* > ctorOps; ///< Currently known type variable constructors 209 ScopedMap< std::string, DeclarationWithType* > copyOps; ///< Currently known type variable copy constructors 210 ScopedMap< std::string, DeclarationWithType* > dtorOps; ///< Currently known type variable destructors 208 211 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; ///< Currently known assignment operators 212 ResolvExpr::TypeMap< DeclarationWithType > scopedCtorOps; ///< Currently known assignment operators 213 ResolvExpr::TypeMap< DeclarationWithType > scopedCopyOps; ///< Currently known assignment operators 214 ResolvExpr::TypeMap< DeclarationWithType > scopedDtorOps; ///< Currently known assignment operators 209 215 ScopedMap< std::string, DeclarationWithType* > adapters; ///< Set of adapter functions in the current scope 210 216 211 217 DeclarationWithType *retval; 212 218 bool useRetval; … … 226 232 virtual Type *mutate( PointerType *pointerType ); 227 233 virtual Type *mutate( FunctionType *funcType ); 228 234 229 235 private: 230 236 void addAdapters( FunctionType *functionType ); … … 297 303 /// Exits the type-variable scope 298 304 void endTypeScope(); 299 305 300 306 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName 301 307 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName … … 351 357 PolyGenericCalculator polyCalculator; 352 358 Pass3 pass3; 353 359 354 360 layoutBuilder.mutateDeclarationList( translationUnit ); 355 361 mutateTranslationUnit/*All*/( translationUnit, pass1 ); … … 370 376 return functionDecl; 371 377 } 372 378 373 379 /// Get a list of type declarations that will affect a layout function 374 380 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { … … 380 386 } 381 387 } 382 388 383 389 return otypeDecls; 384 390 } … … 387 393 void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) { 388 394 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 389 395 390 396 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 391 397 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); … … 444 450 return makeCond( ifCond, ifExpr ); 445 451 } 446 452 447 453 /// adds an expression to a compound statement 448 454 void addExpr( CompoundStmt *stmts, Expression *expr ) { … … 454 460 stmts->get_kids().push_back( stmt ); 455 461 } 456 462 457 463 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) { 458 464 // do not generate layout function for "empty" tag structs … … 467 473 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 468 474 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 469 475 470 476 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 471 477 layoutFnType->get_parameters().push_back( sizeParam ); … … 497 503 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); 498 504 } 499 505 500 506 // place current size in the current offset index 501 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from ( n_members ) ) ),507 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ), 502 508 derefVar( sizeParam ) ) ); 503 509 ++n_members; … … 505 511 // add member size to current size 506 512 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 507 513 508 514 // take max of member alignment and global alignment 509 515 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); … … 515 521 return structDecl; 516 522 } 517 523 518 524 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) { 519 525 // do not generate layout function for "empty" tag unions 520 526 if ( unionDecl->get_members().empty() ) return unionDecl; 521 527 522 528 // get parameters that can change layout, exiting early if none 523 529 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); … … 528 534 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 529 535 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 530 536 531 537 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 532 538 layoutFnType->get_parameters().push_back( sizeParam ); … … 545 551 assert( dwt ); 546 552 Type *memberType = dwt->get_type(); 547 553 548 554 // take max member size and global size 549 555 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 550 556 551 557 // take max of member alignment and global alignment 552 558 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); … … 558 564 return unionDecl; 559 565 } 560 566 561 567 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 562 568 … … 600 606 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {} 601 607 602 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise 603 TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) { 604 if ( decl->get_name() == "?=?" ) { 605 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 606 if ( funType->get_parameters().size() == 2 ) { 607 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 608 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 609 if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 610 if ( refType->get_name() == refType2->get_name() ) { 611 return refType; 612 } // if 608 /// Returns T if the given declaration is a function with parameter (T*) for some TypeInstType T, NULL otherwise 609 TypeInstType *isTypeInstPtrFn( DeclarationWithType *decl ) { 610 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 611 if ( funType->get_parameters().size() == 1 ) { 612 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 613 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 614 return refType; 615 } // if 616 } // if 617 } // if 618 } // if 619 return 0; 620 } 621 622 /// Returns T if the given declaration is a function with parameters (T*, T) for some TypeInstType T, NULL otherwise 623 TypeInstType *isTypeInstPtrValFn( DeclarationWithType *decl ) { 624 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 625 if ( funType->get_parameters().size() == 2 ) { 626 if ( PointerType *pointer = dynamic_cast< PointerType *>( funType->get_parameters().front()->get_type() ) ) { 627 if ( TypeInstType *refType = dynamic_cast< TypeInstType *>( pointer->get_base() ) ) { 628 if ( TypeInstType *refType2 = dynamic_cast< TypeInstType *>( funType->get_parameters().back()->get_type() ) ) { 629 if ( refType->get_name() == refType2->get_name() ) { 630 return refType; 613 631 } // if 614 632 } // if … … 620 638 } 621 639 622 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise 623 /// Only picks assignments where neither parameter is cv-qualified 624 Type *isAssignment( DeclarationWithType *decl ) { 625 if ( decl->get_name() == "?=?" ) { 626 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 627 if ( funType->get_parameters().size() == 2 ) { 628 Type::Qualifiers defaultQualifiers; 629 Type *paramType1 = funType->get_parameters().front()->get_type(); 630 if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0; 631 Type *paramType2 = funType->get_parameters().back()->get_type(); 632 if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0; 633 634 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) { 635 Type *baseType1 = pointerType->get_base(); 636 if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0; 637 SymTab::Indexer dummy; 638 if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) { 639 return baseType1; 640 } // if 640 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise 641 TypeInstType *isTypeInstAssignment( DeclarationWithType *decl ) { 642 return decl->get_name() == "?=?" ? isTypeInstPtrValFn( decl ) : 0; 643 } 644 645 /// Returns T if the given declaration is (*?{})(T *) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise 646 TypeInstType *isTypeInstCtor( DeclarationWithType *decl ) { 647 return decl->get_name() == "?{}" ? isTypeInstPtrFn( decl ) : 0; 648 } 649 650 /// Returns T if the given declaration is (*?{})(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise 651 TypeInstType *isTypeInstCopy( DeclarationWithType *decl ) { 652 return decl->get_name() == "?{}" ? isTypeInstPtrValFn( decl ) : 0; 653 } 654 655 /// Returns T if the given declaration is (*^?{})(T *) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise 656 TypeInstType *isTypeInstDtor( DeclarationWithType *decl ) { 657 return decl->get_name() == "^?{}" ? isTypeInstPtrFn( decl ) : 0; 658 } 659 660 /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified, 661 /// NULL otherwise 662 Type *isNoCvPtrFn( DeclarationWithType *decl ) { 663 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 664 if ( funType->get_parameters().size() == 1 ) { 665 Type::Qualifiers defaultQualifiers; 666 Type *paramType = funType->get_parameters().front()->get_type(); 667 if ( paramType->get_qualifiers() != defaultQualifiers ) return 0; 668 669 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType ) ) { 670 Type *baseType = pointerType->get_base(); 671 if ( baseType->get_qualifiers() == defaultQualifiers ) { 672 return baseType; 641 673 } // if 642 674 } // if … … 645 677 return 0; 646 678 } 647 648 void Pass1::findAssignOps( const std::list< TypeDecl *> &forall ) { 679 680 /// Returns T if the given declaration is a function with parameters (T*, T) for some type T, where neither parameter is cv-qualified, 681 /// NULL otherwise 682 Type *isNoCvPtrValFn( DeclarationWithType *decl ) { 683 if ( FunctionType *funType = getFunctionType( decl->get_type() ) ) { 684 if ( funType->get_parameters().size() == 2 ) { 685 Type::Qualifiers defaultQualifiers; 686 Type *paramType1 = funType->get_parameters().front()->get_type(); 687 if ( paramType1->get_qualifiers() != defaultQualifiers ) return 0; 688 Type *paramType2 = funType->get_parameters().back()->get_type(); 689 if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0; 690 691 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) { 692 Type *baseType1 = pointerType->get_base(); 693 if ( baseType1->get_qualifiers() != defaultQualifiers ) return 0; 694 SymTab::Indexer dummy; 695 if ( ResolvExpr::typesCompatible( baseType1, paramType2, dummy ) ) { 696 return baseType1; 697 } // if 698 } // if 699 } // if 700 } // if 701 return 0; 702 } 703 704 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise 705 /// Only picks assignments where neither parameter is cv-qualified 706 Type *isAssignment( DeclarationWithType *decl ) { 707 return decl->get_name() == "?=?" ? isNoCvPtrValFn( decl ) : 0; 708 } 709 710 /// returns T if the given declaration is: (*?{})(T *) for some type T, NULL otherwise 711 /// Only picks ctors where the parameter is not cv-qualified 712 Type *isCtor( DeclarationWithType *decl ) { 713 return decl->get_name() == "?{}" ? isNoCvPtrFn( decl ) : 0; 714 } 715 716 /// returns T if the given declaration is: (*?{})(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise 717 /// Only picks copy constructors where neither parameter is cv-qualified 718 Type *isCopy( DeclarationWithType *decl ) { 719 return decl->get_name() == "?{}" ? isNoCvPtrValFn( decl ) : 0; 720 } 721 722 /// returns T if the given declaration is: (*?{})(T *) for some type T, NULL otherwise 723 /// Only picks ctors where the parameter is not cv-qualified 724 Type *isDtor( DeclarationWithType *decl ) { 725 return decl->get_name() == "^?{}" ? isNoCvPtrFn( decl ) : 0; 726 } 727 728 void Pass1::findTypeOps( const std::list< TypeDecl *> &forall ) { 649 729 // what if a nested function uses an assignment operator? 650 730 // assignOps.clear(); … … 654 734 if ( TypeInstType *typeInst = isTypeInstAssignment( *assert ) ) { 655 735 assignOps[ typeInst->get_name() ] = *assert; 736 } else if ( TypeInstType *typeInst = isTypeInstCtor( *assert ) ) { 737 ctorOps[ typeInst->get_name() ] = *assert; 738 } else if ( TypeInstType *typeInst = isTypeInstCopy( *assert ) ) { 739 copyOps[ typeInst->get_name() ] = *assert; 740 } else if ( TypeInstType *typeInst = isTypeInstDtor( *assert ) ) { 741 dtorOps[ typeInst->get_name() ] = *assert; 656 742 } // if 657 743 } // for … … 661 747 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 662 748 // if this is a assignment function, put it in the map for this scope 663 if ( Type *assignedType = isAssignment( functionDecl ) ) { 664 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { 665 scopedAssignOps.insert( assignedType, functionDecl ); 749 if ( Type *paramType = isAssignment( functionDecl ) ) { 750 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) { 751 scopedAssignOps.insert( paramType, functionDecl ); 752 } 753 } else if ( Type *paramType = isCtor( functionDecl ) ) { 754 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) { 755 scopedCtorOps.insert( paramType, functionDecl ); 756 } 757 } else if ( Type *paramType = isCopy( functionDecl ) ) { 758 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) { 759 scopedCopyOps.insert( paramType, functionDecl ); 760 } 761 } else if ( Type *paramType = isDtor( functionDecl ) ) { 762 if ( ! dynamic_cast< TypeInstType* >( paramType ) ) { 763 scopedDtorOps.insert( paramType, functionDecl ); 666 764 } 667 765 } … … 671 769 scopeTyVars.beginScope(); 672 770 assignOps.beginScope(); 771 ctorOps.beginScope(); 772 copyOps.beginScope(); 773 dtorOps.beginScope(); 774 673 775 DeclarationWithType *oldRetval = retval; 674 776 bool oldUseRetval = useRetval; … … 688 790 FunctionType *functionType = functionDecl->get_functionType(); 689 791 makeTyVarMap( functionDecl->get_functionType(), scopeTyVars ); 690 find AssignOps( functionDecl->get_functionType()->get_forall() );792 findTypeOps( functionDecl->get_functionType()->get_forall() ); 691 793 692 794 std::list< DeclarationWithType *> ¶mList = functionType->get_parameters(); … … 713 815 scopeTyVars.endScope(); 714 816 assignOps.endScope(); 817 ctorOps.endScope(); 818 copyOps.endScope(); 819 dtorOps.endScope(); 715 820 retval = oldRetval; 716 821 useRetval = oldUseRetval; … … 784 889 arg++; 785 890 } else { 786 throw SemanticError( "unbound type variable in application ", appExpr ); 891 /// xxx - should this be an assertion? 892 throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr ); 787 893 } // if 788 894 } // if … … 803 909 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 804 910 } 805 911 806 912 // add type information args for presently unseen types in parameter list 807 913 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { … … 882 988 assert( env ); 883 989 Type *concrete = replaceWithConcrete( appExpr, polyType ); 884 // add out-parameter for return value 990 // add out-parameter for return value 885 991 return addRetParam( appExpr, function, concrete, arg ); 886 992 } … … 910 1016 } else if ( arg->get_results().front()->get_isLvalue() ) { 911 1017 // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue) 1018 // xxx - need to test that this code is still reachable 912 1019 if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) { 913 1020 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) ); … … 1035 1142 std::list< DeclarationWithType *>::iterator param = adapterType->get_parameters().begin(); 1036 1143 std::list< DeclarationWithType *>::iterator realParam = adaptee->get_parameters().begin(); 1037 param++; // skip adaptee parameter 1144 param++; // skip adaptee parameter in the adapter type 1038 1145 if ( realType->get_returnVals().empty() ) { 1146 // void return 1039 1147 addAdapterParams( adapteeApp, arg, param, adapterType->get_parameters().end(), realParam, tyVars ); 1040 1148 bodyStmt = new ExprStmt( noLabels, adapteeApp ); 1041 1149 } else if ( isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) { 1150 // return type T 1042 1151 if ( (*param)->get_name() == "" ) { 1043 1152 (*param)->set_name( "_ret" ); … … 1291 1400 } else if ( needsAdapter( function, scopeTyVars ) ) { 1292 1401 // std::cerr << "needs adapter: "; 1293 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 1294 // std::cerr << i->first << " "; 1295 // } 1296 // std::cerr << "\n"; 1402 // printTyVarMap( std::cerr, scopeTyVars ); 1403 // std::cerr << *env << std::endl; 1297 1404 // change the application so it calls the adapter rather than the passed function 1298 1405 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); … … 1345 1452 } // if 1346 1453 } // if 1454 // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward 1455 // out of the if condition. 1456 bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ); 1347 1457 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 1348 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env )|| needs ) {1458 if ( polytype || needs ) { 1349 1459 Expression *ret = addrExpr->get_arg(); 1350 1460 delete ret->get_results().front(); … … 1365 1475 functionObj->set_mangleName( functionDecl->get_mangleName() ); 1366 1476 return new VariableExpr( functionObj ); 1477 } 1478 1479 /// Finds the operation declaration for a given type in one of the two maps 1480 DeclarationWithType* findOpForType( Type *formalType, const ScopedMap< std::string, DeclarationWithType* >& ops, ResolvExpr::TypeMap< DeclarationWithType >& scopedOps ) { 1481 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { 1482 ScopedMap< std::string, DeclarationWithType *>::const_iterator opIt = ops.find( formalTypeInstType->get_name() ); 1483 return opIt == ops.end() ? 0 : opIt->second; 1484 } else { 1485 return scopedOps.find( formalType ); 1486 } 1487 } 1488 1489 /// Adds an assertion parameter to the application expression for the actual assertion declaration valued with the assert op 1490 void addAssertionFor( ApplicationExpr *appExpr, DeclarationWithType *actualDecl, DeclarationWithType *assertOp ) { 1491 appExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1492 = ParamEntry( assertOp->get_uniqueId(), assertOp->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertOp ) ); 1367 1493 } 1368 1494 … … 1413 1539 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType ); 1414 1540 1415 // skip types with no assign op(ftype/dtype)1541 // skip non-otype parameters (ftype/dtype) 1416 1542 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; 1417 1543 1418 // find assignment operator for formal type 1419 DeclarationWithType *assertAssign = 0; 1420 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { 1421 ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() ); 1422 if ( assertAssignIt == assignOps.end() ) { 1423 throw SemanticError( "No assignment operation found for ", formalTypeInstType ); 1424 } 1425 assertAssign = assertAssignIt->second; 1426 } else { 1427 assertAssign = scopedAssignOps.find( formalType ); 1428 if ( ! assertAssign ) { 1429 throw SemanticError( "No assignment operation found for ", formalType ); 1430 } 1431 } 1432 1433 // add inferred parameter for field assignment operator to assignment expression 1544 // find otype operators for formal type 1545 DeclarationWithType *assertAssign = findOpForType( formalType, assignOps, scopedAssignOps ); 1546 if ( ! assertAssign ) throw SemanticError( "No assignment operation found for ", formalType ); 1547 1548 DeclarationWithType *assertCtor = findOpForType( formalType, ctorOps, scopedCtorOps ); 1549 if ( ! assertCtor ) throw SemanticError( "No default constructor found for ", formalType ); 1550 1551 DeclarationWithType *assertCopy = findOpForType( formalType, copyOps, scopedCopyOps ); 1552 if ( ! assertCopy ) throw SemanticError( "No copy constructor found for ", formalType ); 1553 1554 DeclarationWithType *assertDtor = findOpForType( formalType, dtorOps, scopedDtorOps ); 1555 if ( ! assertDtor ) throw SemanticError( "No destructor found for ", formalType ); 1556 1557 // add inferred parameters for otype operators to assignment expression 1558 // NOTE: Code here assumes that first four assertions are assign op, ctor, copy ctor, dtor, in that order 1434 1559 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1435 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1436 DeclarationWithType *actualDecl = asserts.front(); 1437 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1438 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); 1560 assert( asserts.size() >= 4 && "Type param needs otype operator assertions" ); 1561 1562 std::list< DeclarationWithType* >::iterator actualIt = asserts.begin(); 1563 addAssertionFor( assignExpr, *actualIt, assertAssign ); 1564 ++actualIt; 1565 addAssertionFor( assignExpr, *actualIt, assertCtor ); 1566 ++actualIt; 1567 addAssertionFor( assignExpr, *actualIt, assertCopy ); 1568 ++actualIt; 1569 addAssertionFor( assignExpr, *actualIt, assertDtor ); 1570 1571 //DeclarationWithType *actualDecl = asserts.front(); 1572 //assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1573 // = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); 1439 1574 } 1440 1575 } … … 1482 1617 adapters.beginScope(); 1483 1618 scopedAssignOps.beginScope(); 1619 scopedCtorOps.beginScope(); 1620 scopedCopyOps.beginScope(); 1621 scopedDtorOps.beginScope(); 1484 1622 } 1485 1623 … … 1487 1625 adapters.endScope(); 1488 1626 scopedAssignOps.endScope(); 1627 scopedCtorOps.endScope(); 1628 scopedCopyOps.endScope(); 1629 scopedDtorOps.endScope(); 1489 1630 } 1490 1631 … … 1886 2027 } 1887 2028 } 1888 2029 1889 2030 Type *ret = Mutator::mutate( funcType ); 1890 2031 … … 1905 2046 1906 2047 std::list<Expression*> designators; 1907 objectDecl->set_init( new SingleInit( alloc, designators ) );2048 objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed 1908 2049 } 1909 2050 } … … 1942 2083 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 1943 2084 derefExpr->get_args().push_back( derefdVar ); 2085 // xxx - should set results on derefExpr 1944 2086 derefdVar = derefExpr; 1945 2087 } 1946 2088 return derefdVar; 1947 2089 } 1948 2090 1949 2091 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) { 1950 2092 // mutate, exiting early if no longer MemberExpr … … 2038 2180 2039 2181 bool PolyGenericCalculator::findGeneric( Type *ty ) { 2182 ty = replaceTypeInst( ty, env ); 2183 2040 2184 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 2041 // duplicate logic from isPolyType()2042 if ( env ) {2043 if ( Type *newType = env->lookup( typeInst->get_name() ) ) {2044 return findGeneric( newType );2045 } // if2046 } // if2047 2185 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) { 2048 2186 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set … … 2066 2204 if ( n_members == 0 ) { 2067 2205 // all empty structs have the same layout - size 1, align 1 2068 makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from ( (unsigned long)1 ) ) ) );2069 makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from ( (unsigned long)1 ) ) ) );2206 makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from_ulong( (unsigned long)1 ) ) ) ); 2207 makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from_ulong( (unsigned long)1 ) ) ) ); 2070 2208 // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array 2071 2209 } else { 2072 2210 ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType ); 2073 2211 ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() ); 2074 ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from ( n_members ) ), false, false ) );2212 ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from_int( n_members ) ), false, false ) ); 2075 2213 2076 2214 // generate call to layout function … … 2144 2282 Type *ty = offsetofExpr->get_type(); 2145 2283 if ( ! findGeneric( ty ) ) return offsetofExpr; 2146 2284 2147 2285 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) { 2148 2286 // replace offsetof expression by index into offset array … … 2191 2329 2192 2330 // build the offset array and replace the pack with a reference to it 2193 ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from ( baseMembers.size() ) ), false, false ),2331 ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from_ulong( baseMembers.size() ) ), false, false ), 2194 2332 new ListInit( inits ) ); 2195 2333 ret = new VariableExpr( offsetArray );
Note:
See TracChangeset
for help on using the changeset viewer.