Ignore:
Timestamp:
Sep 4, 2016, 10:34:35 PM (8 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, 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:
f04a8b81
Parents:
28307be (diff), b16898e (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 plg2:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/GenInit.cc

    r28307be r3403534  
    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                        // xxx - constructed objects should not have initializers nested too deeply
     248
    214249                        // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor
    215250                        // for each constructable object
     
    241276                        }
    242277                }
    243                 return Mutator::mutate( objDecl );
     278                return Parent::mutate( objDecl );
    244279        }
    245280
    246281        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                }
    247294                // parameters should not be constructed and destructed, so don't mutate FunctionType
    248295                mutateAll( functionDecl->get_oldDecls(), *this );
    249296                functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
     297
     298                managedTypes.endScope();
    250299                return functionDecl;
    251300        }
     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
    252323} // namespace InitTweak
    253324
Note: See TracChangeset for help on using the changeset viewer.