Ignore:
Timestamp:
Oct 19, 2017, 12:01:04 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
837ce06
Parents:
b96ec83 (diff), a15b72c (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' into cleanup-dtors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    rb96ec83 r6840e7c  
    8585                // should not have a ConstructorInit generated.
    8686
    87                 bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed
    88                 bool isManaged( Type * type ) const; // determine if type is managed
    89                 void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor
    90                 GenPoly::ScopedSet< std::string > managedTypes;
     87                ManagedTypes managedTypes;
    9188                bool inFunction = false;
    9289        };
     
    129126                // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address
    130127                // is being returned
    131                 if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
     128                if ( returnStmt->expr && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) {
    132129                        // explicitly construct the return value using the return expression and the retVal object
    133                         assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
    134 
    135                         stmtsToAddBefore.push_back( genCtorDtor( "?{}", dynamic_cast< ObjectDecl *>( returnVals.front() ), returnStmt->get_expr() ) );
     130                        assertf( returnVals.front()->name != "", "Function %s has unnamed return value\n", funcName.c_str() );
     131
     132                        ObjectDecl * retVal = strict_dynamic_cast< ObjectDecl * >( returnVals.front() );
     133                        if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( returnStmt->expr ) ) {
     134                                // return statement has already been mutated - don't need to do it again
     135                                if ( varExpr->var == retVal ) return;
     136                        }
     137                        stmtsToAddBefore.push_back( genCtorDtor( "?{}", retVal, returnStmt->get_expr() ) );
    136138
    137139                        // return the retVal object
    138                         returnStmt->set_expr( new VariableExpr( returnVals.front() ) );
     140                        returnStmt->expr = new VariableExpr( returnVals.front() );
    139141                } // if
    140142        }
     
    199201        }
    200202
    201         bool CtorDtor::isManaged( Type * type ) const {
     203        bool ManagedTypes::isManaged( Type * type ) const {
    202204                // references are never constructed
    203205                if ( dynamic_cast< ReferenceType * >( type ) ) return false;
     
    215217        }
    216218
    217         bool CtorDtor::isManaged( ObjectDecl * objDecl ) const {
     219        bool ManagedTypes::isManaged( ObjectDecl * objDecl ) const {
    218220                Type * type = objDecl->get_type();
    219221                while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     
    223225        }
    224226
    225         void CtorDtor::handleDWT( DeclarationWithType * dwt ) {
     227        void ManagedTypes::handleDWT( DeclarationWithType * dwt ) {
    226228                // if this function is a user-defined constructor or destructor, mark down the type as "managed"
    227229                if ( ! LinkageSpec::isOverridable( dwt->get_linkage() ) && CodeGen::isCtorDtor( dwt->get_name() ) ) {
     
    233235                }
    234236        }
     237
     238        void ManagedTypes::handleStruct( StructDecl * aggregateDecl ) {
     239                // don't construct members, but need to take note if there is a managed member,
     240                // because that means that this type is also managed
     241                for ( Declaration * member : aggregateDecl->get_members() ) {
     242                        if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
     243                                if ( isManaged( field ) ) {
     244                                        StructInstType inst( Type::Qualifiers(), aggregateDecl );
     245                                        managedTypes.insert( SymTab::Mangler::mangle( &inst ) );
     246                                        break;
     247                                }
     248                        }
     249                }
     250        }
     251
     252        void ManagedTypes::beginScope() { managedTypes.beginScope(); }
     253        void ManagedTypes::endScope() { managedTypes.endScope(); }
    235254
    236255        ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) {
     
    277296
    278297        void CtorDtor::previsit( ObjectDecl * objDecl ) {
    279                 handleDWT( objDecl );
     298                managedTypes.handleDWT( objDecl );
    280299                // hands off if @=, extern, builtin, etc.
    281300                // even if unmanaged, try to construct global or static if initializer is not constexpr, since this is not legal C
    282                 if ( tryConstruct( objDecl ) && ( isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {
     301                if ( tryConstruct( objDecl ) && ( managedTypes.isManaged( objDecl ) || ((! inFunction || objDecl->get_storageClasses().is_static ) && ! isConstExpr( objDecl->get_init() ) ) ) ) {
    283302                        // constructed objects cannot be designated
    284303                        if ( isDesignated( objDecl->get_init() ) ) throw SemanticError( "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n", objDecl );
     
    295314                inFunction = true;
    296315
    297                 handleDWT( functionDecl );
     316                managedTypes.handleDWT( functionDecl );
    298317
    299318                GuardScope( managedTypes );
     
    301320                for ( auto & tyDecl : functionDecl->get_functionType()->get_forall() ) {
    302321                        for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) {
    303                                 handleDWT( assertion );
     322                                managedTypes.handleDWT( assertion );
    304323                        }
    305324                }
     
    311330                visit_children = false; // do not try to construct and destruct aggregate members
    312331
    313                 // don't construct members, but need to take note if there is a managed member,
    314                 // because that means that this type is also managed
    315                 for ( Declaration * member : aggregateDecl->get_members() ) {
    316                         if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
    317                                 if ( isManaged( field ) ) {
    318                                         StructInstType inst( Type::Qualifiers(), aggregateDecl );
    319                                         managedTypes.insert( SymTab::Mangler::mangle( &inst ) );
    320                                         break;
    321                                 }
    322                         }
    323                 }
     332                managedTypes.handleStruct( aggregateDecl );
    324333        }
    325334
Note: See TracChangeset for help on using the changeset viewer.