Changeset 1ced874 for src/InitTweak


Ignore:
Timestamp:
Sep 6, 2016, 4:36:29 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
e76acbe
Parents:
0362d42 (diff), f04a8b81 (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 tuples

Location:
src/InitTweak
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r0362d42 r1ced874  
    200200                        ObjectDecl * thisParam = 0;
    201201                        bool isCtor = false; // true if current function is a constructor
     202                        StructDecl * structDecl = 0;
    202203                };
    203204
     
    744745                        ValueGuard< ObjectDecl * > oldThisParam( thisParam );
    745746                        ValueGuard< bool > oldIsCtor( isCtor );
     747                        ValueGuard< StructDecl * > oldStructDecl( structDecl );
    746748
    747749                        // need to start with fresh sets
     
    758760                                StructInstType * structType = dynamic_cast< StructInstType * >( ptrType->get_base() );
    759761                                if ( structType ) {
    760                                         StructDecl * structDecl = structType->get_baseStruct();
     762                                        structDecl = structType->get_baseStruct();
    761763                                        for ( Declaration * member : structDecl->get_members() ) {
    762764                                                if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
     
    775777                        std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ) );
    776778                        for ( DeclarationWithType * member : diff ) {
    777                                 emit( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", member ", member->get_name(), " used before being constructed" );
     779                                emit( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", field ", member->get_name(), " used before being constructed" );
    778780                        }
    779781
     
    781783                                // need to explicitly re-add function parameters in order to resolve copy constructors
    782784                                enterScope();
    783                                 // maybeAccept( function->get_functionType(), *this );
    784                                 for ( DeclarationWithType * member : unhandled ) {
    785                                         // insert and resolve default/copy constructor call for each member that's unhandled
     785                                maybeAccept( function->get_functionType(), *this );
     786
     787                                // need to iterate through members in reverse in order for
     788                                // ctor/dtor statements to come out in the right order
     789                                for ( Declaration * member : reverseIterate( structDecl->get_members() ) ) {
     790                                        DeclarationWithType * field = dynamic_cast< DeclarationWithType * >( member );
     791                                        // skip non-DWT members
     792                                        if ( ! field ) continue;
     793                                        // skip handled members
     794                                        if ( ! unhandled.count( field ) ) continue;
     795
     796                                        // insert and resolve default/copy constructor call for each field that's unhandled
    786797                                        std::list< Statement * > stmt;
    787798                                        UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
    788799                                        deref->get_args().push_back( new VariableExpr( thisParam ) );
    789                                         InitExpander srcParam( (Initializer *)NULL ); // xxx - if copy ctor, need to pass appropriate argument - second param of this function dot member
    790                                         SymTab::genImplicitCall( srcParam, new MemberExpr( member, deref ), function->get_name(), back_inserter( stmt ), member, isCtor );
     800
     801                                        Expression * arg2 = 0;
     802                                        if ( isCopyConstructor( function ) ) {
     803                                                // if copy ctor, need to pass second-param-of-this-function.field
     804                                                std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
     805                                                assert( params.size() == 2 );
     806                                                arg2 = new MemberExpr( field, new VariableExpr( params.back() ) );
     807                                        }
     808                                        InitExpander srcParam( arg2 );
     809                                        SymTab::genImplicitCall( srcParam, new MemberExpr( field, deref ), function->get_name(), back_inserter( stmt ), field, isCtor );
    791810
    792811                                        assert( stmt.size() <= 1 );
     
    796815                                                MutatingResolver resolver( *this );
    797816                                                try {
    798                                                         // xxx - these should be in field declaration order
    799817                                                        callStmt->acceptMutator( resolver );
    800818                                                        if ( isCtor ) {
     
    805823                                                        }
    806824                                                } catch ( SemanticError & error ) {
    807                                                         emit( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", member ", member->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed",  " and no ", isCtor ? "default constructor" : "destructor", " found" );
     825                                                        emit( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed",  " and no ", isCtor ? "default constructor" : "destructor", " found" );
    808826                                                }
    809827                                        }
     
    832850                                        handleFirstParam( firstParam );
    833851                                }
    834                         } else if ( fname == "?=?" && isIntrinsicCallExpr( appExpr ) ) {
    835                                 // forgive use of intrinsic assignment to construct, since instrinsic constructors
    836                                 // codegen as assignment anyway.
    837                                 assert( appExpr->get_args().size() == 2 );
    838                                 handleFirstParam( appExpr->get_args().front() );
    839852                        }
    840853
  • src/InitTweak/GenInit.cc

    r0362d42 r1ced874  
    2525#include "SynTree/Mutator.h"
    2626#include "SymTab/Autogen.h"
     27#include "SymTab/Mangler.h"
    2728#include "GenPoly/PolyMutator.h"
    2829#include "GenPoly/DeclMutator.h"
     30#include "GenPoly/ScopedSet.h"
    2931
    3032namespace InitTweak {
     
    5557        class CtorDtor : public GenPoly::PolyMutator {
    5658          public:
     59                typedef GenPoly::PolyMutator Parent;
     60                using Parent::mutate;
    5761                /// create constructor and destructor statements for object declarations.
    5862                /// the actual call statements will be added in after the resolver has run
     
    6569                // should not traverse into any of these declarations to find objects
    6670                // that need to be constructed or destructed
    67                 virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
     71                virtual Declaration* mutate( StructDecl *aggregateDecl );
    6872                virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
    6973                virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
     
    7478                virtual Type * mutate( FunctionType *funcType ) { return funcType; }
    7579
    76           protected:
     80                virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
     81
     82          private:
     83                // set of mangled type names for which a constructor or destructor exists in the current scope.
     84                // these types require a ConstructorInit node to be generated, anything else is a POD type and thus
     85                // should not have a ConstructorInit generated.
     86
     87                bool isManaged( ObjectDecl * objDecl ) const ; // determine if object is managed
     88                void handleDWT( DeclarationWithType * dwt ); // add type to managed if ctor/dtor
     89                GenPoly::ScopedSet< std::string > managedTypes;
     90                bool inFunction = false;
    7791        };
    7892
     
    142156
    143157        DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) {
    144                 std::list<DeclarationWithType*> oldReturnVals = returnVals;
    145                 std::string oldFuncName = funcName;
     158                ValueGuard< std::list<DeclarationWithType*> > oldReturnVals( returnVals );
     159                ValueGuard< std::string > oldFuncName( funcName );
    146160
    147161                FunctionType * type = functionDecl->get_functionType();
     
    149163                funcName = functionDecl->get_name();
    150164                DeclarationWithType * decl = Mutator::mutate( functionDecl );
    151                 returnVals = oldReturnVals;
    152                 funcName = oldFuncName;
    153165                return decl;
    154166        }
     
    197209
    198210        DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
    199                 bool oldInFunc = inFunction;
     211                ValueGuard< bool > oldInFunc( inFunction );
    200212                inFunction = true;
    201213                DeclarationWithType * decl = Parent::mutate( functionDecl );
    202                 inFunction = oldInFunc;
    203214                return decl;
    204215        }
     
    209220        }
    210221
     222        bool CtorDtor::isManaged( ObjectDecl * objDecl ) const {
     223                Type * type = objDecl->get_type();
     224                while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
     225                        type = at->get_base();
     226                }
     227                return managedTypes.find( SymTab::Mangler::mangle( type ) ) != managedTypes.end();
     228        }
     229
     230        void CtorDtor::handleDWT( DeclarationWithType * dwt ) {
     231                // if this function is a user-defined constructor or destructor, mark down the type as "managed"
     232                if ( ! LinkageSpec::isOverridable( dwt->get_linkage() ) && isCtorDtor( dwt->get_name() ) ) {
     233                        std::list< DeclarationWithType * > & params = GenPoly::getFunctionType( dwt->get_type() )->get_parameters();
     234                        assert( ! params.empty() );
     235                        PointerType * type = safe_dynamic_cast< PointerType * >( params.front()->get_type() );
     236                        managedTypes.insert( SymTab::Mangler::mangle( type->get_base() ) );
     237                }
     238        }
     239
    211240        DeclarationWithType * CtorDtor::mutate( ObjectDecl * objDecl ) {
    212                 // hands off if designated, if @=, or if extern
    213                 if ( tryConstruct( objDecl ) ) {
     241                handleDWT( objDecl );
     242                // hands off if @=, extern, builtin, etc.
     243                // if global but initializer is not constexpr, always try to construct, since this is not legal C
     244                if ( ( tryConstruct( objDecl ) && isManaged( objDecl ) ) || (! inFunction && ! isConstExpr( objDecl->get_init() ) ) ) {
     245                        // constructed objects cannot be designated
     246                        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 @=.", objDecl );
     247                        // constructed objects should not have initializers nested too deeply
     248                        if ( ! checkInitDepth( objDecl ) ) throw SemanticError( "Managed object's initializer is too deep ", objDecl );
     249
    214250                        // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
    215251                        // for each constructable object
     
    241277                        }
    242278                }
    243                 return Mutator::mutate( objDecl );
     279                return Parent::mutate( objDecl );
    244280        }
    245281
    246282        DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
     283                ValueGuard< bool > oldInFunc = inFunction;
     284                inFunction = true;
     285
     286                handleDWT( functionDecl );
     287
     288                managedTypes.beginScope();
     289                // go through assertions and recursively add seen ctor/dtors
     290                for ( TypeDecl * tyDecl : functionDecl->get_functionType()->get_forall() ) {
     291                        for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) {
     292                                assertion = assertion->acceptMutator( *this );
     293                        }
     294                }
    247295                // parameters should not be constructed and destructed, so don't mutate FunctionType
    248296                mutateAll( functionDecl->get_oldDecls(), *this );
    249297                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     298
     299                managedTypes.endScope();
    250300                return functionDecl;
    251301        }
     302
     303        Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
     304                // don't construct members, but need to take note if there is a managed member,
     305                // because that means that this type is also managed
     306                for ( Declaration * member : aggregateDecl->get_members() ) {
     307                        if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
     308                                if ( isManaged( field ) ) {
     309                                        managedTypes.insert( SymTab::Mangler::mangle( aggregateDecl ) );
     310                                        break;
     311                                }
     312                        }
     313                }
     314                return aggregateDecl;
     315        }
     316
     317        CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
     318                managedTypes.beginScope();
     319                CompoundStmt * stmt = Parent::mutate( compoundStmt );
     320                managedTypes.endScope();
     321                return stmt;
     322        }
     323
    252324} // namespace InitTweak
    253325
  • src/InitTweak/InitTweak.cc

    r0362d42 r1ced874  
    77#include "SynTree/Attribute.h"
    88#include "GenPoly/GenPoly.h"
     9#include "ResolvExpr/typeops.h"
    910
    1011namespace InitTweak {
     
    2223                };
    2324
     25                class InitDepthChecker : public Visitor {
     26                public:
     27                        bool depthOkay = true;
     28                        Type * type;
     29                        int curDepth = 0, maxDepth = 0;
     30                        InitDepthChecker( Type * type ) : type( type ) {
     31                                Type * t = type;
     32                                while ( ArrayType * at = dynamic_cast< ArrayType * >( t ) ) {
     33                                        maxDepth++;
     34                                        t = at->get_base();
     35                                }
     36                                maxDepth++;
     37                        }
     38                        virtual void visit( ListInit * listInit ) {
     39                                curDepth++;
     40                                if ( curDepth > maxDepth ) depthOkay = false;
     41                                Visitor::visit( listInit );
     42                                curDepth--;
     43                        }
     44                };
     45
    2446                class InitFlattener : public Visitor {
    2547                        public:
     
    5274                maybeAccept( init, finder );
    5375                return finder.hasDesignations;
     76        }
     77
     78        bool checkInitDepth( ObjectDecl * objDecl ) {
     79                InitDepthChecker checker( objDecl->get_type() );
     80                maybeAccept( objDecl->get_init(), checker );
     81                return checker.depthOkay;
    5482        }
    5583
     
    231259                return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    232260                        (objDecl->get_init() == NULL ||
    233                                 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
    234                         ! isDesignated( objDecl->get_init() )
     261                                ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ))
    235262                        && objDecl->get_storageClass() != DeclarationNode::Extern;
    236263        }
     
    390417                virtual void visit( ApplicationExpr *applicationExpr ) { isConstExpr = false; }
    391418                virtual void visit( UntypedExpr *untypedExpr ) { isConstExpr = false; }
    392                 virtual void visit( NameExpr *nameExpr ) { isConstExpr = false; }
    393                 virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
     419                virtual void visit( NameExpr *nameExpr ) {
     420                        // xxx - temporary hack, because 0 and 1 really should be constexprs, even though they technically aren't in Cforall today
     421                        if ( nameExpr->get_name() != "0" && nameExpr->get_name() != "1" ) isConstExpr = false;
     422                }
     423                // virtual void visit( CastExpr *castExpr ) { isConstExpr = false; }
     424                virtual void visit( AddressExpr *addressExpr ) {
     425                        // address of a variable or member expression is constexpr
     426                        Expression * arg = addressExpr->get_arg();
     427                        if ( ! dynamic_cast< NameExpr * >( arg) && ! dynamic_cast< VariableExpr * >( arg ) && ! dynamic_cast< MemberExpr * >( arg ) && ! dynamic_cast< UntypedMemberExpr * >( arg ) ) isConstExpr = false;
     428                }
    394429                virtual void visit( LabelAddressExpr *labAddressExpr ) { isConstExpr = false; }
    395430                virtual void visit( UntypedMemberExpr *memberExpr ) { isConstExpr = false; }
    396431                virtual void visit( MemberExpr *memberExpr ) { isConstExpr = false; }
    397432                virtual void visit( VariableExpr *variableExpr ) { isConstExpr = false; }
    398                 virtual void visit( ConstantExpr *constantExpr ) { /* bottom out */ }
    399433                // these might be okay?
    400434                // virtual void visit( SizeofExpr *sizeofExpr );
     
    439473        bool isDestructor( const std::string & str ) { return str == "^?{}"; }
    440474        bool isCtorDtor( const std::string & str ) { return isConstructor( str ) || isDestructor( str ); }
     475
     476        FunctionDecl * isCopyConstructor( Declaration * decl ) {
     477                FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl );
     478                if ( ! function ) return 0;
     479                if ( ! isConstructor( function->get_name() ) ) return 0;
     480                FunctionType * ftype = function->get_functionType();
     481                if ( ftype->get_parameters().size() != 2 ) return 0;
     482
     483                Type * t1 = ftype->get_parameters().front()->get_type();
     484                Type * t2 = ftype->get_parameters().back()->get_type();
     485                PointerType * ptrType = dynamic_cast< PointerType * > ( t1 );
     486                assert( ptrType );
     487
     488                if ( ResolvExpr::typesCompatible( ptrType->get_base(), t2, SymTab::Indexer() ) ) {
     489                        return function;
     490                } else {
     491                        return 0;
     492                }
     493        }
    441494}
  • src/InitTweak/InitTweak.h

    r0362d42 r1ced874  
    3030        bool isCtorDtor( const std::string & );
    3131
     32        FunctionDecl * isCopyConstructor( Declaration * decl );
     33
    3234        /// transform Initializer into an argument list that can be passed to a call expression
    3335        std::list< Expression * > makeInitList( Initializer * init );
     
    3840        /// True if the Initializer contains designations
    3941        bool isDesignated( Initializer * init );
     42
     43        /// True if the ObjectDecl's Initializer nesting level is not deeper than the depth of its
     44        /// type, where the depth of its type is the number of nested ArrayTypes + 1
     45        bool checkInitDepth( ObjectDecl * objDecl );
    4046
    4147  /// Non-Null if expr is a call expression whose target function is intrinsic
Note: See TracChangeset for help on using the changeset viewer.