Changeset 49148d5


Ignore:
Timestamp:
Jul 12, 2017, 4:57:23 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
c5e3208
Parents:
a61ad31
Message:

Update autogen to generate ctor/dtor/assign with references

Location:
src/SymTab
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    ra61ad31 r49148d5  
    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 PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );
     127                ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
    128128                ftype->get_parameters().push_back( dstParam );
    129129
     
    298298        /// generates a single struct member operation (constructor call, destructor call, assignment call)
    299299        void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) {
    300                 ObjectDecl * returnVal = NULL;
    301                 if ( ! func->get_functionType()->get_returnVals().empty() ) {
    302                         returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() );
    303                 }
    304 
    305300                InitTweak::InitExpander srcParam( src );
    306301
    307                 // assign to destination (and return value if generic)
    308                 UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) );
    309                 Expression *dstselect = new MemberExpr( field, derefExpr );
     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() ) );
    310304                genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
    311 
    312                 if ( isDynamicLayout && returnVal ) {
    313                         // xxx - there used to be a dereference on returnVal, but this seems to have been wrong?
    314                         Expression *retselect = new MemberExpr( field, new VariableExpr( returnVal ) );
    315                         genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
    316                 } // if
    317305        }
    318306
     
    468456                                        // our inheritance model. I think the correct way to handle this is to
    469457                                        // cast the structure to the type of the member and let the resolver
    470                                         // figure out whether it's valid and have a pass afterwards that fixes
    471                                         // the assignment to use pointer arithmetic with the offset of the
    472                                         // member, much like how generic type members are handled.
     458                                        // figure out whether it's valid/choose the correct unnamed member
    473459                                        continue;
    474460                                }
     
    486472        void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) {
    487473                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    488                 copy->get_args().push_back( new VariableExpr( dstParam ) );
     474                copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) );
    489475                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    490476                copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) );
     
    498484                ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() );
    499485                ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() );
    500                 ObjectDecl * returnVal = nullptr;
    501                 if ( ! ftype->get_returnVals().empty() ) {
    502                         returnVal = safe_dynamic_cast< ObjectDecl * >( ftype->get_returnVals().front() );
    503                 }
    504486
    505487                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) );
    506                 if ( returnVal ) {
     488                if ( InitTweak::isAssignment( funcDecl->get_name() ) ) {
     489                        // also generate return statement in assignment
    507490                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    508491                }
     
    513496                // Make function polymorphic in same parameters as generic union, if applicable
    514497                const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions
    515                
     498
    516499                // default ctor/dtor need only first parameter
    517500                // void ?{}(T *); void ^?{}(T *);
  • src/SymTab/Autogen.h

    ra61ad31 r49148d5  
    4343        template< typename OutputIterator >
    4444        Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) {
    45         // want to be able to generate assignment, ctor, and dtor generically,
    46         // so fname is either ?=?, ?{}, or ^?{}
    47         UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
     45                // want to be able to generate assignment, ctor, and dtor generically,
     46                // so fname is either ?=?, ?{}, or ^?{}
     47                UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    4848
    49         // do something special for unnamed members
    50         dstParam = new AddressExpr( dstParam );
    51         if ( addCast ) {
    52                 // cast to T* with qualifiers removed, so that qualified objects can be constructed
    53                 // and destructed with the same functions as non-qualified objects.
    54                 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
    55                 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
    56                 // remove lvalue as a qualifier, this can change to
    57                 //   type->get_qualifiers() = Type::Qualifiers();
    58                 assert( type );
    59                 Type * castType = type->clone();
    60                 castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    61                 castType->set_lvalue( true ); // xxx - might not need this
    62                 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
    63         }
    64         fExpr->get_args().push_back( dstParam );
     49                if ( addCast ) {
     50                        // cast to T& with qualifiers removed, so that qualified objects can be constructed
     51                        // and destructed with the same functions as non-qualified objects.
     52                        // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument
     53                        // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever
     54                        // remove lvalue as a qualifier, this can change to
     55                        //   type->get_qualifiers() = Type::Qualifiers();
     56                        assert( type );
     57                        Type * castType = type->clone();
     58                        castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     59                        // castType->set_lvalue( true ); // xxx - might not need this
     60                        dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) );
     61                }
     62                fExpr->get_args().push_back( dstParam );
    6563
    66         Statement * listInit = srcParam.buildListInit( fExpr );
     64                Statement * listInit = srcParam.buildListInit( fExpr );
    6765
    68         std::list< Expression * > args = *++srcParam;
    69         fExpr->get_args().splice( fExpr->get_args().end(), args );
     66                std::list< Expression * > args = *++srcParam;
     67                fExpr->get_args().splice( fExpr->get_args().end(), args );
    7068
    71         *out++ = new ExprStmt( noLabels, fExpr );
     69                *out++ = new ExprStmt( noLabels, fExpr );
    7270
    73         srcParam.clearArrayIndices();
     71                srcParam.clearArrayIndices();
    7472
    75         return listInit;
     73                return listInit;
    7674        }
    7775
     
    109107
    110108                UntypedExpr *inc = new UntypedExpr( update );
    111                 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     109                inc->get_args().push_back( new VariableExpr( index ) );
    112110
    113111                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
Note: See TracChangeset for help on using the changeset viewer.