Changeset 9cb8e88d for src/SymTab/Validate.cc
- Timestamp:
- Dec 18, 2015, 2:36:53 PM (7 years ago)
- Branches:
- aaron-thesis, arm-eh, 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:
- 267cb3d
- Parents:
- 0ddb713
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
r0ddb713 r9cb8e88d 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 14:32:59 2015 13 // Update Count : 268 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 ); … … 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; … … 188 188 }; 189 189 190 class VerifyCtorDtor : public Visitor { 191 public: 192 /// ensure that constructors and destructors have at least one 193 /// parameter, the first of which must be a pointer, and no 194 /// return values. 195 static void verify( std::list< Declaration * > &translationUnit ); 196 197 // VerifyCtorDtor() {} 198 199 virtual void visit( FunctionDecl *funcDecl ); 200 private: 201 }; 202 190 203 void validate( std::list< Declaration * > &translationUnit, bool doDebug ) { 191 204 Pass1 pass1; … … 198 211 AutogenerateRoutines::autogenerateRoutines( translationUnit ); 199 212 acceptAll( translationUnit, pass3 ); 200 } 201 213 VerifyCtorDtor::verify( translationUnit ); 214 } 215 202 216 void validateType( Type *type, const Indexer *indexer ) { 203 217 Pass1 pass1; … … 307 321 void Pass1::visit( EnumDecl *enumDecl ) { 308 322 // Set the type of each member of the enumeration to be EnumConstant 309 323 310 324 for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) { 311 325 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i ); … … 331 345 ++i; 332 346 func->get_parameters().erase( j ); 333 if ( i != end ) { 347 if ( i != end ) { 334 348 throw SemanticError( "invalid type void in function type ", func ); 335 349 } // if … … 512 526 513 527 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 514 528 515 529 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 516 530 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 517 531 518 532 // do something special for unnamed members 519 533 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) ); 520 534 assignExpr->get_args().push_back( dstselect ); 521 535 522 536 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 523 537 assignExpr->get_args().push_back( srcselect ); 524 538 525 539 *out++ = new ExprStmt( noLabels, assignExpr ); 526 540 } … … 529 543 void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) { 530 544 static UniqueName indexName( "_index" ); 531 545 532 546 // for a flexible array member nothing is done -- user must define own assignment 533 547 if ( ! array->get_dimension() ) return; 534 548 535 549 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 ); 536 550 *out++ = new DeclStmt( noLabels, index ); 537 551 538 552 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) ); 539 553 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); … … 542 556 std::list<Statement *> initList; 543 557 initList.push_back( initStmt ); 544 558 545 559 UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) ); 546 560 cond->get_args().push_back( new VariableExpr( index ) ); 547 561 cond->get_args().push_back( array->get_dimension()->clone() ); 548 562 549 563 UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) ); 550 564 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 551 565 552 566 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 553 567 554 568 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); 555 569 derefExpr->get_args().push_back( new VariableExpr( dstParam ) ); 556 570 557 571 Expression *dstselect = new MemberExpr( member, derefExpr ); 558 572 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) ); … … 560 574 dstIndex->get_args().push_back( new VariableExpr( index ) ); 561 575 assignExpr->get_args().push_back( dstIndex ); 562 576 563 577 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 564 578 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); … … 566 580 srcIndex->get_args().push_back( new VariableExpr( index ) ); 567 581 assignExpr->get_args().push_back( srcIndex ); 568 582 569 583 *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) ); 570 584 } 571 585 572 //E ?=?(E volatile*, int), 586 //E ?=?(E volatile*, int), 573 587 // ?=?(E _Atomic volatile*, int); 574 588 void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) { 575 589 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 576 590 577 591 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 ); 578 592 assignType->get_returnVals().push_back( returnVal ); … … 593 607 // E ?=?(E volatile *, int) 594 608 assignType2->get_parameters().push_back( dstParam->clone() ); 595 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt); 609 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt); 596 610 ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 ); 597 611 assignType2->get_parameters().push_back( srcParam2 ); … … 645 659 structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) ); 646 660 } 647 661 648 662 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 ); 649 663 assignType->get_returnVals().push_back( returnVal ); 650 664 651 665 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 ); 652 666 assignType->get_parameters().push_back( dstParam ); 653 667 654 668 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 ); 655 669 assignType->get_parameters().push_back( srcParam ); … … 659 673 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false ); 660 674 assignDecl->fixUniqueId(); 661 675 662 676 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) { 663 677 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) { 664 // query the type qualifiers of this field and skip assigning it if it is marked const. 678 // query the type qualifiers of this field and skip assigning it if it is marked const. 665 679 // If it is an array type, we need to strip off the array layers to find its qualifiers. 666 680 Type * type = dwt->get_type(); … … 682 696 } // for 683 697 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 684 698 685 699 return assignDecl; 686 700 } … … 697 711 unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) ); 698 712 } 699 713 700 714 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 ); 701 715 assignType->get_returnVals().push_back( returnVal ); 702 716 703 717 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 ); 704 718 assignType->get_parameters().push_back( dstParam ); 705 719 706 720 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 ); 707 721 assignType->get_parameters().push_back( srcParam ); 708 722 709 723 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 710 724 // because each unit generates copies of the default routines for each aggregate. 711 725 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false ); 712 726 assignDecl->fixUniqueId(); 713 727 714 728 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 715 729 copy->get_args().push_back( new VariableExpr( dstParam ) ); … … 719 733 assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) ); 720 734 assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 721 735 722 736 return assignDecl; 723 737 } … … 727 741 EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() ); 728 742 // enumInst->set_baseEnum( enumDecl ); 729 // declsToAdd.push_back( 743 // declsToAdd.push_back( 730 744 makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd ); 731 745 } … … 847 861 848 862 Type *EliminateTypedef::mutate( TypeInstType * typeInst ) { 849 // instances of typedef types will come here. If it is an instance 863 // instances of typedef types will come here. If it is an instance 850 864 // of a typdef type, link the instance to its actual type. 851 865 TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() ); … … 871 885 Declaration *ret = Mutator::mutate( tyDecl ); 872 886 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) { 873 // typedef to the same name from the same scope 887 // typedef to the same name from the same scope 874 888 // must be from the same type 875 889 … … 993 1007 } 994 1008 1009 void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) { 1010 VerifyCtorDtor verifier; 1011 acceptAll( translationUnit, verifier ); 1012 } 1013 1014 void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) { 1015 FunctionType * funcType = funcDecl->get_functionType(); 1016 std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals(); 1017 std::list< DeclarationWithType * > ¶ms = funcType->get_parameters(); 1018 1019 if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) { 1020 if ( params.size() == 0 ) { 1021 throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl ); 1022 } 1023 if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) { 1024 throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl ); 1025 } 1026 if ( returnVals.size() != 0 ) { 1027 throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl ); 1028 } 1029 } 1030 1031 Visitor::visit( funcDecl ); 1032 // original idea: modify signature of ctor/dtors and insert appropriate return statements 1033 // to cause desired behaviour 1034 // new idea: add comma exprs to every ctor call to produce first parameter. 1035 // this requires some memoization of the first parameter, because it can be a 1036 // complicated expression with side effects (see: malloc). idea: add temporary variable 1037 // that is assigned address of constructed object in ctor argument position and 1038 // return the temporary. It should also be done after all implicit ctors are 1039 // added, so not in this pass! 1040 } 995 1041 } // namespace SymTab 996 1042
Note: See TracChangeset
for help on using the changeset viewer.