Changeset 18ca28e
- Timestamp:
- Oct 19, 2017, 11:15:19 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- d411426d
- Parents:
- 0a267c1
- git-author:
- Rob Schluntz <rschlunt@…> (10/13/17 13:49:10)
- git-committer:
- Rob Schluntz <rschlunt@…> (10/19/17 11:15:19)
- Location:
- src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/GenInit.cc
r0a267c1 r18ca28e 128 128 if ( returnStmt->expr && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) { 129 129 // explicitly construct the return value using the return expression and the retVal object 130 assertf( returnVals.front()-> get_name()!= "", "Function %s has unnamed return value\n", funcName.c_str() );130 assertf( returnVals.front()->name != "", "Function %s has unnamed return value\n", funcName.c_str() ); 131 131 132 132 ObjectDecl * retVal = strict_dynamic_cast< ObjectDecl * >( returnVals.front() ); … … 138 138 139 139 // return the retVal object 140 returnStmt-> set_expr( new VariableExpr( returnVals.front()) );140 returnStmt->expr = new VariableExpr( returnVals.front() ); 141 141 } // if 142 142 } -
src/SymTab/Autogen.cc
r0a267c1 r18ca28e 174 174 }; 175 175 176 class EnumFuncGenerator : public FuncGenerator { 177 public: 178 EnumFuncGenerator( EnumInstType * refType, const std::vector< FuncData > & data, unsigned int functionNesting, SymTab::Indexer & indexer ) : FuncGenerator( refType, data, functionNesting, indexer ) {} 179 180 virtual bool shouldAutogen() const override; 181 virtual bool isConcurrentType() const override; 182 183 virtual void genFuncBody( FunctionDecl * dcl ) override; 184 virtual void genFieldCtors() override; 185 186 private: 187 }; 188 176 189 class TypeFuncGenerator : public FuncGenerator { 177 190 TypeDecl * typeDecl; … … 247 260 decl->fixUniqueId(); 248 261 return decl; 249 }250 251 /// generates a single enumeration assignment expression252 ApplicationExpr * genEnumAssign( FunctionType * ftype, FunctionDecl * assignDecl ) {253 // enum copy construct and assignment is just C-style assignment.254 // this looks like a bad recursive call, but code gen will turn it into255 // a C-style assignment.256 // This happens before function pointer type conversion, so need to do it manually here257 // NOTE: ftype is not necessarily the functionType belonging to assignDecl - ftype is the258 // type of the function that this expression is being generated for (so that the correct259 // parameters) are using in the variable exprs260 assert( ftype->get_parameters().size() == 2 );261 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() );262 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() );263 264 VariableExpr * assignVarExpr = new VariableExpr( assignDecl );265 Type * assignVarExprType = assignVarExpr->get_result();266 assignVarExprType = new PointerType( Type::Qualifiers(), assignVarExprType );267 assignVarExpr->set_result( assignVarExprType );268 ApplicationExpr * assignExpr = new ApplicationExpr( assignVarExpr );269 assignExpr->get_args().push_back( new VariableExpr( dstParam ) );270 assignExpr->get_args().push_back( new VariableExpr( srcParam ) );271 return assignExpr;272 }273 274 // E ?=?(E volatile*, int),275 // ?=?(E _Atomic volatile*, int);276 void makeEnumFunctions( EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd, SymTab::Indexer & indexer ) {277 278 // T ?=?(E *, E);279 FunctionType *assignType = genAssignType( refType );280 281 // void ?{}(E *); void ^?{}(E *);282 FunctionType * ctorType = genDefaultType( refType->clone() );283 FunctionType * dtorType = genDefaultType( refType->clone() );284 285 // void ?{}(E *, E);286 FunctionType *copyCtorType = genCopyType( refType->clone() );287 288 // add unused attribute to parameters of default constructor and destructor289 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) );290 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) );291 292 // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)?293 // right now these cases work, but that might change.294 295 // xxx - Temporary: make these functions intrinsic so they codegen as C assignment.296 // Really they're something of a cross between instrinsic and autogen, so should297 // probably make a new linkage type298 FunctionDecl *assignDecl = genFunc( "?=?", assignType, functionNesting, true );299 FunctionDecl *ctorDecl = genFunc( "?{}", ctorType, functionNesting, true );300 FunctionDecl *copyCtorDecl = genFunc( "?{}", copyCtorType, functionNesting, true );301 FunctionDecl *dtorDecl = genFunc( "^?{}", dtorType, functionNesting, true );302 303 // body is either return stmt or expr stmt304 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, genEnumAssign( assignType, assignDecl ) ) );305 copyCtorDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, genEnumAssign( copyCtorType, assignDecl ) ) );306 307 declsToAdd.push_back( ctorDecl );308 declsToAdd.push_back( copyCtorDecl );309 declsToAdd.push_back( dtorDecl );310 declsToAdd.push_back( assignDecl ); // assignment should come last since it uses copy constructor in return311 312 indexer.addId( ctorDecl );313 indexer.addId( copyCtorDecl );314 indexer.addId( dtorDecl );315 indexer.addId( assignDecl );316 262 } 317 263 … … 586 532 } 587 533 534 void EnumFuncGenerator::genFuncBody( FunctionDecl * funcDecl ) { 535 // xxx - Temporary: make these functions intrinsic so they codegen as C assignment. 536 // Really they're something of a cross between instrinsic and autogen, so should 537 // probably make a new linkage type 538 funcDecl->linkage = LinkageSpec::Intrinsic; 539 FunctionType * ftype = funcDecl->type; 540 if ( InitTweak::isCopyConstructor( funcDecl ) || InitTweak::isAssignment( funcDecl ) ) { 541 assert( ftype->parameters.size() == 2 ); 542 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 543 ObjectDecl * srcParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.back() ); 544 545 // enum copy construct and assignment is just C-style assignment. 546 // this looks like a bad recursive call, but code gen will turn it into 547 // a C-style assignment. 548 // This happens before function pointer type conversion, so need to do it manually here 549 ApplicationExpr * callExpr = new ApplicationExpr( VariableExpr::functionPointer( funcDecl ) ); 550 callExpr->get_args().push_back( new VariableExpr( dstParam ) ); 551 callExpr->get_args().push_back( new VariableExpr( srcParam ) ); 552 funcDecl->statements->push_back( new ExprStmt( noLabels, callExpr ) ); 553 if ( CodeGen::isAssignment( funcDecl->name ) ) { 554 // also generate return statement in assignment 555 funcDecl->statements->push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 556 } 557 } else { 558 // default ctor/dtor body is empty - add unused attribute to parameter to silence warnings 559 assert( ftype->parameters.size() == 1 ); 560 ObjectDecl * dstParam = strict_dynamic_cast< ObjectDecl * >( ftype->parameters.front() ); 561 dstParam->attributes.push_back( new Attribute( "unused" ) ); 562 } 563 } 564 565 bool EnumFuncGenerator::shouldAutogen() const { return true; } 566 bool EnumFuncGenerator::isConcurrentType() const { return false; } 567 // enums do not have field constructors 568 void EnumFuncGenerator::genFieldCtors() {} 569 588 570 bool TypeFuncGenerator::shouldAutogen() const { return true; }; 589 571 … … 611 593 612 594 // opaque types do not have field constructors 613 void TypeFuncGenerator::genFieldCtors() { return;};595 void TypeFuncGenerator::genFieldCtors() {}; 614 596 615 597 //============================================================================================= … … 628 610 // must visit children (enum constants) to add them to the indexer 629 611 if ( enumDecl->has_body() ) { 630 EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() ); 631 enumInst->set_baseEnum( enumDecl ); 632 makeEnumFunctions( enumInst, functionNesting, declsToAddAfter, indexer ); 612 EnumInstType enumInst( Type::Qualifiers(), enumDecl->get_name() ); 613 enumInst.set_baseEnum( enumDecl ); 614 EnumFuncGenerator gen( &enumInst, data, functionNesting, indexer ); 615 generateFunctions( gen, declsToAddAfter ); 633 616 } 634 617 }
Note: See TracChangeset
for help on using the changeset viewer.