Changeset 88e79ad


Ignore:
Timestamp:
Oct 20, 2017, 2:00:55 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
0b9be4d
Parents:
72f85de
Message:

Add Destructor type and updated handling for member destructor calls

Location:
src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r72f85de r88e79ad  
    177177                        DeclarationWithType * postmutate( ObjectDecl *objDecl );
    178178
    179                         DeclarationWithType * getDtorFunc( ObjectDecl * objDecl, Statement * dtor );
    180 
    181179                        std::list< Declaration * > staticDtorDecls;
    182180                };
     
    202200                        static void generate( std::list< Declaration * > & translationUnit );
    203201
     202                        void previsit( StructDecl * structDecl );
     203
    204204                        void previsit( FunctionDecl * funcDecl );
    205205                        void postvisit( FunctionDecl * funcDecl );
     
    219219                        bool isCtor = false; // true if current function is a constructor
    220220                        StructDecl * structDecl = nullptr;
     221
     222                        // special built-in functions necessary for this to work
     223                        StructDecl * dtorStruct = nullptr;
     224                        FunctionDecl * dtorStructDestroy = nullptr;
    221225                };
    222226
     
    635639                }
    636640
    637                 DeclarationWithType * FixInit::getDtorFunc( ObjectDecl * objDecl, Statement * dtor ) {
     641                DeclarationWithType * getDtorFunc( ObjectDecl * objDecl, Statement * dtor, std::list< Statement * > & stmtsToAdd ) {
    638642                        if ( dynamic_cast< ExprStmt * >( dtor ) ) {
    639643                                if ( DeclarationWithType * func = getFunction( getCtorDtorCall( dtor ) ) ) {
     
    653657                        // wraps the more complicated code.
    654658                        static UniqueName dtorNamer( "__cleanup_dtor" );
    655                         FunctionDecl * dtorFunc = FunctionDecl::newFunction( dtorNamer.newName(), SymTab::genDefaultType( objDecl->type, false ), new CompoundStmt( noLabels ) );
    656                         stmtsToAddBefore.push_back( new DeclStmt( noLabels, dtorFunc ) );
     659                        FunctionDecl * dtorFunc = FunctionDecl::newFunction( dtorNamer.newName(), SymTab::genDefaultType( objDecl->type->stripReferences(), false ), new CompoundStmt( noLabels ) );
     660                        stmtsToAdd.push_back( new DeclStmt( noLabels, dtorFunc ) );
    657661
    658662                        // the original code contains uses of objDecl - replace them with the newly generated 'this' parameter.
     
    785789                                                        if ( ! isIntrinsicSingleArgCallStmt( dtorStmt ) ) {
    786790                                                                // set dtor location to the object's location for error messages
    787                                                                 DeclarationWithType * dtorFunc = getDtorFunc( objDecl, dtorStmt );
     791                                                                DeclarationWithType * dtorFunc = getDtorFunc( objDecl, dtorStmt, stmtsToAddBefore );
    788792                                                                objDecl->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( dtorFunc ) } ) );
    789793                                                                // objDecl->attributes.push_back( new Attribute( "cleanup", { new NameExpr( dtorFunc->name ) } ) );
     
    910914                }
    911915
     916                void GenStructMemberCalls::previsit( StructDecl * structDecl ) {
     917                        if ( ! dtorStruct && structDecl->name == "__Destructor" ) {
     918                                dtorStruct = structDecl;
     919                        }
     920                }
     921
    912922                void GenStructMemberCalls::previsit( FunctionDecl * funcDecl ) {
    913923                        GuardValue( function );
     
    922932                        unhandled.clear();
    923933                        usedUninit.clear();
     934
     935                        if ( ! dtorStructDestroy && funcDecl->name == "__destroy_Destructor" ) {
     936                                dtorStructDestroy = funcDecl;
     937                                return;
     938                        }
    924939
    925940                        function = funcDecl;
     
    933948                                if ( structType ) {
    934949                                        structDecl = structType->get_baseStruct();
     950                                        if ( structDecl == dtorStruct ) return;
    935951                                        for ( Declaration * member : structDecl->get_members() ) {
    936952                                                if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {
     
    10041020                                                        callStmt->acceptMutator( resolver );
    10051021                                                        if ( isCtor ) {
    1006                                                                 function->get_statements()->push_front( callStmt );
     1022                                                                function->statements->push_front( callStmt );
    10071023                                                        } else {
    10081024                                                                // destructor statements should be added at the end
    1009                                                                 function->get_statements()->push_back( callStmt );
     1025                                                                // function->get_statements()->push_back( callStmt );
     1026
     1027                                                                // Destructor _dtor0 = { &b.a1, _destroy_A };
     1028                                                                std::list< Statement * > stmtsToAdd;
     1029
     1030                                                                static UniqueName memberDtorNamer = { "__memberDtor" };
     1031                                                                assertf( dtorStruct, "builtin __Destructor not found." );
     1032                                                                assertf( dtorStructDestroy, "builtin __destroy_Destructor not found." );
     1033
     1034                                                                Expression * thisExpr = new AddressExpr( new VariableExpr( thisParam ) );
     1035                                                                Expression * dtorExpr = new VariableExpr( getDtorFunc( thisParam, callStmt, stmtsToAdd ) );
     1036
     1037                                                                ObjectDecl * destructor = ObjectDecl::newObject( memberDtorNamer.newName(), new StructInstType( Type::Qualifiers(), dtorStruct ), new ListInit( { new SingleInit( thisExpr ), new SingleInit( dtorExpr ) } ) );
     1038                                                                function->statements->push_front( new DeclStmt( noLabels, destructor ) );
     1039                                                                destructor->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( dtorStructDestroy ) } ) );
     1040
     1041                                                                function->statements->kids.splice( function->statements->kids.begin(), stmtsToAdd );
    10101042                                                        }
    10111043                                                } catch ( SemanticError & error ) {
  • src/prelude/builtins.c

    r72f85de r88e79ad  
    9191static inline unsigned int ?\=?( unsigned int & x, unsigned long int y ) { x = x \ y; return x; }
    9292
     93// type that wraps a pointer and a destructor-like function - used in generating implicit destructor calls for struct members in user-defined functions
     94forall(dtype T)
     95struct __Destructor {
     96  T * object;
     97  void (*dtor)(T *);
     98};
     99
     100// defined destructor in the case that non-generated code wants to use __Destructor
     101forall(dtype T)
     102static inline void ^?{}(__Destructor(T) & x) {
     103  x.dtor(x.object);
     104}
     105
     106// easy interface into __Destructor's destructor for easy codegen purposes
     107extern "C" {
     108  forall(dtype T)
     109  static inline void __destroy_Destructor(__Destructor(T) * dtor) {
     110    ^(*dtor){};
     111  }
     112}
     113
    93114// Local Variables: //
    94115// mode: c //
Note: See TracChangeset for help on using the changeset viewer.