Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r9b4c936 ra465caff  
    6464
    6565        template< typename OutputIterator >
    66         void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, OutputIterator out ) {
     66        void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
    6767                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    6868                copy->get_args().push_back( new VariableExpr( dstParam ) );
     
    173173        }
    174174
    175         void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout, bool forward = true ) {
    176 //              if ( isDynamicLayout && src ) {
    177 //                      genericSubs.apply( src );
    178 //              }
     175        void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
     176                if ( isGeneric ) {
     177                        // rewrite member type in terms of the type variables on this operator
     178                        field = field->clone();
     179                        genericSubs.apply( field );
     180
     181                        if ( src ) {
     182                                genericSubs.apply( src );
     183                        }
     184                }
    179185
    180186                ObjectDecl * returnVal = NULL;
     
    191197                genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
    192198
    193                 if ( isDynamicLayout && returnVal ) {
     199                if ( isGeneric && returnVal ) {
    194200                        UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
    195201                        derefRet->get_args().push_back( new VariableExpr( returnVal ) );
     
    200206
    201207        template<typename Iterator>
    202         void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout, bool forward = true ) {
     208        void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
    203209                for ( ; member != end; ++member ) {
    204210                        if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate
     
    236242
    237243                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
    238                                 makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isDynamicLayout, forward );
     244                                makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric, forward );
    239245                        } // if
    240246                } // for
     
    244250        /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields.
    245251        template<typename Iterator>
    246         void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout ) {
     252        void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric ) {
    247253                FunctionType * ftype = func->get_functionType();
    248254                std::list<DeclarationWithType*> & params = ftype->get_parameters();
     
    270276                                        // matching parameter, initialize field with copy ctor
    271277                                        Expression *srcselect = new VariableExpr(*parameter);
    272                                         makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isDynamicLayout );
     278                                        makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric );
    273279                                        ++parameter;
    274280                                } else {
    275281                                        // no matching parameter, initialize field with default ctor
    276                                         makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isDynamicLayout );
     282                                        makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isGeneric );
    277283                                }
    278284                        }
     
    284290
    285291                // Make function polymorphic in same parameters as generic struct, if applicable
    286                 bool isDynamicLayout = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
     292                bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    287293                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    288294                std::list< Expression* > structParams;  // List of matching parameters to put on types
    289295                TypeSubstitution genericSubs; // Substitutions to make to member types of struct
    290296                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    291                         if ( (*param)->get_kind() == TypeDecl::Any ) isDynamicLayout = true;
     297                        isGeneric = true;
    292298                        TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    293299                        assignType->get_forall().push_back( typeParam );
     
    349355                        FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType->clone(), new CompoundStmt( noLabels ), true, false );
    350356                        ctor->fixUniqueId();
    351                         makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isDynamicLayout );
     357                        makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isGeneric );
    352358                        memCtors.push_back( ctor );
    353359                }
     
    355361
    356362                // generate appropriate calls to member ctor, assignment
    357                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, isDynamicLayout );
    358                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, genericSubs, isDynamicLayout );
    359                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, genericSubs, isDynamicLayout );
     363                makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, isGeneric );
     364                makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, genericSubs, isGeneric );
     365                makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, genericSubs, isGeneric );
    360366                // needs to do everything in reverse, so pass "forward" as false
    361                 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, genericSubs, isDynamicLayout, false );
    362 
    363                 if ( ! isDynamicLayout ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     367                makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, genericSubs, isGeneric, false );
     368
     369                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    364370
    365371                declsToAdd.push_back( assignDecl );
     
    374380
    375381                // Make function polymorphic in same parameters as generic union, if applicable
    376                 bool isDynamicLayout = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
     382                bool isGeneric = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
    377383                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    378384                std::list< Expression* > unionParams;  // List of matching parameters to put on types
    379385                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    380                         if ( (*param)->get_kind() == TypeDecl::Any ) isDynamicLayout = true;
     386                        isGeneric = true;
    381387                        TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    382388                        assignType->get_forall().push_back( typeParam );
     
    413419                dtorDecl->fixUniqueId();
    414420
    415                 makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( assignDecl->get_statements()->get_kids() ) );
    416                 if ( isDynamicLayout ) makeUnionFieldsAssignment( srcParam, returnVal, back_inserter( assignDecl->get_statements()->get_kids() ) );
     421                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
     422                if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    417423                else assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    418424
     
    434440                                ctor->fixUniqueId();
    435441
    436                                 makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( ctor->get_statements()->get_kids() ) );
     442                                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( ctor->get_statements()->get_kids() ) );
    437443                                memCtors.push_back( ctor );
    438444                                // only generate a ctor for the first field
Note: See TracChangeset for help on using the changeset viewer.