Changes in src/CodeGen/CodeGenerator.cc [4b2589a:afc1045]
- File:
-
- 1 edited
-
src/CodeGen/CodeGenerator.cc (modified) (43 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r4b2589a rafc1045 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // CodeGenerator.cc -- 7 // CodeGenerator.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jun 9 13:21:00201613 // Update Count : 2 5612 // Last Modified On : Wed Mar 2 17:32:16 2016 13 // Update Count : 243 14 14 // 15 15 … … 26 26 #include "SynTree/Statement.h" 27 27 #include "SynTree/Type.h" 28 #include "SynTree/Attribute.h"29 28 30 29 #include "Common/utility.h" … … 34 33 #include "OperatorTable.h" 35 34 #include "GenType.h" 36 37 #include "InitTweak/InitTweak.h"38 35 39 36 using namespace std; … … 48 45 } 49 46 50 ostream & CodeGenerator::Indenter::operator()( ostream & output ) const{47 ostream & CodeGenerator::Indenter::operator()( ostream & output ) { 51 48 return output << string( cg.cur_indent, ' ' ); 52 49 } 53 50 54 ostream & operator<<( ostream & output, constCodeGenerator::Indenter &indent ) {51 ostream & operator<<( ostream & output, CodeGenerator::Indenter &indent ) { 55 52 return indent( output ); 56 53 } 57 54 58 CodeGenerator::LabelPrinter & CodeGenerator::LabelPrinter::operator()( std::list< Label > & l ) { 59 labels = &l; 60 return *this; 61 } 62 63 ostream & operator<<( ostream & output, CodeGenerator::LabelPrinter &printLabels ) { 64 std::list< Label > & labs = *printLabels.labels; 65 // l.unique(); // assumes a sorted list. Why not use set? Does order matter? 66 for ( Label & l : labs ) { 67 output << l.get_name() + ": "; 68 printLabels.cg.genAttributes( l.get_attributes() ); 69 } 70 return output; 71 } 72 73 CodeGenerator::CodeGenerator( std::ostream &os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ) { } 55 CodeGenerator::CodeGenerator( std::ostream &os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ) { } 74 56 75 57 CodeGenerator::CodeGenerator( std::ostream &os, std::string init, int indentation, bool infunp ) 76 : indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ) , printLabels( *this ){58 : indent( *this), cur_indent( indentation ), insideFunction( infunp ), output( os ) { 77 59 //output << std::string( init ); 78 60 } 79 61 80 62 CodeGenerator::CodeGenerator( std::ostream &os, char *init, int indentation, bool infunp ) 81 : indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ) , printLabels( *this ){63 : indent( *this ), cur_indent( indentation ), insideFunction( infunp ), output( os ) { 82 64 //output << std::string( init ); 83 65 } … … 85 67 string mangleName( DeclarationWithType *decl ) { 86 68 if ( decl->get_mangleName() != "" ) { 87 // need to incorporate scope level in order to differentiate names for destructors 88 return decl->get_scopedMangleName(); 69 return decl->get_mangleName(); 89 70 } else { 90 71 return decl->get_name(); 91 72 } // if 92 73 } 93 94 void CodeGenerator::genAttributes( std::list< Attribute * > & attributes ) {95 if ( ! attributes.empty() ) {96 output << "__attribute__ ((";97 for ( Attribute *& attr : attributes ) {98 if ( ! attr->empty() ) {99 output << attr->get_name() << "(";100 genCommaList( attr->get_parameters().begin(), attr->get_parameters().end() );101 output << ")";102 }103 output << ",";104 }105 output << ")) ";106 }107 }108 109 74 110 75 //*** Declarations 111 76 void CodeGenerator::visit( FunctionDecl *functionDecl ) { 112 genAttributes( functionDecl->get_attributes() );113 114 77 handleStorageClass( functionDecl ); 115 78 if ( functionDecl->get_isInline() ) { … … 136 99 handleStorageClass( objectDecl ); 137 100 output << genType( objectDecl->get_type(), mangleName( objectDecl ) ); 138 101 139 102 if ( objectDecl->get_init() ) { 140 103 output << " = "; … … 150 113 if ( aggDecl->get_name() != "" ) 151 114 output << aggDecl->get_name(); 152 115 153 116 std::list< Declaration * > &memb = aggDecl->get_members(); 154 117 … … 156 119 output << " {" << endl; 157 120 158 cur_indent += CodeGenerator::tabsize; 121 cur_indent += CodeGenerator::tabsize; 159 122 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 160 output << indent; 123 output << indent; 161 124 (*i)->accept( *this ); 162 125 output << ";" << endl; 163 126 } 164 127 165 cur_indent -= CodeGenerator::tabsize; 128 cur_indent -= CodeGenerator::tabsize; 166 129 167 130 output << indent << "}"; … … 178 141 handleAggregate( aggregateDecl ); 179 142 } 180 143 181 144 void CodeGenerator::visit( EnumDecl *aggDecl ) { 182 145 output << "enum "; … … 184 147 if ( aggDecl->get_name() != "" ) 185 148 output << aggDecl->get_name(); 186 149 187 150 std::list< Declaration* > &memb = aggDecl->get_members(); 188 151 … … 190 153 output << " {" << endl; 191 154 192 cur_indent += CodeGenerator::tabsize; 155 cur_indent += CodeGenerator::tabsize; 193 156 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 194 157 ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i ); 195 158 assert( obj ); 196 output << indent << mangleName( obj ); 159 output << indent << mangleName( obj ); 197 160 if ( obj->get_init() ) { 198 161 output << " = "; … … 202 165 } // for 203 166 204 cur_indent -= CodeGenerator::tabsize; 167 cur_indent -= CodeGenerator::tabsize; 205 168 206 169 output << indent << "}"; 207 170 } // if 208 171 } 209 172 210 173 void CodeGenerator::visit( TraitDecl *aggregateDecl ) {} 211 174 212 175 void CodeGenerator::visit( TypedefDecl *typeDecl ) { 213 176 output << "typedef "; 214 177 output << genType( typeDecl->get_base(), typeDecl->get_name() ); 215 178 } 216 179 217 180 void CodeGenerator::visit( TypeDecl *typeDecl ) { 218 181 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes, … … 250 213 printDesignators( init->get_designators() ); 251 214 output << "{ "; 252 if ( init->begin_initializers() == init->end_initializers() ) { 253 // illegal to leave initializer list empty for scalar initializers, 254 // but always legal to have 0 255 output << "0"; 256 } else { 257 genCommaList( init->begin_initializers(), init->end_initializers() ); 258 } 215 genCommaList( init->begin_initializers(), init->end_initializers() ); 259 216 output << " }"; 260 217 } 261 218 262 void CodeGenerator::visit( Constant *constant ) { 219 void CodeGenerator::visit( Constant *constant ) { 263 220 output << constant->get_value() ; 264 221 } … … 266 223 //*** Expressions 267 224 void CodeGenerator::visit( ApplicationExpr *applicationExpr ) { 268 extension( applicationExpr );269 225 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) { 270 226 OperatorInfo opInfo; … … 275 231 case OT_POSTFIXASSIGN: 276 232 case OT_INFIXASSIGN: 277 case OT_CTOR:278 case OT_DTOR:279 233 { 280 234 assert( arg != applicationExpr->get_args().end() ); 281 235 if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) { 282 // remove & from first assignment/ctor argument236 283 237 *arg = addrExpr->get_arg(); 284 238 } else { 285 // no address-of operator, so must be a pointer - add dereference286 239 UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 287 240 newExpr->get_args().push_back( *arg ); 288 assert( (*arg)->get_results().size() == 1 );289 Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() );290 assert( type );291 newExpr->get_results().push_back( type );292 241 *arg = newExpr; 293 242 } // if 294 243 break; 295 244 } 296 245 297 246 default: 298 247 // do nothing 299 248 ; 300 249 } 301 250 302 251 switch ( opInfo.type ) { 303 252 case OT_INDEX: … … 308 257 output << "]"; 309 258 break; 310 259 311 260 case OT_CALL: 312 261 // there are no intrinsic definitions of the function call operator 313 262 assert( false ); 314 263 break; 315 316 case OT_CTOR: 317 case OT_DTOR: 318 if ( applicationExpr->get_args().size() == 1 ) { 319 // the expression fed into a single parameter constructor or destructor 320 // may contain side effects, so must still output this expression 321 output << "("; 322 (*arg++)->accept( *this ); 323 output << ") /* " << opInfo.inputName << " */"; 324 } else if ( applicationExpr->get_args().size() == 2 ) { 325 // intrinsic two parameter constructors are essentially bitwise assignment 326 output << "("; 327 (*arg++)->accept( *this ); 328 output << opInfo.symbol; 329 (*arg)->accept( *this ); 330 output << ") /* " << opInfo.inputName << " */"; 331 } else { 332 // no constructors with 0 or more than 2 parameters 333 assert( false ); 334 } 335 break; 336 264 337 265 case OT_PREFIX: 338 266 case OT_PREFIXASSIGN: … … 343 271 output << ")"; 344 272 break; 345 273 346 274 case OT_POSTFIX: 347 275 case OT_POSTFIXASSIGN: … … 350 278 output << opInfo.symbol; 351 279 break; 352 353 280 354 281 case OT_INFIX: … … 361 288 output << ")"; 362 289 break; 363 290 364 291 case OT_CONSTANT: 365 292 case OT_LABELADDRESS: … … 380 307 } // if 381 308 } 382 309 383 310 void CodeGenerator::visit( UntypedExpr *untypedExpr ) { 384 extension( untypedExpr );385 311 if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { 386 312 OperatorInfo opInfo; … … 395 321 output << "]"; 396 322 break; 397 323 398 324 case OT_CALL: 399 325 assert( false ); 400 401 402 case OT_CTOR: 403 case OT_DTOR: 404 if ( untypedExpr->get_args().size() == 1 ) { 405 // the expression fed into a single parameter constructor or destructor 406 // may contain side effects, so must still output this expression 407 output << "("; 408 (*arg++)->accept( *this ); 409 output << ") /* " << opInfo.inputName << " */"; 410 } else if ( untypedExpr->get_args().size() == 2 ) { 411 // intrinsic two parameter constructors are essentially bitwise assignment 412 output << "("; 413 (*arg++)->accept( *this ); 414 output << opInfo.symbol; 415 (*arg)->accept( *this ); 416 output << ") /* " << opInfo.inputName << " */"; 417 } else { 418 // no constructors with 0 or more than 2 parameters 419 assert( false ); 420 } 421 break; 422 326 break; 327 423 328 case OT_PREFIX: 424 329 case OT_PREFIXASSIGN: … … 430 335 output << ")"; 431 336 break; 432 337 433 338 case OT_POSTFIX: 434 339 case OT_POSTFIXASSIGN: … … 437 342 output << opInfo.symbol; 438 343 break; 439 344 440 345 case OT_INFIX: 441 346 case OT_INFIXASSIGN: … … 447 352 output << ")"; 448 353 break; 449 354 450 355 case OT_CONSTANT: 451 356 // there are no intrinsic definitions of 0 or 1 as functions … … 465 370 } // if 466 371 } 467 372 468 373 void CodeGenerator::visit( NameExpr *nameExpr ) { 469 extension( nameExpr );470 374 OperatorInfo opInfo; 471 375 if ( operatorLookup( nameExpr->get_name(), opInfo ) ) { … … 476 380 } // if 477 381 } 478 382 479 383 void CodeGenerator::visit( AddressExpr *addressExpr ) { 480 extension( addressExpr );481 384 output << "(&"; 482 385 // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address … … 490 393 491 394 void CodeGenerator::visit( CastExpr *castExpr ) { 492 extension( castExpr );493 395 output << "("; 494 396 if ( castExpr->get_results().empty() ) { … … 507 409 output << ")"; 508 410 } 509 411 510 412 void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) { 511 413 assert( false ); 512 414 } 513 415 514 416 void CodeGenerator::visit( MemberExpr *memberExpr ) { 515 extension( memberExpr );516 417 memberExpr->get_aggregate()->accept( *this ); 517 418 output << "." << mangleName( memberExpr->get_member() ); 518 419 } 519 420 520 421 void CodeGenerator::visit( VariableExpr *variableExpr ) { 521 extension( variableExpr );522 422 OperatorInfo opInfo; 523 423 if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) { … … 527 427 } // if 528 428 } 529 429 530 430 void CodeGenerator::visit( ConstantExpr *constantExpr ) { 531 431 assert( constantExpr->get_constant() ); 532 extension( constantExpr );533 432 constantExpr->get_constant()->accept( *this ); 534 433 } 535 434 536 435 void CodeGenerator::visit( SizeofExpr *sizeofExpr ) { 537 extension( sizeofExpr );538 436 output << "sizeof("; 539 437 if ( sizeofExpr->get_isType() ) { … … 546 444 547 445 void CodeGenerator::visit( AlignofExpr *alignofExpr ) { 548 extension( alignofExpr );549 446 // use GCC extension to avoid bumping std to C11 550 447 output << "__alignof__("; … … 562 459 563 460 void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) { 564 extension( offsetofExpr );565 461 // use GCC builtin 566 462 output << "__builtin_offsetof("; … … 573 469 assert( false && "OffsetPackExpr should not reach code generation" ); 574 470 } 575 471 576 472 void CodeGenerator::visit( LogicalExpr *logicalExpr ) { 577 extension( logicalExpr );578 473 output << "("; 579 474 logicalExpr->get_arg1()->accept( *this ); … … 586 481 output << ")"; 587 482 } 588 483 589 484 void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) { 590 extension( conditionalExpr );591 485 output << "("; 592 486 conditionalExpr->get_arg1()->accept( *this ); … … 597 491 output << ")"; 598 492 } 599 493 600 494 void CodeGenerator::visit( CommaExpr *commaExpr ) { 601 extension( commaExpr );602 495 output << "("; 603 496 commaExpr->get_arg1()->accept( *this ); … … 606 499 output << ")"; 607 500 } 608 501 609 502 void CodeGenerator::visit( TupleExpr *tupleExpr ) {} 610 503 611 504 void CodeGenerator::visit( TypeExpr *typeExpr ) {} 612 505 613 506 void CodeGenerator::visit( AsmExpr *asmExpr ) { 614 extension( asmExpr );615 507 if ( asmExpr->get_inout() ) { 616 508 output << "[ "; … … 640 532 } 641 533 } 642 cur_indent -= CodeGenerator::tabsize; 534 cur_indent -= CodeGenerator::tabsize; 643 535 644 536 output << indent << "}"; … … 646 538 647 539 void CodeGenerator::visit( ExprStmt *exprStmt ) { 540 // I don't see why this check is necessary. 541 // If this starts to cause problems then put it back in, 542 // with an explanation 648 543 assert( exprStmt ); 649 // cast the top-level expression to void to reduce gcc warnings. 650 Expression * expr = new CastExpr( exprStmt->get_expr() ); 651 expr->accept( *this ); 652 output << ";"; 544 545 // if ( exprStmt != 0 ) { 546 exprStmt->get_expr()->accept( *this ); 547 output << ";" ; 548 // } // if 653 549 } 654 550 … … 693 589 switchStmt->get_condition()->accept( *this ); 694 590 output << " ) "; 695 591 696 592 output << "{" << std::endl; 697 593 cur_indent += CodeGenerator::tabsize; … … 713 609 } // if 714 610 output << ":\n"; 715 611 716 612 std::list<Statement *> sts = caseStmt->get_statements(); 717 613 … … 730 626 if ( ! branchStmt->get_target().empty() ) 731 627 output << "goto " << branchStmt->get_target(); 732 else { 628 else { 733 629 if ( branchStmt->get_computedTarget() != 0 ) { 734 630 output << "goto *"; … … 750 646 void CodeGenerator::visit( ReturnStmt *returnStmt ) { 751 647 output << "return "; 752 maybeAccept( returnStmt->get_expr(), *this ); 648 649 // xxx -- check for null expression; 650 if ( returnStmt->get_expr() ) { 651 returnStmt->get_expr()->accept( *this ); 652 } // if 753 653 output << ";"; 754 654 } 755 655 756 656 void CodeGenerator::visit( WhileStmt *whileStmt ) { 757 if ( whileStmt->get_isDoWhile() ) {657 if ( whileStmt->get_isDoWhile() ) 758 658 output << "do" ; 759 }else {659 else { 760 660 output << "while (" ; 761 661 whileStmt->get_condition()->accept( *this ); … … 777 677 778 678 void CodeGenerator::visit( ForStmt *forStmt ) { 779 // initialization is always hoisted, so don't 780 // bother doing anything with that 679 // initialization is always hoisted, so don't 680 // bother doing anything with that 781 681 output << "for (;"; 782 682 783 if ( forStmt->get_condition() != 0 ) {683 if ( forStmt->get_condition() != 0 ) 784 684 forStmt->get_condition()->accept( *this ); 785 }786 685 output << ";"; 787 686 788 if ( forStmt->get_increment() != 0 ) { 789 // cast the top-level expression to void to reduce gcc warnings. 790 Expression * expr = new CastExpr( forStmt->get_increment() ); 791 expr->accept( *this ); 792 } 687 if ( forStmt->get_increment() != 0 ) 688 forStmt->get_increment()->accept( *this ); 793 689 output << ") "; 794 690 … … 806 702 void CodeGenerator::visit( DeclStmt *declStmt ) { 807 703 declStmt->get_decl()->accept( *this ); 808 704 809 705 if ( doSemicolon( declStmt->get_decl() ) ) { 810 706 output << ";"; 811 707 } // if 708 } 709 710 std::string CodeGenerator::printLabels( std::list< Label > &l ) { 711 std::string str( "" ); 712 l.unique(); // assumes a sorted list. Why not use set? 713 714 for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ ) 715 str += *i + ": "; 716 717 return str; 812 718 } 813 719
Note:
See TracChangeset
for help on using the changeset viewer.