Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    rf9cebb5 rdcd73d1  
    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
Note: See TracChangeset for help on using the changeset viewer.