Changeset 4ef7506


Ignore:
Timestamp:
Jan 22, 2016, 11:00:19 AM (9 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
4a79e3c9
Parents:
567bb17
Message:

Kludge auto-generated assignment operator for generic types into playing nice with existing signature by doing explicit double-copy

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    r567bb17 r4ef7506  
    585585        }
    586586
     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
    587597        //E ?=?(E volatile*, int),
    588598        //  ?=?(E _Atomic volatile*, int);
     
    653663
    654664                // Make function polymorphic in same parameters as generic struct, if applicable
     665                bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    655666                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    656667                std::list< Expression* > structParams;  // List of matching parameters to put on types
    657668                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
     669                        isGeneric = true;
    658670                        TypeDecl *typeParam = (*param)->clone();
    659671                        assignType->get_forall().push_back( typeParam );
     
    661673                }
    662674
    663                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
     675                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    664676                assignType->get_returnVals().push_back( returnVal );
    665677
     
    691703                                if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    692704                                        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() ) );
    693706                                } else {
    694707                                        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() ) );
    695709                                } // if
    696710                        } // if
    697711                } // for
    698                 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     712                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    699713
    700714                return assignDecl;
     
    705719
    706720                // Make function polymorphic in same parameters as generic union, if applicable
     721                bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
    707722                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    708723                std::list< Expression* > unionParams;  // List of matching parameters to put on types
    709724                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
     725                        isGeneric = true;
    710726                        TypeDecl *typeParam = (*param)->clone();
    711727                        assignType->get_forall().push_back( typeParam );
     
    713729                }
    714730
    715                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
     731                ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    716732                assignType->get_returnVals().push_back( returnVal );
    717733
     
    727743                assignDecl->fixUniqueId();
    728744
    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 ) ) );
     745                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
     746                if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
     747               
     748                if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    736749
    737750                return assignDecl;
Note: See TracChangeset for help on using the changeset viewer.