Changeset 9cb8e88d
- Timestamp:
- Dec 18, 2015, 2:36:53 PM (9 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 267cb3d
- Parents:
- 0ddb713
- Location:
- src
- Files:
-
- 2 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 -
src/initialization.txt
r0ddb713 r9cb8e88d 34 34 sure that resolved initializers for all declarations are being 35 35 generated. 36 37 38 ------ 39 40 More recent email: (I am quoted; Richard is the responder) 41 > As far as I'm aware, the only way that I could currently get the correct 42 > results from the unification engine is by feeding it an expression that 43 > looks like "?=?( ((struct Y)x.y).a, 10 )", then picking out the pieces that 44 > I need (namely the correct choice for a). Does this seem like a reasonable 45 > approach to solve this problem? 46 47 No, unfortunately. Initialization isn't being rewritten as assignment, 48 so you shouldn't allow the particular selection of assignment 49 operators that happen to be in scope (and which may include 50 user-defined operators) to guide the type resolution. 51 52 I don't think there is any way to rewrite an initializer as a single 53 expression and have the resolver just do the right thing. I see the 54 algorithm as: 55 56 For each alternative interpretation of the designator: 57 Construct an expression that casts the initializer to the type of 58 the designator 59 Construct an AlternativeFinder and use it to find the lowest cost 60 interpretation of the expression 61 Add this interpretation to a list of possibilities 62 Go through the list of possibilities and pick the lowest cost 63 64 As with many things in the resolver, it's conceptually simple but the 65 implementation may be a bit of a pain. It fits in with functions like 66 findSingleExpression, findIntegralExpression in Resolver.cc, although 67 it will be significantly more complicated than any of the existing 68 ones. 69 70 71
Note: See TracChangeset
for help on using the changeset viewer.