Changeset c8ffe20b for translator/SymTab
- Timestamp:
- Nov 15, 2014, 10:46:42 PM (11 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:
- 1ead581
- Parents:
- 8c17ab0
- File:
-
- 1 edited
-
translator/SymTab/Validate.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
translator/SymTab/Validate.cc
r8c17ab0 rc8ffe20b 1 1 /* 2 * This file is part of the Cforall project 3 * 4 * $Id: Validate.cc,v 1.22 2005/08/29 20:14:18 rcbilson Exp $ 5 * 6 */ 7 8 /* 9 The "validate" phase of translation is used to take a syntax tree and convert it into a 10 standard form that aims to be as regular in structure as possible. Some assumptions can be 11 made regarding the state of the tree after this pass is complete, including: 12 13 - No nested structure or union definitions; any in the input are "hoisted" to the level of 14 the containing struct or union. 15 16 - All enumeration constants have type EnumInstType. 17 18 - The type "void" never occurs in lists of function parameter or return types; neither do 19 tuple types. A function taking no arguments has no argument types, and tuples are flattened. 20 21 - No context instances exist; they are all replaced by the set of declarations signified by 22 the context, instantiated by the particular set of type arguments. 23 24 - Every declaration is assigned a unique id. 25 26 - No typedef declarations or instances exist; the actual type is substituted for each instance. 27 28 - Each type, struct, and union definition is followed by an appropriate assignment operator. 29 30 - Each use of a struct or union is connected to a complete definition of that struct or union, 31 even if that definition occurs later in the input. 2 The "validate" phase of translation is used to take a syntax tree and convert it into a 3 standard form that aims to be as regular in structure as possible. Some assumptions can be 4 made regarding the state of the tree after this pass is complete, including: 5 6 - No nested structure or union definitions; any in the input are "hoisted" to the level of 7 the containing struct or union. 8 9 - All enumeration constants have type EnumInstType. 10 11 - The type "void" never occurs in lists of function parameter or return types; neither do 12 tuple types. A function taking no arguments has no argument types, and tuples are flattened. 13 14 - No context instances exist; they are all replaced by the set of declarations signified by 15 the context, instantiated by the particular set of type arguments. 16 17 - Every declaration is assigned a unique id. 18 19 - No typedef declarations or instances exist; the actual type is substituted for each instance. 20 21 - Each type, struct, and union definition is followed by an appropriate assignment operator. 22 23 - Each use of a struct or union is connected to a complete definition of that struct or union, 24 even if that definition occurs later in the input. 32 25 */ 33 26 … … 48 41 49 42 50 #define debugPrint( x) if( doDebug ) { std::cout << x; }43 #define debugPrint( x ) if ( doDebug ) { std::cout << x; } 51 44 52 45 namespace SymTab { 53 54 class HoistStruct : public Visitor 55 { 56 public: 57 static void hoistStruct( std::list< Declaration* > &translationUnit ); 58 59 std::list< Declaration* > &get_declsToAdd() { return declsToAdd; } 60 61 virtual void visit(StructDecl *aggregateDecl); 62 virtual void visit(UnionDecl *aggregateDecl); 63 64 virtual void visit(CompoundStmt *compoundStmt); 65 virtual void visit(IfStmt *ifStmt); 66 virtual void visit(WhileStmt *whileStmt); 67 virtual void visit(ForStmt *forStmt); 68 virtual void visit(SwitchStmt *switchStmt); 69 virtual void visit(ChooseStmt *chooseStmt); 70 virtual void visit(CaseStmt *caseStmt); 71 virtual void visit(CatchStmt *catchStmt); 72 73 private: 74 HoistStruct(); 75 76 template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl ); 77 78 std::list< Declaration* > declsToAdd; 79 bool inStruct; 80 }; 81 82 class Pass1 : public Visitor 83 { 84 typedef Visitor Parent; 85 virtual void visit( EnumDecl *aggregateDecl); 86 virtual void visit( FunctionType *func ); 87 }; 88 89 class Pass2 : public Indexer 90 { 91 typedef Indexer Parent; 92 93 public: 94 Pass2( bool doDebug, const Indexer *indexer ); 95 96 private: 97 virtual void visit( StructInstType *structInst ); 98 virtual void visit( UnionInstType *unionInst ); 99 virtual void visit( ContextInstType *contextInst ); 100 virtual void visit( StructDecl *structDecl ); 101 virtual void visit( UnionDecl *unionDecl ); 102 virtual void visit( TypeInstType *typeInst ); 103 104 const Indexer *indexer; 105 106 typedef std::map< std::string, std::list< StructInstType* > > ForwardStructsType; 107 typedef std::map< std::string, std::list< UnionInstType* > > ForwardUnionsType; 108 ForwardStructsType forwardStructs; 109 ForwardUnionsType forwardUnions; 110 }; 111 112 class Pass3 : public Indexer 113 { 114 typedef Indexer Parent; 115 116 public: 117 Pass3( const Indexer *indexer ); 118 119 private: 120 virtual void visit( ObjectDecl *object ); 121 virtual void visit( FunctionDecl *func ); 122 123 const Indexer *indexer; 124 }; 125 126 class AddStructAssignment : public Visitor 127 { 128 public: 129 static void addStructAssignment( std::list< Declaration* > &translationUnit ); 130 131 std::list< Declaration* > &get_declsToAdd() { return declsToAdd; } 132 133 virtual void visit( StructDecl *structDecl ); 134 virtual void visit( UnionDecl *structDecl ); 135 virtual void visit( TypeDecl *typeDecl ); 136 virtual void visit( ContextDecl *ctxDecl ); 137 138 virtual void visit( FunctionType *ftype ); 139 virtual void visit( PointerType *ftype ); 140 141 virtual void visit(CompoundStmt *compoundStmt); 142 virtual void visit(IfStmt *ifStmt); 143 virtual void visit(WhileStmt *whileStmt); 144 virtual void visit(ForStmt *forStmt); 145 virtual void visit(SwitchStmt *switchStmt); 146 virtual void visit(ChooseStmt *chooseStmt); 147 virtual void visit(CaseStmt *caseStmt); 148 virtual void visit(CatchStmt *catchStmt); 149 150 private: 151 template< typename StmtClass > void visitStatement(StmtClass *stmt); 152 153 std::list< Declaration* > declsToAdd; 154 std::set< std::string > structsDone; 155 }; 156 157 class EliminateTypedef : public Mutator 158 { 159 public: 160 static void eliminateTypedef( std::list< Declaration* > &translationUnit ); 161 162 private: 163 virtual Declaration* mutate(TypedefDecl *typeDecl); 164 virtual TypeDecl* mutate(TypeDecl *typeDecl); 165 virtual DeclarationWithType* mutate(FunctionDecl *funcDecl); 166 virtual ObjectDecl* mutate(ObjectDecl *objDecl); 167 virtual CompoundStmt* mutate(CompoundStmt *compoundStmt); 168 virtual Type* mutate(TypeInstType *aggregateUseType); 169 virtual Expression* mutate(CastExpr *castExpr); 170 171 std::map< std::string, TypedefDecl* > typedefNames; 172 }; 173 174 void 175 validate( std::list< Declaration* > &translationUnit, bool doDebug, const Indexer *indexer ) 176 { 177 Pass1 pass1; 178 Pass2 pass2( doDebug, indexer ); 179 Pass3 pass3( indexer ); 180 EliminateTypedef::eliminateTypedef( translationUnit ); 181 HoistStruct::hoistStruct( translationUnit ); 182 acceptAll( translationUnit, pass1 ); 183 acceptAll( translationUnit, pass2 ); 184 AddStructAssignment::addStructAssignment( translationUnit ); 185 acceptAll( translationUnit, pass3 ); 186 } 187 188 void 189 validateType( Type *type, const Indexer *indexer ) 190 { 191 Pass1 pass1; 192 Pass2 pass2( false, indexer ); 193 Pass3 pass3( indexer ); 194 type->accept( pass1 ); 195 type->accept( pass2 ); 196 type->accept( pass3 ); 197 } 198 199 template< typename Visitor > 200 void 201 acceptAndAdd( std::list< Declaration* > &translationUnit, Visitor &visitor, bool addBefore ) 202 { 203 std::list< Declaration* >::iterator i = translationUnit.begin(); 204 while( i != translationUnit.end() ) { 205 (*i)->accept( visitor ); 206 std::list< Declaration* >::iterator next = i; 207 next++; 208 if( !visitor.get_declsToAdd().empty() ) { 209 translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() ); 210 } 211 i = next; 212 } 213 } 214 215 /* static class method */ 216 void 217 HoistStruct::hoistStruct( std::list< Declaration* > &translationUnit ) 218 { 219 HoistStruct hoister; 220 acceptAndAdd( translationUnit, hoister, true ); 221 } 222 223 HoistStruct::HoistStruct() 224 : inStruct( false ) 225 { 226 } 227 228 void 229 filter( std::list< Declaration* > &declList, bool (*pred)( Declaration* ), bool doDelete ) 230 { 231 std::list< Declaration* >::iterator i = declList.begin(); 232 while( i != declList.end() ) { 233 std::list< Declaration* >::iterator next = i; 234 ++next; 235 if( pred( *i ) ) { 236 if( doDelete ) { 237 delete *i; 238 } 239 declList.erase( i ); 240 } 241 i = next; 242 } 243 } 244 245 bool 246 isStructOrUnion( Declaration *decl ) 247 { 248 return dynamic_cast< StructDecl* >( decl ) || dynamic_cast< UnionDecl* >( decl ); 249 } 250 251 template< typename AggDecl > 252 void 253 HoistStruct::handleAggregate( AggDecl *aggregateDecl ) 254 { 255 if( inStruct ) { 256 declsToAdd.push_back( aggregateDecl ); 257 Visitor::visit( aggregateDecl ); 258 } else { 259 inStruct = true; 260 Visitor::visit( aggregateDecl ); 261 inStruct = false; 262 filter( aggregateDecl->get_members(), isStructOrUnion, false ); 263 } 264 } 265 266 void 267 HoistStruct::visit(StructDecl *aggregateDecl) 268 { 269 handleAggregate( aggregateDecl ); 270 } 271 272 void 273 HoistStruct::visit(UnionDecl *aggregateDecl) 274 { 275 handleAggregate( aggregateDecl ); 276 } 277 278 void 279 HoistStruct::visit(CompoundStmt *compoundStmt) 280 { 281 addVisit( compoundStmt, *this ); 282 } 283 284 void 285 HoistStruct::visit(IfStmt *ifStmt) 286 { 287 addVisit( ifStmt, *this ); 288 } 289 290 void 291 HoistStruct::visit(WhileStmt *whileStmt) 292 { 293 addVisit( whileStmt, *this ); 294 } 295 296 void 297 HoistStruct::visit(ForStmt *forStmt) 298 { 299 addVisit( forStmt, *this ); 300 } 301 302 void 303 HoistStruct::visit(SwitchStmt *switchStmt) 304 { 305 addVisit( switchStmt, *this ); 306 } 307 308 void 309 HoistStruct::visit(ChooseStmt *switchStmt) 310 { 311 addVisit( switchStmt, *this ); 312 } 313 314 void 315 HoistStruct::visit(CaseStmt *caseStmt) 316 { 317 addVisit( caseStmt, *this ); 318 } 319 320 void 321 HoistStruct::visit(CatchStmt *cathStmt) 322 { 323 addVisit( cathStmt, *this ); 324 } 325 326 void 327 Pass1::visit( EnumDecl *enumDecl) 328 { 329 // Set the type of each member of the enumeration to be EnumConstant 330 331 for( std::list< Declaration* >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) { 332 ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i ); 333 assert( obj ); 334 obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false ), enumDecl->get_name() ) ); 335 } 336 Parent::visit( enumDecl ); 337 } 338 339 namespace { 340 template< typename DWTIterator > 341 void 342 fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func ) 343 { 344 // the only case in which "void" is valid is where it is the only one in the list; then 345 // it should be removed entirely 346 // other fix ups are handled by the FixFunction class 347 if( begin == end ) return; 348 FixFunction fixer; 349 DWTIterator i = begin; 350 *i = (*i)->acceptMutator( fixer ); 351 if( fixer.get_isVoid() ) { 352 DWTIterator j = i; 353 ++i; 354 func->get_parameters().erase( j ); 355 if( i != end ) { 356 throw SemanticError( "invalid type void in function type ", func ); 357 } 358 } else { 359 ++i; 360 for( ; i != end; ++i ) { 361 FixFunction fixer; 362 *i = (*i)->acceptMutator( fixer ); 363 if( fixer.get_isVoid() ) { 364 throw SemanticError( "invalid type void in function type ", func ); 365 } 366 } 367 } 368 } 369 } 370 371 void 372 Pass1::visit( FunctionType *func ) 373 { 374 // Fix up parameters and return types 375 fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func ); 376 fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func ); 377 Visitor::visit( func ); 378 } 379 380 Pass2::Pass2( bool doDebug, const Indexer *other_indexer ) 381 : Indexer( doDebug ) 382 { 383 if( other_indexer ) { 384 indexer = other_indexer; 385 } else { 386 indexer = this; 387 } 388 } 389 390 void 391 Pass2::visit( StructInstType *structInst ) 392 { 393 Parent::visit( structInst ); 394 StructDecl *st = indexer->lookupStruct( structInst->get_name() ); 395 // it's not a semantic error if the struct is not found, just an implicit forward declaration 396 if( st ) { 397 assert( !structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || !st->get_members().empty() ); 398 structInst->set_baseStruct( st ); 399 } 400 if( !st || st->get_members().empty() ) { 401 // use of forward declaration 402 forwardStructs[ structInst->get_name() ].push_back( structInst ); 403 } 404 } 405 406 void 407 Pass2::visit( UnionInstType *unionInst ) 408 { 409 Parent::visit( unionInst ); 410 UnionDecl *un = indexer->lookupUnion( unionInst->get_name() ); 411 // it's not a semantic error if the union is not found, just an implicit forward declaration 412 if( un ) { 413 unionInst->set_baseUnion( un ); 414 } 415 if( !un || un->get_members().empty() ) { 416 // use of forward declaration 417 forwardUnions[ unionInst->get_name() ].push_back( unionInst ); 418 } 419 } 420 421 void 422 Pass2::visit( ContextInstType *contextInst ) 423 { 424 Parent::visit( contextInst ); 425 ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() ); 426 if( !ctx ) { 427 throw SemanticError( "use of undeclared context " + contextInst->get_name() ); 428 } 429 for( std::list< TypeDecl* >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) { 430 for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) { 431 if( ContextInstType *otherCtx = dynamic_cast< ContextInstType* >(*assert) ) { 432 cloneAll( otherCtx->get_members(), contextInst->get_members() ); 433 } else { 434 contextInst->get_members().push_back( (*assert)->clone() ); 435 } 436 } 437 } 438 applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) ); 439 } 440 441 void 442 Pass2::visit( StructDecl *structDecl ) 443 { 444 if( !structDecl->get_members().empty() ) { 445 ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() ); 446 if( fwds != forwardStructs.end() ) { 447 for( std::list< StructInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 448 (*inst)->set_baseStruct( structDecl ); 449 } 450 forwardStructs.erase( fwds ); 451 } 452 } 453 Indexer::visit( structDecl ); 454 } 455 456 void 457 Pass2::visit( UnionDecl *unionDecl ) 458 { 459 if( !unionDecl->get_members().empty() ) { 460 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() ); 461 if( fwds != forwardUnions.end() ) { 462 for( std::list< UnionInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 463 (*inst)->set_baseUnion( unionDecl ); 464 } 465 forwardUnions.erase( fwds ); 466 } 467 } 468 Indexer::visit( unionDecl ); 469 } 470 471 void 472 Pass2::visit( TypeInstType *typeInst ) 473 { 474 if( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) { 475 if( TypeDecl *typeDecl = dynamic_cast< TypeDecl* >( namedTypeDecl ) ) { 476 typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype ); 477 } 478 } 479 } 480 481 Pass3::Pass3( const Indexer *other_indexer ) 482 : Indexer( false ) 483 { 484 if( other_indexer ) { 485 indexer = other_indexer; 486 } else { 487 indexer = this; 488 } 489 } 490 491 void 492 forallFixer( Type *func ) 493 { 494 // Fix up assertions 495 for( std::list< TypeDecl* >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) { 496 std::list< DeclarationWithType* > toBeDone, nextRound; 497 toBeDone.splice( toBeDone.end(), (*type)->get_assertions() ); 498 while( !toBeDone.empty() ) { 499 for( std::list< DeclarationWithType* >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) { 500 if( ContextInstType *ctx = dynamic_cast< ContextInstType* >( (*assertion)->get_type() ) ) { 501 for( std::list< Declaration* >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) { 502 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ); 503 assert( dwt ); 504 nextRound.push_back( dwt->clone() ); 505 } 506 delete ctx; 507 } else { 508 FixFunction fixer; 509 *assertion = (*assertion)->acceptMutator( fixer ); 510 if( fixer.get_isVoid() ) { 511 throw SemanticError( "invalid type void in assertion of function ", func ); 512 } 513 (*type)->get_assertions().push_back( *assertion ); 514 } 515 } 516 toBeDone.clear(); 517 toBeDone.splice( toBeDone.end(), nextRound ); 518 } 519 } 520 } 521 522 void 523 Pass3::visit( ObjectDecl *object ) 524 { 525 forallFixer( object->get_type() ); 526 if( PointerType *pointer = dynamic_cast< PointerType* >( object->get_type() ) ) { 527 forallFixer( pointer->get_base() ); 528 } 529 Parent::visit( object ); 530 object->fixUniqueId(); 531 } 532 533 void 534 Pass3::visit( FunctionDecl *func ) 535 { 536 forallFixer( func->get_type() ); 537 Parent::visit( func ); 538 func->fixUniqueId(); 539 } 540 541 static const std::list< std::string > noLabels; 542 543 /* static class method */ 544 void 545 AddStructAssignment::addStructAssignment( std::list< Declaration* > &translationUnit ) 546 { 547 AddStructAssignment visitor; 548 acceptAndAdd( translationUnit, visitor, false ); 549 } 550 551 template< typename OutputIterator > 552 void 553 makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) 554 { 555 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member ); // PAB: unnamed bit fields are not copied 556 if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return; 557 558 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 559 560 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 561 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 562 563 // do something special for unnamed members 564 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) ); 565 assignExpr->get_args().push_back( dstselect ); 566 567 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 568 assignExpr->get_args().push_back( srcselect ); 569 570 *out++ = new ExprStmt( noLabels, assignExpr ); 571 } 572 573 template< typename OutputIterator > 574 void 575 makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) 576 { 577 static UniqueName indexName( "_index" ); 578 579 // for a flexible array member nothing is done -- user must define own assignment 580 if( !array->get_dimension() ) return; 581 582 ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ); 583 *out++ = new DeclStmt( noLabels, index ); 584 585 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) ); 586 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 587 init->get_args().push_back( new NameExpr( "0" ) ); 588 Statement *initStmt = new ExprStmt( noLabels, init ); 589 590 UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) ); 591 cond->get_args().push_back( new VariableExpr( index ) ); 592 cond->get_args().push_back( array->get_dimension()->clone() ); 593 594 UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) ); 595 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 596 597 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 598 599 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 600 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 601 602 Expression *dstselect = new MemberExpr( member, derefExpr ); 603 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) ); 604 dstIndex->get_args().push_back( dstselect ); 605 dstIndex->get_args().push_back( new VariableExpr( index ) ); 606 assignExpr->get_args().push_back( dstIndex ); 607 608 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 609 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 610 srcIndex->get_args().push_back( srcselect ); 611 srcIndex->get_args().push_back( new VariableExpr( index ) ); 612 assignExpr->get_args().push_back( srcIndex ); 613 614 *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) ); 615 } 616 617 Declaration* 618 makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType ) 619 { 620 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 621 622 ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 ); 623 assignType->get_returnVals().push_back( returnVal ); 624 625 ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 ); 626 assignType->get_parameters().push_back( dstParam ); 627 628 ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 ); 629 assignType->get_parameters().push_back( srcParam ); 630 631 FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true ); 632 assignDecl->fixUniqueId(); 633 634 for( std::list< Declaration* >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) { 635 if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *member ) ) { 636 if( ArrayType *array = dynamic_cast< ArrayType* >( dwt->get_type() ) ) { 637 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 638 } else { 639 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) ); 640 } 641 } 642 } 643 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 644 645 return assignDecl; 646 } 647 648 Declaration* 649 makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType ) 650 { 651 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 652 653 ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 ); 654 assignType->get_returnVals().push_back( returnVal ); 655 656 ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 ); 657 assignType->get_parameters().push_back( dstParam ); 658 659 ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 ); 660 assignType->get_parameters().push_back( srcParam ); 661 662 FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true ); 663 assignDecl->fixUniqueId(); 664 665 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 666 copy->get_args().push_back( new VariableExpr( dstParam ) ); 667 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 668 copy->get_args().push_back( new SizeofExpr( refType->clone() ) ); 669 670 assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) ); 671 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 672 673 return assignDecl; 674 } 675 676 void 677 AddStructAssignment::visit( StructDecl *structDecl ) 678 { 679 if( !structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) { 680 StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() ); 681 structInst->set_baseStruct( structDecl ); 682 declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) ); 683 structsDone.insert( structDecl->get_name() ); 684 } 685 } 686 687 void 688 AddStructAssignment::visit( UnionDecl *unionDecl ) 689 { 690 if( !unionDecl->get_members().empty() ) { 691 UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() ); 692 unionInst->set_baseUnion( unionDecl ); 693 declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) ); 694 } 695 } 696 697 void 698 AddStructAssignment::visit( TypeDecl *typeDecl ) 699 { 700 CompoundStmt *stmts = 0; 701 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false ); 702 typeInst->set_baseType( typeDecl ); 703 ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 ); 704 ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 ); 705 if( typeDecl->get_base() ) { 706 stmts = new CompoundStmt( std::list< Label >() ); 707 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 708 assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) ); 709 assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) ); 710 stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) ); 711 } 712 FunctionType *type = new FunctionType( Type::Qualifiers(), false ); 713 type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) ); 714 type->get_parameters().push_back( dst ); 715 type->get_parameters().push_back( src ); 716 FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false ); 717 declsToAdd.push_back( func ); 718 } 719 720 void 721 addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i ) 722 { 723 if( !declsToAdd.empty() ) { 724 for( std::list< Declaration* >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) { 725 statements.insert( i, new DeclStmt( noLabels, *decl ) ); 726 } 727 declsToAdd.clear(); 728 } 729 } 730 731 void 732 AddStructAssignment::visit(FunctionType *) 733 { 734 // ensure that we don't add assignment ops for types defined 735 // as part of the function 736 } 737 738 void 739 AddStructAssignment::visit(PointerType *) 740 { 741 // ensure that we don't add assignment ops for types defined 742 // as part of the pointer 743 } 744 745 void 746 AddStructAssignment::visit(ContextDecl *) 747 { 748 // ensure that we don't add assignment ops for types defined 749 // as part of the context 750 } 751 752 template< typename StmtClass > 753 inline void 754 AddStructAssignment::visitStatement(StmtClass *stmt) 755 { 756 std::set< std::string > oldStructs = structsDone; 757 addVisit( stmt, *this ); 758 structsDone = oldStructs; 759 } 760 761 void 762 AddStructAssignment::visit(CompoundStmt *compoundStmt) 763 { 764 visitStatement( compoundStmt ); 765 } 766 767 void 768 AddStructAssignment::visit(IfStmt *ifStmt) 769 { 770 visitStatement( ifStmt ); 771 } 772 773 void 774 AddStructAssignment::visit(WhileStmt *whileStmt) 775 { 776 visitStatement( whileStmt ); 777 } 778 779 void 780 AddStructAssignment::visit(ForStmt *forStmt) 781 { 782 visitStatement( forStmt ); 783 } 784 785 void 786 AddStructAssignment::visit(SwitchStmt *switchStmt) 787 { 788 visitStatement( switchStmt ); 789 } 790 791 void 792 AddStructAssignment::visit(ChooseStmt *switchStmt) 793 { 794 visitStatement( switchStmt ); 795 } 796 797 void 798 AddStructAssignment::visit(CaseStmt *caseStmt) 799 { 800 visitStatement( caseStmt ); 801 } 802 803 void 804 AddStructAssignment::visit(CatchStmt *cathStmt) 805 { 806 visitStatement( cathStmt ); 807 } 808 809 bool 810 isTypedef( Declaration *decl ) 811 { 812 return dynamic_cast< TypedefDecl* >( decl ); 813 } 814 815 816 /* static class method */ 817 void 818 EliminateTypedef::eliminateTypedef( std::list< Declaration* > &translationUnit ) 819 { 820 EliminateTypedef eliminator; 821 mutateAll( translationUnit, eliminator ); 822 filter( translationUnit, isTypedef, true ); 823 } 824 825 Type* 826 EliminateTypedef::mutate( TypeInstType *typeInst ) 827 { 828 std::map< std::string, TypedefDecl* >::const_iterator def = typedefNames.find( typeInst->get_name() ); 829 if( def != typedefNames.end() ) { 830 Type *ret = def->second->get_base()->clone(); 831 ret->get_qualifiers() += typeInst->get_qualifiers(); 832 delete typeInst; 833 return ret; 834 } 835 return typeInst; 836 } 837 838 Declaration* 839 EliminateTypedef::mutate( TypedefDecl *tyDecl ) 840 { 841 Declaration *ret = Mutator::mutate( tyDecl ); 842 typedefNames[ tyDecl->get_name() ] = tyDecl; 843 if( AggregateDecl *aggDecl = dynamic_cast< AggregateDecl* >( tyDecl->get_base() ) ) { 844 tyDecl->set_base( 0 ); 845 delete tyDecl; 846 return aggDecl; 847 } else { 848 return ret; 849 } 850 } 851 852 TypeDecl* 853 EliminateTypedef::mutate(TypeDecl *typeDecl) 854 { 855 std::map< std::string, TypedefDecl* >::iterator i = typedefNames.find( typeDecl->get_name() ); 856 if( i != typedefNames.end() ) { 857 typedefNames.erase( i ) ; 858 } 859 return typeDecl; 860 } 861 862 DeclarationWithType* 863 EliminateTypedef::mutate(FunctionDecl *funcDecl) 864 { 865 std::map< std::string, TypedefDecl* > oldNames = typedefNames; 866 DeclarationWithType *ret = Mutator::mutate( funcDecl ); 867 typedefNames = oldNames; 868 return ret; 869 } 870 871 ObjectDecl* 872 EliminateTypedef::mutate(ObjectDecl *objDecl) 873 { 874 std::map< std::string, TypedefDecl* > oldNames = typedefNames; 875 ObjectDecl *ret = Mutator::mutate( objDecl ); 876 typedefNames = oldNames; 877 return ret; 878 } 879 880 Expression* 881 EliminateTypedef::mutate(CastExpr *castExpr) 882 { 883 std::map< std::string, TypedefDecl* > oldNames = typedefNames; 884 Expression *ret = Mutator::mutate( castExpr ); 885 typedefNames = oldNames; 886 return ret; 887 } 888 889 CompoundStmt * 890 EliminateTypedef::mutate( CompoundStmt *compoundStmt ) 891 { 892 std::map< std::string, TypedefDecl* > oldNames = typedefNames; 893 CompoundStmt *ret = Mutator::mutate( compoundStmt ); 894 std::list< Statement* >::iterator i = compoundStmt->get_kids().begin(); 895 while( i != compoundStmt->get_kids().end() ) { 896 std::list< Statement* >::iterator next = i; 897 ++next; 898 if( DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *i ) ) { 899 if( dynamic_cast< TypedefDecl* >( declStmt->get_decl() ) ) { 900 delete *i; 901 compoundStmt->get_kids().erase( i ); 902 } 903 } 904 i = next; 905 } 906 typedefNames = oldNames; 907 return ret; 908 } 909 46 class HoistStruct : public Visitor { 47 public: 48 static void hoistStruct( std::list< Declaration * > &translationUnit ); 49 50 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 51 52 virtual void visit( StructDecl *aggregateDecl ); 53 virtual void visit( UnionDecl *aggregateDecl ); 54 55 virtual void visit( CompoundStmt *compoundStmt ); 56 virtual void visit( IfStmt *ifStmt ); 57 virtual void visit( WhileStmt *whileStmt ); 58 virtual void visit( ForStmt *forStmt ); 59 virtual void visit( SwitchStmt *switchStmt ); 60 virtual void visit( ChooseStmt *chooseStmt ); 61 virtual void visit( CaseStmt *caseStmt ); 62 virtual void visit( CatchStmt *catchStmt ); 63 private: 64 HoistStruct(); 65 66 template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl ); 67 68 std::list< Declaration * > declsToAdd; 69 bool inStruct; 70 }; 71 72 class Pass1 : public Visitor { 73 typedef Visitor Parent; 74 virtual void visit( EnumDecl *aggregateDecl ); 75 virtual void visit( FunctionType *func ); 76 }; 77 78 class Pass2 : public Indexer { 79 typedef Indexer Parent; 80 public: 81 Pass2( bool doDebug, const Indexer *indexer ); 82 private: 83 virtual void visit( StructInstType *structInst ); 84 virtual void visit( UnionInstType *unionInst ); 85 virtual void visit( ContextInstType *contextInst ); 86 virtual void visit( StructDecl *structDecl ); 87 virtual void visit( UnionDecl *unionDecl ); 88 virtual void visit( TypeInstType *typeInst ); 89 90 const Indexer *indexer; 91 92 typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType; 93 typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType; 94 ForwardStructsType forwardStructs; 95 ForwardUnionsType forwardUnions; 96 }; 97 98 class Pass3 : public Indexer { 99 typedef Indexer Parent; 100 public: 101 Pass3( const Indexer *indexer ); 102 private: 103 virtual void visit( ObjectDecl *object ); 104 virtual void visit( FunctionDecl *func ); 105 106 const Indexer *indexer; 107 }; 108 109 class AddStructAssignment : public Visitor { 110 public: 111 static void addStructAssignment( std::list< Declaration * > &translationUnit ); 112 113 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 114 115 virtual void visit( StructDecl *structDecl ); 116 virtual void visit( UnionDecl *structDecl ); 117 virtual void visit( TypeDecl *typeDecl ); 118 virtual void visit( ContextDecl *ctxDecl ); 119 120 virtual void visit( FunctionType *ftype ); 121 virtual void visit( PointerType *ftype ); 122 123 virtual void visit( CompoundStmt *compoundStmt ); 124 virtual void visit( IfStmt *ifStmt ); 125 virtual void visit( WhileStmt *whileStmt ); 126 virtual void visit( ForStmt *forStmt ); 127 virtual void visit( SwitchStmt *switchStmt ); 128 virtual void visit( ChooseStmt *chooseStmt ); 129 virtual void visit( CaseStmt *caseStmt ); 130 virtual void visit( CatchStmt *catchStmt ); 131 private: 132 template< typename StmtClass > void visitStatement( StmtClass *stmt ); 133 134 std::list< Declaration * > declsToAdd; 135 std::set< std::string > structsDone; 136 }; 137 138 class EliminateTypedef : public Mutator { 139 public: 140 static void eliminateTypedef( std::list< Declaration * > &translationUnit ); 141 private: 142 virtual Declaration *mutate( TypedefDecl *typeDecl ); 143 virtual TypeDecl *mutate( TypeDecl *typeDecl ); 144 virtual DeclarationWithType *mutate( FunctionDecl *funcDecl ); 145 virtual ObjectDecl *mutate( ObjectDecl *objDecl ); 146 virtual CompoundStmt *mutate( CompoundStmt *compoundStmt ); 147 virtual Type *mutate( TypeInstType *aggregateUseType ); 148 virtual Expression *mutate( CastExpr *castExpr ); 149 150 std::map< std::string, TypedefDecl * > typedefNames; 151 }; 152 153 void validate( std::list< Declaration * > &translationUnit, bool doDebug, const Indexer *indexer ) { 154 Pass1 pass1; 155 Pass2 pass2( doDebug, indexer ); 156 Pass3 pass3( indexer ); 157 EliminateTypedef::eliminateTypedef( translationUnit ); 158 HoistStruct::hoistStruct( translationUnit ); 159 acceptAll( translationUnit, pass1 ); 160 acceptAll( translationUnit, pass2 ); 161 AddStructAssignment::addStructAssignment( translationUnit ); 162 acceptAll( translationUnit, pass3 ); 163 } 164 165 void validateType( Type *type, const Indexer *indexer ) { 166 Pass1 pass1; 167 Pass2 pass2( false, indexer ); 168 Pass3 pass3( indexer ); 169 type->accept( pass1 ); 170 type->accept( pass2 ); 171 type->accept( pass3 ); 172 } 173 174 template< typename Visitor > 175 void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) { 176 std::list< Declaration * >::iterator i = translationUnit.begin(); 177 while ( i != translationUnit.end() ) { 178 (*i )->accept( visitor ); 179 std::list< Declaration * >::iterator next = i; 180 next++; 181 if ( ! visitor.get_declsToAdd().empty() ) { 182 translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() ); 183 } 184 i = next; 185 } 186 } 187 188 void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) { 189 HoistStruct hoister; 190 acceptAndAdd( translationUnit, hoister, true ); 191 } 192 193 HoistStruct::HoistStruct() 194 : inStruct( false ) { 195 } 196 197 void filter( std::list< Declaration * > &declList, bool (*pred )( Declaration * ), bool doDelete ) { 198 std::list< Declaration * >::iterator i = declList.begin(); 199 while ( i != declList.end() ) { 200 std::list< Declaration * >::iterator next = i; 201 ++next; 202 if ( pred( *i ) ) { 203 if ( doDelete ) { 204 delete *i; 205 } 206 declList.erase( i ); 207 } 208 i = next; 209 } 210 } 211 212 bool 213 isStructOrUnion( Declaration *decl ) { 214 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ); 215 } 216 217 template< typename AggDecl > 218 void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) { 219 if ( inStruct ) { 220 declsToAdd.push_back( aggregateDecl ); 221 Visitor::visit( aggregateDecl ); 222 } else { 223 inStruct = true; 224 Visitor::visit( aggregateDecl ); 225 inStruct = false; 226 filter( aggregateDecl->get_members(), isStructOrUnion, false ); 227 } 228 } 229 230 void HoistStruct::visit( StructDecl *aggregateDecl ) { 231 handleAggregate( aggregateDecl ); 232 } 233 234 void HoistStruct::visit( UnionDecl *aggregateDecl ) { 235 handleAggregate( aggregateDecl ); 236 } 237 238 void HoistStruct::visit( CompoundStmt *compoundStmt ) { 239 addVisit( compoundStmt, *this ); 240 } 241 242 void HoistStruct::visit( IfStmt *ifStmt ) { 243 addVisit( ifStmt, *this ); 244 } 245 246 void HoistStruct::visit( WhileStmt *whileStmt ) { 247 addVisit( whileStmt, *this ); 248 } 249 250 void HoistStruct::visit( ForStmt *forStmt ) { 251 addVisit( forStmt, *this ); 252 } 253 254 void HoistStruct::visit( SwitchStmt *switchStmt ) { 255 addVisit( switchStmt, *this ); 256 } 257 258 void HoistStruct::visit( ChooseStmt *switchStmt ) { 259 addVisit( switchStmt, *this ); 260 } 261 262 void HoistStruct::visit( CaseStmt *caseStmt ) { 263 addVisit( caseStmt, *this ); 264 } 265 266 void HoistStruct::visit( CatchStmt *cathStmt ) { 267 addVisit( cathStmt, *this ); 268 } 269 270 void Pass1::visit( EnumDecl *enumDecl ) { 271 // Set the type of each member of the enumeration to be EnumConstant 272 273 for( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) { 274 ObjectDecl *obj = dynamic_cast< ObjectDecl * >( *i ); 275 assert( obj ); 276 obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false ), enumDecl->get_name() ) ); 277 } 278 Parent::visit( enumDecl ); 279 } 280 281 namespace { 282 template< typename DWTIterator > 283 void 284 fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func ) { 285 // the only case in which "void" is valid is where it is the only one in the list; then 286 // it should be removed entirely 287 // other fix ups are handled by the FixFunction class 288 if ( begin == end ) return; 289 FixFunction fixer; 290 DWTIterator i = begin; 291 *i = (*i )->acceptMutator( fixer ); 292 if ( fixer.get_isVoid() ) { 293 DWTIterator j = i; 294 ++i; 295 func->get_parameters().erase( j ); 296 if ( i != end ) { 297 throw SemanticError( "invalid type void in function type ", func ); 298 } 299 } else { 300 ++i; 301 for( ; i != end; ++i ) { 302 FixFunction fixer; 303 *i = (*i )->acceptMutator( fixer ); 304 if ( fixer.get_isVoid() ) { 305 throw SemanticError( "invalid type void in function type ", func ); 306 } 307 } 308 } 309 } 310 } 311 312 void Pass1::visit( FunctionType *func ) { 313 // Fix up parameters and return types 314 fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func ); 315 fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func ); 316 Visitor::visit( func ); 317 } 318 319 Pass2::Pass2( bool doDebug, const Indexer *other_indexer ) 320 : Indexer( doDebug ) { 321 if ( other_indexer ) { 322 indexer = other_indexer; 323 } else { 324 indexer = this; 325 } 326 } 327 328 void Pass2::visit( StructInstType *structInst ) { 329 Parent::visit( structInst ); 330 StructDecl *st = indexer->lookupStruct( structInst->get_name() ); 331 // it's not a semantic error if the struct is not found, just an implicit forward declaration 332 if ( st ) { 333 assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() ); 334 structInst->set_baseStruct( st ); 335 } 336 if ( ! st || st->get_members().empty() ) { 337 // use of forward declaration 338 forwardStructs[ structInst->get_name() ].push_back( structInst ); 339 } 340 } 341 342 void Pass2::visit( UnionInstType *unionInst ) { 343 Parent::visit( unionInst ); 344 UnionDecl *un = indexer->lookupUnion( unionInst->get_name() ); 345 // it's not a semantic error if the union is not found, just an implicit forward declaration 346 if ( un ) { 347 unionInst->set_baseUnion( un ); 348 } 349 if ( ! un || un->get_members().empty() ) { 350 // use of forward declaration 351 forwardUnions[ unionInst->get_name() ].push_back( unionInst ); 352 } 353 } 354 355 void Pass2::visit( ContextInstType *contextInst ) { 356 Parent::visit( contextInst ); 357 ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() ); 358 if ( ! ctx ) { 359 throw SemanticError( "use of undeclared context " + contextInst->get_name() ); 360 } 361 for( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) { 362 for( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) { 363 if ( ContextInstType *otherCtx = dynamic_cast< ContextInstType * >(*assert ) ) { 364 cloneAll( otherCtx->get_members(), contextInst->get_members() ); 365 } else { 366 contextInst->get_members().push_back( (*assert )->clone() ); 367 } 368 } 369 } 370 applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) ); 371 } 372 373 void Pass2::visit( StructDecl *structDecl ) { 374 if ( ! structDecl->get_members().empty() ) { 375 ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() ); 376 if ( fwds != forwardStructs.end() ) { 377 for( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 378 (*inst )->set_baseStruct( structDecl ); 379 } 380 forwardStructs.erase( fwds ); 381 } 382 } 383 Indexer::visit( structDecl ); 384 } 385 386 void Pass2::visit( UnionDecl *unionDecl ) { 387 if ( ! unionDecl->get_members().empty() ) { 388 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() ); 389 if ( fwds != forwardUnions.end() ) { 390 for( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 391 (*inst )->set_baseUnion( unionDecl ); 392 } 393 forwardUnions.erase( fwds ); 394 } 395 } 396 Indexer::visit( unionDecl ); 397 } 398 399 void Pass2::visit( TypeInstType *typeInst ) { 400 if ( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) { 401 if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) { 402 typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype ); 403 } 404 } 405 } 406 407 Pass3::Pass3( const Indexer *other_indexer ) 408 : Indexer( false ) { 409 if ( other_indexer ) { 410 indexer = other_indexer; 411 } else { 412 indexer = this; 413 } 414 } 415 416 void forallFixer( Type *func ) { 417 // Fix up assertions 418 for( std::list< TypeDecl * >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) { 419 std::list< DeclarationWithType * > toBeDone, nextRound; 420 toBeDone.splice( toBeDone.end(), (*type )->get_assertions() ); 421 while ( ! toBeDone.empty() ) { 422 for( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) { 423 if ( ContextInstType *ctx = dynamic_cast< ContextInstType * >( (*assertion )->get_type() ) ) { 424 for( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) { 425 DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i ); 426 assert( dwt ); 427 nextRound.push_back( dwt->clone() ); 428 } 429 delete ctx; 430 } else { 431 FixFunction fixer; 432 *assertion = (*assertion )->acceptMutator( fixer ); 433 if ( fixer.get_isVoid() ) { 434 throw SemanticError( "invalid type void in assertion of function ", func ); 435 } 436 (*type )->get_assertions().push_back( *assertion ); 437 } 438 } 439 toBeDone.clear(); 440 toBeDone.splice( toBeDone.end(), nextRound ); 441 } 442 } 443 } 444 445 void Pass3::visit( ObjectDecl *object ) { 446 forallFixer( object->get_type() ); 447 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) { 448 forallFixer( pointer->get_base() ); 449 } 450 Parent::visit( object ); 451 object->fixUniqueId(); 452 } 453 454 void Pass3::visit( FunctionDecl *func ) { 455 forallFixer( func->get_type() ); 456 Parent::visit( func ); 457 func->fixUniqueId(); 458 } 459 460 static const std::list< std::string > noLabels; 461 462 void AddStructAssignment::addStructAssignment( std::list< Declaration * > &translationUnit ) { 463 AddStructAssignment visitor; 464 acceptAndAdd( translationUnit, visitor, false ); 465 } 466 467 template< typename OutputIterator > 468 void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) { 469 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member ); // PAB: unnamed bit fields are not copied 470 if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return; 471 472 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 473 474 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 475 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 476 477 // do something special for unnamed members 478 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) ); 479 assignExpr->get_args().push_back( dstselect ); 480 481 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 482 assignExpr->get_args().push_back( srcselect ); 483 484 *out++ = new ExprStmt( noLabels, assignExpr ); 485 } 486 487 template< typename OutputIterator > 488 void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) { 489 static UniqueName indexName( "_index" ); 490 491 // for a flexible array member nothing is done -- user must define own assignment 492 if ( ! array->get_dimension() ) return; 493 494 ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ); 495 *out++ = new DeclStmt( noLabels, index ); 496 497 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) ); 498 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 499 init->get_args().push_back( new NameExpr( "0" ) ); 500 Statement *initStmt = new ExprStmt( noLabels, init ); 501 502 UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) ); 503 cond->get_args().push_back( new VariableExpr( index ) ); 504 cond->get_args().push_back( array->get_dimension()->clone() ); 505 506 UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) ); 507 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 508 509 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 510 511 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 512 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 513 514 Expression *dstselect = new MemberExpr( member, derefExpr ); 515 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) ); 516 dstIndex->get_args().push_back( dstselect ); 517 dstIndex->get_args().push_back( new VariableExpr( index ) ); 518 assignExpr->get_args().push_back( dstIndex ); 519 520 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 521 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 522 srcIndex->get_args().push_back( srcselect ); 523 srcIndex->get_args().push_back( new VariableExpr( index ) ); 524 assignExpr->get_args().push_back( srcIndex ); 525 526 *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) ); 527 } 528 529 Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType ) { 530 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 531 532 ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 ); 533 assignType->get_returnVals().push_back( returnVal ); 534 535 ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 ); 536 assignType->get_parameters().push_back( dstParam ); 537 538 ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 ); 539 assignType->get_parameters().push_back( srcParam ); 540 541 FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true ); 542 assignDecl->fixUniqueId(); 543 544 for( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) { 545 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) { 546 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) { 547 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 548 } else { 549 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) ); 550 } 551 } 552 } 553 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 554 555 return assignDecl; 556 } 557 558 Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType ) { 559 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 560 561 ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 ); 562 assignType->get_returnVals().push_back( returnVal ); 563 564 ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 ); 565 assignType->get_parameters().push_back( dstParam ); 566 567 ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 ); 568 assignType->get_parameters().push_back( srcParam ); 569 570 FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true ); 571 assignDecl->fixUniqueId(); 572 573 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 574 copy->get_args().push_back( new VariableExpr( dstParam ) ); 575 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 576 copy->get_args().push_back( new SizeofExpr( refType->clone() ) ); 577 578 assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) ); 579 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 580 581 return assignDecl; 582 } 583 584 void AddStructAssignment::visit( StructDecl *structDecl ) { 585 if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) { 586 StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() ); 587 structInst->set_baseStruct( structDecl ); 588 declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) ); 589 structsDone.insert( structDecl->get_name() ); 590 } 591 } 592 593 void AddStructAssignment::visit( UnionDecl *unionDecl ) { 594 if ( ! unionDecl->get_members().empty() ) { 595 UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() ); 596 unionInst->set_baseUnion( unionDecl ); 597 declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) ); 598 } 599 } 600 601 void AddStructAssignment::visit( TypeDecl *typeDecl ) { 602 CompoundStmt *stmts = 0; 603 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false ); 604 typeInst->set_baseType( typeDecl ); 605 ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 ); 606 ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 ); 607 if ( typeDecl->get_base() ) { 608 stmts = new CompoundStmt( std::list< Label >() ); 609 UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) ); 610 assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) ); 611 assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) ); 612 stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) ); 613 } 614 FunctionType *type = new FunctionType( Type::Qualifiers(), false ); 615 type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) ); 616 type->get_parameters().push_back( dst ); 617 type->get_parameters().push_back( src ); 618 FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false ); 619 declsToAdd.push_back( func ); 620 } 621 622 void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) { 623 if ( ! declsToAdd.empty() ) { 624 for( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) { 625 statements.insert( i, new DeclStmt( noLabels, *decl ) ); 626 } 627 declsToAdd.clear(); 628 } 629 } 630 631 void AddStructAssignment::visit( FunctionType *) { 632 // ensure that we don't add assignment ops for types defined 633 // as part of the function 634 } 635 636 void AddStructAssignment::visit( PointerType *) { 637 // ensure that we don't add assignment ops for types defined 638 // as part of the pointer 639 } 640 641 void AddStructAssignment::visit( ContextDecl *) { 642 // ensure that we don't add assignment ops for types defined 643 // as part of the context 644 } 645 646 template< typename StmtClass > 647 inline void AddStructAssignment::visitStatement( StmtClass *stmt ) { 648 std::set< std::string > oldStructs = structsDone; 649 addVisit( stmt, *this ); 650 structsDone = oldStructs; 651 } 652 653 void AddStructAssignment::visit( CompoundStmt *compoundStmt ) { 654 visitStatement( compoundStmt ); 655 } 656 657 void AddStructAssignment::visit( IfStmt *ifStmt ) { 658 visitStatement( ifStmt ); 659 } 660 661 void AddStructAssignment::visit( WhileStmt *whileStmt ) { 662 visitStatement( whileStmt ); 663 } 664 665 void AddStructAssignment::visit( ForStmt *forStmt ) { 666 visitStatement( forStmt ); 667 } 668 669 void AddStructAssignment::visit( SwitchStmt *switchStmt ) { 670 visitStatement( switchStmt ); 671 } 672 673 void AddStructAssignment::visit( ChooseStmt *switchStmt ) { 674 visitStatement( switchStmt ); 675 } 676 677 void AddStructAssignment::visit( CaseStmt *caseStmt ) { 678 visitStatement( caseStmt ); 679 } 680 681 void AddStructAssignment::visit( CatchStmt *cathStmt ) { 682 visitStatement( cathStmt ); 683 } 684 685 bool isTypedef( Declaration *decl ) { 686 return dynamic_cast< TypedefDecl * >( decl ); 687 } 688 689 void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) { 690 EliminateTypedef eliminator; 691 mutateAll( translationUnit, eliminator ); 692 filter( translationUnit, isTypedef, true ); 693 } 694 695 Type *EliminateTypedef::mutate( TypeInstType *typeInst ) { 696 std::map< std::string, TypedefDecl * >::const_iterator def = typedefNames.find( typeInst->get_name() ); 697 if ( def != typedefNames.end() ) { 698 Type *ret = def->second->get_base()->clone(); 699 ret->get_qualifiers() += typeInst->get_qualifiers(); 700 delete typeInst; 701 return ret; 702 } 703 return typeInst; 704 } 705 706 Declaration *EliminateTypedef::mutate( TypedefDecl *tyDecl ) { 707 Declaration *ret = Mutator::mutate( tyDecl ); 708 typedefNames[ tyDecl->get_name() ] = tyDecl; 709 if ( AggregateDecl *aggDecl = dynamic_cast< AggregateDecl * >( tyDecl->get_base() ) ) { 710 tyDecl->set_base( 0 ); 711 delete tyDecl; 712 return aggDecl; 713 } else { 714 return ret; 715 } 716 } 717 718 TypeDecl *EliminateTypedef::mutate( TypeDecl *typeDecl ) { 719 std::map< std::string, TypedefDecl * >::iterator i = typedefNames.find( typeDecl->get_name() ); 720 if ( i != typedefNames.end() ) { 721 typedefNames.erase( i ) ; 722 } 723 return typeDecl; 724 } 725 726 DeclarationWithType *EliminateTypedef::mutate( FunctionDecl *funcDecl ) { 727 std::map< std::string, TypedefDecl * > oldNames = typedefNames; 728 DeclarationWithType *ret = Mutator::mutate( funcDecl ); 729 typedefNames = oldNames; 730 return ret; 731 } 732 733 ObjectDecl *EliminateTypedef::mutate( ObjectDecl *objDecl ) { 734 std::map< std::string, TypedefDecl * > oldNames = typedefNames; 735 ObjectDecl *ret = Mutator::mutate( objDecl ); 736 typedefNames = oldNames; 737 return ret; 738 } 739 740 Expression *EliminateTypedef::mutate( CastExpr *castExpr ) { 741 std::map< std::string, TypedefDecl * > oldNames = typedefNames; 742 Expression *ret = Mutator::mutate( castExpr ); 743 typedefNames = oldNames; 744 return ret; 745 } 746 747 CompoundStmt *EliminateTypedef::mutate( CompoundStmt *compoundStmt ) { 748 std::map< std::string, TypedefDecl * > oldNames = typedefNames; 749 CompoundStmt *ret = Mutator::mutate( compoundStmt ); 750 std::list< Statement * >::iterator i = compoundStmt->get_kids().begin(); 751 while ( i != compoundStmt->get_kids().end() ) { 752 std::list< Statement * >::iterator next = i; 753 ++next; 754 if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) { 755 if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) { 756 delete *i; 757 compoundStmt->get_kids().erase( i ); 758 } 759 } 760 i = next; 761 } 762 typedefNames = oldNames; 763 return ret; 764 } 910 765 } // namespace SymTab
Note:
See TracChangeset
for help on using the changeset viewer.