Changes in src/SymTab/Validate.cc [a9a259c:98735ef]
- File:
-
- 1 edited
-
src/SymTab/Validate.cc (modified) (14 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Validate.cc
ra9a259c r98735ef 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:50:04 2015 11 // Last Modified By : Rob Schluntz12 // Last Modified On : Mon Feb 22 12:26:37201613 // Update Count : 2 9711 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jan 27 22:03:12 2016 13 // Update Count : 225 14 14 // 15 15 … … 202 202 }; 203 203 204 class VerifyCtorDtor : public Visitor {205 public:206 /// ensure that constructors and destructors have at least one207 /// parameter, the first of which must be a pointer, and no208 /// return values.209 static void verify( std::list< Declaration * > &translationUnit );210 211 // VerifyCtorDtor() {}212 213 virtual void visit( FunctionDecl *funcDecl );214 private:215 };216 217 204 void validate( std::list< Declaration * > &translationUnit, bool doDebug ) { 218 205 Pass1 pass1; … … 226 213 AutogenerateRoutines::autogenerateRoutines( translationUnit ); 227 214 acceptAll( translationUnit, pass3 ); 228 VerifyCtorDtor::verify( translationUnit );229 215 } 230 216 … … 535 521 536 522 template< typename OutputIterator > 537 void makeScalar Function( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, std::string fname, OutputIterator out ) {523 void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) { 538 524 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member ); 539 525 // unnamed bit fields are not copied as they cannot be accessed 540 526 if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return; 541 527 542 // want to be able to generate assignment, ctor, and dtor generically, 543 // so fname is either ?=?, ?{}, or ^?{} 544 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 528 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 545 529 546 530 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); … … 549 533 // do something special for unnamed members 550 534 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) ); 551 fExpr->get_args().push_back( dstselect );535 assignExpr->get_args().push_back( dstselect ); 552 536 553 537 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); 554 fExpr->get_args().push_back( srcselect );555 556 *out++ = new ExprStmt( noLabels, fExpr );538 assignExpr->get_args().push_back( srcselect ); 539 540 *out++ = new ExprStmt( noLabels, assignExpr ); 557 541 } 558 542 559 543 template< typename OutputIterator > 560 void makeArray Function( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, std::string fname, OutputIterator out ) {544 void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) { 561 545 static UniqueName indexName( "_index" ); 562 546 … … 581 565 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 582 566 583 // want to be able to generate assignment, ctor, and dtor generically, 584 // so fname is either ?=?, ?{}, or ^?{} 585 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 567 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) ); 586 568 587 569 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) ); … … 592 574 dstIndex->get_args().push_back( dstselect ); 593 575 dstIndex->get_args().push_back( new VariableExpr( index ) ); 594 fExpr->get_args().push_back( dstIndex );576 assignExpr->get_args().push_back( dstIndex ); 595 577 596 578 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) ); … … 598 580 srcIndex->get_args().push_back( srcselect ); 599 581 srcIndex->get_args().push_back( new VariableExpr( index ) ); 600 fExpr->get_args().push_back( srcIndex );601 602 *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, fExpr ) );582 assignExpr->get_args().push_back( srcIndex ); 583 584 *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) ); 603 585 } 604 586 … … 750 732 // assign to both destination and return value 751 733 if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) { 752 makeArray Function( srcParam, dstParam, fixedMember, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );753 makeArray Function( srcParam, returnVal, fixedMember, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );734 makeArrayAssignment( srcParam, dstParam, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 735 makeArrayAssignment( srcParam, returnVal, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 754 736 } else { 755 makeScalar Function( srcParam, dstParam, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );756 makeScalar Function( srcParam, returnVal, fixedMember, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );737 makeScalarAssignment( srcParam, dstParam, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) ); 738 makeScalarAssignment( srcParam, returnVal, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) ); 757 739 } // if 758 740 } else { 759 741 // assign to destination 760 742 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) { 761 makeArray Function( srcParam, dstParam, dwt, array, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );743 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) ); 762 744 } else { 763 makeScalar Function( srcParam, dstParam, dwt, "?=?", back_inserter( assignDecl->get_statements()->get_kids() ) );745 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) ); 764 746 } // if 765 747 } // if … … 771 753 } 772 754 773 void makeStructCtorDtor( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) { 774 FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false ); 775 776 // Make function polymorphic in same parameters as generic struct, if applicable 777 bool isGeneric = false; // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union) 778 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters(); 779 std::list< Expression* > structParams; // List of matching parameters to put on types 780 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) { 781 isGeneric = true; 782 TypeDecl *typeParam = (*param)->clone(); 783 ctorType->get_forall().push_back( typeParam ); 784 structParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) ); 785 } 786 787 ObjectDecl *thisParam = new ObjectDecl( "_this", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 ); 788 ctorType->get_parameters().push_back( thisParam ); 789 790 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 791 // because each unit generates copies of the default routines for each aggregate. 792 FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, 0, true, false ); 793 FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType->clone(), 0, true, false ); 794 FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType->clone(), 0, true, false ); 795 ctorDecl->fixUniqueId(); 796 copyCtorDecl->fixUniqueId(); 797 dtorDecl->fixUniqueId(); 798 799 // add definitions 800 // TODO: add in calls to default constructors and destructors for fields 801 ctorDecl->set_statements( new CompoundStmt( noLabels ) ); 802 copyCtorDecl->set_statements( new CompoundStmt( noLabels ) ); 803 dtorDecl->set_statements( new CompoundStmt( noLabels ) ); 804 declsToAdd.push_back( ctorDecl ); 805 declsToAdd.push_back( copyCtorDecl ); 806 declsToAdd.push_back( dtorDecl ); 807 808 ObjectDecl * srcParam = new ObjectDecl( "_other", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 ); 809 copyCtorDecl->get_functionType()->get_parameters().push_back( srcParam ); 810 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) { 811 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) { 812 // query the type qualifiers of this field and skip assigning it if it is marked const. 813 // If it is an array type, we need to strip off the array layers to find its qualifiers. 814 Type * type = dwt->get_type(); 815 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 816 type = at->get_base(); 817 } 818 819 if ( type->get_qualifiers().isConst ) { 820 // don't assign const members 821 continue; 822 } 823 824 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) { 825 makeArrayFunction( srcParam, thisParam, dwt, array, "?{}", back_inserter( copyCtorDecl->get_statements()->get_kids() ) ); 826 // if ( isGeneric ) makeArrayFunction( srcParam, returnVal, dwt, array, back_inserter( copyCtorDecl->get_statements()->get_kids() ) ); 827 } else { 828 makeScalarFunction( srcParam, thisParam, dwt, "?{}", back_inserter( copyCtorDecl->get_statements()->get_kids() ) ); 829 // if ( isGeneric ) makeScalarCtor( srcParam, returnVal, dwt, back_inserter( copyCtorDecl->get_statements()->get_kids() ) ); 830 } // if 831 } // if 832 } // for 833 // if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 834 } 835 836 void makeUnionFunctions( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd ) { 755 Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) { 837 756 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 838 757 … … 848 767 } 849 768 769 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 ); 770 assignType->get_returnVals().push_back( returnVal ); 771 850 772 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 ); 851 773 assignType->get_parameters().push_back( dstParam ); 852 774 853 // default ctor/dtor need only first parameter854 FunctionType * ctorType = assignType->clone();855 FunctionType * dtorType = assignType->clone();856 857 775 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 ); 858 776 assignType->get_parameters().push_back( srcParam ); 859 860 // copy ctor needs both parameters861 FunctionType * copyCtorType = assignType->clone();862 863 // assignment needs both and return value864 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );865 assignType->get_returnVals().push_back( returnVal );866 777 867 778 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 868 779 // because each unit generates copies of the default routines for each aggregate. 869 780 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false ); 870 FunctionDecl *ctorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, ctorType, new CompoundStmt( noLabels ), true, false );871 FunctionDecl *copyCtorDecl = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, copyCtorType, NULL, true, false );872 FunctionDecl *dtorDecl = new FunctionDecl( "^?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, dtorType, new CompoundStmt( noLabels ), true, false );873 874 781 assignDecl->fixUniqueId(); 875 ctorDecl->fixUniqueId();876 copyCtorDecl->fixUniqueId();877 dtorDecl->fixUniqueId();878 782 879 783 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 880 784 if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) ); 881 785 882 786 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 883 787 884 // body of assignment and copy ctor is the same 885 copyCtorDecl->set_statements( assignDecl->get_statements()->clone() ); 886 887 declsToAdd.push_back( assignDecl ); 888 declsToAdd.push_back( ctorDecl ); 889 declsToAdd.push_back( copyCtorDecl ); 890 declsToAdd.push_back( dtorDecl ); 788 return assignDecl; 891 789 } 892 790 … … 904 802 StructInstType structInst( Type::Qualifiers(), structDecl->get_name() ); 905 803 structInst.set_baseStruct( structDecl ); 906 907 804 declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) ); 908 makeStructCtorDtor( structDecl, &structInst, functionNesting, declsToAdd );909 805 structsDone.insert( structDecl->get_name() ); 910 806 } // if … … 915 811 UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() ); 916 812 unionInst.set_baseUnion( unionDecl ); 917 makeUnionFunctions( unionDecl, &unionInst, functionNesting, declsToAdd);813 declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) ); 918 814 } // if 919 815 } … … 1184 1080 } 1185 1081 1186 void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {1187 VerifyCtorDtor verifier;1188 acceptAll( translationUnit, verifier );1189 }1190 1191 void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {1192 FunctionType * funcType = funcDecl->get_functionType();1193 std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();1194 std::list< DeclarationWithType * > ¶ms = funcType->get_parameters();1195 1196 if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {1197 if ( params.size() == 0 ) {1198 throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );1199 }1200 if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {1201 throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );1202 }1203 if ( returnVals.size() != 0 ) {1204 throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );1205 }1206 }1207 1208 Visitor::visit( funcDecl );1209 // original idea: modify signature of ctor/dtors and insert appropriate return statements1210 // to cause desired behaviour1211 // new idea: add comma exprs to every ctor call to produce first parameter.1212 // this requires some memoization of the first parameter, because it can be a1213 // complicated expression with side effects (see: malloc). idea: add temporary variable1214 // that is assigned address of constructed object in ctor argument position and1215 // return the temporary. It should also be done after all implicit ctors are1216 // added, so not in this pass!1217 }1218 1082 } // namespace SymTab 1219 1083
Note:
See TracChangeset
for help on using the changeset viewer.