Changeset de91427b
- Timestamp:
- Dec 18, 2015, 3:40:22 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:
- 083cf31, 1cced28
- Parents:
- 8762501
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
r8762501 rde91427b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Validate.cc -- 7 // Validate.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:50:04 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Nov 20 16:33:52201513 // Update Count : 2 0112 // Last Modified On : Fri Dec 18 15:34:05 2015 13 // Update Count : 218 14 14 // 15 15 … … 63 63 /// Flattens nested struct types 64 64 static void hoistStruct( std::list< Declaration * > &translationUnit ); 65 65 66 66 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 67 67 68 68 virtual void visit( StructDecl *aggregateDecl ); 69 69 virtual void visit( UnionDecl *aggregateDecl ); … … 86 86 }; 87 87 88 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers 88 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 89 89 class Pass1 : public Visitor { 90 90 typedef Visitor Parent; … … 107 107 108 108 const Indexer *indexer; 109 109 110 110 typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType; 111 111 typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType; … … 132 132 133 133 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 134 134 135 135 virtual void visit( EnumDecl *enumDecl ); 136 136 virtual void visit( StructDecl *structDecl ); … … 142 142 virtual void visit( FunctionType *ftype ); 143 143 virtual void visit( PointerType *ftype ); 144 144 145 145 virtual void visit( CompoundStmt *compoundStmt ); 146 146 virtual void visit( IfStmt *ifStmt ); … … 155 155 private: 156 156 template< typename StmtClass > void visitStatement( StmtClass *stmt ); 157 157 158 158 std::list< Declaration * > declsToAdd; 159 159 std::set< std::string > structsDone; … … 161 161 }; 162 162 163 class ReturnChecker : public Visitor { 164 public: 165 /// Checks that return statements return nothing if their return type is void 166 /// and return something if the return type is non-void. 167 static void checkFunctionReturns( std::list< Declaration * > & translationUnit ); 168 169 private: 170 virtual void visit( FunctionDecl * functionDecl ); 171 172 virtual void visit( ReturnStmt * returnStmt ); 173 174 std::list< DeclarationWithType * > returnVals; 175 }; 176 163 177 class EliminateTypedef : public Mutator { 164 178 public: 165 166 179 EliminateTypedef() : scopeLevel( 0 ) {} 180 /// Replaces typedefs by forward declarations 167 181 static void eliminateTypedef( std::list< Declaration * > &translationUnit ); 168 182 private: … … 196 210 acceptAll( translationUnit, pass1 ); 197 211 acceptAll( translationUnit, pass2 ); 212 ReturnChecker::checkFunctionReturns( translationUnit ); 198 213 AutogenerateRoutines::autogenerateRoutines( translationUnit ); 199 214 acceptAll( translationUnit, pass3 ); 200 215 } 201 216 202 217 void validateType( Type *type, const Indexer *indexer ) { 203 218 Pass1 pass1; … … 307 322 void Pass1::visit( EnumDecl *enumDecl ) { 308 323 // Set the type of each member of the enumeration to be EnumConstant 309 324 310 325 for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) { 311 326 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i ); … … 331 346 ++i; 332 347 func->get_parameters().erase( j ); 333 if ( i != end ) { 348 if ( i != end ) { 334 349 throw SemanticError( "invalid type void in function type ", func ); 335 350 } // if … … 512 527 513 528 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 514 529 515 530 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 516 531 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 517 532 518 533 // do something special for unnamed members 519 534 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) ); 520 535 assignExpr->get_args().push_back( dstselect ); 521 536 522 537 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 523 538 assignExpr->get_args().push_back( srcselect ); 524 539 525 540 *out++ = new ExprStmt( noLabels, assignExpr ); 526 541 } … … 529 544 void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) { 530 545 static UniqueName indexName( "_index" ); 531 546 532 547 // for a flexible array member nothing is done -- user must define own assignment 533 548 if ( ! array->get_dimension() ) return; 534 549 535 550 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ); 536 551 *out++ = new DeclStmt( noLabels, index ); 537 552 538 553 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) ); 539 554 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); … … 542 557 std::list<Statement *> initList; 543 558 initList.push_back( initStmt ); 544 559 545 560 UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) ); 546 561 cond->get_args().push_back( new VariableExpr( index ) ); 547 562 cond->get_args().push_back( array->get_dimension()->clone() ); 548 563 549 564 UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) ); 550 565 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 551 566 552 567 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 553 568 554 569 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 555 570 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 556 571 557 572 Expression *dstselect = new MemberExpr( member, derefExpr ); 558 573 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) ); … … 560 575 dstIndex->get_args().push_back( new VariableExpr( index ) ); 561 576 assignExpr->get_args().push_back( dstIndex ); 562 577 563 578 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 564 579 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); … … 566 581 srcIndex->get_args().push_back( new VariableExpr( index ) ); 567 582 assignExpr->get_args().push_back( srcIndex ); 568 583 569 584 *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) ); 570 585 } 571 586 572 //E ?=?(E volatile*, int), 587 //E ?=?(E volatile*, int), 573 588 // ?=?(E _Atomic volatile*, int); 574 589 void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) { 575 590 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 576 591 577 592 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 ); 578 593 assignType->get_returnVals().push_back( returnVal ); … … 593 608 // E ?=?(E volatile *, int) 594 609 assignType2->get_parameters().push_back( dstParam->clone() ); 595 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt); 610 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt); 596 611 ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 ); 597 612 assignType2->get_parameters().push_back( srcParam2 ); … … 645 660 structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) ); 646 661 } 647 662 648 663 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 ); 649 664 assignType->get_returnVals().push_back( returnVal ); 650 665 651 666 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 ); 652 667 assignType->get_parameters().push_back( dstParam ); 653 668 654 669 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 ); 655 670 assignType->get_parameters().push_back( srcParam ); … … 659 674 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false ); 660 675 assignDecl->fixUniqueId(); 661 676 662 677 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) { 663 678 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) { 664 // query the type qualifiers of this field and skip assigning it if it is marked const. 679 // query the type qualifiers of this field and skip assigning it if it is marked const. 665 680 // If it is an array type, we need to strip off the array layers to find its qualifiers. 666 681 Type * type = dwt->get_type(); … … 682 697 } // for 683 698 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 684 699 685 700 return assignDecl; 686 701 } … … 697 712 unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) ); 698 713 } 699 714 700 715 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 ); 701 716 assignType->get_returnVals().push_back( returnVal ); 702 717 703 718 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 ); 704 719 assignType->get_parameters().push_back( dstParam ); 705 720 706 721 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 ); 707 722 assignType->get_parameters().push_back( srcParam ); 708 723 709 724 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 710 725 // because each unit generates copies of the default routines for each aggregate. 711 726 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false ); 712 727 assignDecl->fixUniqueId(); 713 728 714 729 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 715 730 copy->get_args().push_back( new VariableExpr( dstParam ) ); … … 719 734 assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) ); 720 735 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 721 736 722 737 return assignDecl; 723 738 } … … 727 742 EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() ); 728 743 // enumInst->set_baseEnum( enumDecl ); 729 // declsToAdd.push_back( 744 // declsToAdd.push_back( 730 745 makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd ); 731 746 } … … 836 851 } 837 852 853 void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) { 854 ReturnChecker checker; 855 acceptAll( translationUnit, checker ); 856 } 857 858 void ReturnChecker::visit( FunctionDecl * functionDecl ) { 859 std::list< DeclarationWithType * > oldReturnVals = returnVals; 860 returnVals = functionDecl->get_functionType()->get_returnVals(); 861 Visitor::visit( functionDecl ); 862 returnVals = oldReturnVals; 863 } 864 865 void ReturnChecker::visit( ReturnStmt * returnStmt ) { 866 if ( returnStmt->get_expr() == NULL && returnVals.size() != 0 ) { 867 throw SemanticError( "Non-void function returns no values: " , returnStmt ); 868 } else if ( returnStmt->get_expr() != NULL && returnVals.size() == 0 ) { 869 throw SemanticError( "void function returns values: " , returnStmt ); 870 } 871 } 872 873 838 874 bool isTypedef( Declaration *decl ) { 839 875 return dynamic_cast< TypedefDecl * >( decl ); … … 847 883 848 884 Type *EliminateTypedef::mutate( TypeInstType * typeInst ) { 849 // instances of typedef types will come here. If it is an instance 885 // instances of typedef types will come here. If it is an instance 850 886 // of a typdef type, link the instance to its actual type. 851 887 TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() ); … … 871 907 Declaration *ret = Mutator::mutate( tyDecl ); 872 908 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) { 873 // typedef to the same name from the same scope 909 // typedef to the same name from the same scope 874 910 // must be from the same type 875 911
Note: See TracChangeset
for help on using the changeset viewer.