Changeset 2be1023 for src/SymTab
- Timestamp:
- Jul 18, 2016, 4:13:51 PM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, 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:
- 5f98ce5
- Parents:
- 956a9c7
- Location:
- src/SymTab
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
r956a9c7 r2be1023 62 62 63 63 template< typename OutputIterator > 64 void makeScalarFunction( Expression *src, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {65 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );66 // unnamed bit fields are not copied as they cannot be accessed67 if ( isUnnamedBitfield( obj ) ) return;68 69 // want to be able to generate assignment, ctor, and dtor generically,70 // so fname is either ?=?, ?{}, or ^?{}71 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );72 73 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );74 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );75 76 // do something special for unnamed members77 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );78 fExpr->get_args().push_back( dstselect );79 80 if ( src ) {81 fExpr->get_args().push_back( src );82 }83 84 Statement * callStmt = new ExprStmt( noLabels, fExpr );85 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) {86 // implicitly generated ctor/dtor calls should be wrapped87 // so that later passes are aware they were generated.88 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield,89 // because this causes the address to be taken at codegen, which is illegal in C.90 callStmt = new ImplicitCtorDtorStmt( callStmt );91 }92 *out++ = callStmt;93 }94 95 template< typename OutputIterator >96 64 void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) { 97 65 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); … … 220 188 221 189 // assign to destination (and return value if generic) 222 if ( ArrayType *array = dynamic_cast< ArrayType * >( field->get_type() ) ) { 223 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 224 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 225 Expression *dstselect = new MemberExpr( field, derefExpr ); 226 227 makeArrayFunction( src, dstselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward ); 228 if ( isGeneric && returnVal ) { 229 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) ); 230 derefRet->get_args().push_back( new VariableExpr( returnVal ) ); 231 Expression *retselect = new MemberExpr( field, derefRet ); 232 233 makeArrayFunction( src, retselect, array, func->get_name(), back_inserter( func->get_statements()->get_kids() ), forward ); 234 } 235 } else { 236 makeScalarFunction( src, dstParam, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) ); 237 if ( isGeneric && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) ); 190 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 191 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 192 Expression *dstselect = new MemberExpr( field, derefExpr ); 193 genImplicitCall( src, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 194 195 if ( isGeneric && returnVal ) { 196 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) ); 197 derefRet->get_args().push_back( new VariableExpr( returnVal ) ); 198 Expression *retselect = new MemberExpr( field, derefRet ); 199 genImplicitCall( src, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 238 200 } // if 239 201 } -
src/SymTab/Autogen.h
r956a9c7 r2be1023 24 24 25 25 namespace SymTab { 26 27 26 /// Generates assignment operators, constructors, and destructor for aggregate types as required 27 void autogenerateRoutines( std::list< Declaration * > &translationUnit ); 28 28 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 29 /// returns true if obj's name is the empty string and it has a bitfield width 30 bool isUnnamedBitfield( ObjectDecl * obj ); 31 31 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" ); 32 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 33 template< typename OutputIterator > 34 void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward = true ); 37 35 38 // for a flexible array member nothing is done -- user must define own assignment 39 if ( ! array->get_dimension() ) return; 36 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 37 template< typename OutputIterator > 38 void genScalarCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out ) { 39 // want to be able to generate assignment, ctor, and dtor generically, 40 // so fname is either ?=?, ?{}, or ^?{} 41 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 40 42 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 } 43 // do something special for unnamed members 44 fExpr->get_args().push_back( new AddressExpr( dstParam ) ); 57 45 58 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL ); 46 if ( srcParam ) { 47 fExpr->get_args().push_back( srcParam ); 48 } 59 49 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*>() ) ); 50 *out++ = new ExprStmt( noLabels, fExpr ); 51 } 64 52 65 UntypedExpr *cond = new UntypedExpr( cmp ); 66 cond->get_args().push_back( new VariableExpr( index ) ); 67 cond->get_args().push_back( end ); 53 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 54 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 55 template< typename OutputIterator > 56 void genArrayCall( Expression *srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool forward = true ) { 57 static UniqueName indexName( "_index" ); 68 58 69 UntypedExpr *inc = new UntypedExpr( update ); 70 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );59 // for a flexible array member nothing is done -- user must define own assignment 60 if ( ! array->get_dimension() ) return ; 71 61 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 ) ); 62 Expression * begin, * end, * update, * cmp; 63 if ( forward ) { 64 // generate: for ( int i = 0; i < 0; ++i ) 65 begin = new NameExpr( "0" ); 66 end = array->get_dimension()->clone(); 67 cmp = new NameExpr( "?<?" ); 68 update = new NameExpr( "++?" ); 69 } else { 70 // generate: for ( int i = N-1; i >= 0; --i ) 71 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 72 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 73 ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) ); 74 end = new NameExpr( "0" ); 75 cmp = new NameExpr( "?>=?" ); 76 update = new NameExpr( "--?" ); 77 } 75 78 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 ); 79 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL ); 80 80 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 } 81 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) ); 82 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 83 init->get_args().push_back( begin ); 84 index->set_init( new SingleInit( init, std::list<Expression*>() ) ); 88 85 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 ) ) ); 86 UntypedExpr *cond = new UntypedExpr( cmp ); 87 cond->get_args().push_back( new VariableExpr( index ) ); 88 cond->get_args().push_back( end ); 93 89 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 ); 99 } 100 *out++ = stmt; 101 } 90 UntypedExpr *inc = new UntypedExpr( update ); 91 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 92 93 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 94 dstIndex->get_args().push_back( dstParam ); 95 dstIndex->get_args().push_back( new VariableExpr( index ) ); 96 dstParam = dstIndex; 97 98 // srcParam is NULL for default ctor/dtor 99 if ( srcParam ) { 100 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 101 srcIndex->get_args().push_back( srcParam ); 102 srcIndex->get_args().push_back( new VariableExpr( index ) ); 103 srcParam = srcIndex; 104 } 105 106 // for stmt's body, eventually containing call 107 CompoundStmt * body = new CompoundStmt( noLabels ); 108 genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), forward ); 109 110 // block containing for stmt and index variable 111 std::list<Statement *> initList; 112 CompoundStmt * block = new CompoundStmt( noLabels ); 113 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 114 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 115 116 *out++ = block; 117 } 118 119 template< typename OutputIterator > 120 void genCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool forward ) { 121 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 122 genArrayCall( srcParam, dstParam, fname, out, at, forward ); 123 } else { 124 genScalarCall( srcParam, dstParam, fname, out ); 125 } 126 } 127 128 /// inserts into out a generated call expression to function fname with arguments dstParam 129 /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the 130 /// object being constructed. The function wraps constructor and destructor calls in an 131 /// ImplicitCtorDtorStmt node. 132 template< typename OutputIterator > 133 void genImplicitCall( Expression * srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 134 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 135 assert( obj ); 136 // unnamed bit fields are not copied as they cannot be accessed 137 if ( isUnnamedBitfield( obj ) ) return; 138 139 std::list< Statement * > stmts; 140 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), forward ); 141 142 // currently genCall should produce only one element, but if that changes then the next line needs to be updated to grab the statement which contains the call 143 assert( stmts.size() == 1 ); 144 Statement * callStmt = stmts.front(); 145 if ( (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ) ) { 146 // implicitly generated ctor/dtor calls should be wrapped 147 // so that later passes are aware they were generated. 148 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 149 // because this causes the address to be taken at codegen, which is illegal in C. 150 callStmt = new ImplicitCtorDtorStmt( callStmt ); 151 } 152 *out++ = callStmt; 153 } 102 154 } // namespace SymTab 103 155 #endif // AUTOGEN_H
Note: See TracChangeset
for help on using the changeset viewer.