Changes in src/SymTab/Autogen.h [8913de4:e6cf857f]
- File:
-
- 1 edited
-
src/SymTab/Autogen.h (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.h
r8913de4 re6cf857f 9 9 // Author : Rob Schluntz 10 10 // Created On : Sun May 17 21:53:34 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Apr 14 15:06:00 202313 // Update Count : 1 711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 13 16:38:06 2019 13 // Update Count : 16 14 14 // 15 15 … … 20 20 #include <string> // for string 21 21 22 #include "AST/Decl.hpp" 23 #include "AST/Expr.hpp" 24 #include "AST/Init.hpp" 25 #include "AST/Node.hpp" 26 #include "AST/Stmt.hpp" 27 #include "AST/Type.hpp" 22 28 #include "CodeGen/OperatorTable.h" 23 29 #include "Common/UniqueName.h" // for UniqueName … … 39 45 /// returns true if obj's name is the empty string and it has a bitfield width 40 46 bool isUnnamedBitfield( ObjectDecl * obj ); 47 bool isUnnamedBitfield( const ast::ObjectDecl * obj ); 41 48 42 49 /// generate the type of an assignment function for paramType. … … 48 55 FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic = true ); 49 56 57 ast::FunctionDecl * genDefaultFunc(const CodeLocation loc, const std::string fname, const ast::Type * paramType, bool maybePolymorphic = true); 58 50 59 /// generate the type of a copy constructor for paramType. 51 60 /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic 52 61 FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true ); 53 62 63 /// Enum for loop direction 64 enum LoopDirection { LoopBackward, LoopForward }; 65 54 66 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 55 67 template< typename OutputIterator > 56 68 Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true ); 69 70 template< typename OutIter > 71 ast::ptr< ast::Stmt > genCall( 72 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 73 const CodeLocation & loc, const std::string & fname, OutIter && out, 74 const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward ); 57 75 58 76 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. … … 103 121 104 122 *out++ = new ExprStmt( fExpr ); 123 124 srcParam.clearArrayIndices(); 125 126 return listInit; 127 } 128 129 /// inserts into out a generated call expression to function fname with arguments dstParam and 130 /// srcParam. Should only be called with non-array types. 131 /// optionally returns a statement which must be inserted prior to the containing loop, if 132 /// there is one 133 template< typename OutIter > 134 ast::ptr< ast::Stmt > genScalarCall( 135 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 136 const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type, 137 const ast::Type * addCast = nullptr 138 ) { 139 bool isReferenceCtorDtor = false; 140 if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) { 141 // reference constructors are essentially application of the rebind operator. 142 // apply & to both arguments, do not need a cast 143 fname = "?=?"; 144 dstParam = new ast::AddressExpr{ dstParam }; 145 addCast = nullptr; 146 isReferenceCtorDtor = true; 147 } 148 149 // want to be able to generate assignment, ctor, and dtor generically, so fname is one of 150 // "?=?", "?{}", or "^?{}" 151 ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } }; 152 153 if ( addCast ) { 154 // cast to T& with qualifiers removed, so that qualified objects can be constructed and 155 // destructed with the same functions as non-qualified objects. Unfortunately, lvalue 156 // is considered a qualifier - for AddressExpr to resolve, its argument must have an 157 // lvalue-qualified type, so remove all qualifiers except lvalue. 158 // xxx -- old code actually removed lvalue too... 159 ast::ptr< ast::Type > guard = addCast; // prevent castType from mutating addCast 160 ast::ptr< ast::Type > castType = addCast; 161 ast::remove_qualifiers( 162 castType, 163 ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic ); 164 dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } }; 165 } 166 fExpr->args.emplace_back( dstParam ); 167 168 ast::ptr<ast::Stmt> listInit = srcParam.buildListInit( fExpr ); 169 170 // fetch next set of arguments 171 ++srcParam; 172 173 // return if adding reference fails -- will happen on default ctor and dtor 174 if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit; 175 176 std::vector< ast::ptr< ast::Expr > > args = *srcParam; 177 splice( fExpr->args, args ); 178 179 *out++ = new ast::ExprStmt{ loc, fExpr }; 105 180 106 181 srcParam.clearArrayIndices(); … … 173 248 } 174 249 250 /// Store in out a loop which calls fname on each element of the array with srcParam and 251 /// dstParam as arguments. If forward is true, loop goes from 0 to N-1, else N-1 to 0 252 template< typename OutIter > 253 void genArrayCall( 254 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 255 const CodeLocation & loc, const std::string & fname, OutIter && out, 256 const ast::ArrayType * array, const ast::Type * addCast = nullptr, 257 LoopDirection forward = LoopForward 258 ) { 259 static UniqueName indexName( "_index" ); 260 261 // for a flexible array member nothing is done -- user must define own assignment 262 if ( ! array->dimension ) return; 263 264 if ( addCast ) { 265 // peel off array layer from cast 266 addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base; 267 } 268 269 ast::ptr< ast::Expr > begin, end; 270 std::string cmp, update; 271 272 if ( forward ) { 273 // generate: for ( int i = 0; i < N; ++i ) 274 begin = ast::ConstantExpr::from_int( loc, 0 ); 275 end = array->dimension; 276 cmp = "?<?"; 277 update = "++?"; 278 } else { 279 // generate: for ( int i = N-1; i >= 0; --i ) 280 begin = ast::UntypedExpr::createCall( loc, "?-?", 281 { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } ); 282 end = ast::ConstantExpr::from_int( loc, 0 ); 283 cmp = "?>=?"; 284 update = "--?"; 285 } 286 287 ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{ 288 loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt }, 289 new ast::SingleInit{ loc, begin } }; 290 ast::ptr< ast::Expr > indexVar = new ast::VariableExpr{ loc, index }; 291 292 ast::ptr< ast::Expr > cond = ast::UntypedExpr::createCall( 293 loc, cmp, { indexVar, end } ); 294 295 ast::ptr< ast::Expr > inc = ast::UntypedExpr::createCall( 296 loc, update, { indexVar } ); 297 298 ast::ptr< ast::Expr > dstIndex = ast::UntypedExpr::createCall( 299 loc, "?[?]", { dstParam, indexVar } ); 300 301 // srcParam must keep track of the array indices to build the source parameter and/or 302 // array list initializer 303 srcParam.addArrayIndex( indexVar, array->dimension ); 304 305 // for stmt's body, eventually containing call 306 ast::CompoundStmt * body = new ast::CompoundStmt{ loc }; 307 ast::ptr< ast::Stmt > listInit = genCall( 308 srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast, 309 forward ); 310 311 // block containing the stmt and index variable 312 ast::CompoundStmt * block = new ast::CompoundStmt{ loc }; 313 block->push_back( new ast::DeclStmt{ loc, index } ); 314 if ( listInit ) { block->push_back( listInit ); } 315 block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } ); 316 317 *out++ = block; 318 } 319 175 320 template< typename OutputIterator > 176 321 Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) { … … 180 325 } else { 181 326 return genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 327 } 328 } 329 330 template< typename OutIter > 331 ast::ptr< ast::Stmt > genCall( 332 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 333 const CodeLocation & loc, const std::string & fname, OutIter && out, 334 const ast::Type * type, const ast::Type * addCast, LoopDirection forward 335 ) { 336 if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) { 337 genArrayCall( 338 srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast, 339 forward ); 340 return {}; 341 } else { 342 return genScalarCall( 343 srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast ); 182 344 } 183 345 } … … 217 379 } 218 380 381 static inline ast::ptr< ast::Stmt > genImplicitCall( 382 InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam, 383 const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj, 384 LoopDirection forward = LoopForward 385 ) { 386 // unnamed bit fields are not copied as they cannot be accessed 387 if ( isUnnamedBitfield( obj ) ) return {}; 388 389 ast::ptr< ast::Type > addCast; 390 if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) { 391 assert( dstParam->result ); 392 addCast = dstParam->result; 393 } 394 395 std::vector< ast::ptr< ast::Stmt > > stmts; 396 genCall( 397 srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward ); 398 399 if ( stmts.empty() ) { 400 return {}; 401 } else if ( stmts.size() == 1 ) { 402 const ast::Stmt * callStmt = stmts.front(); 403 if ( addCast ) { 404 // implicitly generated ctor/dtor calls should be wrapped so that later passes are 405 // aware they were generated. 406 callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt }; 407 } 408 return callStmt; 409 } else { 410 assert( false ); 411 return {}; 412 } 413 } 219 414 } // namespace SymTab 220 415
Note:
See TracChangeset
for help on using the changeset viewer.