Ignore:
Timestamp:
Aug 4, 2016, 4:10:06 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
4819cac
Parents:
73bf8cf2
Message:

add gcc attributes to ObjectDecl?, hoist destructed static variables, add breaks to end of generated switch

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r73bf8cf2 rf9cebb5  
    2626#include "SynTree/Type.h"
    2727#include "SynTree/Expression.h"
     28#include "SynTree/Attribute.h"
    2829#include "SynTree/Statement.h"
    2930#include "SynTree/Initializer.h"
     
    208209                                try {
    209210                                        *i = maybeMutate( *i, fixer );
    210                                         // if (! fixer.staticDtorDecls.empty() ) {
    211                                                 translationUnit.splice( i, fixer.staticDtorDecls );
    212                                         // }
     211                                        translationUnit.splice( i, fixer.staticDtorDecls );
    213212                                } catch( SemanticError &e ) {
    214213                                        errors.append( e );
     
    446445                                        if ( objDecl->get_storageClass() == DeclarationNode::Static ) {
    447446                                                // originally wanted to take advantage of gcc nested functions, but
    448                                                 // we get memory errors with this approach. To remedy this, create a
    449                                                 // global static pointer that is set to refer to the object and make
    450                                                 // the dtor-caller function global so that.
     447                                                // we get memory errors with this approach. To remedy this, the static
     448                                                // variable is hoisted when the destructor needs to be called.
    451449                                                //
    452450                                                // generate:
    453                                                 // T * __objName_static_ptrN;
     451                                                // static T __objName_static_varN;
    454452                                                // void __objName_dtor_atexitN() {
    455                                                 //   __dtor(__objName_static_ptrN);
     453                                                //   __dtor__...;
    456454                                                // }
    457455                                                // int f(...) {
    458456                                                //   ...
    459                                                 //   static T __objName;
    460457                                                //   static bool __objName_uninitialized = true;
    461458                                                //   if (__objName_uninitialized) {
    462                                                 //     __objName_ptr = &__objName;
    463459                                                //     __ctor(__objName);
    464                                                 //     on_exit(__objName_dtor_atexitN, &__objName);
    465460                                                //     __objName_uninitialized = false;
     461                                                //     atexit(__objName_dtor_atexitN);
    466462                                                //   }
    467463                                                //   ...
    468464                                                // }
    469465
    470                                                 static UniqueName ptrNamer( "_static_ptr" );
    471466                                                static UniqueName dtorCallerNamer( "_dtor_atexit" );
    472 
    473                                                 // T * __objName_ptrN
    474                                                 ObjectDecl * objPtr = new ObjectDecl( objDecl->get_mangleName() + ptrNamer.newName(), DeclarationNode::Static, LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), objDecl->get_type()->clone() ), 0 );
    475                                                 objPtr->fixUniqueId();
    476 
    477                                                 // void __objName_dtor_atexitN(...) {...}
    478                                                 // need to modify dtor call so that it refers to objPtr, since function will be global
    479                                                 Statement * dtorStmt = ctorInit->get_dtor()->clone();
    480                                                 ApplicationExpr * dtor = dynamic_cast< ApplicationExpr * >( InitTweak::getCtorDtorCall( dtorStmt ) );
    481                                                 assert( dtor );
    482                                                 delete dtor->get_args().front();
    483                                                 dtor->get_args().front() = new VariableExpr( objPtr );
    484 
    485                                                 FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
    486                                                 dtorCaller->fixUniqueId();
    487                                                 dtorCaller->get_statements()->get_kids().push_back( dtorStmt );
    488467
    489468                                                // static bool __objName_uninitialized = true
     
    493472                                                isUninitializedVar->fixUniqueId();
    494473
    495                                                 // __objName_static_ptrN = &__objName;
    496                                                 UntypedExpr * ptrAssign = new UntypedExpr( new NameExpr( "?=?" ) );
    497                                                 ptrAssign->get_args().push_back( new VariableExpr( objPtr ) );
    498                                                 ptrAssign->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    499 
    500                                                 // atexit(dtor_atexit);
    501                                                 UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
    502                                                 callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
    503 
    504474                                                // __objName_uninitialized = false;
    505475                                                UntypedExpr * setTrue = new UntypedExpr( new NameExpr( "?=?" ) );
     
    511481                                                std::list< Statement * > & body = initStmts->get_kids();
    512482                                                body.push_back( ctor );
    513                                                 body.push_back( new ExprStmt( noLabels, ptrAssign ) );
    514                                                 body.push_back( new ExprStmt( noLabels, callAtexit ) );
    515483                                                body.push_back( new ExprStmt( noLabels, setTrue ) );
    516484
     
    520488                                                stmtsToAddAfter.push_back( ifStmt );
    521489
    522                                                 // add pointer and dtor caller decls to list of decls that will be added into global scope
    523                                                 staticDtorDecls.push_back( objPtr );
    524                                                 staticDtorDecls.push_back( dtorCaller );
     490                                                if ( ctorInit->get_dtor() ) {
     491                                                        // if the object has a non-trivial destructor, have to
     492                                                        // hoist it and the object into the global space and
     493                                                        // call the destructor function with atexit.
     494
     495                                                        Statement * dtorStmt = ctorInit->get_dtor()->clone();
     496
     497                                                        // void __objName_dtor_atexitN(...) {...}
     498                                                        FunctionDecl * dtorCaller = new FunctionDecl( objDecl->get_mangleName() + dtorCallerNamer.newName(), DeclarationNode::Static, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false );
     499                                                        dtorCaller->fixUniqueId();
     500                                                        dtorCaller->get_statements()->get_kids().push_back( dtorStmt );
     501
     502                                                        // atexit(dtor_atexit);
     503                                                        UntypedExpr * callAtexit = new UntypedExpr( new NameExpr( "atexit" ) );
     504                                                        callAtexit->get_args().push_back( new VariableExpr( dtorCaller ) );
     505
     506                                                        body.push_back( new ExprStmt( noLabels, callAtexit ) );
     507
     508                                                        // hoist variable and dtor caller decls to list of decls that will be added into global scope
     509                                                        staticDtorDecls.push_back( objDecl );
     510                                                        staticDtorDecls.push_back( dtorCaller );
     511
     512                                                        // need to rename object uniquely since it now appears
     513                                                        // at global scope and there could be multiple function-scoped
     514                                                        // static variables with the same name in different functions.
     515                                                        static UniqueName staticNamer( "_static_var" );
     516                                                        objDecl->set_mangleName( objDecl->get_mangleName() + staticNamer.newName() );
     517
     518                                                        objDecl->set_init( NULL );
     519                                                        ctorInit->set_ctor( NULL );
     520                                                        delete ctorInit;
     521
     522                                                        // xxx - temporary hack: need to return a declaration, but want to hoist the current object out of this scope
     523                                                        // create a new object which is never used
     524                                                        static UniqueName dummyNamer( "_dummy" );
     525                                                        ObjectDecl * dummy = new ObjectDecl( dummyNamer.newName(), DeclarationNode::Static, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), 0, std::list< Attribute * >{ new Attribute("unused") } );
     526                                                        return dummy;
     527                                                }
    525528                                        } else {
    526529                                                stmtsToAddAfter.push_back( ctor );
     
    582585                                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    583586                                        Statement * dtor = ctorInit->get_dtor();
    584                                         if ( dtor && ! isInstrinsicSingleArgCallStmt( dtor ) ) {
     587                                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    585588                                                // don't need to call intrinsic dtor, because it does nothing, but
    586589                                                // non-intrinsic dtors must be called
Note: See TracChangeset for help on using the changeset viewer.