Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r1ba88a0 rf9cebb5  
    2525#include "SynTree/Mutator.h"
    2626#include "SymTab/Autogen.h"
    27 #include "SymTab/Mangler.h"
    2827#include "GenPoly/PolyMutator.h"
    2928#include "GenPoly/DeclMutator.h"
    30 #include "GenPoly/ScopedSet.h"
    3129
    3230namespace InitTweak {
     
    5755        class CtorDtor : public GenPoly::PolyMutator {
    5856          public:
    59                 typedef GenPoly::PolyMutator Parent;
    60                 using Parent::mutate;
    6157                /// create constructor and destructor statements for object declarations.
    6258                /// the actual call statements will be added in after the resolver has run
     
    6965                // should not traverse into any of these declarations to find objects
    7066                // that need to be constructed or destructed
    71                 virtual Declaration* mutate( StructDecl *aggregateDecl );
     67                virtual Declaration* mutate( StructDecl *aggregateDecl ) { return aggregateDecl; }
    7268                virtual Declaration* mutate( UnionDecl *aggregateDecl ) { return aggregateDecl; }
    7369                virtual Declaration* mutate( EnumDecl *aggregateDecl ) { return aggregateDecl; }
     
    7874                virtual Type * mutate( FunctionType *funcType ) { return funcType; }
    7975
    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;
     76          protected:
    9177        };
    9278
     
    156142
    157143        DeclarationWithType* ReturnFixer::mutate( FunctionDecl *functionDecl ) {
    158                 ValueGuard< std::list<DeclarationWithType*> > oldReturnVals( returnVals );
    159                 ValueGuard< std::string > oldFuncName( funcName );
     144                std::list<DeclarationWithType*> oldReturnVals = returnVals;
     145                std::string oldFuncName = funcName;
    160146
    161147                FunctionType * type = functionDecl->get_functionType();
     
    163149                funcName = functionDecl->get_name();
    164150                DeclarationWithType * decl = Mutator::mutate( functionDecl );
     151                returnVals = oldReturnVals;
     152                funcName = oldFuncName;
    165153                return decl;
    166154        }
     
    209197
    210198        DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) {
    211                 ValueGuard< bool > oldInFunc( inFunction );
     199                bool oldInFunc = inFunction;
    212200                inFunction = true;
    213201                DeclarationWithType * decl = Parent::mutate( functionDecl );
     202                inFunction = oldInFunc;
    214203                return decl;
    215204        }
     
    220209        }
    221210
    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 
    240211        DeclarationWithType * CtorDtor::mutate( ObjectDecl * 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                         // xxx - constructed objects should not have initializers nested too deeply
    248 
     212                // hands off if designated, if @=, or if extern
     213                if ( tryConstruct( objDecl ) ) {
    249214                        // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
    250215                        // for each constructable object
     
    276241                        }
    277242                }
    278                 return Parent::mutate( objDecl );
     243                return Mutator::mutate( objDecl );
    279244        }
    280245
    281246        DeclarationWithType * CtorDtor::mutate( FunctionDecl *functionDecl ) {
    282                 ValueGuard< bool > oldInFunc = inFunction;
    283                 inFunction = true;
    284 
    285                 handleDWT( functionDecl );
    286 
    287                 managedTypes.beginScope();
    288                 // go through assertions and recursively add seen ctor/dtors
    289                 for ( TypeDecl * tyDecl : functionDecl->get_functionType()->get_forall() ) {
    290                         for ( DeclarationWithType *& assertion : tyDecl->get_assertions() ) {
    291                                 assertion = assertion->acceptMutator( *this );
    292                         }
    293                 }
    294247                // parameters should not be constructed and destructed, so don't mutate FunctionType
    295248                mutateAll( functionDecl->get_oldDecls(), *this );
    296249                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    297 
    298                 managedTypes.endScope();
    299250                return functionDecl;
    300251        }
    301 
    302         Declaration* CtorDtor::mutate( StructDecl *aggregateDecl ) {
    303                 // don't construct members, but need to take note if there is a managed member,
    304                 // because that means that this type is also managed
    305                 for ( Declaration * member : aggregateDecl->get_members() ) {
    306                         if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
    307                                 if ( isManaged( field ) ) {
    308                                         managedTypes.insert( SymTab::Mangler::mangle( aggregateDecl ) );
    309                                         break;
    310                                 }
    311                         }
    312                 }
    313                 return aggregateDecl;
    314         }
    315 
    316         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    317                 managedTypes.beginScope();
    318                 CompoundStmt * stmt = Parent::mutate( compoundStmt );
    319                 managedTypes.endScope();
    320                 return stmt;
    321         }
    322 
    323252} // namespace InitTweak
    324253
Note: See TracChangeset for help on using the changeset viewer.