Changes in src/SymTab/Autogen.h [6cf27a07:cad355a]
- File:
-
- 1 edited
-
src/SymTab/Autogen.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.h
r6cf27a07 rcad355a 24 24 25 25 namespace SymTab { 26 /// Generates assignment operators, constructors, and destructor for aggregate types as required27 void autogenerateRoutines( std::list< Declaration * > &translationUnit );26 /// Generates assignment operators, constructors, and destructor for aggregate types as required 27 void autogenerateRoutines( std::list< Declaration * > &translationUnit ); 28 28 29 /// returns true if obj's name is the empty string and it has a bitfield width 30 bool isUnnamedBitfield( ObjectDecl * obj ); 29 // originally makeArrayAssignment - changed to Function because it is now used for ctors and dtors as well 30 // admittedly not a great name change. This used to live in Validate.cc, but has been moved so it can be reused elsewhere 31 31 32 /// size_t type - set when size_t typedef is seen. Useful in a few places, 33 /// such as in determining array dimension type 34 extern Type * SizeType; 32 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 33 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 34 template< typename OutputIterator > 35 void makeArrayFunction( Expression *srcParam, Expression *dstParam, ArrayType *array, std::string fname, OutputIterator out, bool forward = true ) { 36 static UniqueName indexName( "_index" ); 35 37 36 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 37 template< typename OutputIterator > 38 void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward = true ); 38 // for a flexible array member nothing is done -- user must define own assignment 39 if ( ! array->get_dimension() ) return; 39 40 40 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 41 template< typename OutputIterator > 42 void genScalarCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out ) { 43 // want to be able to generate assignment, ctor, and dtor generically, 44 // so fname is either ?=?, ?{}, or ^?{} 45 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 41 Expression * begin, * end, * update, * cmp; 42 if ( forward ) { 43 // generate: for ( int i = 0; i < 0; ++i ) 44 begin = new NameExpr( "0" ); 45 end = array->get_dimension()->clone(); 46 cmp = new NameExpr( "?<?" ); 47 update = new NameExpr( "++?" ); 48 } else { 49 // generate: for ( int i = N-1; i >= 0; --i ) 50 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 51 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 52 ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) ); 53 end = new NameExpr( "0" ); 54 cmp = new NameExpr( "?>=?" ); 55 update = new NameExpr( "--?" ); 56 } 46 57 47 // do something special for unnamed members 48 fExpr->get_args().push_back( new AddressExpr( dstParam ) ); 58 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL ); 49 59 50 if ( srcParam ) { 51 fExpr->get_args().push_back( srcParam ); 52 } 60 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) ); 61 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 62 init->get_args().push_back( begin ); 63 index->set_init( new SingleInit( init, std::list<Expression*>() ) ); 53 64 54 *out++ = new ExprStmt( noLabels, fExpr ); 55 } 65 UntypedExpr *cond = new UntypedExpr( cmp ); 66 cond->get_args().push_back( new VariableExpr( index ) ); 67 cond->get_args().push_back( end ); 56 68 57 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 58 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 59 template< typename OutputIterator > 60 void genArrayCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool forward = true ) { 61 static UniqueName indexName( "_index" ); 69 UntypedExpr *inc = new UntypedExpr( update ); 70 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 62 71 63 // for a flexible array member nothing is done -- user must define own assignment 64 if ( ! array->get_dimension() ) return ; 72 // want to be able to generate assignment, ctor, and dtor generically, 73 // so fname is either ?=?, ?{}, or ^?{} 74 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 65 75 66 Expression * begin, * end, * update, * cmp; 67 if ( forward ) { 68 // generate: for ( int i = 0; i < 0; ++i ) 69 begin = new NameExpr( "0" ); 70 end = array->get_dimension()->clone(); 71 cmp = new NameExpr( "?<?" ); 72 update = new NameExpr( "++?" ); 73 } else { 74 // generate: for ( int i = N-1; i >= 0; --i ) 75 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 76 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 77 ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) ); 78 end = new NameExpr( "0" ); 79 cmp = new NameExpr( "?>=?" ); 80 update = new NameExpr( "--?" ); 81 } 76 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) ); 77 dstIndex->get_args().push_back( dstParam ); 78 dstIndex->get_args().push_back( new VariableExpr( index ) ); 79 fExpr->get_args().push_back( dstIndex ); 82 80 83 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL ); 81 // srcParam is NULL for default ctor/dtor 82 if ( srcParam ) { 83 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 84 srcIndex->get_args().push_back( srcParam ); 85 srcIndex->get_args().push_back( new VariableExpr( index ) ); 86 fExpr->get_args().push_back( srcIndex ); 87 } 84 88 85 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );86 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ));87 init->get_args().push_back( begin);88 index->set_init( new SingleInit( init, std::list<Expression*>() ) );89 std::list<Statement *> initList; 90 CompoundStmt * block = new CompoundStmt( noLabels ); 91 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 92 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) ) ); 89 93 90 UntypedExpr *cond = new UntypedExpr( cmp ); 91 cond->get_args().push_back( new VariableExpr( index ) ); 92 cond->get_args().push_back( end ); 93 94 UntypedExpr *inc = new UntypedExpr( update ); 95 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 96 97 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 98 dstIndex->get_args().push_back( dstParam ); 99 dstIndex->get_args().push_back( new VariableExpr( index ) ); 100 dstParam = dstIndex; 101 102 // srcParam is NULL for default ctor/dtor 103 if ( srcParam ) { 104 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 105 srcIndex->get_args().push_back( srcParam ); 106 srcIndex->get_args().push_back( new VariableExpr( index ) ); 107 srcParam = srcIndex; 108 } 109 110 // for stmt's body, eventually containing call 111 CompoundStmt * body = new CompoundStmt( noLabels ); 112 genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), forward ); 113 114 // block containing for stmt and index variable 115 std::list<Statement *> initList; 116 CompoundStmt * block = new CompoundStmt( noLabels ); 117 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 118 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 119 120 *out++ = block; 121 } 122 123 template< typename OutputIterator > 124 void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward ) { 125 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 126 genArrayCall( srcParam, dstParam, fname, out, at, forward ); 127 } else { 128 genScalarCall( srcParam, dstParam, fname, out ); 129 } 130 } 131 132 /// inserts into out a generated call expression to function fname with arguments dstParam 133 /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the 134 /// object being constructed. The function wraps constructor and destructor calls in an 135 /// ImplicitCtorDtorStmt node. 136 template< typename OutputIterator > 137 void genImplicitCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 138 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 139 assert( obj ); 140 // unnamed bit fields are not copied as they cannot be accessed 141 if ( isUnnamedBitfield( obj ) ) return; 142 143 std::list< Statement * > stmts; 144 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), forward ); 145 146 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call 147 assert( stmts.size() <= 1 ); 148 if ( stmts.size() == 1 ) { 149 Statement * callStmt = stmts.front(); 150 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) { 151 // implicitly generated ctor/dtor calls should be wrapped 152 // so that later passes are aware they were generated. 153 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 154 // because this causes the address to be taken at codegen, which is illegal in C. 155 callStmt = new ImplicitCtorDtorStmt( callStmt ); 156 } 157 *out++ = callStmt; 94 Statement * stmt = block; 95 if ( fname == "?{}" || fname == "^?{}" ) { 96 // implicitly generated ctor/dtor calls should be wrapped 97 // so that later passes are aware they were generated 98 stmt = new ImplicitCtorDtorStmt( stmt ); 158 99 } 159 } 100 *out++ = stmt; 101 } 160 102 } // namespace SymTab 161 103 #endif // AUTOGEN_H
Note:
See TracChangeset
for help on using the changeset viewer.