source: src/InitTweak/InitTweak.cc @ e034675

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since e034675 was 2b46a13, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

missing InitTweak?.cc/.h

  • Property mode set to 100644
File size: 3.2 KB
Line 
1#include "InitTweak.h"
2#include "SynTree/Visitor.h"
3#include "SynTree/Statement.h"
4#include "SynTree/Initializer.h"
5#include "SynTree/Expression.h"
6#include "GenPoly/GenPoly.h"
7
8namespace 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    };
21
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    };
29
30    void InitExpander::visit( SingleInit * singleInit ) {
31      argList.push_back( singleInit->get_value()->clone() );
32    }
33
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  }
42
43  std::list< Expression * > makeInitList( Initializer * init ) {
44    InitExpander expander;
45    maybeAccept( init, expander );
46    return expander.argList;
47  }
48
49  bool isDesignated( Initializer * init ) {
50    HasDesignations finder;
51    maybeAccept( init, finder );
52    return finder.hasDesignations;
53  }
54
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  }
61
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  }
85}
Note: See TracBrowser for help on using the repository browser.