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