Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r49148d5 rfa4805f  
    125125        FunctionType * genDefaultType( Type * paramType ) {
    126126                FunctionType *ftype = new FunctionType( Type::Qualifiers(), false );
    127                 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
     127                ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );
    128128                ftype->get_parameters().push_back( dstParam );
    129129
     
    176176                        FunctionType * ftype = funcDecl->get_functionType();
    177177                        assert( ! ftype->get_parameters().empty() );
    178                         Type * t = InitTweak::getPointerBase( ftype->get_parameters().front()->get_type() );
    179                         assert( t );
     178                        Type * t = safe_dynamic_cast< PointerType * >( ftype->get_parameters().front()->get_type() )->get_base();
    180179                        map.insert( Mangler::mangleType( t ), true );
    181180                }
     
    298297        /// generates a single struct member operation (constructor call, destructor call, assignment call)
    299298        void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) {
     299                ObjectDecl * returnVal = NULL;
     300                if ( ! func->get_functionType()->get_returnVals().empty() ) {
     301                        returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
     302                }
     303
    300304                InitTweak::InitExpander srcParam( src );
    301305
    302                 // assign to destination
    303                 Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), safe_dynamic_cast< ReferenceType* >( dstParam->get_type() )->get_base()->clone() ) );
     306                // assign to destination (and return value if generic)
     307                UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) );
     308                Expression *dstselect = new MemberExpr( field, derefExpr );
    304309                genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
     310
     311                if ( isDynamicLayout && returnVal ) {
     312                        // xxx - there used to be a dereference on returnVal, but this seems to have been wrong?
     313                        Expression *retselect = new MemberExpr( field, new VariableExpr( returnVal ) );
     314                        genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
     315                } // if
    305316        }
    306317
     
    456467                                        // our inheritance model. I think the correct way to handle this is to
    457468                                        // cast the structure to the type of the member and let the resolver
    458                                         // figure out whether it's valid/choose the correct unnamed member
     469                                        // figure out whether it's valid and have a pass afterwards that fixes
     470                                        // the assignment to use pointer arithmetic with the offset of the
     471                                        // member, much like how generic type members are handled.
    459472                                        continue;
    460473                                }
     
    472485        void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {
    473486                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    474                 copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) );
     487                copy->get_args().push_back( new VariableExpr( dstParam ) );
    475488                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    476489                copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
     
    484497                ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() );
    485498                ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() );
     499                ObjectDecl * returnVal = nullptr;
     500                if ( ! ftype->get_returnVals().empty() ) {
     501                        returnVal = safe_dynamic_cast< ObjectDecl * >( ftype->get_returnVals().front() );
     502                }
    486503
    487504                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) );
    488                 if ( InitTweak::isAssignment( funcDecl->get_name() ) ) {
    489                         // also generate return statement in assignment
     505                if ( returnVal ) {
    490506                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    491507                }
     
    496512                // Make function polymorphic in same parameters as generic union, if applicable
    497513                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    498 
     514               
    499515                // default ctor/dtor need only first parameter
    500516                // void ?{}(T *); void ^?{}(T *);
Note: See TracChangeset for help on using the changeset viewer.