Ticket #133: copy-update.diff

File copy-update.diff, 15.4 KB (added by ajbeach, 4 months ago)

Diff from attempt to make this change.

  • libcfa/prelude/prelude-gen.cc

    diff --git a/libcfa/prelude/prelude-gen.cc b/libcfa/prelude/prelude-gen.cc
    index 2fe54ca11..90ffeb8a2 100644
    a b int main() {  
    205205        cout << "/////////////////////////////" << endl;
    206206        cout << endl;
    207207
    208         auto otype = [](const std::string & type, bool do_volatile = false) {
     208        // The general pattern for arithmetic types.
     209        auto arithmetic = [](const std::string & type,
     210                        bool do_zero_one = true, bool do_volatile = false) {
    209211                cout << "void ?{} (" << type << " &);" << endl;
    210                 cout << "void ?{} (" << type << " &, " << type << ");" << endl;
    211                 cout << type << " ?=? (" << type << " &, " << type << ")";
     212                cout << "void ?{} (" << type << " &, " << type << " const &);" << endl;
     213                cout << type << " & ?=? (" << type << " &, " << type << " const &)";
    212214                if ( do_volatile ) {
    213                         cout << ", ?=?(volatile " << type << " &, " << type << ")";
     215                        cout << ", ?=?(volatile " << type << " &, " << type << " const &)";
    214216                }
    215217                cout << ";" << endl;
    216                 cout << "void ^?{}( " << type << " & );" << endl;
     218                if ( do_zero_one ) {
     219                        cout << "void ?{}(" << type << " &, zero_t);" << endl;
     220                        cout << "void ?{}(" << type << " &, one_t);" << endl;
     221                }
     222                cout << "void ^?{}(" << type << " &);" << endl;
    217223        };
    218224
    219         otype("zero_t");
     225        arithmetic("zero_t", false);
    220226        cout << endl;
    221         otype("one_t");
     227        arithmetic("one_t", false);
    222228        cout << endl;
    223         otype("_Bool", true);
     229        arithmetic("_Bool", false, true);
    224230        cout << endl;
    225231
    226232        for (auto type : basicTypes) {
    227                 cout << "void ?{}(" << type.name << " &);" << endl;
    228                 cout << "void ?{}(" << type.name << " &, " << type.name << ");" << endl;
    229                 cout << "void ?{}(" << type.name << " &, zero_t);" << endl;
    230                 cout << "void ?{}(" << type.name << " &, one_t);" << endl;
    231                 cout << "void ^?{}(" << type.name << " &);" << endl;
     233                arithmetic(type.name);
    232234                cout << endl;
    233235        }
    234236        cout << endl;
    int main() {  
    238240        cout << "//////////////////////////" << endl;
    239241        cout << endl;
    240242
    241         cout << "forall(ftype FT) void ?{}( FT *&, FT * );" << endl;
    242         cout << "forall(ftype FT) void ?{}( FT * volatile &, FT * );" << endl;
     243        cout << "forall(ftype FT) void ?{}( FT *&, FT * const & );" << endl;
     244        cout << "forall(ftype FT) void ?{}( FT * volatile &, FT * const & );" << endl;
    243245
    244246        // generate qualifiers
    245247        vector<string> qualifiersSingle;
    int main() {  
    263265        for (auto type : { "  DT", "void" }) {
    264266                for (auto cvq : qualifiersPair) {
    265267                        for (auto is_vol : { "        ", "volatile" }) {
    266                                 cout << "forall(DT &) void  ?{}(" << cvq.first << type << " * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
     268                                cout << "forall(DT &) void  ?{}(" << cvq.first << type << " * " << is_vol << " &, " << cvq.second << "DT * const &);" << endl;
    267269                        }
    268270                }
    269271        }
    int main() {  
    297299        cout << endl;
    298300
    299301        cout << "forall(ftype FT) void  ?{}( FT *          &, zero_t );" << endl;
    300         cout << "forall(ftype FT) FT *                  ?=?( FT *          &, zero_t );" << endl;
    301         cout << "forall(ftype FT) FT *                  ?=?( FT * volatile &, zero_t );" << endl;
     302        cout << "forall(ftype FT) FT *&                 ?=?( FT *          &, zero_t const & );" << endl;
     303        cout << "forall(ftype FT) FT *&                 ?=?( FT * volatile &, zero_t const & );" << endl;
    302304        cout << "forall(ftype FT) void  ?{}( FT *          & );" << endl;
    303305        cout << "forall(ftype FT) void  ^?{}( FT *         & );" << endl;
    304306        cout << endl;
    int main() {  
    307309        cout << "// Pointer Operators //" << endl;
    308310        cout << "///////////////////////" << endl;
    309311
    310         cout << "forall(ftype FT) FT *                  ?=?( FT *&, FT * );" << endl;
    311         cout << "forall(ftype FT) FT *                  ?=?( FT * volatile &, FT * );" << endl;
     312        cout << "forall(ftype FT) FT *&                 ?=?( FT *&, FT * const &);" << endl;
     313        cout << "forall(ftype FT) FT *&                 ?=?( FT * volatile &, FT * const &);" << endl;
    312314        cout << "forall(ftype FT) int !?( FT * );" << endl;
    313315        cout << "forall(ftype FT) signed int ?==?( FT *, FT * );" << endl;
    314316        cout << "forall(ftype FT) signed int ?!=?( FT *, FT * );" << endl;
    int main() {  
    328330                                                        for (auto q : qualifiersSingle){
    329331                                                                for (auto q2 : { "        ", "volatile" }) {
    330332                                                                        forall();
    331                                                                         cout << q << type << " * " << op.name << "(";
     333                                                                        cout << q << type << " * &" << op.name << "(";
    332334                                                                        cout << q << type << " * " << q2 << " &";
    333335                                                                        cout << ");" << endl;
    334336                                                                }
    int main() {  
    337339                                                        for (auto q : qualifiersPair){
    338340                                                                for (auto q2 : { "        ", "volatile" }) {
    339341                                                                        forall();
    340                                                                         cout << q.first << type << " * " << op.name << "(";
     342                                                                        cout << q.first << type << " * &" << op.name << "(";
    341343                                                                        cout << q.first << type << " * " << q2 << " &";
    342344
    343345                                                                        for (int i = 1; i < operands; ++i) {
    344                                                                                 cout << ", " << q.second << type << " *";
     346                                                                                cout << ", " << q.second << type << " * " << q2 << " const &";
    345347                                                                        }
    346348                                                                        cout << ");" << endl;
    347349                                                                }
    int main() {  
    407409
    408410        for (auto is_vol : { "        ", "volatile" }) {
    409411                for (auto cvq : qualifiersPair) {
    410                                 cout << "forall(DT &) " << cvq.first << "void * ?=?( " << cvq.first << "void * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
     412                                cout << "forall(DT &) " << cvq.first << "void *& ?=?( " << cvq.first << "void * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
    411413                }
    412414                for (auto cvq : qualifiersSingle) {
    413                         cout << "forall(DT &) " << cvq <<   "  DT * ?=?( " << cvq << "  DT * " << is_vol << " &, zero_t);" << endl;
     415                        cout << "forall(DT &) " << cvq <<   "  DT *& ?=?( " << cvq << "  DT * " << is_vol << " &, zero_t);" << endl;
    414416                }
    415417        }
    416418        cout << endl;
  • src/GenPoly/Lvalue.cpp

    diff --git a/src/GenPoly/Lvalue.cpp b/src/GenPoly/Lvalue.cpp
    index a2e83f512..f2c09b326 100644
    a b struct CollapseAddressDeref final {  
    103103        ast::Expr const * postvisit( ast::ApplicationExpr const * expr );
    104104};
    105105
     106struct RValueCastAdjustment final {
     107        ast::Expr const * postvisit( ast::AddressExpr const * expr );
     108};
     109
    106110/// GCC-like Generalized Lvalues (which have since been removed from GCC).
    107111/// https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Lvalues.html#Lvalues
    108112/// Replaces &(a,b) with (a, &b), &(a ? b : c) with (a ? &b : &c)
    ast::Expr const * CollapseAddressDeref::postvisit(  
    533537                        ret->env = expr->env;
    534538                        return ret;
    535539                }
    536         } else {
    537                 return moveAddressUnderCast( expr );
    538540        }
    539541        return expr;
    540542}
    ast::Expr const * CollapseAddressDeref::postvisit(  
    560562        return expr;
    561563}
    562564
     565ast::Expr const * RValueCastAdjustment::postvisit(
     566                ast::AddressExpr const * expr ) {
     567        return moveAddressUnderCast( expr );
     568}
     569
    563570ast::Expr const * GeneralizedLvalue::postvisit(
    564571                ast::AddressExpr const * expr ) {
    565572        return applyTransformation( expr, &ast::AddressExpr::arg,
    void convertLvalue( ast::TranslationUnit & translationUnit ) {  
    639646        ast::Pass<ReferenceConversions>::run( translationUnit );
    640647        ast::Pass<FixIntrinsicArgs>::run( translationUnit );
    641648        ast::Pass<CollapseAddressDeref>::run( translationUnit );
     649        ast::Pass<RValueCastAdjustment>::run( translationUnit );
    642650        ast::Pass<GeneralizedLvalue>::run( translationUnit );
    643651        // Last because other passes need reference types to work.
    644652        ast::Pass<ReferenceTypeElimination>::run( translationUnit );
  • src/InitTweak/FixInit.cpp

    diff --git a/src/InitTweak/FixInit.cpp b/src/InitTweak/FixInit.cpp
    index 5304dcda6..6657b3668 100644
    a b const ast::DeclWithType * FixInit::postvisit( const ast::ObjectDecl *_objDecl )  
    912912                                // ctorCall should be gone afterwards
    913913                                auto mutArg = mutate(ctorArg);
    914914                                mutArg->env = ctorCall->env;
     915                                // TODO: Get rid of layer of reference.
     916                                if ( auto cast = dynamic_cast<ast::CastExpr *>( mutArg ) ) {
     917                                        if ( auto refType = cast->result.as<ast::ReferenceType>() ) {
     918                                                cast->result = refType->base;
     919                                                mutArg = cast;
     920                                        }
     921                                }
    915922                                objDecl->init = new ast::SingleInit(loc, mutArg );
    916923                        } else {
    917924                                stmtsToAddAfter.push_back( ctor );
  • src/InitTweak/InitTweak.cpp

    diff --git a/src/InitTweak/InitTweak.cpp b/src/InitTweak/InitTweak.cpp
    index b0c932ecd..a1ae61dab 100644
    a b bool isCopyFunction( const ast::FunctionDecl * decl ) {  
    319319
    320320        const ast::Type * t1 = ast::getPointerBase( ftype->params.front() );
    321321        if ( ! t1 ) return false;
    322         const ast::Type * t2 = ftype->params.back();
     322        const ast::Type * t2 = ast::getPointerBase( ftype->params.back() );
     323        if ( ! t2 ) return false;
    323324
    324325        return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2 );
    325326}
  • src/Parser/TypeData.cpp

    diff --git a/src/Parser/TypeData.cpp b/src/Parser/TypeData.cpp
    index 135a0331d..5d7d3077c 100644
    a b void buildForall(  
    731731                const CodeLocation & location = mutTypeDecl->location;
    732732                *i = mutTypeDecl;
    733733
    734                 // add assertion parameters to `type' tyvars in reverse order
    735                 // add assignment operator:  T * ?=?(T *, T)
     734                // TODO: Helper functions!
     735
     736                ast::TypeInstType * mut0 = ast::shallowCopy( i->get() );
     737                mut0->set_const( true );
     738
     739                // Add assertion parameters to `type' tyvars in reverse order:
     740                // Add assignment operator:  T & ?=?(T &, T const &)
    736741                newAssertions.push_back( new ast::FunctionDecl(
    737742                        location,
    738743                        "?=?",
    void buildForall(  
    749754                                new ast::ObjectDecl(
    750755                                        location,
    751756                                        "",
    752                                         i->get(),
     757                                        new ast::ReferenceType( mut0 ),
    753758                                        (ast::Init *)nullptr,
    754759                                        ast::Storage::Classes(),
    755760                                        ast::Linkage::Cforall,
    void buildForall(  
    760765                                new ast::ObjectDecl(
    761766                                        location,
    762767                                        "",
    763                                         i->get(),
     768                                        new ast::ReferenceType( i->get() ),
    764769                                        (ast::Init *)nullptr,
    765770                                        ast::Storage::Classes(),
    766771                                        ast::Linkage::Cforall,
    void buildForall(  
    772777                        ast::Linkage::Cforall
    773778                ) );
    774779
    775                 // add default ctor:  void ?{}(T *)
     780                // Add default ctor:  void ?{}(T &)
    776781                newAssertions.push_back( new ast::FunctionDecl(
    777782                        location,
    778783                        "?{}",
    void buildForall(  
    793798                        ast::Linkage::Cforall
    794799                ) );
    795800
    796                 // add copy ctor:  void ?{}(T *, T)
     801                // Add copy ctor:  void ?{}(T &, T const &)
    797802                newAssertions.push_back( new ast::FunctionDecl(
    798803                        location,
    799804                        "?{}",
    void buildForall(  
    810815                                new ast::ObjectDecl(
    811816                                        location,
    812817                                        "",
    813                                         i->get(),
     818                                        new ast::ReferenceType( mut0 ),
    814819                                        (ast::Init *)nullptr,
    815820                                        ast::Storage::Classes(),
    816821                                        ast::Linkage::Cforall,
    void buildForall(  
    823828                        ast::Linkage::Cforall
    824829                ) );
    825830
    826                 // add dtor:  void ^?{}(T *)
     831                // Add dtor:  void ^?{}(T &)
    827832                newAssertions.push_back( new ast::FunctionDecl(
    828833                        location,
    829834                        "^?{}",
    void buildForall(  
    868873                const CodeLocation & location = mutTypeDecl->location;
    869874                *i = mutTypeDecl;
    870875
    871                 // add assertion parameters to `type' tyvars in reverse order
    872                 // add assignment operator:  T * ?=?(T *, T)
     876                // TODO: Helper functions!
     877
     878                // Add assertion parameters to `type' tyvars in reverse order:
     879                // Add assignment operator:  T & ?=?(T &, T const &)
    873880                newAssertions.push_back( new ast::FunctionDecl(
    874881                        location,
    875882                        "?=?",
    void buildForall(  
    886893                                new ast::ObjectDecl(
    887894                                        location,
    888895                                        "",
    889                                         new ast::TypeInstType( td->name, *i ),
     896                                        new ast::ReferenceType(
     897                                                new ast::TypeInstType( td->name, *i, ast::CV::Const ) ),
    890898                                        (ast::Init *)nullptr,
    891899                                        ast::Storage::Classes(),
    892900                                        ast::Linkage::Cforall,
    void buildForall(  
    897905                                new ast::ObjectDecl(
    898906                                        location,
    899907                                        "",
    900                                         new ast::TypeInstType( td->name, *i ),
     908                                        new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
    901909                                        (ast::Init *)nullptr,
    902910                                        ast::Storage::Classes(),
    903911                                        ast::Linkage::Cforall,
    void buildForall(  
    909917                        ast::Linkage::Cforall
    910918                ) );
    911919
    912                 // add default ctor:  void ?{}(T *)
     920                // add default ctor:  void ?{}(T &)
    913921                newAssertions.push_back( new ast::FunctionDecl(
    914922                        location,
    915923                        "?{}",
    void buildForall(  
    931939                        ast::Linkage::Cforall
    932940                ) );
    933941
    934                 // add copy ctor:  void ?{}(T *, T)
     942                // Add copy ctor:  void ?{}(T &, T const &)
    935943                newAssertions.push_back( new ast::FunctionDecl(
    936944                        location,
    937945                        "?{}",
    void buildForall(  
    949957                                new ast::ObjectDecl(
    950958                                        location,
    951959                                        "",
    952                                         new ast::TypeInstType( td->name, *i ),
     960                                        new ast::ReferenceType(
     961                                                new ast::TypeInstType( td->name, *i, ast::CV::Const ) ),
    953962                                        (ast::Init *)nullptr,
    954963                                        ast::Storage::Classes(),
    955964                                        ast::Linkage::Cforall,
    void buildForall(  
    962971                        ast::Linkage::Cforall
    963972                ) );
    964973
    965                 // add dtor:  void ^?{}(T *)
     974                // Add dtor:  void ^?{}(T &)
    966975                newAssertions.push_back( new ast::FunctionDecl(
    967976                        location,
    968977                        "^?{}",
  • src/Validate/Autogen.cpp

    diff --git a/src/Validate/Autogen.cpp b/src/Validate/Autogen.cpp
    index 4f753fed5..ce0a5a701 100644
    a b ast::ObjectDecl * FuncGenerator::dstParam() const {  
    378378}
    379379
    380380ast::ObjectDecl * FuncGenerator::srcParam() const {
     381        ast::ptr<ast::Type> srcType = ast::deepCopy( type );
     382        add_qualifiers( srcType, { ast::CV::Const } );
    381383        return addUnusedAttribute(
    382384                new ast::ObjectDecl( getLocation(), "_src",
    383                         ast::deepCopy( type ) ) );
     385                        new ast::ReferenceType( srcType.release() ) ) );
    384386}
    385387
    386388/// Use the current type T to create `void ?{}(T & _dst)`.
    ast::FunctionDecl * FuncGenerator::genCtorProto() const {  
    388390        return genProto( "?{}", { dstParam() }, {} );
    389391}
    390392
    391 /// Use the current type T to create `void ?{}(T & _dst, T _src)`.
     393/// Use the current type T to create `void ?{}(T & _dst, T const & _src)`.
    392394ast::FunctionDecl * FuncGenerator::genCopyProto() const {
    393395        return genProto( "?{}", { dstParam(), srcParam() }, {} );
    394396}
    ast::FunctionDecl * FuncGenerator::genDtorProto() const {  
    403405        return genProto( "^?{}", { dst }, {} );
    404406}
    405407
    406 /// Use the current type T to create `T ?=?(T & _dst, T _src)`.
     408/// Use the current type T to create `T & ?=?(T & _dst, T const & _src)`.
    407409ast::FunctionDecl * FuncGenerator::genAssignProto() const {
    408410        // Only the name is different, so just reuse the generation function.
    409         auto retval = srcParam();
     411        auto retval = dstParam();
    410412        retval->name = "_ret";
    411413        return genProto( "?=?", { dstParam(), srcParam() }, { retval } );
    412414}
    void StructFuncGenerator::makeFunctionBody( Iterator current, Iterator end,  
    549551
    550552        ast::CompoundStmt * stmts = new ast::CompoundStmt( location );
    551553
     554        assert( !func->params.empty() );
     555        const ast::ObjectDecl * dstParam =
     556                func->params.front().strict_as<ast::ObjectDecl>();
     557        const ast::ObjectDecl * srcParam = nullptr;
     558        if ( 2 == func->params.size() ) {
     559                srcParam = func->params.back().strict_as<ast::ObjectDecl>();
     560        }
     561
    552562        for ( ; current != end ; ++current ) {
    553563                const ast::ptr<ast::Decl> & member = *current;
    554564                auto field = member.as<ast::ObjectDecl>();
    void StructFuncGenerator::makeFunctionBody( Iterator current, Iterator end,  
    568578                        }
    569579                }
    570580
    571                 assert( !func->params.empty() );
    572                 const ast::ObjectDecl * dstParam =
    573                         func->params.front().strict_as<ast::ObjectDecl>();
    574                 const ast::ObjectDecl * srcParam = nullptr;
    575                 if ( 2 == func->params.size() ) {
    576                         srcParam = func->params.back().strict_as<ast::ObjectDecl>();
    577                 }
     581                ast::MemberExpr * srcSelect = (!srcParam) ? nullptr :
     582                        new ast::MemberExpr(
     583                                location,
     584                                field,
     585                                new ast::CastExpr(
     586                                        location,
     587                                        new ast::VariableExpr( location, srcParam ),
     588                                        srcParam->type.strict_as<ast::ReferenceType>()->base
     589                                )
     590                        );
    578591
    579                 ast::MemberExpr * srcSelect = (srcParam) ? new ast::MemberExpr(
    580                         location, field, new ast::VariableExpr( location, srcParam )
    581                 ) : nullptr;
    582592                const ast::Stmt * stmt =
    583593                        makeMemberOp( location, dstParam, srcSelect, field, func, direction );
    584594