Changes in src/SymTab/Validate.cc [d3b7937:98735ef]
- File:
-
- 1 edited
-
src/SymTab/Validate.cc (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
rd3b7937 r98735ef 382 382 // it's not a semantic error if the struct is not found, just an implicit forward declaration 383 383 if ( st ) { 384 assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );384 //assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() ); 385 385 structInst->set_baseStruct( st ); 386 386 } // if … … 585 585 } 586 586 587 template< typename OutputIterator > 588 void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) { 589 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 590 copy->get_args().push_back( new VariableExpr( dstParam ) ); 591 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 592 copy->get_args().push_back( new SizeofExpr( unionType ) ); 593 594 *out++ = new ExprStmt( noLabels, copy ); 595 } 596 587 597 //E ?=?(E volatile*, int), 588 598 // ?=?(E _Atomic volatile*, int); … … 649 659 } 650 660 661 /// Creates a new type decl that's the same as src, but renamed and with only the ?=? assertion (for complete types only) 662 TypeDecl *cloneAndRename( TypeDecl *src, const std::string &name ) { 663 TypeDecl *dst = new TypeDecl( name, src->get_storageClass(), 0, src->get_kind() ); 664 665 if ( src->get_kind() == TypeDecl::Any ) { 666 // just include assignment operator assertion 667 TypeInstType *assignParamType = new TypeInstType( Type::Qualifiers(), name, dst ); 668 FunctionType *assignFunctionType = new FunctionType( Type::Qualifiers(), false ); 669 assignFunctionType->get_returnVals().push_back( 670 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType->clone(), 0 ) ); 671 assignFunctionType->get_parameters().push_back( 672 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), assignParamType->clone() ), 0 ) ); 673 assignFunctionType->get_parameters().push_back( 674 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType, 0 ) ); 675 FunctionDecl *assignAssert = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignFunctionType, 0, false, false ); 676 dst->get_assertions().push_back( assignAssert ); 677 } 678 679 return dst; 680 } 681 651 682 Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) { 652 683 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 653 684 654 685 // Make function polymorphic in same parameters as generic struct, if applicable 686 bool isGeneric = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union) 655 687 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters(); 656 688 std::list< Expression* > structParams; // List of matching parameters to put on types 689 TypeSubstitution genericSubs; // Substitutions to make to member types of struct 657 690 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) { 658 TypeDecl *typeParam = (*param)->clone(); 691 isGeneric = true; 692 TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() ); 659 693 assignType->get_forall().push_back( typeParam ); 660 structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) ); 694 TypeInstType *newParamType = new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ); 695 genericSubs.add( (*param)->get_name(), newParamType ); 696 structParams.push_back( new TypeExpr( newParamType ) ); 661 697 } 662 698 663 ObjectDecl *returnVal = new ObjectDecl( " ", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );699 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 ); 664 700 assignType->get_returnVals().push_back( returnVal ); 665 701 … … 689 725 } 690 726 691 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) { 692 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 727 if ( isGeneric ) { 728 // rewrite member type in terms of the type variables on this operator 729 DeclarationWithType *fixedMember = dwt->clone(); 730 genericSubs.apply( fixedMember ); 731 732 // assign to both destination and return value 733 if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) { 734 makeArrayAssignment( srcParam, dstParam, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 735 makeArrayAssignment( srcParam, returnVal, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 736 } else { 737 makeScalarAssignment( srcParam, dstParam, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) ); 738 makeScalarAssignment( srcParam, returnVal, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) ); 739 } // if 693 740 } else { 694 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) ); 741 // assign to destination 742 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) { 743 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 744 } else { 745 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) ); 746 } // if 695 747 } // if 696 748 } // if 697 749 } // for 698 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );750 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 699 751 700 752 return assignDecl; … … 705 757 706 758 // Make function polymorphic in same parameters as generic union, if applicable 759 bool isGeneric = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct) 707 760 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters(); 708 761 std::list< Expression* > unionParams; // List of matching parameters to put on types 709 762 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) { 710 TypeDecl *typeParam = (*param)->clone(); 763 isGeneric = true; 764 TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() ); 711 765 assignType->get_forall().push_back( typeParam ); 712 766 unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) ); 713 767 } 714 768 715 ObjectDecl *returnVal = new ObjectDecl( " ", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );769 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 ); 716 770 assignType->get_returnVals().push_back( returnVal ); 717 771 … … 727 781 assignDecl->fixUniqueId(); 728 782 729 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 730 copy->get_args().push_back( new VariableExpr( dstParam ) ); 731 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 732 copy->get_args().push_back( new SizeofExpr( cloneWithParams( refType, unionParams ) ) ); 733 734 assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) ); 735 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 783 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 784 if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 785 786 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 736 787 737 788 return assignDecl;
Note:
See TracChangeset
for help on using the changeset viewer.