Changes in / [52f85e0:cce7872]


Ignore:
Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r52f85e0 rcce7872  
    992992                }
    993993
     994                /// Wraps a function declaration in a new pointer-to-function variable expression
     995                VariableExpr *wrapFunctionDecl( DeclarationWithType *functionDecl ) {
     996                        // line below cloned from FixFunction.cc
     997                        ObjectDecl *functionObj = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
     998                                                                  new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     999                        functionObj->set_mangleName( functionDecl->get_mangleName() );
     1000                        return new VariableExpr( functionObj );
     1001                }
     1002               
    9941003                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    9951004                        if ( retval && returnStmt->get_expr() ) {
     
    10071016
    10081017                                // find assignment operator for (polymorphic) return type
    1009                                 DeclarationWithType *assignDecl = 0;
     1018                                ApplicationExpr *assignExpr = 0;
    10101019                                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) {
     1020                                        // find assignment operator for type variable
    10111021                                        std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );
    10121022                                        if ( assignIter == assignOps.end() ) {
    10131023                                                throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() );
    10141024                                        } // if
    1015                                         assignDecl = assignIter->second;
     1025                                        assignExpr = new ApplicationExpr( new VariableExpr( assignIter->second ) );
    10161026                                } else if ( ReferenceToType *refType = dynamic_cast< ReferenceToType *>( retval->get_type() ) ) {
     1027                                        // find assignment operator for generic type
    10171028                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = scopedAssignOps.find( refType->get_name() );
    10181029                                        if ( assignIter == scopedAssignOps.end() ) {
    10191030                                                throw SemanticError( "Attempt to return dtype or ftype generic object in ", returnStmt->get_expr() );
    10201031                                        }
     1032
     1033                                        // wrap it up in an application expression
    10211034                                        DeclarationWithType *functionDecl = assignIter->second;
    1022                                         // line below cloned from FixFunction.cc
    1023                                         assignDecl = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0,
    1024                                                                      new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    1025                                         assignDecl->set_mangleName( functionDecl->get_mangleName() );
     1035                                        assignExpr = new ApplicationExpr( wrapFunctionDecl( functionDecl ) );
     1036                                        assignExpr->set_env( env->clone() );
     1037
     1038                                        // find each of its needed secondary assignment operators
     1039                                        std::list< Expression* > &tyParams = refType->get_parameters();
     1040                                        std::list< TypeDecl* > &forallParams = functionDecl->get_type()->get_forall();
     1041                                        std::list< Expression* >::const_iterator tyIt = tyParams.begin();
     1042                                        std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin();
     1043                                        for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) {
     1044                                                if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype)
     1045
     1046                                                std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions();
     1047                                                assert( ! asserts.empty() && "Type param needs assignment operator assertion" );
     1048                                                DeclarationWithType *actualDecl = asserts.front();
     1049                                                ReferenceToType *actualType = isAssignment( actualDecl );
     1050                                                assert( actualType && "First assertion of type with assertions should be assignment operator" );
     1051                                                TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt );
     1052                                                assert( formalTypeExpr && "type parameters must be type expressions" );
     1053                                                Type *formalType = formalTypeExpr->get_type();
     1054                                                assignExpr->get_env()->add( actualType->get_name(), formalType );
     1055                                               
     1056                                                DeclarationWithType *assertAssign = 0;
     1057                                                if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) {
     1058                                                        std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );
     1059                                                        if ( assertAssignIt == assignOps.end() ) {
     1060                                                                throw SemanticError( "No assignment operation found for ", formalTypeInstType );
     1061                                                        }
     1062                                                        assertAssign = assertAssignIt->second;
     1063                                                        //assignExpr->get_env()->add( formalTypeInstType->get_name(), actualType );
     1064                                                } else if ( ReferenceToType *formalReferenceType = dynamic_cast< ReferenceToType* >( formalType ) )  {
     1065                                                        ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = scopedAssignOps.find( formalReferenceType->get_name() );
     1066                                                        if ( assertAssignIt == scopedAssignOps.end() ) {
     1067                                                                throw SemanticError( "No assignment operation found for ", formalReferenceType );
     1068                                                        }
     1069                                                        assertAssign = assertAssignIt->second;
     1070                                                } else assert( false && "returning polymorphic types with non struct/polymorphic parameters not yet supported" );
     1071                                               
     1072
     1073                                                assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ]
     1074                                                        = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) );
     1075                                        }
    10261076                                }
    1027                                 assert( assignDecl );
     1077                                assert( assignExpr );
    10281078
    10291079                                // replace return statement with appropriate assignment to out parameter
    1030                                 ApplicationExpr *assignExpr = new ApplicationExpr( new VariableExpr( assignDecl ) );
    10311080                                Expression *retParm = new NameExpr( retval->get_name() );
    10321081                                retParm->get_results().push_back( new PointerType( Type::Qualifiers(), retval->get_type()->clone() ) );
     
    13531402                                delete memberExpr;
    13541403                                return fieldLoc;
    1355                         } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
     1404                        } else if ( dynamic_cast< UnionInstType* >( objectType ) ) {
    13561405                                // union members are all at offset zero, so build appropriately-dereferenced variable
    13571406                                Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );
  • src/SymTab/Validate.cc

    r52f85e0 rcce7872  
    382382                // it's not a semantic error if the struct is not found, just an implicit forward declaration
    383383                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() );
    385385                        structInst->set_baseStruct( st );
    386386                } // if
     
    659659        }
    660660
     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
    661682        Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
    662683                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     
    666687                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    667688                std::list< Expression* > structParams;  // List of matching parameters to put on types
     689                TypeSubstitution genericSubs; // Substitutions to make to member types of struct
    668690                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    669691                        isGeneric = true;
    670                         TypeDecl *typeParam = (*param)->clone();
     692                        TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    671693                        assignType->get_forall().push_back( typeParam );
    672                         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 ) );
    673697                }
    674698
     
    701725                                }
    702726
    703                                 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    704                                         makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    705                                         if ( isGeneric ) makeArrayAssignment( srcParam, returnVal, 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
    706740                                } else {
    707                                         makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    708                                         if ( isGeneric ) makeScalarAssignment( srcParam, returnVal, 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
    709747                                } // if
    710748                        } // if
     
    724762                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    725763                        isGeneric = true;
    726                         TypeDecl *typeParam = (*param)->clone();
     764                        TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    727765                        assignType->get_forall().push_back( typeParam );
    728766                        unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
Note: See TracChangeset for help on using the changeset viewer.