Changeset 7b3f66b


Ignore:
Timestamp:
May 13, 2016, 1:18:35 PM (9 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, 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:
d668182
Parents:
fb24492
Message:

Don't construct global extern variables, handle global array construction separately, stub for array initialization list with constructors

Location:
src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    rfb24492 r7b3f66b  
    1010// Created On       : Mon May 04 15:14:56 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 09 11:44:29 2016
     12// Last Modified On : Fri May 13 11:37:30 2016
    1313// Update Count     : 2
    1414//
    1515
    1616#include "FixGlobalInit.h"
    17 #include "GenInit.h"
     17#include "InitTweak.h"
    1818#include "SynTree/Declaration.h"
    1919#include "SynTree/Type.h"
     
    125125                std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
    126126
    127                 if ( objDecl->get_init() == NULL ) return;
     127                // if ( objDecl->get_init() == NULL ) return;
    128128                if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
    129129                if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable
     130                if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
    130131                // C allows you to initialize objects with constant expressions
    131132                // xxx - this is an optimization. Need to first resolve constructors before we decide
     
    133134                // if ( isConstExpr( objDecl->get_init() ) ) return;
    134135
    135                 // steal initializer from object and attach it to a new temporary
    136                 ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() );
    137                 objDecl->set_init( NULL );
    138                 initStatements.push_back( new DeclStmt( noLabels, newObj ) );
     136                if ( ArrayType * at = dynamic_cast< ArrayType * > ( objDecl->get_type() ) ) {
     137                        // xxx - initialize each element of the array
     138                } else {
     139                        // steal initializer from object and attach it to a new temporary
     140                        ObjectDecl *newObj = new ObjectDecl( tempNamer.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, objDecl->get_type()->clone(), objDecl->get_init() );
     141                        objDecl->set_init( NULL );
     142                        initStatements.push_back( new DeclStmt( noLabels, newObj ) );
    139143
    140                 // copy construct objDecl using temporary
    141                 UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) );
    142                 init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    143                 init->get_args().push_back( new VariableExpr( newObj ) );
    144                 initStatements.push_back( new ExprStmt( noLabels, init ) );
     144                        // copy construct objDecl using temporary
     145                        UntypedExpr * init = new UntypedExpr( new NameExpr( "?{}" ) );
     146                        init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
     147                        init->get_args().push_back( new VariableExpr( newObj ) );
     148                        initStatements.push_back( new ExprStmt( noLabels, init ) );
    145149
    146                 // add destructor calls to global destroy function
    147                 UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
    148                 destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    149                 destroyStatements.push_front( new ExprStmt( noLabels, destroy ) );
     150                        // add destructor calls to global destroy function
     151                        UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
     152                        destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
     153                        destroyStatements.push_front( new ExprStmt( noLabels, destroy ) );
     154                }
    150155        }
    151156
  • src/InitTweak/FixInit.cc

    rfb24492 r7b3f66b  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 09 12:36:02 2016
     12// Last Modified On : Fri May 13 11:44:26 2016
    1313// Update Count     : 30
    1414//
     
    1717#include <list>
    1818#include "FixInit.h"
     19#include "InitTweak.h"
    1920#include "ResolvExpr/Resolver.h"
    2021#include "ResolvExpr/typeops.h"
     
    2728#include "SymTab/Indexer.h"
    2829#include "GenPoly/PolyMutator.h"
    29 #include "GenPoly/GenPoly.h"
    3030
    3131bool ctordtorp = false;
     
    398398        }
    399399
    400         bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
    401                 if ( stmt == NULL ) return false;
    402                 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    403                         ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
    404                         assert( appExpr );
    405                         VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
    406                         assert( function );
    407                         // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
    408                         // will call all member dtors, and some members may have a user defined dtor.
    409                         FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
    410                         assert( funcType );
    411                         return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
    412                 } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
    413                         // could also be a compound statement with a loop, in the case of an array
    414                         assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop
    415                         ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
    416                         assert( forStmt && forStmt->get_body() );
    417                         return isInstrinsicSingleArgCallStmt( forStmt->get_body() );
    418                 } else {
    419                         // should never get here
    420                         assert( false && "encountered unknown call statement" );
    421                 }
    422         }
    423 
    424400        namespace {
    425401                template<typename Iterator, typename OutputIterator>
     
    428404                                // remove if instrinsic destructor statement. Note that this is only called
    429405                                // on lists of implicit dtors, so if the user manually calls an intrinsic
    430                                 // dtor then the call will still be generated
     406                                // dtor then the call must (and will) still be generated since the argument
     407                                // may contain side effects.
    431408                                if ( ! isInstrinsicSingleArgCallStmt( *it ) ) {
    432409                                        // don't need to call intrinsic dtor, because it does nothing, but
  • src/InitTweak/FixInit.h

    rfb24492 r7b3f66b  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 09 12:08:11 2016
     12// Last Modified On : Fri May 13 11:27:52 2016
    1313// Update Count     : 5
    1414//
     
    2828  /// and unwrap basic C-style initializers
    2929        void fix( std::list< Declaration * > & translationUnit );
    30 
    31   /// True if stmt is a call statement where the function called is intrinsic and takes one parameter.
    32   /// Intended to be used for default ctor/dtor calls, but might have use elsewhere.
    33   /// Currently has assertions that make it less than fully general.
    34   bool isInstrinsicSingleArgCallStmt( Statement * expr );
    3530} // namespace
    3631
  • src/InitTweak/GenInit.cc

    rfb24492 r7b3f66b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 06 16:11:15 2016
     12// Last Modified On : Fri May 13 11:37:48 2016
    1313// Update Count     : 166
    1414//
     
    1717#include <list>
    1818#include "GenInit.h"
     19#include "InitTweak.h"
    1920#include "SynTree/Declaration.h"
    2021#include "SynTree/Type.h"
     
    129130        }
    130131
    131         bool tryConstruct( ObjectDecl * objDecl ) {
    132                 // xxx - handle designations
    133                 return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    134                         (objDecl->get_init() == NULL ||
    135                         ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() ));
    136         }
    137132        namespace {
    138 
    139133                Expression * makeCtorDtorExpr( std::string name, ObjectDecl * objDecl, std::list< Expression * > args ) {
    140134                        UntypedExpr * expr = new UntypedExpr( new NameExpr( name ) );
     
    142136                        expr->get_args().splice( expr->get_args().end(), args );
    143137                        return expr;
    144                 }
    145 
    146                 class InitExpander : public Visitor {
    147                   public:
    148                   InitExpander() {}
    149                   // ~InitExpander() {}
    150                         virtual void visit( SingleInit * singleInit );
    151                         virtual void visit( ListInit * listInit );
    152                         std::list< Expression * > argList;
    153                 };
    154 
    155                 void InitExpander::visit( SingleInit * singleInit ) {
    156                         argList.push_back( singleInit->get_value()->clone() );
    157                 }
    158 
    159                 void InitExpander::visit( ListInit * listInit ) {
    160                         // xxx - for now, assume no nested list inits
    161                         std::list<Initializer*>::iterator it = listInit->begin_initializers();
    162                         for ( ; it != listInit->end_initializers(); ++it ) {
    163                                 (*it)->accept( *this );
    164                         }
    165                 }
    166 
    167                 std::list< Expression * > makeInitList( Initializer * init ) {
    168                         InitExpander expander;
    169                         maybeAccept( init, expander );
    170                         return expander.argList;
    171138                }
    172139        }
     
    179146                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
    180147                                        // TODO: walk initializer and generate appropriate copy ctor if element has initializer
    181                                         std::list< Statement * > ctor;
    182                                         std::list< Statement * > dtor;
    183 
    184                                         SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
    185                                         SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
    186 
    187                                         // Currently makeArrayFunction produces a single Statement - a CompoundStmt
    188                                         // which  wraps everything that needs to happen. As such, it's technically
    189                                         // possible to use a Statement ** in the above calls, but this is inherently
    190                                         // unsafe, so instead we take the slightly less efficient route, but will be
    191                                         // immediately informed if somehow the above assumption is broken. In this case,
    192                                         // we could always wrap the list of statements at this point with a CompoundStmt,
    193                                         // but it seems reasonable at the moment for this to be done by makeArrayFunction
    194                                         // itself
    195                                         assert( ctor.size() == 1 );
    196                                         assert( dtor.size() == 1 );
    197 
    198                                         objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     148                                        std::list< Expression * > args = makeInitList( objDecl->get_init() );
     149                                        if ( args.empty() ) {
     150                                                std::list< Statement * > ctor;
     151                                                std::list< Statement * > dtor;
     152
     153                                                SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "?{}", back_inserter( ctor ) );
     154                                                SymTab::makeArrayFunction( NULL, new VariableExpr( objDecl ), at, "^?{}", front_inserter( dtor ), false );
     155
     156                                                // Currently makeArrayFunction produces a single Statement - a CompoundStmt
     157                                                // which  wraps everything that needs to happen. As such, it's technically
     158                                                // possible to use a Statement ** in the above calls, but this is inherently
     159                                                // unsafe, so instead we take the slightly less efficient route, but will be
     160                                                // immediately informed if somehow the above assumption is broken. In this case,
     161                                                // we could always wrap the list of statements at this point with a CompoundStmt,
     162                                                // but it seems reasonable at the moment for this to be done by makeArrayFunction
     163                                                // itself
     164                                                assert( ctor.size() == 1 );
     165                                                assert( dtor.size() == 1 );
     166
     167                                                objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init() ) );
     168                                        } else {
     169                                                // array came with an initializer list: initialize each element
     170                                                // may have more initializers than elements in the array - need to check at each index that
     171                                                // we haven't exceeded size. This requires precomputing the size because it might be a side-effecting
     172                                                // computation.
     173                                                // may have fewer initializers than eleemnts in the array - need to default construct
     174                                                // remaining elements.
     175                                                // might be able to merge this with the case above.
     176                                        }
    199177                                } else {
    200178                                        // it's sufficient to attempt to call the ctor/dtor for the given object and its initializer
  • src/InitTweak/GenInit.h

    rfb24492 r7b3f66b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 06 16:18:22 2016
     12// Last Modified On : Fri May 13 11:27:19 2016
    1313// Update Count     : 3
    1414//
     
    2727        /// Adds return value temporaries and wraps Initializers in ConstructorInit nodes
    2828        void genInit( std::list< Declaration * > & translationUnit );
    29         /// True if the resolver should try to construct objDecl
    30         bool tryConstruct( ObjectDecl * objDecl );
    3129} // namespace
    3230
  • src/InitTweak/module.mk

    rfb24492 r7b3f66b  
    1111## Created On       : Mon Jun  1 17:49:17 2015
    1212## Last Modified By : Rob Schluntz
    13 ## Last Modified On : Fri May 06 15:59:27 2016
     13## Last Modified On : Fri May 13 11:36:24 2016
    1414## Update Count     : 3
    1515###############################################################################
     
    1717SRC += InitTweak/GenInit.cc \
    1818        InitTweak/FixInit.cc \
    19         InitTweak/FixGlobalInit.cc
     19        InitTweak/FixGlobalInit.cc \
     20        InitTweak/InitTweak.cc
    2021
  • src/Makefile.in

    rfb24492 r7b3f66b  
    126126        InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT) \
    127127        InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT) \
     128        InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT) \
    128129        Parser/driver_cfa_cpp-parser.$(OBJEXT) \
    129130        Parser/driver_cfa_cpp-lex.$(OBJEXT) \
     
    350351        GenPoly/DeclMutator.cc InitTweak/GenInit.cc \
    351352        InitTweak/FixInit.cc InitTweak/FixGlobalInit.cc \
    352         Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
    353         Parser/ParseNode.cc Parser/DeclarationNode.cc \
    354         Parser/ExpressionNode.cc Parser/StatementNode.cc \
    355         Parser/InitializerNode.cc Parser/TypeData.cc \
    356         Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \
     353        InitTweak/InitTweak.cc Parser/parser.yy Parser/lex.ll \
     354        Parser/TypedefTable.cc Parser/ParseNode.cc \
     355        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
     356        Parser/StatementNode.cc Parser/InitializerNode.cc \
     357        Parser/TypeData.cc Parser/LinkageSpec.cc \
     358        Parser/parseutility.cc Parser/Parser.cc \
    357359        ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
    358360        ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
     
    571573        InitTweak/$(DEPDIR)/$(am__dirstamp)
    572574InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT):  \
     575        InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
     576InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT):  \
    573577        InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
    574578Parser/parser.h: Parser/parser.cc
     
    806810        -rm -f InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT)
    807811        -rm -f InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT)
     812        -rm -f InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT)
    808813        -rm -f Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT)
    809814        -rm -f Parser/driver_cfa_cpp-ExpressionNode.$(OBJEXT)
     
    914919@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po@am__quote@
    915920@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po@am__quote@
     921@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po@am__quote@
    916922@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@
    917923@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po@am__quote@
     
    14251431@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi`
    14261432
     1433InitTweak/driver_cfa_cpp-InitTweak.o: InitTweak/InitTweak.cc
     1434@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-InitTweak.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo -c -o InitTweak/driver_cfa_cpp-InitTweak.o `test -f 'InitTweak/InitTweak.cc' || echo '$(srcdir)/'`InitTweak/InitTweak.cc
     1435@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po
     1436@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/InitTweak.cc' object='InitTweak/driver_cfa_cpp-InitTweak.o' libtool=no @AMDEPBACKSLASH@
     1437@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1438@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-InitTweak.o `test -f 'InitTweak/InitTweak.cc' || echo '$(srcdir)/'`InitTweak/InitTweak.cc
     1439
     1440InitTweak/driver_cfa_cpp-InitTweak.obj: InitTweak/InitTweak.cc
     1441@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-InitTweak.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo -c -o InitTweak/driver_cfa_cpp-InitTweak.obj `if test -f 'InitTweak/InitTweak.cc'; then $(CYGPATH_W) 'InitTweak/InitTweak.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/InitTweak.cc'; fi`
     1442@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po
     1443@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/InitTweak.cc' object='InitTweak/driver_cfa_cpp-InitTweak.obj' libtool=no @AMDEPBACKSLASH@
     1444@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1445@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-InitTweak.obj `if test -f 'InitTweak/InitTweak.cc'; then $(CYGPATH_W) 'InitTweak/InitTweak.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/InitTweak.cc'; fi`
     1446
    14271447Parser/driver_cfa_cpp-parser.o: Parser/parser.cc
    14281448@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parser.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo -c -o Parser/driver_cfa_cpp-parser.o `test -f 'Parser/parser.cc' || echo '$(srcdir)/'`Parser/parser.cc
  • src/ResolvExpr/Resolver.cc

    rfb24492 r7b3f66b  
    1010// Created On       : Sun May 17 12:17:01 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 09 12:10:19 2016
     12// Last Modified On : Fri May 13 11:36:40 2016
    1313// Update Count     : 203
    1414//
     
    2525#include "SymTab/Indexer.h"
    2626#include "Common/utility.h"
    27 #include "InitTweak/FixInit.h"
     27#include "InitTweak/InitTweak.h"
    2828
    2929#include <iostream>
Note: See TracChangeset for help on using the changeset viewer.