Changeset 5b2f5bb


Ignore:
Timestamp:
Mar 30, 2016, 3:48:55 PM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
e0323a2
Parents:
4cc4286
Message:

choose destructor at at object declaration (CtorInit?), overhaul and simplification of resolver code for CtorInit?

Location:
src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r4cc4286 r5b2f5bb  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Feb 09 13:24:40 2016
     12// Last Modified On : Wed Mar 30 14:39:30 2016
    1313// Update Count     : 255
    1414//
     
    282282                                  case OT_DTOR:
    283283                                  // intrinsic destructors do nothing - don't generate any code
    284                                   output << " // " << dynamic_cast<VariableExpr*>(applicationExpr->get_function())->get_var()->get_name() << endl;
     284                                  output << " /* " << dynamic_cast<VariableExpr*>(applicationExpr->get_function())->get_var()->get_name() << " */";
    285285                                  break;
    286286
  • src/InitTweak/FixInit.cc

    r4cc4286 r5b2f5bb  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Jan 19 16:36:59 2016
     12// Last Modified On : Wed Mar 30 14:34:46 2016
    1313// Update Count     : 30
    1414//
     
    3737
    3838                virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
     39
     40          private:
     41                std::list< Statement * > dtorStmts;
    3942        };
    4043
     
    5255                        // a decision should have been made by the resolver, so ctor and init are not both non-NULL
    5356                        assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    54                         if ( Expression * ctor = ctorInit->get_ctor() ) {
    55                                 ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
    56                                 stmtsToAddAfter.push_back( ctorStmt );
     57                        if ( Statement * ctor = ctorInit->get_ctor() ) {
     58                                stmtsToAddAfter.push_back( ctor );
     59                                dtorStmts.push_front( ctorInit->get_dtor() );
    5760                                objDecl->set_init( NULL );
    5861                                ctorInit->set_ctor( NULL );
     62                                ctorInit->set_dtor( NULL );  // xxx - only destruct when constructing? Probably not?
    5963                        } else if ( Initializer * init = ctorInit->get_init() ) {
    6064                                objDecl->set_init( init );
     
    7074
    7175        CompoundStmt * FixInit::mutate( CompoundStmt * compoundStmt ) {
     76                // mutate statements - this will also populate dtorStmts list
     77                // don't want to dump all destructors when block is left,
     78                // just the destructors associated with variables defined in this block
     79                std::list< Statement * > oldDestructorStmts = dtorStmts;
     80                dtorStmts = std::list<Statement *>();
     81
     82                compoundStmt = PolyMutator::mutate( compoundStmt );
    7283                std::list< Statement * > & statements = compoundStmt->get_kids();
    73                 for ( std::list< Statement * >::iterator it = statements.begin(); it != statements.end(); ) {
     84                for ( std::list< Statement * >::iterator it = dtorStmts.begin(); it != dtorStmts.end(); ++it ) {
    7485                        // remove if instrinsic destructor statement
    7586                        // xxx - test user manually calling intrinsic functions - what happens?
    7687                        if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( *it ) ) {
    77                                 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() ) ) {
    78                                         if ( VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() ) ) {
    79                                                 // check for Intrinsic only - don't want to remove all overridable dtors because autogenerated dtor
    80                                                 // will call all member dtors, and some members may have a user defined dtor.
    81                                                 if ( function->get_var()->get_name() == "^?{}" && function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    82                                                         statements.erase(it++);
    83                                                         continue;
    84                                                 } else {
    85                                                 }
    86                                         }
     88                                ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
     89                                assert( appExpr );
     90                                VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
     91                                assert( function );
     92                                // check for Intrinsic only - don't want to remove all overridable dtors because autogenerated dtor
     93                                // will call all member dtors, and some members may have a user defined dtor.
     94                                if ( function->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
     95                                        // don't ned to call intrinsic dtor, because it does nothing
     96                                        delete *it;
     97                                } else {
     98                                        // non-intrinsic dtors must be called
     99                                        statements.push_back( *it );
    87100                                }
     101                        } else {
     102                                // could also be a compound statement with a loop, in the case of an array
     103                                statements.push_back( *it );
    88104                        }
    89                         ++it;
    90105                }
    91                 // mutate non-destructor statements
    92                 return PolyMutator::mutate( compoundStmt );
     106                // TODO: adding to the end of a block isn't sufficient, since
     107                // return/break/goto should trigger destructor when block is left.
     108                dtorStmts = oldDestructorStmts;
     109                return compoundStmt;
    93110        }
    94111
  • src/InitTweak/RemoveInit.cc

    r4cc4286 r5b2f5bb  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Feb 09 15:12:29 2016
     12// Last Modified On : Wed Mar 30 15:45:12 2016
    1313// Update Count     : 166
    1414//
     
    7272                virtual Declaration* mutate( TypedefDecl *typeDecl );
    7373
    74                 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt );
    75 
    7674          protected:
    7775                bool inFunction;
    78 
    79                 // to be added before block ends - use push_front so order is correct
    80                 std::list< Statement * > destructorStmts;
    8176        };
    8277
     
    199194                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
    200195                                        // TODO: walk initializer and generate appropriate copy ctor if element has initializer
    201                                         SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( stmtsToAddAfter ) );
    202                                         SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( destructorStmts ), false );
     196                                        std::list< Statement * > ctor;
     197                                        std::list< Statement * > dtor;
     198
     199                                        SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
     200                                        SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
     201
     202                                        // Currently makeArrayFunction produces a single Statement - a CompoundStmt
     203                                        // which  wraps everything that needs to happen. As such, it's technically
     204                                        // possible to use a Statement ** in the above calls, but this is inherently
     205                                        // unsafe, so instead we take the slightly less efficient route, but will be
     206                                        // immediately informed if somehow the above assumption is broken. In this case,
     207                                        // we could always wrap the list of statements at this point with a CompoundStmt,
     208                                        // but it seems reasonable at the moment for this to be done by makeArrayFunction
     209                                        // itself
     210                                        assert( ctor.size() == 1 );
     211                                        assert( dtor.size() == 1 );
     212
     213                                        objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
    203214                                } else {
    204215                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
     
    209220                                        // if ctor does exist, want to use ctor expression instead of init
    210221                                        // push this decision to the resolver
    211                                         objDecl->set_init( new ConstructorInit( ctor, objDecl->get_init() ) );
    212                                         destructorStmts.push_front( new ExprStmt( noLabels, dtor ) );
     222                                        ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
     223                                        ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
     224                                        objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init() ) );
    213225                                }
    214226                        } else {
     
    234246        }
    235247
    236         CompoundStmt * CtorDtor::mutate( CompoundStmt * compoundStmt ) {
    237                 // don't want to dump all destructors when block is left,
    238                 // just the destructors associated with variables defined in this block
    239                 std::list< Statement * > oldDestructorStmts = destructorStmts;
    240                 destructorStmts = std::list<Statement *>();
    241 
    242                 CompoundStmt * ret = PolyMutator::mutate( compoundStmt );
    243                 std::list< Statement * > &statements = ret->get_kids();
    244                 if ( ! destructorStmts.empty() ) {
    245                         // TODO: adding to the end of a block isn't sufficient, since
    246                         // return/break/goto should trigger destructor when block is left.
    247                         statements.splice( statements.end(), destructorStmts );
    248                 } // if
    249 
    250                 destructorStmts = oldDestructorStmts;
    251                 return ret;
    252         }
    253 
    254248        // should not traverse into any of these declarations to find objects
    255249        // that need to be constructed or destructed
  • src/ResolvExpr/Resolver.cc

    r4cc4286 r5b2f5bb  
    1010// Created On       : Sun May 17 12:17:01 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Thu Jan 14 16:45:32 2016
     12// Last Modified On : Wed Mar 30 15:47:19 2016
    1313// Update Count     : 203
    1414//
     
    478478        void Resolver::visit( ConstructorInit *ctorInit ) {
    479479                TypeEnvironment env;
    480                 AlternativeFinder finder( *this, env );
    481480                try {
    482                         finder.find( ctorInit->get_ctor() );
     481                        maybeAccept( ctorInit->get_ctor(), *this );
     482                        maybeAccept( ctorInit->get_dtor(), *this );
    483483                } catch ( SemanticError ) {
    484484                        // no alternatives for the constructor initializer - fallback on C-style initializer
     
    488488                }
    489489
    490                 assert( ! finder.get_alternatives().empty() );
    491 
    492                 if ( finder.get_alternatives().size() == 1 ) {
    493                         Alternative &choice = finder.get_alternatives().front();
    494                         if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( choice.expr ) ) {
    495                                 if ( VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() ) ) {
    496                                         if ( LinkageSpec::isOverridable( function->get_var()->get_linkage() ) ) {
    497                                                 // if the constructor that was found is intrinsic or autogenerated, reset to C-style
    498                                                 // initializer so that code generation is easy to handle
    499                                                 fallbackInit( ctorInit );
    500                                                 return;
    501                                         }
    502                                 }
     490                if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * > ( ctorInit->get_ctor() ) ) {
     491                        ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
     492                        assert( appExpr );
     493                        VariableExpr * function = dynamic_cast< VariableExpr * > ( appExpr->get_function() );
     494                        assert( function );
     495                        if ( LinkageSpec::isOverridable( function->get_var()->get_linkage() ) ) {
     496                                // if the constructor that was found is intrinsic or autogenerated, reset to C-style
     497                                // initializer so that code generation is easy to handle
     498                                fallbackInit( ctorInit );
     499                                return;
    503500                        }
    504                         // found a constructor - can get rid of C-style initializer
    505                         Expression *newExpr = choice.expr->clone();
    506                         finishExpr( newExpr, choice.env );
    507                         ctorInit->set_ctor( newExpr );
    508                         delete ctorInit->get_init();
    509                         ctorInit->set_init( NULL );
    510                 } else {
    511                         // too many constructors found
    512                         assert(false);
    513                 }
     501                }
     502                // found a constructor - can get rid of C-style initializer
     503                delete ctorInit->get_init();
     504                ctorInit->set_init( NULL );
    514505        }
    515506} // namespace ResolvExpr
  • src/SynTree/Initializer.cc

    r4cc4286 r5b2f5bb  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jan 13 15:31:45 2016
     12// Last Modified On : Wed Mar 30 13:58:32 2016
    1313// Update Count     : 28
    1414//
     
    1616#include "Initializer.h"
    1717#include "Expression.h"
     18#include "Statement.h"
    1819#include "Common/utility.h"
    1920
     
    8182
    8283
    83 ConstructorInit::ConstructorInit( Expression * ctor, Initializer * init ) : Initializer( true ), ctor( ctor ), init( init ) {}
     84ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {}
    8485ConstructorInit::~ConstructorInit() {
    8586        delete ctor;
     
    9899        } // if
    99100
     101        if ( dtor ) {
     102                os << " destructed with ";
     103                dtor->print( os, indent+2 );
     104        }
     105
    100106        if ( init ) {
    101107                os << " with fallback C-style initializer: ";
  • src/SynTree/Initializer.h

    r4cc4286 r5b2f5bb  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Feb 09 14:40:15 2016
     12// Last Modified On : Wed Mar 30 13:22:08 2016
    1313// Update Count     : 19
    1414//
     
    107107class ConstructorInit : public Initializer {
    108108  public:
    109         ConstructorInit( Expression * ctor, Initializer * init );
     109        ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init );
    110110        virtual ~ConstructorInit();
    111111
    112         void set_ctor( Expression * newValue ) { ctor = newValue; }
    113         Expression * get_ctor() const { return ctor; }
     112        void set_ctor( Statement * newValue ) { ctor = newValue; }
     113        Statement * get_ctor() const { return ctor; }
     114        void set_dtor( Statement * newValue ) { dtor = newValue; }
     115        Statement * get_dtor() const { return dtor; }
    114116        void set_init( Initializer * newValue ) { init = newValue; }
    115117        Initializer * get_init() const { return init; }
     
    121123
    122124  private:
    123         Expression * ctor;
     125        Statement * ctor;
     126        Statement * dtor;
    124127        // C-style initializer made up of SingleInit and ListInit nodes to use as a fallback
    125128        // if an appropriate constructor definition is not found by the resolver
  • src/libcfa/Makefile.am

    r4cc4286 r5b2f5bb  
    6060        ${CC} ${CFLAGS} -c -o $@ $<
    6161
    62 libs = # stdlib iostream fstream iterator  # temporarily getting rid of these until ctor/dtor autogen works
     62libs = stdlib iostream fstream iterator
    6363libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c}
    6464
  • src/libcfa/Makefile.in

    r4cc4286 r5b2f5bb  
    8383libcfa_a_AR = $(AR) $(ARFLAGS)
    8484libcfa_a_LIBADD =
    85 am__objects_1 =
     85am__objects_1 = stdlib.$(OBJEXT) iostream.$(OBJEXT) fstream.$(OBJEXT) \
     86        iterator.$(OBJEXT)
    8687am_libcfa_a_OBJECTS = libcfa-prelude.$(OBJEXT) $(am__objects_1)
    8788libcfa_a_OBJECTS = $(am_libcfa_a_OBJECTS)
     
    212213MAINTAINERCLEANFILES = ${addprefix ${libdir}/,${cfalib_DATA}} \
    213214        ${addprefix ${libdir}/,${lib_LIBRARIES}} ${includedir}/*
    214 libs = # stdlib iostream fstream iterator  # temporarily getting rid of these until ctor/dtor autogen works
     215libs = stdlib iostream fstream iterator
    215216libcfa_a_SOURCES = libcfa-prelude.c ${libs:=.c}
    216217cheaders = bfd bfdlink demangle dialog evdns evhttp evrpc expat fcntl form gcrypt math
     
    292293        -rm -f *.tab.c
    293294
     295@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstream.Po@am__quote@
     296@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iostream.Po@am__quote@
     297@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iterator.Po@am__quote@
    294298@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa-prelude.Po@am__quote@
     299@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stdlib.Po@am__quote@
    295300
    296301.c.obj:
Note: See TracChangeset for help on using the changeset viewer.