Ignore:
Timestamp:
Aug 16, 2016, 3:20:06 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
1f6d4624
Parents:
950f7a7 (diff), 7880579 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r950f7a7 r7527e63  
    2626
    2727namespace SymTab {
     28        Type * SizeType = 0;
     29
    2830        class AutogenerateRoutines : public Visitor {
    2931                public:
     
    5961        bool isUnnamedBitfield( ObjectDecl * obj ) {
    6062                return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;
    61         }
    62 
    63         template< typename OutputIterator >
    64         void makeScalarFunction( Expression *src, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {
    65                 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    66                 // unnamed bit fields are not copied as they cannot be accessed
    67                 if ( isUnnamedBitfield( obj ) ) return;
    68 
    69                 // want to be able to generate assignment, ctor, and dtor generically,
    70                 // so fname is either ?=?, ?{}, or ^?{}
    71                 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );
    72 
    73                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    74                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    75 
    76                 // do something special for unnamed members
    77                 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    78                 fExpr->get_args().push_back( dstselect );
    79 
    80                 if ( src ) {
    81                         fExpr->get_args().push_back( src );
    82                 }
    83 
    84                 Statement * callStmt = new ExprStmt( noLabels, fExpr );
    85                 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) {
    86                         // implicitly generated ctor/dtor calls should be wrapped
    87                         // so that later passes are aware they were generated.
    88                         // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,
    89                         // because this causes the address to be taken at codegen, which is illegal in C.
    90                         callStmt = new ImplicitCtorDtorStmt( callStmt );
    91                 }
    92                 *out++ = callStmt;
    9363        }
    9464
     
    203173        }
    204174
    205         void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
    206                 if ( isGeneric ) {
    207                         // rewrite member type in terms of the type variables on this operator
    208                         field = field->clone();
    209                         genericSubs.apply( field );
    210 
    211                         if ( src ) {
    212                                 genericSubs.apply( src );
    213                         }
    214                 }
     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//              }
    215179
    216180                ObjectDecl * returnVal = NULL;
     
    219183                }
    220184
     185                InitTweak::InitExpander srcParam( src );
     186
    221187                // assign to destination (and return value if generic)
    222                 if ( ArrayType *array = dynamic_cast< ArrayType * >( field->get_type() ) ) {
    223                         UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    224                         derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    225                         Expression *dstselect = new MemberExpr( field, derefExpr );
    226 
    227                         makeArrayFunction( src, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
    228                         if ( isGeneric && returnVal ) {
    229                                 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
    230                                 derefRet->get_args().push_back( new VariableExpr( returnVal ) );
    231                                 Expression *retselect = new MemberExpr( field, derefRet );
    232 
    233                                 makeArrayFunction( src, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward );
    234                         }
    235                 } else {
    236                         makeScalarFunction( src, dstParam, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
    237                         if ( isGeneric && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) );
     188                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     189                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     190                Expression *dstselect = new MemberExpr( field, derefExpr );
     191                genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
     192
     193                if ( isDynamicLayout && returnVal ) {
     194                        UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) );
     195                        derefRet->get_args().push_back( new VariableExpr( returnVal ) );
     196                        Expression *retselect = new MemberExpr( field, derefRet );
     197                        genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );
    238198                } // if
    239199        }
    240200
    241201        template<typename Iterator>
    242         void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric, bool forward = true ) {
     202        void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout, bool forward = true ) {
    243203                for ( ; member != end; ++member ) {
    244204                        if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate
     
    276236
    277237                                Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;
    278                                 makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric, forward );
     238                                makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isDynamicLayout, forward );
    279239                        } // if
    280240                } // for
     
    284244        /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields.
    285245        template<typename Iterator>
    286         void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isGeneric ) {
     246        void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func, TypeSubstitution & genericSubs, bool isDynamicLayout ) {
    287247                FunctionType * ftype = func->get_functionType();
    288248                std::list<DeclarationWithType*> & params = ftype->get_parameters();
     
    310270                                        // matching parameter, initialize field with copy ctor
    311271                                        Expression *srcselect = new VariableExpr(*parameter);
    312                                         makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isGeneric );
     272                                        makeStructMemberOp( dstParam, srcselect, field, func, genericSubs, isDynamicLayout );
    313273                                        ++parameter;
    314274                                } else {
    315275                                        // no matching parameter, initialize field with default ctor
    316                                         makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isGeneric );
     276                                        makeStructMemberOp( dstParam, NULL, field, func, genericSubs, isDynamicLayout );
    317277                                }
    318278                        }
     
    324284
    325285                // Make function polymorphic in same parameters as generic struct, if applicable
    326                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
     286                bool isDynamicLayout = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    327287                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    328288                std::list< Expression* > structParams;  // List of matching parameters to put on types
    329289                TypeSubstitution genericSubs; // Substitutions to make to member types of struct
    330290                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    331                         isGeneric = true;
     291                        if ( (*param)->get_kind() == TypeDecl::Any ) isDynamicLayout = true;
    332292                        TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    333293                        assignType->get_forall().push_back( typeParam );
     
    389349                        FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType->clone(), new CompoundStmt( noLabels ), true, false );
    390350                        ctor->fixUniqueId();
    391                         makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isGeneric );
     351                        makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor, genericSubs, isDynamicLayout );
    392352                        memCtors.push_back( ctor );
    393353                }
     
    395355
    396356                // generate appropriate calls to member ctor, assignment
    397                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), assignDecl, genericSubs, isGeneric );
    398                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctorDecl, genericSubs, isGeneric );
    399                 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), copyCtorDecl, genericSubs, isGeneric );
     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 );
    400360                // needs to do everything in reverse, so pass "forward" as false
    401                 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dtorDecl, genericSubs, isGeneric, false );
    402 
    403                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     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 ) ) );
    404364
    405365                declsToAdd.push_back( assignDecl );
     
    414374
    415375                // Make function polymorphic in same parameters as generic union, if applicable
    416                 bool isGeneric = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
     376                bool isDynamicLayout = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
    417377                std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    418378                std::list< Expression* > unionParams;  // List of matching parameters to put on types
    419379                for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    420                         isGeneric = true;
     380                        if ( (*param)->get_kind() == TypeDecl::Any ) isDynamicLayout = true;
    421381                        TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    422382                        assignType->get_forall().push_back( typeParam );
     
    454414
    455415                makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    456                 if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    457 
    458                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     416                if ( isDynamicLayout ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
     417                else assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    459418
    460419                // body of assignment and copy ctor is the same
Note: See TracChangeset for help on using the changeset viewer.