Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/InitTweak.cc

    r64071c2 r2b46a13  
    77
    88namespace InitTweak {
    9         namespace {
    10                 class HasDesignations : public Visitor {
    11                 public:
    12                         bool hasDesignations = false;
    13                         template<typename Init>
    14                         void handleInit( Init * init ) {
    15                                 if ( ! init->get_designators().empty() ) hasDesignations = true;
    16                                 else Visitor::visit( init );
    17                         }
    18                         virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
    19                         virtual void visit( ListInit * listInit ) { handleInit( listInit); }
    20                 };
     9  namespace {
     10    class HasDesignations : public Visitor {
     11    public:
     12      bool hasDesignations = false;
     13      template<typename Init>
     14      void handleInit( Init * init ) {
     15        if ( ! init->get_designators().empty() ) hasDesignations = true;
     16        else Visitor::visit( init );
     17      }
     18      virtual void visit( SingleInit * singleInit ) { handleInit( singleInit); }
     19      virtual void visit( ListInit * listInit ) { handleInit( listInit); }
     20    };
    2121
    22                 class InitExpander : public Visitor {
    23                         public:
    24                         InitExpander() {}
    25                         virtual void visit( SingleInit * singleInit );
    26                         virtual void visit( ListInit * listInit );
    27                         std::list< Expression * > argList;
    28                 };
     22    class InitExpander : public Visitor {
     23      public:
     24      InitExpander() {}
     25      virtual void visit( SingleInit * singleInit );
     26      virtual void visit( ListInit * listInit );
     27      std::list< Expression * > argList;
     28    };
    2929
    30                 void InitExpander::visit( SingleInit * singleInit ) {
    31                         argList.push_back( singleInit->get_value()->clone() );
    32                 }
     30    void InitExpander::visit( SingleInit * singleInit ) {
     31      argList.push_back( singleInit->get_value()->clone() );
     32    }
    3333
    34                 void InitExpander::visit( ListInit * listInit ) {
    35                         // xxx - for now, assume no nested list inits
    36                         std::list<Initializer*>::iterator it = listInit->begin_initializers();
    37                         for ( ; it != listInit->end_initializers(); ++it ) {
    38                                 (*it)->accept( *this );
    39                         }
    40                 }
    41         }
     34    void InitExpander::visit( ListInit * listInit ) {
     35      // xxx - for now, assume no nested list inits
     36      std::list<Initializer*>::iterator it = listInit->begin_initializers();
     37      for ( ; it != listInit->end_initializers(); ++it ) {
     38        (*it)->accept( *this );
     39      }
     40    }
     41  }
    4242
    43         std::list< Expression * > makeInitList( Initializer * init ) {
    44                 InitExpander expander;
    45                 maybeAccept( init, expander );
    46                 return expander.argList;
    47         }
     43  std::list< Expression * > makeInitList( Initializer * init ) {
     44    InitExpander expander;
     45    maybeAccept( init, expander );
     46    return expander.argList;
     47  }
    4848
    49         bool isDesignated( Initializer * init ) {
    50                 HasDesignations finder;
    51                 maybeAccept( init, finder );
    52                 return finder.hasDesignations;
    53         }
     49  bool isDesignated( Initializer * init ) {
     50    HasDesignations finder;
     51    maybeAccept( init, finder );
     52    return finder.hasDesignations;
     53  }
    5454
    55         bool tryConstruct( ObjectDecl * objDecl ) {
    56                 return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
    57                         (objDecl->get_init() == NULL ||
    58                                 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
    59                         ! isDesignated( objDecl->get_init() );
    60         }
     55  bool tryConstruct( ObjectDecl * objDecl ) {
     56    return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) &&
     57      (objDecl->get_init() == NULL ||
     58        ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) &&
     59      ! isDesignated( objDecl->get_init() );
     60  }
    6161
    62         Expression * getCtorDtorCall( Statement * stmt ) {
    63                 if ( stmt == NULL ) return NULL;
    64                 if ( ExprStmt * exprStmt = dynamic_cast< ExprStmt * >( stmt ) ) {
    65                         return exprStmt->get_expr();
    66                 } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
    67                         // could also be a compound statement with a loop, in the case of an array
    68                         assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop
    69                         ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
    70                         assert( forStmt && forStmt->get_body() );
    71                         return getCtorDtorCall( forStmt->get_body() );
    72                 } if ( ImplicitCtorDtorStmt * impCtorDtorStmt = dynamic_cast< ImplicitCtorDtorStmt * > ( stmt ) ) {
    73                         return getCtorDtorCall( impCtorDtorStmt->get_callStmt() );
    74                 } else {
    75                         // should never get here
    76                         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" );
    113                 }
    114         }
    115 
    116         namespace {
    117                 template<typename CallExpr>
    118                 std::string funcName( CallExpr * expr ) {
    119                         Expression * func = expr->get_function();
    120                         if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( func ) ) {
    121                                 return nameExpr->get_name();
    122                         } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( func ) ) {
    123                                 return varExpr->get_var()->get_name();
    124                         } else {
    125                                 assert( false && "Unexpected expression type being called as a function in call expression" );
    126                         }
    127                 }
    128         }
    129 
    130         std::string getFunctionName( Expression * expr ) {
    131                 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ) ) {
    132                         return funcName( appExpr );
    133                 } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * > ( expr ) ) {
    134                         return funcName( untypedExpr );
    135                 } else {
    136                         assert( false && "Unexpected expression type passed to getFunctionName" );
    137                 }
    138         }
    139 
    140         Type * getPointerBase( Type * type ) {
    141                 if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) {
    142                         return ptrType->get_base();
    143                 } else if ( ArrayType * arrayType = dynamic_cast< ArrayType * >( type ) ) {
    144                         return arrayType->get_base();
    145                 } else {
    146                         return NULL;
    147                 }
    148         }
    149 
    150         Type * isPointerType( Type * type ) {
    151                 if ( getPointerBase( type ) ) return type;
    152                 else return NULL;
    153         }
     62  bool isInstrinsicSingleArgCallStmt( Statement * stmt ) {
     63    if ( stmt == NULL ) return false;
     64    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;
     74    } else if ( CompoundStmt * compoundStmt = dynamic_cast< CompoundStmt * >( stmt ) ) {
     75      // could also be a compound statement with a loop, in the case of an array
     76      assert( compoundStmt->get_kids().size() == 2 ); // loop variable and loop
     77      ForStmt * forStmt = dynamic_cast< ForStmt * >( compoundStmt->get_kids().back() );
     78      assert( forStmt && forStmt->get_body() );
     79      return isInstrinsicSingleArgCallStmt( forStmt->get_body() );
     80    } else {
     81      // should never get here
     82      assert( false && "encountered unknown call statement" );
     83    }
     84  }
    15485}
Note: See TracChangeset for help on using the changeset viewer.