Changeset 4e24610
- Timestamp:
- May 6, 2016, 1:56:08 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, with_gc
- Children:
- d029162e
- Parents:
- 711eee5
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r711eee5 r4e24610 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 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 17:32:16201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 06 11:39:01 2016 13 13 // Update Count : 243 14 14 // … … 84 84 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ) ); 85 85 86 // generalize this 87 switch ( functionDecl->get_attribute() ) { 88 case FunctionDecl::Constructor: 89 output << " __attribute__ ((constructor))"; 90 break; 91 case FunctionDecl::Destructor: 92 output << " __attribute__ ((destructor))"; 93 break; 94 default: 95 break; 96 } 97 86 98 // how to get this to the Functype? 87 99 std::list< Declaration * > olds = functionDecl->get_oldDecls(); … … 99 111 handleStorageClass( objectDecl ); 100 112 output << genType( objectDecl->get_type(), mangleName( objectDecl ) ); 101 113 102 114 if ( objectDecl->get_init() ) { 103 115 output << " = "; … … 113 125 if ( aggDecl->get_name() != "" ) 114 126 output << aggDecl->get_name(); 115 127 116 128 std::list< Declaration * > &memb = aggDecl->get_members(); 117 129 … … 119 131 output << " {" << endl; 120 132 121 cur_indent += CodeGenerator::tabsize; 133 cur_indent += CodeGenerator::tabsize; 122 134 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 123 output << indent; 135 output << indent; 124 136 (*i)->accept( *this ); 125 137 output << ";" << endl; 126 138 } 127 139 128 cur_indent -= CodeGenerator::tabsize; 140 cur_indent -= CodeGenerator::tabsize; 129 141 130 142 output << indent << "}"; … … 141 153 handleAggregate( aggregateDecl ); 142 154 } 143 155 144 156 void CodeGenerator::visit( EnumDecl *aggDecl ) { 145 157 output << "enum "; … … 147 159 if ( aggDecl->get_name() != "" ) 148 160 output << aggDecl->get_name(); 149 161 150 162 std::list< Declaration* > &memb = aggDecl->get_members(); 151 163 … … 153 165 output << " {" << endl; 154 166 155 cur_indent += CodeGenerator::tabsize; 167 cur_indent += CodeGenerator::tabsize; 156 168 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 157 169 ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i ); 158 170 assert( obj ); 159 output << indent << mangleName( obj ); 171 output << indent << mangleName( obj ); 160 172 if ( obj->get_init() ) { 161 173 output << " = "; … … 165 177 } // for 166 178 167 cur_indent -= CodeGenerator::tabsize; 179 cur_indent -= CodeGenerator::tabsize; 168 180 169 181 output << indent << "}"; 170 182 } // if 171 183 } 172 184 173 185 void CodeGenerator::visit( TraitDecl *aggregateDecl ) {} 174 186 175 187 void CodeGenerator::visit( TypedefDecl *typeDecl ) { 176 188 output << "typedef "; 177 189 output << genType( typeDecl->get_base(), typeDecl->get_name() ); 178 190 } 179 191 180 192 void CodeGenerator::visit( TypeDecl *typeDecl ) { 181 193 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes, … … 217 229 } 218 230 219 void CodeGenerator::visit( Constant *constant ) { 231 void CodeGenerator::visit( Constant *constant ) { 220 232 output << constant->get_value() ; 221 233 } … … 234 246 assert( arg != applicationExpr->get_args().end() ); 235 247 if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) { 236 248 237 249 *arg = addrExpr->get_arg(); 238 250 } else { … … 243 255 break; 244 256 } 245 257 246 258 default: 247 259 // do nothing 248 260 ; 249 261 } 250 262 251 263 switch ( opInfo.type ) { 252 264 case OT_INDEX: … … 257 269 output << "]"; 258 270 break; 259 271 260 272 case OT_CALL: 261 273 // there are no intrinsic definitions of the function call operator 262 274 assert( false ); 263 275 break; 264 276 265 277 case OT_PREFIX: 266 278 case OT_PREFIXASSIGN: … … 271 283 output << ")"; 272 284 break; 273 285 274 286 case OT_POSTFIX: 275 287 case OT_POSTFIXASSIGN: … … 288 300 output << ")"; 289 301 break; 290 302 291 303 case OT_CONSTANT: 292 304 case OT_LABELADDRESS: … … 307 319 } // if 308 320 } 309 321 310 322 void CodeGenerator::visit( UntypedExpr *untypedExpr ) { 311 323 if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { … … 321 333 output << "]"; 322 334 break; 323 335 324 336 case OT_CALL: 325 337 assert( false ); 326 338 break; 327 339 328 340 case OT_PREFIX: 329 341 case OT_PREFIXASSIGN: … … 335 347 output << ")"; 336 348 break; 337 349 338 350 case OT_POSTFIX: 339 351 case OT_POSTFIXASSIGN: … … 342 354 output << opInfo.symbol; 343 355 break; 344 356 345 357 case OT_INFIX: 346 358 case OT_INFIXASSIGN: … … 352 364 output << ")"; 353 365 break; 354 366 355 367 case OT_CONSTANT: 356 368 // there are no intrinsic definitions of 0 or 1 as functions … … 370 382 } // if 371 383 } 372 384 373 385 void CodeGenerator::visit( NameExpr *nameExpr ) { 374 386 OperatorInfo opInfo; … … 380 392 } // if 381 393 } 382 394 383 395 void CodeGenerator::visit( AddressExpr *addressExpr ) { 384 396 output << "(&"; … … 409 421 output << ")"; 410 422 } 411 423 412 424 void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) { 413 425 assert( false ); 414 426 } 415 427 416 428 void CodeGenerator::visit( MemberExpr *memberExpr ) { 417 429 memberExpr->get_aggregate()->accept( *this ); 418 430 output << "." << mangleName( memberExpr->get_member() ); 419 431 } 420 432 421 433 void CodeGenerator::visit( VariableExpr *variableExpr ) { 422 434 OperatorInfo opInfo; … … 427 439 } // if 428 440 } 429 441 430 442 void CodeGenerator::visit( ConstantExpr *constantExpr ) { 431 443 assert( constantExpr->get_constant() ); 432 444 constantExpr->get_constant()->accept( *this ); 433 445 } 434 446 435 447 void CodeGenerator::visit( SizeofExpr *sizeofExpr ) { 436 448 output << "sizeof("; … … 469 481 assert( false && "OffsetPackExpr should not reach code generation" ); 470 482 } 471 483 472 484 void CodeGenerator::visit( LogicalExpr *logicalExpr ) { 473 485 output << "("; … … 481 493 output << ")"; 482 494 } 483 495 484 496 void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) { 485 497 output << "("; … … 491 503 output << ")"; 492 504 } 493 505 494 506 void CodeGenerator::visit( CommaExpr *commaExpr ) { 495 507 output << "("; … … 499 511 output << ")"; 500 512 } 501 513 502 514 void CodeGenerator::visit( TupleExpr *tupleExpr ) {} 503 515 504 516 void CodeGenerator::visit( TypeExpr *typeExpr ) {} 505 517 … … 532 544 } 533 545 } 534 cur_indent -= CodeGenerator::tabsize; 546 cur_indent -= CodeGenerator::tabsize; 535 547 536 548 output << indent << "}"; … … 538 550 539 551 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, 552 // I don't see why this check is necessary. 553 // If this starts to cause problems then put it back in, 542 554 // with an explanation 543 555 assert( exprStmt ); … … 589 601 switchStmt->get_condition()->accept( *this ); 590 602 output << " ) "; 591 603 592 604 output << "{" << std::endl; 593 605 cur_indent += CodeGenerator::tabsize; … … 609 621 } // if 610 622 output << ":\n"; 611 623 612 624 std::list<Statement *> sts = caseStmt->get_statements(); 613 625 … … 626 638 if ( ! branchStmt->get_target().empty() ) 627 639 output << "goto " << branchStmt->get_target(); 628 else { 640 else { 629 641 if ( branchStmt->get_computedTarget() != 0 ) { 630 642 output << "goto *"; … … 677 689 678 690 void CodeGenerator::visit( ForStmt *forStmt ) { 679 // initialization is always hoisted, so don't 680 // bother doing anything with that 691 // initialization is always hoisted, so don't 692 // bother doing anything with that 681 693 output << "for (;"; 682 694 … … 702 714 void CodeGenerator::visit( DeclStmt *declStmt ) { 703 715 declStmt->get_decl()->accept( *this ); 704 716 705 717 if ( doSemicolon( declStmt->get_decl() ) ) { 706 718 output << ";"; -
src/InitTweak/FixGlobalInit.cc
r711eee5 r4e24610 10 10 // Created On : Mon May 04 15:14:56 2016 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed May 04 16:53:12201612 // Last Modified On : Fri May 06 13:51:00 2016 13 13 // Update Count : 2 14 14 // … … 30 30 class GlobalFixer : public Visitor { 31 31 public: 32 GlobalFixer( const std::string & fileName);32 GlobalFixer(); 33 33 34 34 virtual void visit( ObjectDecl *objDecl ); 35 35 virtual void visit( FunctionDecl *functionDecl ); 36 virtual void visit( StructDecl *aggregateDecl ); 37 virtual void visit( UnionDecl *aggregateDecl ); 38 virtual void visit( EnumDecl *aggregateDecl ); 39 virtual void visit( TraitDecl *aggregateDecl ); 40 virtual void visit( TypeDecl *typeDecl ); 36 41 37 42 UniqueName tempNamer; 38 FunctionDecl * initFunction;43 CompoundStmt * block; 39 44 }; 40 45 … … 83 88 84 89 void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name ) { 85 GlobalFixer fixer ( name );90 GlobalFixer fixer; 86 91 acceptAll( translationUnit, fixer ); 87 translationUnit.push_back( fixer.initFunction ); 92 // attribute only appears on the forward declaration, so need to make two function decls: 93 // one with the body, one with the attribute. 94 FunctionDecl * initFunction = new FunctionDecl( initName( name ), DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), 0, false, false ); 95 FunctionDecl * forward = initFunction->clone(); 96 forward->set_attribute( FunctionDecl::Constructor ); 97 initFunction->set_statements( fixer.block ); 98 translationUnit.push_back( forward ); 99 translationUnit.push_back( initFunction ); 88 100 } 89 101 … … 97 109 } 98 110 99 GlobalFixer::GlobalFixer( const std::string & fileName ) : tempNamer( "_global_init" ) { 100 initFunction = new FunctionDecl( initName( fileName ), DeclarationNode::NoStorageClass, LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt( noLabels ), false, false ); 111 GlobalFixer::GlobalFixer() : tempNamer( "_global_init" ), block( new CompoundStmt( noLabels ) ) { 101 112 } 102 113 103 114 void GlobalFixer::visit( ObjectDecl *objDecl ) { 104 std::list< Statement * > & statements = initFunction->get_statements()->get_kids();115 std::list< Statement * > & statements = block->get_kids(); 105 116 117 if ( objDecl->get_init() == NULL ) return; 118 if ( objDecl->get_type()->get_isConst() ) return; // temporary: can't assign to a const variable 106 119 // C allows you to initialize objects with constant expressions 107 if ( isConstExpr( objDecl->get_init() ) ) return; 120 // xxx - this is an optimization. Need to first resolve constructors before we decide 121 // to keep C-style initializer. 122 // if ( isConstExpr( objDecl->get_init() ) ) return; 108 123 109 124 // steal initializer from object and attach it to a new temporary … … 121 136 } 122 137 123 void GlobalFixer::visit( FunctionDecl *functionDecl ) { 124 // only modify global variables 125 } 138 // only modify global variables 139 void GlobalFixer::visit( FunctionDecl *functionDecl ) {} 140 void GlobalFixer::visit( StructDecl *aggregateDecl ) {} 141 void GlobalFixer::visit( UnionDecl *aggregateDecl ) {} 142 void GlobalFixer::visit( EnumDecl *aggregateDecl ) {} 143 void GlobalFixer::visit( TraitDecl *aggregateDecl ) {} 144 void GlobalFixer::visit( TypeDecl *typeDecl ) {} 145 126 146 } // namespace InitTweak 127 147 -
src/SynTree/Declaration.h
r711eee5 r4e24610 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Declaration.h -- 7 // Declaration.h -- 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 : Wed Mar 2 17:28:11201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 06 11:16:45 2016 13 13 // Update Count : 33 14 14 // … … 106 106 typedef DeclarationWithType Parent; 107 107 public: 108 FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn ); 108 // temporary - merge this into general GCC attributes 109 enum Attribute { 110 NoAttribute, Constructor, Destructor, 111 }; 112 113 FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute = NoAttribute ); 109 114 FunctionDecl( const FunctionDecl &other ); 110 115 virtual ~FunctionDecl(); … … 119 124 std::list< std::string >& get_oldIdents() { return oldIdents; } 120 125 std::list< Declaration* >& get_oldDecls() { return oldDecls; } 126 Attribute get_attribute() const { return attribute; } 127 void set_attribute( Attribute newValue ) { attribute = newValue; } 121 128 122 129 virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); } … … 130 137 std::list< std::string > oldIdents; 131 138 std::list< Declaration* > oldDecls; 139 Attribute attribute; 132 140 }; 133 141 -
src/SynTree/FunctionDecl.cc
r711eee5 r4e24610 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Apr 01 11:40:07201612 // Last Modified On : Fri May 06 11:35:09 2016 13 13 // Update Count : 19 14 14 // … … 21 21 #include "Common/utility.h" 22 22 23 FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn )24 : Parent( name, sc, linkage ), type( type ), statements( statements ) {23 FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute ) 24 : Parent( name, sc, linkage ), type( type ), statements( statements ), attribute( attribute ) { 25 25 set_isInline( isInline ); 26 26 set_isNoreturn( isNoreturn ); 27 // this is a brazen hack to force the function "main" to have C linkage 28 if ( name == "main" ) { 29 set_linkage( LinkageSpec::C ); 30 } // if 27 31 } 28 32 29 33 FunctionDecl::FunctionDecl( const FunctionDecl &other ) 30 : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ) {34 : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), attribute( other.attribute ) { 31 35 } 32 36 … … 61 65 os << "_Noreturn "; 62 66 } // if 67 switch ( attribute ) { 68 case Constructor: 69 os << "Global Constructor "; 70 break; 71 case Destructor: 72 os << "Global Destructor "; 73 break; 74 default: 75 break; 76 } 63 77 if ( get_storageClass() != DeclarationNode::NoStorageClass ) { 64 78 os << DeclarationNode::storageName[ get_storageClass() ] << ' '; … … 100 114 os << "_Noreturn "; 101 115 } // if 116 switch ( attribute ) { 117 case Constructor: 118 os << " Global Constructor "; 119 break; 120 case Destructor: 121 os << " Global Destructor "; 122 break; 123 default: 124 break; 125 } 102 126 if ( get_storageClass() != DeclarationNode::NoStorageClass ) { 103 127 os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
Note: See TracChangeset
for help on using the changeset viewer.