Changeset f1b1e4c for src/InitTweak


Ignore:
Timestamp:
Jun 1, 2016, 11:54:23 AM (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:
be945ac
Parents:
70f89d00
Message:

can construct global const objects, except with intrinsic constructors

Location:
src/InitTweak
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixGlobalInit.cc

    r70f89d00 rf1b1e4c  
    125125                std::list< Statement * > & destroyStatements = destroyFunction->get_statements()->get_kids();
    126126
    127                 // if ( objDecl->get_init() == NULL ) return;
    128127                if ( ! tryConstruct( objDecl ) ) return; // don't construct @= or designated objects
    129                 if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable
    130128                if ( objDecl->get_storageClass() == DeclarationNode::Extern ) return;
    131129                // C allows you to initialize objects with constant expressions
     
    146144                        init->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    147145                        init->get_args().push_back( new VariableExpr( newObj ) );
    148                         initStatements.push_back( new ExprStmt( noLabels, init ) );
     146                        initStatements.push_back( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, init ) ) );
    149147
    150148                        // add destructor calls to global destroy function
    151149                        UntypedExpr * destroy = new UntypedExpr( new NameExpr( "^?{}" ) );
    152150                        destroy->get_args().push_back( new AddressExpr( new VariableExpr( objDecl ) ) );
    153                         destroyStatements.push_front( new ExprStmt( noLabels, destroy ) );
     151                        destroyStatements.push_front( new ImplicitCtorDtorStmt( new ExprStmt( noLabels, destroy ) ) );
    154152                }
    155153        }
  • src/InitTweak/FixInit.cc

    r70f89d00 rf1b1e4c  
    132132                                return appExpr;
    133133                        } else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) {
    134                                 // FunctionType * ftype = funcDecl->get_functionType();
    135134                                FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) );
    136135                                assert( ftype );
  • src/InitTweak/GenInit.cc

    r70f89d00 rf1b1e4c  
    143143                if ( tryConstruct( objDecl ) ) {
    144144                        if ( inFunction ) {
    145                                 // remove qualifiers so that const objects can be initialized, and attach the
    146                                 // qualifiers to ConstructorInit so that they can be replaced after resolving
    147                                 Type * type = objDecl->get_type();
    148                                 Type::Qualifiers qualifiers = type->get_qualifiers();
    149                                 type->get_qualifiers() = Type::Qualifiers();
    150 
    151145                                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
    152146                                        // call into makeArrayFunction from validate.cc to generate calls to ctor/dtor for each element of array
     
    170164                                                assert( ctor.size() == 1 );
    171165                                                assert( dtor.size() == 1 );
    172 
    173                                                 objDecl->set_init( new ConstructorInit( ctor.front(), dtor.front(), objDecl->get_init(), objDecl, qualifiers ) );
     166                                                objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctor.front() ), new ImplicitCtorDtorStmt( dtor.front() ), objDecl->get_init() ) );
    174167                                        } else {
    175168                                                // array came with an initializer list: initialize each element
     
    191184                                        ExprStmt * ctorStmt = new ExprStmt( noLabels, ctor );
    192185                                        ExprStmt * dtorStmt = new ExprStmt( noLabels, dtor );
    193                                         objDecl->set_init( new ConstructorInit( ctorStmt, dtorStmt, objDecl->get_init(), objDecl, qualifiers ) );
     186                                        objDecl->set_init( new ConstructorInit( new ImplicitCtorDtorStmt( ctorStmt ), new ImplicitCtorDtorStmt( dtorStmt ), objDecl->get_init() ) );
    194187                                }
    195188                        }
  • src/InitTweak/InitTweak.cc

    r70f89d00 rf1b1e4c  
    6060  }
    6161
    62   bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
    63     if ( stmt == NULL ) return false;
     62  Expression * getCtorDtorCall( Statement * stmt ) {
     63    if ( stmt == NULL ) return NULL;
    6464    if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    65       ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( exprStmt->get_expr() );
    66       assert( appExpr );
    67       VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
    68       assert( function );
    69       // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
    70       // will call all member dtors, and some members may have a user defined dtor.
    71       FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
    72       assert( funcType );
    73       return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
     65      return exprStmt->get_expr();
    7466    } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
    7567      // could also be a compound statement with a loop, in the case of an array
     
    7769      ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
    7870      assert( forStmt && forStmt->get_body() );
    79       return isInstrinsicSingleArgCallStmt( forStmt->get_body() );
     71      return getCtorDtorCall( forStmt->get_body() );
     72    } if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) {
     73      return getCtorDtorCall( impCtorDtorStmt->get_callStmt() );
    8074    } else {
    8175      // should never get here
    8276      assert( false && "encountered unknown call statement" );
     77    }
     78  }
     79
     80  bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
     81    Expression * callExpr = getCtorDtorCall( stmt );
     82    if ( ! callExpr ) return false;
     83    ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr );
     84    assert( appExpr );
     85    VariableExpr * function = dynamic_cast< VariableExpr * >( appExpr->get_function() );
     86    assert( function );
     87    // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor
     88    // will call all member dtors, and some members may have a user defined dtor.
     89    FunctionType * funcType = GenPoly::getFunctionType( function->get_var()->get_type() );
     90    assert( funcType );
     91    return function->get_var()->get_linkage() == LinkageSpec::Intrinsic && funcType->get_parameters().size() == 1;
     92  }
     93
     94  namespace {
     95    template<typename CallExpr>
     96    Expression * callArg( CallExpr * callExpr, unsigned int pos ) {
     97      if ( pos >= callExpr->get_args().size() ) assert( false && "asking for argument that doesn't exist. Return NULL/throw exception?" );
     98      for ( Expression * arg : callExpr->get_args() ) {
     99        if ( pos == 0 ) return arg;
     100        pos--;
     101      }
     102      assert( false );
     103    }
     104  }
     105
     106  Expression * getCallArg( Expression * callExpr, unsigned int pos ) {
     107    if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( callExpr ) ) {
     108      return callArg( appExpr, pos );
     109    } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( callExpr ) ) {
     110      return callArg( untypedExpr, pos );
     111    } else {
     112      assert( false && "Unexpected expression type passed to getCallArg" );
    83113    }
    84114  }
  • src/InitTweak/InitTweak.h

    r70f89d00 rf1b1e4c  
    4040  bool isInstrinsicSingleArgCallStmt( Statement * expr );
    4141
     42  /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
     43  Expression * getCtorDtorCall( Statement * stmt );
     44
    4245  /// returns the name of the function being called
    43   std::string getFunctionName(Expression * expr);
     46  std::string getFunctionName( Expression * expr );
     47
     48  /// returns the argument to a call expression in position N indexed from 0
     49  Expression * getCallArg( Expression * callExpr, unsigned int pos );
    4450} // namespace
    4551
Note: See TracChangeset for help on using the changeset viewer.