Changeset 937e51d for src/CodeGen/CodeGenerator.cc
- Timestamp:
- Jun 26, 2015, 4:00:26 PM (10 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 0df292b, e0ff3e6
- Parents:
- eb50842 (diff), 1869adf (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. - File:
-
- 1 moved
-
src/CodeGen/CodeGenerator.cc (moved) (moved from src/CodeGen/CodeGenerator2.cc ) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
reb50842 r937e51d 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // CodeGenerator 2.cc --7 // CodeGenerator.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu May 21 17:13:35201513 // Update Count : 711 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jun 24 16:11:41 2015 13 // Update Count : 143 14 14 // 15 15 … … 19 19 #include <list> 20 20 21 #include "Parser/ParseNode.h" 22 21 23 #include "SynTree/Type.h" 22 #include "SynTree/Declaration.h"23 #include "SynTree/Statement.h"24 24 #include "SynTree/Expression.h" 25 25 #include "SynTree/Initializer.h" 26 #include "SynTree/Statement.h" 26 27 27 28 #include "utility.h" 28 29 #include "UnimplementedError.h" 29 30 30 #include "CodeGenerator 2.h"31 #include "CodeGenerator.h" 31 32 #include "OperatorTable.h" 32 33 #include "GenType.h" … … 35 36 36 37 namespace CodeGen { 37 int CodeGenerator2::tabsize = 4; 38 39 CodeGenerator2::CodeGenerator2( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), before( os ), after() { } 40 41 CodeGenerator2::CodeGenerator2( std::ostream &os, std::string init, int indent, bool infunp ) 42 : cur_indent( indent ), insideFunction( infunp ), before( os ) { 43 //before << std::string( init ); 44 } 45 46 CodeGenerator2::CodeGenerator2( std::ostream &os, char *init, int indent, bool infunp ) 47 : cur_indent( indent ), insideFunction( infunp ), before( os ) { 48 //before << std::string( init ); 38 int CodeGenerator::tabsize = 4; 39 40 // the kinds of statements that would ideally be separated by more whitespace 41 bool wantSpacing( Statement * stmt) { 42 return dynamic_cast< IfStmt * >( stmt ) || dynamic_cast< CompoundStmt * >( stmt ) || 43 dynamic_cast< WhileStmt * >( stmt ) || dynamic_cast< ForStmt * > ( stmt ) || dynamic_cast< SwitchStmt *>( stmt ); 44 } 45 46 ostream & CodeGenerator::Indenter::operator()( ostream & output ) { 47 return output << string( cg.cur_indent, ' ' ); 48 } 49 50 ostream & operator<<( ostream & output, CodeGenerator::Indenter &indent ) { 51 return indent( output ); 52 } 53 54 CodeGenerator::CodeGenerator( std::ostream &os ) : indent(*this), cur_indent( 0 ), insideFunction( false ), output( os ) { } 55 56 CodeGenerator::CodeGenerator( std::ostream &os, std::string init, int indentation, bool infunp ) 57 : indent(*this), cur_indent( indentation ), insideFunction( infunp ), output( os ) { 58 //output << std::string( init ); 59 } 60 61 CodeGenerator::CodeGenerator( std::ostream &os, char *init, int indentation, bool infunp ) 62 : indent(*this), cur_indent( indentation ), insideFunction( infunp ), output( os ) { 63 //output << std::string( init ); 49 64 } 50 65 … … 56 71 } // if 57 72 } 58 73 59 74 //*** Declarations 60 void CodeGenerator 2::visit( FunctionDecl *functionDecl ) {75 void CodeGenerator::visit( FunctionDecl *functionDecl ) { 61 76 handleStorageClass( functionDecl ); 62 before << genType( functionDecl->get_functionType(), mangleName( functionDecl ) ); 77 if ( functionDecl->get_isInline() ) { 78 output << "inline "; 79 } // if 80 if ( functionDecl->get_isNoreturn() ) { 81 output << "_Noreturn "; 82 } // if 83 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ) ); 63 84 64 85 // how to get this to the Functype? 65 86 std::list< Declaration * > olds = functionDecl->get_oldDecls(); 66 87 if ( ! olds.empty() ) { 67 before<< " /* function has old declaration */";88 output << " /* function has old declaration */"; 68 89 } // if 69 90 … … 74 95 } 75 96 76 void CodeGenerator 2::visit( ObjectDecl *objectDecl ) {97 void CodeGenerator::visit( ObjectDecl *objectDecl ) { 77 98 handleStorageClass( objectDecl ); 78 before<< genType( objectDecl->get_type(), mangleName( objectDecl ) );99 output << genType( objectDecl->get_type(), mangleName( objectDecl ) ); 79 100 80 101 if ( objectDecl->get_init() ) { 81 before<< " = ";102 output << " = "; 82 103 objectDecl->get_init()->accept( *this ); 83 104 } // if 84 105 if ( objectDecl->get_bitfieldWidth() ) { 85 before<< ":";106 output << ":"; 86 107 objectDecl->get_bitfieldWidth()->accept( *this ); 87 108 } // if 88 109 } 89 110 90 void CodeGenerator 2::handleAggregate( AggregateDecl *aggDecl ) {111 void CodeGenerator::handleAggregate( AggregateDecl *aggDecl ) { 91 112 if ( aggDecl->get_name() != "" ) 92 before<< aggDecl->get_name();113 output << aggDecl->get_name(); 93 114 94 115 std::list< Declaration * > &memb = aggDecl->get_members(); 95 116 96 117 if ( ! memb.empty() ) { 97 before << endl << string( cur_indent, ' ' ) << "{" << endl;98 99 cur_indent += CodeGenerator 2::tabsize;118 output << " {" << endl; 119 120 cur_indent += CodeGenerator::tabsize; 100 121 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 101 before << string( cur_indent, ' ' );122 output << indent; 102 123 (*i)->accept(*this ); 103 before<< ";" << endl;124 output << ";" << endl; 104 125 } 105 126 106 cur_indent -= CodeGenerator 2::tabsize;107 108 before << string( cur_indent, ' ' )<< "}";109 } // if 110 } 111 112 void CodeGenerator 2::visit( StructDecl *structDecl ) {113 before<< "struct ";127 cur_indent -= CodeGenerator::tabsize; 128 129 output << indent << "}"; 130 } // if 131 } 132 133 void CodeGenerator::visit( StructDecl *structDecl ) { 134 output << "struct "; 114 135 handleAggregate( structDecl ); 115 136 } 116 137 117 void CodeGenerator 2::visit( UnionDecl *aggregateDecl ) {118 before<< "union ";138 void CodeGenerator::visit( UnionDecl *aggregateDecl ) { 139 output << "union "; 119 140 handleAggregate( aggregateDecl ); 120 141 } 121 142 122 void CodeGenerator 2::visit( EnumDecl *aggDecl ) {123 before<< "enum ";143 void CodeGenerator::visit( EnumDecl *aggDecl ) { 144 output << "enum "; 124 145 125 146 if ( aggDecl->get_name() != "" ) 126 before<< aggDecl->get_name();147 output << aggDecl->get_name(); 127 148 128 149 std::list< Declaration* > &memb = aggDecl->get_members(); 129 150 130 151 if ( ! memb.empty() ) { 131 before << endl << "{" << endl;132 133 cur_indent += CodeGenerator 2::tabsize;152 output << " {" << endl; 153 154 cur_indent += CodeGenerator::tabsize; 134 155 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 135 156 ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i ); 136 157 assert( obj ); 137 before << string( cur_indent, ' ' )<< mangleName( obj );158 output << indent << mangleName( obj ); 138 159 if ( obj->get_init() ) { 139 before<< " = ";160 output << " = "; 140 161 obj->get_init()->accept(*this ); 141 162 } // if 142 before<< "," << endl;163 output << "," << endl; 143 164 } // for 144 165 145 cur_indent -= CodeGenerator 2::tabsize;146 147 before << "}" << endl;148 } // if 149 } 150 151 void CodeGenerator 2::visit( ContextDecl *aggregateDecl ) {}152 153 void CodeGenerator 2::visit( TypedefDecl *typeDecl ) {154 before<< "typedef ";155 before<< genType( typeDecl->get_base(), typeDecl->get_name() );156 } 157 158 void CodeGenerator 2::visit( TypeDecl *typeDecl ) {166 cur_indent -= CodeGenerator::tabsize; 167 168 output << indent << "}"; 169 } // if 170 } 171 172 void CodeGenerator::visit( ContextDecl *aggregateDecl ) {} 173 174 void CodeGenerator::visit( TypedefDecl *typeDecl ) { 175 output << "typedef "; 176 output << genType( typeDecl->get_base(), typeDecl->get_name() ); 177 } 178 179 void CodeGenerator::visit( TypeDecl *typeDecl ) { 159 180 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes, 160 181 // still to be done 161 before<< "extern unsigned long " << typeDecl->get_name();182 output << "extern unsigned long " << typeDecl->get_name(); 162 183 if ( typeDecl->get_base() ) { 163 before<< " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";164 } // if 165 } 166 167 void CodeGenerator 2::visit( SingleInit *init ) {184 output << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )"; 185 } // if 186 } 187 188 void CodeGenerator::visit( SingleInit *init ) { 168 189 init->get_value()->accept( *this ); 169 190 } 170 191 171 void CodeGenerator 2::visit( ListInit *init ) {172 before<< "{ ";192 void CodeGenerator::visit( ListInit *init ) { 193 output << "{ "; 173 194 genCommaList( init->begin_initializers(), init->end_initializers() ); 174 before<< " }";175 } 176 177 void CodeGenerator 2::visit( Constant *constant ) {178 before<< constant->get_value() ;195 output << " }"; 196 } 197 198 void CodeGenerator::visit( Constant *constant ) { 199 output << constant->get_value() ; 179 200 } 180 201 181 202 //*** Expressions 182 void CodeGenerator 2::visit( ApplicationExpr *applicationExpr ) {203 void CodeGenerator::visit( ApplicationExpr *applicationExpr ) { 183 204 if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) { 184 205 OperatorInfo opInfo; … … 211 232 assert( applicationExpr->get_args().size() == 2 ); 212 233 (*arg++)->accept( *this ); 213 before<< "[";214 (*arg)->accept( *this ); 215 before<< "]";234 output << "["; 235 (*arg)->accept( *this ); 236 output << "]"; 216 237 break; 217 238 … … 224 245 case OT_PREFIXASSIGN: 225 246 assert( applicationExpr->get_args().size() == 1 ); 226 before<< "(";227 before<< opInfo.symbol;228 (*arg)->accept( *this ); 229 before<< ")";247 output << "("; 248 output << opInfo.symbol; 249 (*arg)->accept( *this ); 250 output << ")"; 230 251 break; 231 252 … … 234 255 assert( applicationExpr->get_args().size() == 1 ); 235 256 (*arg)->accept( *this ); 236 before<< opInfo.symbol;257 output << opInfo.symbol; 237 258 break; 238 259 … … 240 261 case OT_INFIXASSIGN: 241 262 assert( applicationExpr->get_args().size() == 2 ); 242 before<< "(";263 output << "("; 243 264 (*arg++)->accept( *this ); 244 before<< opInfo.symbol;245 (*arg)->accept( *this ); 246 before<< ")";265 output << opInfo.symbol; 266 (*arg)->accept( *this ); 267 output << ")"; 247 268 break; 248 269 … … 253 274 } else { 254 275 varExpr->accept( *this ); 255 before<< "(";276 output << "("; 256 277 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() ); 257 before<< ")";278 output << ")"; 258 279 } // if 259 280 } else { 260 281 applicationExpr->get_function()->accept( *this ); 261 before<< "(";282 output << "("; 262 283 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() ); 263 before<< ")";264 } // if 265 } 266 267 void CodeGenerator 2::visit( UntypedExpr *untypedExpr ) {284 output << ")"; 285 } // if 286 } 287 288 void CodeGenerator::visit( UntypedExpr *untypedExpr ) { 268 289 if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { 269 290 OperatorInfo opInfo; … … 274 295 assert( untypedExpr->get_args().size() == 2 ); 275 296 (*arg++)->accept( *this ); 276 before<< "[";277 (*arg)->accept( *this ); 278 before<< "]";297 output << "["; 298 (*arg)->accept( *this ); 299 output << "]"; 279 300 break; 280 301 … … 285 306 case OT_PREFIX: 286 307 case OT_PREFIXASSIGN: 308 case OT_LABELADDRESS: 287 309 assert( untypedExpr->get_args().size() == 1 ); 288 before<< "(";289 before<< opInfo.symbol;290 (*arg)->accept( *this ); 291 before<< ")";310 output << "("; 311 output << opInfo.symbol; 312 (*arg)->accept( *this ); 313 output << ")"; 292 314 break; 293 315 … … 296 318 assert( untypedExpr->get_args().size() == 1 ); 297 319 (*arg)->accept( *this ); 298 before<< opInfo.symbol;320 output << opInfo.symbol; 299 321 break; 300 322 … … 302 324 case OT_INFIXASSIGN: 303 325 assert( untypedExpr->get_args().size() == 2 ); 304 before<< "(";326 output << "("; 305 327 (*arg++)->accept( *this ); 306 before<< opInfo.symbol;307 (*arg)->accept( *this ); 308 before<< ")";309 break; 310 328 output << opInfo.symbol; 329 (*arg)->accept( *this ); 330 output << ")"; 331 break; 332 311 333 case OT_CONSTANT: 312 334 // there are no intrinsic definitions of 0 or 1 as functions … … 315 337 } else { 316 338 nameExpr->accept( *this ); 317 before<< "(";339 output << "("; 318 340 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); 319 before<< ")";341 output << ")"; 320 342 } // if 321 343 } else { 322 344 untypedExpr->get_function()->accept( *this ); 323 before<< "(";345 output << "("; 324 346 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); 325 before<< ")";326 } // if 327 } 328 329 void CodeGenerator 2::visit( NameExpr *nameExpr ) {347 output << ")"; 348 } // if 349 } 350 351 void CodeGenerator::visit( NameExpr *nameExpr ) { 330 352 OperatorInfo opInfo; 331 353 if ( operatorLookup( nameExpr->get_name(), opInfo ) ) { 332 354 assert( opInfo.type == OT_CONSTANT ); 333 before<< opInfo.symbol;334 } else { 335 before<< nameExpr->get_name();336 } // if 337 } 338 339 void CodeGenerator 2::visit( AddressExpr *addressExpr ) {340 before<< "(&";355 output << opInfo.symbol; 356 } else { 357 output << nameExpr->get_name(); 358 } // if 359 } 360 361 void CodeGenerator::visit( AddressExpr *addressExpr ) { 362 output << "(&"; 341 363 // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address 342 364 if ( VariableExpr *variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) { 343 before<< mangleName( variableExpr->get_var() );365 output << mangleName( variableExpr->get_var() ); 344 366 } else { 345 367 addressExpr->get_arg()->accept( *this ); 346 368 } // if 347 before<< ")";348 } 349 350 void CodeGenerator 2::visit( CastExpr *castExpr ) {351 before<< "((";369 output << ")"; 370 } 371 372 void CodeGenerator::visit( CastExpr *castExpr ) { 373 output << "(("; 352 374 if ( castExpr->get_results().empty() ) { 353 before<< "void" ;354 } else { 355 before<< genType( castExpr->get_results().front(), "" );356 } // if 357 before<< ")";375 output << "void" ; 376 } else { 377 output << genType( castExpr->get_results().front(), "" ); 378 } // if 379 output << ")"; 358 380 castExpr->get_arg()->accept( *this ); 359 before<< ")";360 } 361 362 void CodeGenerator 2::visit( UntypedMemberExpr *memberExpr ) {381 output << ")"; 382 } 383 384 void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) { 363 385 assert( false ); 364 386 } 365 387 366 void CodeGenerator 2::visit( MemberExpr *memberExpr ) {388 void CodeGenerator::visit( MemberExpr *memberExpr ) { 367 389 memberExpr->get_aggregate()->accept( *this ); 368 before<< "." << mangleName( memberExpr->get_member() );369 } 370 371 void CodeGenerator 2::visit( VariableExpr *variableExpr ) {390 output << "." << mangleName( memberExpr->get_member() ); 391 } 392 393 void CodeGenerator::visit( VariableExpr *variableExpr ) { 372 394 OperatorInfo opInfo; 373 395 if ( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) { 374 before<< opInfo.symbol;375 } else { 376 before<< mangleName( variableExpr->get_var() );377 } // if 378 } 379 380 void CodeGenerator 2::visit( ConstantExpr *constantExpr ) {396 output << opInfo.symbol; 397 } else { 398 output << mangleName( variableExpr->get_var() ); 399 } // if 400 } 401 402 void CodeGenerator::visit( ConstantExpr *constantExpr ) { 381 403 assert( constantExpr->get_constant() ); 382 404 constantExpr->get_constant()->accept( *this ); 383 405 } 384 406 385 void CodeGenerator 2::visit( SizeofExpr *sizeofExpr ) {386 before<< "sizeof(";407 void CodeGenerator::visit( SizeofExpr *sizeofExpr ) { 408 output << "sizeof("; 387 409 if ( sizeofExpr->get_isType() ) { 388 before<< genType( sizeofExpr->get_type(), "" );410 output << genType( sizeofExpr->get_type(), "" ); 389 411 } else { 390 412 sizeofExpr->get_expr()->accept( *this ); 391 413 } // if 392 before<< ")";393 } 394 395 void CodeGenerator 2::visit( LogicalExpr *logicalExpr ) {396 before<< "(";414 output << ")"; 415 } 416 417 void CodeGenerator::visit( LogicalExpr *logicalExpr ) { 418 output << "("; 397 419 logicalExpr->get_arg1()->accept( *this ); 398 420 if ( logicalExpr->get_isAnd() ) { 399 before<< " && ";400 } else { 401 before<< " || ";421 output << " && "; 422 } else { 423 output << " || "; 402 424 } // if 403 425 logicalExpr->get_arg2()->accept( *this ); 404 before<< ")";405 } 406 407 void CodeGenerator 2::visit( ConditionalExpr *conditionalExpr ) {408 before<< "(";426 output << ")"; 427 } 428 429 void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) { 430 output << "("; 409 431 conditionalExpr->get_arg1()->accept( *this ); 410 before<< " ? ";432 output << " ? "; 411 433 conditionalExpr->get_arg2()->accept( *this ); 412 before<< " : ";434 output << " : "; 413 435 conditionalExpr->get_arg3()->accept( *this ); 414 before<< ")";415 } 416 417 void CodeGenerator 2::visit( CommaExpr *commaExpr ) {418 before<< "(";436 output << ")"; 437 } 438 439 void CodeGenerator::visit( CommaExpr *commaExpr ) { 440 output << "("; 419 441 commaExpr->get_arg1()->accept( *this ); 420 before<< " , ";442 output << " , "; 421 443 commaExpr->get_arg2()->accept( *this ); 422 before << ")"; 423 } 424 425 void CodeGenerator2::visit( TupleExpr *tupleExpr ) {} 426 427 void CodeGenerator2::visit( TypeExpr *typeExpr ) {} 428 429 444 output << ")"; 445 } 446 447 void CodeGenerator::visit( TupleExpr *tupleExpr ) {} 448 449 void CodeGenerator::visit( TypeExpr *typeExpr ) {} 450 430 451 //*** Statements 431 void CodeGenerator 2::visit( CompoundStmt *compoundStmt ) {452 void CodeGenerator::visit( CompoundStmt *compoundStmt ) { 432 453 std::list<Statement*> ks = compoundStmt->get_kids(); 433 434 before << endl << string( cur_indent, ' ' ) << "{" << endl; 435 436 cur_indent += CodeGenerator2::tabsize; 454 output << "{" << endl; 455 456 cur_indent += CodeGenerator::tabsize; 437 457 438 458 for ( std::list<Statement *>::iterator i = ks.begin(); i != ks.end(); i++) { 439 before << string( cur_indent, ' ' ) << printLabels( (*i)->get_labels() );459 output << indent << printLabels( (*i)->get_labels() ); 440 460 (*i)->accept(*this ); 441 shift_left(); 442 before << endl; 461 462 output << endl; 463 if ( wantSpacing( *i ) ) { 464 output << endl; 465 } 443 466 } 444 cur_indent -= CodeGenerator2::tabsize; 445 446 before << string( cur_indent, ' ' ) << "}" << endl; 447 } 448 449 void CodeGenerator2::visit( ExprStmt *exprStmt ) { 450 if ( exprStmt != 0 ) { 451 exprStmt->get_expr()->accept( *this ); 452 shift_left(); 453 before << ";" ; 454 } // if 455 } 456 457 void CodeGenerator2::visit( IfStmt *ifStmt ) { 458 before << "if ("; 467 cur_indent -= CodeGenerator::tabsize; 468 469 output << indent << "}"; 470 } 471 472 void CodeGenerator::visit( ExprStmt *exprStmt ) { 473 // I don't see why this check is necessary. 474 // If this starts to cause problems then put it back in, 475 // with an explanation 476 assert( exprStmt ); 477 478 // if ( exprStmt != 0 ) { 479 exprStmt->get_expr()->accept( *this ); 480 output << ";" ; 481 // } // if 482 } 483 484 void CodeGenerator::visit( IfStmt *ifStmt ) { 485 output << "if ("; 459 486 ifStmt->get_condition()->accept(*this ); 460 after += ")\n"; 461 shift_left(); 462 463 cur_indent += CodeGenerator2::tabsize; 464 before << string( cur_indent, ' ' ); 487 output << ") "; 488 465 489 ifStmt->get_thenPart()->accept(*this ); 466 cur_indent -= CodeGenerator2::tabsize;467 shift_left(); before << endl;468 490 469 491 if ( ifStmt->get_elsePart() != 0) { 470 before << string( cur_indent, ' ' ) << " else " << endl ; 471 472 cur_indent += CodeGenerator2::tabsize; 492 output << " else "; 473 493 ifStmt->get_elsePart()->accept(*this ); 474 cur_indent -= CodeGenerator2::tabsize; 475 } // if 476 } 477 478 void CodeGenerator2::visit( SwitchStmt *switchStmt ) { 479 //before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( switchStmt->get_labels() ) 480 before << "switch (" ; 494 } // if 495 } 496 497 void CodeGenerator::visit( SwitchStmt *switchStmt ) { 498 output << "switch (" ; 481 499 switchStmt->get_condition()->accept(*this ); 482 after += ")\n"; 483 shift_left(); 484 485 before << string( cur_indent, ' ' ) << "{" << std::endl; 486 cur_indent += CodeGenerator2::tabsize; 487 488 std::list< Statement * > stmts = switchStmt->get_branches(); 489 bool lastBreak = false; 490 491 // horrible, horrible hack 492 if ( dynamic_cast<BranchStmt *>( stmts.back() ) != 0 ) { 493 lastBreak = true; 494 stmts.pop_back(); 495 } // if 496 acceptAll( stmts, *this ); 497 if ( lastBreak ) { 498 Statement *st = switchStmt->get_branches().back(); 499 before << CodeGenerator2::printLabels( st->get_labels()); 500 st->accept( *this ); 501 } // if 502 503 cur_indent -= CodeGenerator2::tabsize; 504 505 before << /* "\r" << */ string( cur_indent, ' ' ) << "}" << endl ; 506 } 507 508 void CodeGenerator2::visit( CaseStmt *caseStmt ) { 509 before << string( cur_indent, ' ' ); 510 if ( caseStmt->isDefault()) 511 before << "default " ; 512 else { 513 before << "case " ; 500 output << ") "; 501 502 output << "{" << std::endl; 503 cur_indent += CodeGenerator::tabsize; 504 505 acceptAll( switchStmt->get_branches(), *this ); 506 507 cur_indent -= CodeGenerator::tabsize; 508 509 output << indent << "}"; 510 } 511 512 void CodeGenerator::visit( CaseStmt *caseStmt ) { 513 output << indent; 514 if ( caseStmt->isDefault()) { 515 output << "default"; 516 } else { 517 output << "case "; 514 518 caseStmt->get_condition()->accept(*this ); 515 519 } // if 516 after += ":\n"; 517 shift_left(); 518 520 output << ":\n"; 521 519 522 std::list<Statement *> sts = caseStmt->get_statements(); 520 523 521 cur_indent += CodeGenerator 2::tabsize;524 cur_indent += CodeGenerator::tabsize; 522 525 for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end(); i++) { 523 before << /* "\r" << */ string( cur_indent, ' ' )<< printLabels( (*i)->get_labels() ) ;526 output << indent << printLabels( (*i)->get_labels() ) ; 524 527 (*i)->accept(*this ); 525 shift_left(); 526 before << ";" << endl; 528 output << endl; 527 529 } 528 cur_indent -= CodeGenerator 2::tabsize;529 } 530 531 void CodeGenerator 2::visit( BranchStmt *branchStmt ) {530 cur_indent -= CodeGenerator::tabsize; 531 } 532 533 void CodeGenerator::visit( BranchStmt *branchStmt ) { 532 534 switch ( branchStmt->get_type()) { 533 535 case BranchStmt::Goto: 534 536 if ( ! branchStmt->get_target().empty() ) 535 before<< "goto " << branchStmt->get_target();537 output << "goto " << branchStmt->get_target(); 536 538 else { 537 539 if ( branchStmt->get_computedTarget() != 0 ) { 538 before<< "goto *";540 output << "goto *"; 539 541 branchStmt->get_computedTarget()->accept( *this ); 540 542 } // if … … 542 544 break; 543 545 case BranchStmt::Break: 544 before<< "break";546 output << "break"; 545 547 break; 546 548 case BranchStmt::Continue: 547 before<< "continue";549 output << "continue"; 548 550 break; 549 551 } 550 before<< ";";551 } 552 553 554 void CodeGenerator 2::visit( ReturnStmt *returnStmt ) {555 before<< "return ";552 output << ";"; 553 } 554 555 556 void CodeGenerator::visit( ReturnStmt *returnStmt ) { 557 output << "return "; 556 558 557 559 // xxx -- check for null expression; … … 559 561 returnStmt->get_expr()->accept( *this ); 560 562 } // if 561 after +=";";562 } 563 564 void CodeGenerator 2::visit( WhileStmt *whileStmt ) {563 output << ";"; 564 } 565 566 void CodeGenerator::visit( WhileStmt *whileStmt ) { 565 567 if ( whileStmt->get_isDoWhile() ) 566 before<< "do" ;568 output << "do" ; 567 569 else { 568 before<< "while (" ;570 output << "while (" ; 569 571 whileStmt->get_condition()->accept(*this ); 570 after +=")";571 } // if 572 after += "{\n";573 shift_left(); 574 572 output << ")"; 573 } // if 574 output << " "; 575 576 output << CodeGenerator::printLabels( whileStmt->get_body()->get_labels() ); 575 577 whileStmt->get_body()->accept( *this ); 576 578 577 before << /* "\r" << */ string( cur_indent, ' ' ) << "}";579 output << indent; 578 580 579 581 if ( whileStmt->get_isDoWhile() ) { 580 before<< " while (" ;582 output << " while (" ; 581 583 whileStmt->get_condition()->accept(*this ); 582 after += ");"; 583 } // if 584 585 after += "\n"; 586 } 587 588 void CodeGenerator2::visit( ForStmt *forStmt ) { 589 before << "for ("; 584 output << ");"; 585 } // if 586 } 587 588 void CodeGenerator::visit( ForStmt *forStmt ) { 589 output << "for ("; 590 590 591 591 if ( forStmt->get_initialization() != 0 ) 592 592 forStmt->get_initialization()->accept( *this ); 593 593 else 594 before << ";"; 595 shift_left(); 596 594 output << ";"; 595 597 596 if ( forStmt->get_condition() != 0 ) 598 597 forStmt->get_condition()->accept( *this ); 599 shift_left(); before<< ";";598 output << ";"; 600 599 601 600 if ( forStmt->get_increment() != 0 ) 602 601 forStmt->get_increment()->accept( *this ); 603 shift_left(); before << ")" << endl;602 output << ") "; 604 603 605 604 if ( forStmt->get_body() != 0 ) { 606 cur_indent += CodeGenerator2::tabsize; 607 before << string( cur_indent, ' ' ) << CodeGenerator2::printLabels( forStmt->get_body()->get_labels() ); 605 output << CodeGenerator::printLabels( forStmt->get_body()->get_labels() ); 608 606 forStmt->get_body()->accept( *this ); 609 cur_indent -= CodeGenerator2::tabsize; 610 } // if 611 } 612 613 void CodeGenerator2::visit( NullStmt *nullStmt ) { 614 //before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( nullStmt->get_labels() ); 615 before << "/* null statement */ ;"; 616 } 617 618 void CodeGenerator2::visit( DeclStmt *declStmt ) { 607 } // if 608 } 609 610 void CodeGenerator::visit( NullStmt *nullStmt ) { 611 //output << indent << CodeGenerator::printLabels( nullStmt->get_labels() ); 612 output << "/* null statement */ ;"; 613 } 614 615 void CodeGenerator::visit( DeclStmt *declStmt ) { 619 616 declStmt->get_decl()->accept( *this ); 620 617 621 618 if ( doSemicolon( declStmt->get_decl() ) ) { 622 after += ";"; 623 } // if 624 shift_left(); 625 } 626 627 std::string CodeGenerator2::printLabels( std::list< Label > &l ) { 619 output << ";"; 620 } // if 621 } 622 623 std::string CodeGenerator::printLabels( std::list< Label > &l ) { 628 624 std::string str( "" ); 629 l.unique(); 625 l.unique(); // assumes a sorted list. Why not use set? 630 626 631 627 for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ ) … … 635 631 } 636 632 637 void CodeGenerator2::shift_left() { 638 before << after; 639 after = ""; 640 } 641 642 void CodeGenerator2::handleStorageClass( Declaration *decl ) { 633 void CodeGenerator::handleStorageClass( Declaration *decl ) { 643 634 switch ( decl->get_storageClass() ) { 644 case Declaration::NoStorageClass: 645 break; 646 case Declaration::Extern: 647 before << "extern "; 648 break; 649 case Declaration::Static: 650 before << "static "; 651 break; 652 case Declaration::Auto: 635 case DeclarationNode::Extern: 636 output << "extern "; 637 break; 638 case DeclarationNode::Static: 639 output << "static "; 640 break; 641 case DeclarationNode::Auto: 653 642 // silently drop storage class 654 643 break; 655 case Declaration::Register: 656 before << "register "; 644 case DeclarationNode::Register: 645 output << "register "; 646 break; 647 case DeclarationNode::Inline: 648 output << "inline "; 649 break; 650 case DeclarationNode::Fortran: 651 output << "fortran "; 652 break; 653 case DeclarationNode::Noreturn: 654 output << "_Noreturn "; 655 break; 656 case DeclarationNode::Threadlocal: 657 output << "_Thread_local "; 658 break; 659 case DeclarationNode::NoStorageClass: 657 660 break; 658 661 } // switch
Note:
See TracChangeset
for help on using the changeset viewer.