Changeset c331406 for src/SymTab
- Timestamp:
- Aug 5, 2016, 11:03:04 AM (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:
- a2f920f
- Parents:
- 5070fe4 (diff), 1b0020a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/SymTab
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/AddVisit.h
r5070fe4 rc331406 10 10 // Created On : Sun May 17 16:14:32 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Jul 12 17:46:33201613 // Update Count : 612 // Last Modified On : Thu Aug 4 11:22:01 2016 13 // Update Count : 9 14 14 // 15 15 … … 33 33 template< typename Visitor > 34 34 inline void addVisit(SwitchStmt *switchStmt, Visitor &visitor) { 35 addVisitStatementList( switchStmt->get_ branches(), visitor );35 addVisitStatementList( switchStmt->get_statements(), visitor ); 36 36 maybeAccept( switchStmt->get_condition(), visitor ); 37 37 } -
src/SymTab/Autogen.cc
r5070fe4 rc331406 26 26 27 27 namespace SymTab { 28 Type * SizeType = 0; 29 28 30 class AutogenerateRoutines : public Visitor { 29 31 public: … … 59 61 bool isUnnamedBitfield( ObjectDecl * obj ) { 60 62 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL; 61 }62 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 63 } 94 64 … … 219 189 } 220 190 191 InitTweak::InitExpander srcParam( src ); 192 221 193 // 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 ( isDynamicLayout && 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 ( isDynamicLayout && returnVal ) makeScalarFunction( src, returnVal, field, func->get_name(), back_inserter( func->get_statements()->get_kids() ) ); 194 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 195 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 196 Expression *dstselect = new MemberExpr( field, derefExpr ); 197 genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 198 199 if ( isDynamicLayout && returnVal ) { 200 UntypedExpr *derefRet = new UntypedExpr( new NameExpr( "*?" ) ); 201 derefRet->get_args().push_back( new VariableExpr( returnVal ) ); 202 Expression *retselect = new MemberExpr( field, derefRet ); 203 genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 238 204 } // if 239 205 } -
src/SymTab/Autogen.h
r5070fe4 rc331406 22 22 #include "SynTree/Declaration.h" 23 23 #include "SynTree/Initializer.h" 24 #include "InitTweak/InitTweak.h" 24 25 25 26 namespace SymTab { 26 27 27 /// Generates assignment operators, constructors, and destructor for aggregate types as required 28 void autogenerateRoutines( std::list< Declaration * > &translationUnit ); 28 29 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 30 /// returns true if obj's name is the empty string and it has a bitfield width 31 bool isUnnamedBitfield( ObjectDecl * obj ); 31 32 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" ); 33 /// size_t type - set when size_t typedef is seen. Useful in a few places, 34 /// such as in determining array dimension type 35 extern Type * SizeType; 37 36 38 // for a flexible array member nothing is done -- user must define own assignment 39 if ( ! array->get_dimension() ) return; 37 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 38 template< typename OutputIterator > 39 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true ); 40 40 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 } 41 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 42 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 43 template< typename OutputIterator > 44 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) { 45 // want to be able to generate assignment, ctor, and dtor generically, 46 // so fname is either ?=?, ?{}, or ^?{} 47 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 57 48 58 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL ); 49 // do something special for unnamed members 50 dstParam = new AddressExpr( dstParam ); 51 if ( addCast ) { 52 // cast to T* with qualifiers removed, so that qualified objects can be constructed 53 // and destructed with the same functions as non-qualified objects. 54 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 55 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 56 // remove lvalue as a qualifier, this can change to 57 // type->get_qualifiers() = Type::Qualifiers(); 58 assert( type ); 59 Type * castType = type->clone(); 60 castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, true); 61 castType->set_isLvalue( true ); // xxx - might not need this 62 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) ); 63 } 64 fExpr->get_args().push_back( dstParam ); 59 65 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*>() ) ); 66 Statement * listInit = srcParam.buildListInit( fExpr ); 64 67 65 UntypedExpr *cond = new UntypedExpr( cmp ); 66 cond->get_args().push_back( new VariableExpr( index ) ); 67 cond->get_args().push_back( end ); 68 std::list< Expression * > args = *++srcParam; 69 fExpr->get_args().splice( fExpr->get_args().end(), args ); 68 70 69 UntypedExpr *inc = new UntypedExpr( update ); 70 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 71 *out++ = new ExprStmt( noLabels, fExpr ); 71 72 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 ) ); 73 srcParam.clearArrayIndices(); 75 74 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 ); 75 return listInit; 76 } 80 77 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 } 78 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 79 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 80 template< typename OutputIterator > 81 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) { 82 static UniqueName indexName( "_index" ); 88 83 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 ) ) ); 84 // for a flexible array member nothing is done -- user must define own assignment 85 if ( ! array->get_dimension() ) return ; 93 86 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 } 87 Expression * begin, * end, * update, * cmp; 88 if ( forward ) { 89 // generate: for ( int i = 0; i < 0; ++i ) 90 begin = new NameExpr( "0" ); 91 end = array->get_dimension()->clone(); 92 cmp = new NameExpr( "?<?" ); 93 update = new NameExpr( "++?" ); 94 } else { 95 // generate: for ( int i = N-1; i >= 0; --i ) 96 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 97 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 98 ((UntypedExpr*)begin)->get_args().push_back( new NameExpr( "1" ) ); 99 end = new NameExpr( "0" ); 100 cmp = new NameExpr( "?>=?" ); 101 update = new NameExpr( "--?" ); 102 } 103 104 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL ); 105 106 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) ); 107 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 108 init->get_args().push_back( begin ); 109 index->set_init( new SingleInit( init, std::list<Expression*>() ) ); 110 111 UntypedExpr *cond = new UntypedExpr( cmp ); 112 cond->get_args().push_back( new VariableExpr( index ) ); 113 cond->get_args().push_back( end ); 114 115 UntypedExpr *inc = new UntypedExpr( update ); 116 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 117 118 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 119 dstIndex->get_args().push_back( dstParam ); 120 dstIndex->get_args().push_back( new VariableExpr( index ) ); 121 dstParam = dstIndex; 122 123 // srcParam must keep track of the array indices to build the 124 // source parameter and/or array list initializer 125 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() ); 126 127 // for stmt's body, eventually containing call 128 CompoundStmt * body = new CompoundStmt( noLabels ); 129 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward ); 130 131 // block containing for stmt and index variable 132 std::list<Statement *> initList; 133 CompoundStmt * block = new CompoundStmt( noLabels ); 134 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 135 if ( listInit ) block->get_kids().push_back( listInit ); 136 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 137 138 *out++ = block; 139 } 140 141 template< typename OutputIterator > 142 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) { 143 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 144 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); 145 return 0; 146 } else { 147 return genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 148 } 149 } 150 151 /// inserts into out a generated call expression to function fname with arguments dstParam 152 /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the 153 /// object being constructed. The function wraps constructor and destructor calls in an 154 /// ImplicitCtorDtorStmt node. 155 template< typename OutputIterator > 156 void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 157 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 158 assert( obj ); 159 // unnamed bit fields are not copied as they cannot be accessed 160 if ( isUnnamedBitfield( obj ) ) return; 161 162 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ); 163 std::list< Statement * > stmts; 164 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward ); 165 166 // 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 167 assert( stmts.size() <= 1 ); 168 if ( stmts.size() == 1 ) { 169 Statement * callStmt = stmts.front(); 170 if ( addCast ) { 171 // implicitly generated ctor/dtor calls should be wrapped 172 // so that later passes are aware they were generated. 173 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 174 // because this causes the address to be taken at codegen, which is illegal in C. 175 callStmt = new ImplicitCtorDtorStmt( callStmt ); 176 } 177 *out++ = callStmt; 178 } 179 } 102 180 } // namespace SymTab 103 181 #endif // AUTOGEN_H -
src/SymTab/FixFunction.cc
r5070fe4 rc331406 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FixFunction.cc -- 7 // FixFunction.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 44 44 45 45 Type * FixFunction::mutate(ArrayType *arrayType) { 46 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), maybeClone( arrayType->get_base()->clone() ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() ); 46 // need to recursively mutate the base type in order for multi-dimensional arrays to work. 47 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone()->acceptMutator( *this ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() ); 47 48 delete arrayType; 48 49 return pointerType; -
src/SymTab/Validate.cc
r5070fe4 rc331406 174 174 175 175 virtual void visit( FunctionDecl *funcDecl ); 176 };176 }; 177 177 178 178 class CompoundLiteral : public GenPoly::DeclMutator { … … 191 191 EliminateTypedef::eliminateTypedef( translationUnit ); 192 192 HoistStruct::hoistStruct( translationUnit ); 193 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs Pass1 193 194 acceptAll( translationUnit, pass1 ); 194 195 acceptAll( translationUnit, pass2 ); 195 196 ReturnChecker::checkFunctionReturns( translationUnit ); 196 mutateAll( translationUnit, compoundliteral ); 197 autogenerateRoutines( translationUnit ); 197 compoundliteral.mutateDeclarationList( translationUnit ); 198 198 acceptAll( translationUnit, pass3 ); 199 199 VerifyCtorDtor::verify( translationUnit ); … … 490 490 EliminateTypedef eliminator; 491 491 mutateAll( translationUnit, eliminator ); 492 if ( eliminator.typedefNames.count( "size_t" ) ) { 493 // grab and remember declaration of size_t 494 SizeType = eliminator.typedefNames["size_t"].first->get_base()->clone(); 495 } else { 496 // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong 497 // eventually should have a warning for this case. 498 SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 499 } 492 500 filter( translationUnit, isTypedef, true ); 501 493 502 } 494 503 … … 518 527 Declaration *EliminateTypedef::mutate( TypedefDecl * tyDecl ) { 519 528 Declaration *ret = Mutator::mutate( tyDecl ); 529 520 530 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) { 521 531 // typedef to the same name from the same scope
Note: See TracChangeset
for help on using the changeset viewer.