Changeset 60aaa51d for src/ResolvExpr
- Timestamp:
- Jun 7, 2019, 4:14:48 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 05d55ff
- Parents:
- 5684736
- git-author:
- Aaron Moss <a3moss@…> (06/07/19 16:14:40)
- git-committer:
- Aaron Moss <a3moss@…> (06/07/19 16:14:48)
- Location:
- src/ResolvExpr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/CurrentObject.cc
r5684736 r60aaa51d 16 16 #include <stddef.h> // for size_t 17 17 #include <cassert> // for assertf, assert, safe_dynamic_... 18 #include <deque> 18 19 #include <iostream> // for ostream, operator<<, basic_ost... 19 20 #include <stack> // for stack … … 21 22 22 23 #include "AST/Expr.hpp" // for InitAlternative 24 #include "AST/GenericSubstitution.hpp" // for genericSubstitution 23 25 #include "AST/Init.hpp" // for Designation 24 26 #include "AST/Node.hpp" // for readonly 27 #include "AST/Type.hpp" 25 28 #include "Common/Indenter.h" // for Indenter, operator<< 26 29 #include "Common/SemanticError.h" // for SemanticError … … 583 586 584 587 namespace ast { 585 586 /// Iterates members of a type by initializer 587 class MemberIterator { 588 public: 589 virtual ~MemberIterator() {} 590 591 /// retrieve the list of possible (Type,Designation) pairs for the current position in the 592 /// current object 593 virtual std::vector< InitAlternative > operator* () const = 0; 594 595 protected: 596 /// helper for operator*; aggregates must add designator to each init alternative, but 597 /// adding designators in operator* creates duplicates 598 virtual std::vector< InitAlternative > first() const = 0; 599 }; 588 /// create a new MemberIterator that traverses a type correctly 589 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ); 600 590 601 591 /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry … … 606 596 SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {} 607 597 608 std::vector< InitAlternative > operator* () const override { return first(); } 609 610 protected: 611 std::vector< InitAlternative > first() const override { 598 void setPosition( 599 std::deque< ptr< Expr > >::const_iterator begin, 600 std::deque< ptr< Expr > >::const_iterator end 601 ) override { 602 if ( begin != end ) { 603 SemanticError( location, "Un-designated initializer given non-empty designator" ); 604 } 605 } 606 607 std::deque< InitAlternative > operator* () const override { return first(); } 608 609 operator bool() const override { return type; } 610 611 SimpleIterator & bigStep() override { return smallStep(); } 612 SimpleIterator & smallStep() override { 613 type = nullptr; // empty on increment because no members 614 return *this; 615 } 616 617 const Type * getType() override { return type; } 618 619 const Type * getNext() override { return type; } 620 621 std::deque< InitAlternative > first() const override { 612 622 if ( type ) return { InitAlternative{ type, new Designation{ location } } }; 613 623 return {}; … … 615 625 }; 616 626 627 /// Iterates array types 628 class ArrayIterator final : public MemberIterator { 629 CodeLocation location; 630 readonly< ArrayType > array = nullptr; 631 readonly< Type > base = nullptr; 632 size_t index = 0; 633 size_t size = 0; 634 std::unique_ptr< MemberIterator > memberIter; 635 636 void setSize( const Expr * expr ) { 637 auto res = eval(expr); 638 if ( ! res.second ) { 639 SemanticError( location, 640 toString("Array designator must be a constant expression: ", expr ) ); 641 } 642 size = res.first; 643 } 644 645 public: 646 ArrayIterator( const CodeLocation & loc, const ArrayType * at ) 647 : location( loc ), array( at ), base( at->base ) { 648 PRINT( std::cerr << "Creating array iterator: " << at << std::endl; ) 649 memberIter.reset( createMemberIterator( loc, base ) ); 650 if ( at->isVarLen ) { 651 SemanticError( location, at, "VLA initialization does not support @=: " ); 652 } 653 setSize( at->dimension ); 654 } 655 656 void setPosition( const Expr * expr ) { 657 // need to permit integer-constant-expressions, including: integer constants, 658 // enumeration constants, character constants, sizeof expressions, alignof expressions, 659 // cast expressions 660 if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) { 661 try { 662 index = constExpr->intValue(); 663 } catch ( SemanticErrorException & ) { 664 SemanticError( expr, 665 "Constant expression of non-integral type in array designator: " ); 666 } 667 } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) { 668 setPosition( castExpr->arg ); 669 } else if ( 670 dynamic_cast< const SizeofExpr * >( expr ) 671 || dynamic_cast< const AlignofExpr * >( expr ) 672 ) { 673 index = 0; 674 } else { 675 assertf( false, 676 "bad designator given to ArrayIterator: %s", toString( expr ).c_str() ); 677 } 678 } 679 680 void setPosition( 681 std::deque< ptr< Expr > >::const_iterator begin, 682 std::deque< ptr< Expr > >::const_iterator end 683 ) override { 684 if ( begin == end ) return; 685 686 setPosition( *begin ); 687 memberIter->setPosition( ++begin, end ); 688 } 689 690 std::deque< InitAlternative > operator* () const override { return first(); } 691 692 operator bool() const override { return index < size; } 693 694 ArrayIterator & bigStep() override { 695 PRINT( std::cerr << "bigStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 696 ++index; 697 memberIter.reset( index < size ? createMemberIterator( location, base ) : nullptr ); 698 return *this; 699 } 700 701 ArrayIterator & smallStep() override { 702 PRINT( std::cerr << "smallStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 703 if ( memberIter ) { 704 PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; ) 705 memberIter->smallStep(); 706 if ( *memberIter ) { 707 PRINT( std::cerr << "has valid member iter" << std::endl; ) 708 return *this; 709 } 710 } 711 return bigStep(); 712 } 713 714 const Type * getType() override { return array; } 715 716 const Type * getNext() override { return base; } 717 718 std::deque< InitAlternative > first() const override { 719 PRINT( std::cerr << "first in ArrayIterator (" << index << "/" << size << ")" << std::endl; ) 720 if ( memberIter && *memberIter ) { 721 std::deque< InitAlternative > ret = memberIter->first(); 722 for ( InitAlternative & alt : ret ) { 723 alt.designation.get_and_mutate()->designators.emplace_front( 724 ConstantExpr::from_ulong( location, index ) ); 725 } 726 return ret; 727 } 728 return {}; 729 } 730 }; 731 732 class AggregateIterator : public MemberIterator { 733 protected: 734 using MemberList = std::vector< ptr< Decl > >; 735 736 CodeLocation location; 737 std::string kind; // for debug 738 std::string name; 739 const Type * inst; 740 const MemberList & members; 741 MemberList::const_iterator curMember; 742 bool atbegin = true; // false at first {small,big}Step 743 const Type * curType = nullptr; 744 std::unique_ptr< MemberIterator > memberIter = nullptr; 745 TypeSubstitution sub; 746 747 bool init() { 748 PRINT( std::cerr << "--init()--" << members.size() << std::endl; ) 749 if ( curMember != members.end() ) { 750 if ( auto field = curMember->as< ObjectDecl >() ) { 751 PRINT( std::cerr << "incremented to field: " << field << std::endl; ) 752 curType = field->get_type(); 753 memberIter.reset( createMemberIterator( location, curType ) ); 754 return true; 755 } 756 } 757 return false; 758 } 759 760 AggregateIterator( 761 const CodeLocation & loc, const std::string k, const std::string & n, const Type * i, 762 const MemberList & ms ) 763 : location( loc ), kind( k ), name( n ), inst( i ), members( ms ), curMember( ms.begin() ), 764 sub( genericSubstitution( i ) ) { 765 PRINT( std::cerr << "Creating " << kind << "(" << name << ")"; ) 766 init(); 767 } 768 769 public: 770 void setPosition( 771 std::deque< ptr< Expr > >::const_iterator begin, 772 std::deque< ptr< Expr > >::const_iterator end 773 ) final { 774 if ( begin == end ) return; 775 776 if ( auto varExpr = begin->as< VariableExpr >() ) { 777 for ( curMember = members.begin(); curMember != members.end(); ++curMember ) { 778 if ( *curMember != varExpr->var ) continue; 779 780 ++begin; 781 782 memberIter.reset( createMemberIterator( location, varExpr->result ) ); 783 curType = varExpr->result; 784 atbegin = curMember == members.begin() && begin == end; 785 memberIter->setPosition( begin, end ); 786 return; 787 } 788 assertf( false, 789 "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() ); 790 } else { 791 assertf( false, 792 "bad designator given to %s: %s", kind.c_str(), toString( *begin ).c_str() ); 793 } 794 } 795 796 std::deque< InitAlternative > operator* () const final { 797 if ( memberIter && *memberIter ) { 798 std::deque< InitAlternative > ret = memberIter->first(); 799 PRINT( std::cerr << "sub: " << sub << std::endl; ) 800 for ( InitAlternative & alt : ret ) { 801 PRINT( std::cerr << "iterating and adding designators" << std::endl; ) 802 alt.designation.get_and_mutate()->designators.emplace_front( 803 new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } ); 804 // need to substitute for generic types so that casts are to concrete types 805 PRINT( std::cerr << " type is: " << alt.type; ) 806 sub.apply( alt.type ); // also apply to designation?? 807 PRINT( std::cerr << " ==> " << alt.type << std::endl; ) 808 } 809 return ret; 810 } 811 return {}; 812 } 813 814 AggregateIterator & smallStep() final { 815 PRINT( std::cerr << "smallStep in " << kind << std::endl; ) 816 atbegin = false; 817 if ( memberIter ) { 818 PRINT( std::cerr << "has member iter, incrementing..." << std::endl; ) 819 memberIter->smallStep(); 820 if ( *memberIter ) { 821 PRINT( std::cerr << "success!" << std::endl; ) 822 return *this; 823 } 824 } 825 return bigStep(); 826 } 827 828 AggregateIterator & bigStep() override = 0; 829 830 const Type * getType() final { return inst; } 831 832 const Type * getNext() final { 833 return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr; 834 } 835 836 std::deque< InitAlternative > first() const final { 837 std::deque< InitAlternative > ret; 838 PRINT( std::cerr << "first " << kind << std::endl; ) 839 if ( memberIter && *memberIter ) { 840 PRINT( std::cerr << "adding children" << std::endl; ) 841 ret = memberIter->first(); 842 for ( InitAlternative & alt : ret ) { 843 PRINT( std::cerr << "iterating and adding designators" << std::endl; ) 844 alt.designation.get_and_mutate()->designators.emplace_front( 845 new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } ); 846 } 847 } 848 if ( atbegin ) { 849 // only add self if at the very beginning of the structure 850 PRINT( std::cerr << "adding self" << std::endl; ) 851 ret.emplace_front( inst, new Designation{ location } ); 852 } 853 return ret; 854 } 855 }; 856 857 class StructIterator final : public AggregateIterator { 858 public: 859 StructIterator( const CodeLocation & loc, const StructInstType * inst ) 860 : AggregateIterator( loc, "StructIterator", inst->name, inst, inst->base->members ) {} 861 862 operator bool() const override { 863 return curMember != members.end() || (memberIter && *memberIter); 864 } 865 866 StructIterator & bigStep() override { 867 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 868 atbegin = false; 869 memberIter = nullptr; 870 curType = nullptr; 871 while ( curMember != members.end() ) { 872 ++curMember; 873 if ( init() ) return *this; 874 } 875 return *this; 876 } 877 }; 878 879 class UnionIterator final : public AggregateIterator { 880 public: 881 UnionIterator( const CodeLocation & loc, const UnionInstType * inst ) 882 : AggregateIterator( loc, "UnionIterator", inst->name, inst, inst->base->members ) {} 883 884 operator bool() const override { return memberIter && *memberIter; } 885 886 UnionIterator & bigStep() override { 887 // unions only initialize one member 888 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 889 atbegin = false; 890 memberIter = nullptr; 891 curType = nullptr; 892 curMember = members.end(); 893 return *this; 894 } 895 }; 896 897 class TupleIterator final : public AggregateIterator { 898 public: 899 TupleIterator( const CodeLocation & loc, const TupleType * inst ) 900 : AggregateIterator( 901 loc, "TupleIterator", toString("Tuple", inst->size()), inst, inst->members 902 ) {} 903 904 operator bool() const override { 905 return curMember != members.end() || (memberIter && *memberIter); 906 } 907 908 TupleIterator & bigStep() override { 909 PRINT( std::cerr << "bigStep in " << kind << std::endl; ) 910 atbegin = false; 911 memberIter = nullptr; 912 curType = nullptr; 913 while ( curMember != members.end() ) { 914 ++curMember; 915 if ( init() ) return *this; 916 } 917 return *this; 918 } 919 }; 920 921 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ) { 922 if ( auto aggr = dynamic_cast< const ReferenceToType * >( type ) ) { 923 if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) { 924 return new StructIterator{ loc, sit }; 925 } else if ( auto uit = dynamic_cast< const UnionInstType * >( aggr ) ) { 926 return new UnionIterator{ loc, uit }; 927 } else { 928 assertf( 929 dynamic_cast< const EnumInstType * >( aggr ) 930 || dynamic_cast< const TypeInstType * >( aggr ), 931 "Encountered unhandled ReferenceToType in createMemberIterator: %s", 932 toString( type ).c_str() ); 933 return new SimpleIterator{ loc, type }; 934 } 935 } else if ( auto at = dynamic_cast< const ArrayType * >( type ) ) { 936 return new ArrayIterator{ loc, at }; 937 } else if ( auto tt = dynamic_cast< const TupleType * >( type ) ) { 938 return new TupleIterator{ loc, tt }; 939 } else { 940 return new SimpleIterator{ loc, type }; 941 } 942 } 943 617 944 CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() { 618 945 objStack.emplace_back( new SimpleIterator{ loc, type } ); 619 946 } 620 947 621 std::vector< InitAlternative > CurrentObject::getOptions() { 948 void CurrentObject::setNext( const ast::Designation * designation ) { 949 PRINT( std::cerr << "____setNext" << designation << std::endl; ) 950 assertf( ! objStack.empty(), "obj stack empty in setNext" ); 951 objStack.back()->setPosition( designation->designators ); 952 } 953 954 void CurrentObject::increment() { 955 PRINT( std::cerr << "____increment" << std::endl; ) 956 if ( objStack.empty() ) return; 957 PRINT( std::cerr << *objStack.back() << std::endl; ) 958 objStack.back()->smallStep(); 959 } 960 961 void CurrentObject::enterListInit( const CodeLocation & loc ) { 962 PRINT( std::cerr << "____entering list init" << std::endl; ) 963 assertf( ! objStack.empty(), "empty obj stack entering list init" ); 964 const ast::Type * type = objStack.back()->getNext(); 965 assert( type ); 966 objStack.emplace_back( createMemberIterator( loc, type ) ); 967 } 968 969 void CurrentObject::exitListInit() { 970 PRINT( std::cerr << "____exiting list init" << std::endl; ) 971 assertf( ! objStack.empty(), "objstack empty" ); 972 objStack.pop_back(); 973 if ( ! objStack.empty() ) { 974 PRINT( std::cerr << *objStack.back() << std::endl; ) 975 objStack.back()->bigStep(); 976 } 977 } 978 979 std::deque< InitAlternative > CurrentObject::getOptions() { 622 980 PRINT( std::cerr << "____getting current options" << std::endl; ) 623 981 assertf( ! objStack.empty(), "objstack empty in getOptions" ); 624 982 return **objStack.back(); 983 } 984 985 const Type * CurrentObject::getCurrentType() { 986 PRINT( std::cerr << "____getting current type" << std::endl; ) 987 assertf( ! objStack.empty(), "objstack empty in getCurrentType" ); 988 return objStack.back()->getNext(); 625 989 } 626 990 } -
src/ResolvExpr/CurrentObject.h
r5684736 r60aaa51d 16 16 #pragma once 17 17 18 #include <deque> 18 19 #include <list> // for list 19 20 #include <memory> // for unique_ptr … … 21 22 #include <vector> 22 23 24 #include "AST/Node.hpp" // for ptr 23 25 #include "Common/CodeLocation.h" 24 26 … … 59 61 // AST class types 60 62 class Designation; 61 classInitAlternative;63 struct InitAlternative; 62 64 class Type; 63 65 64 // forward declaration of internal detail 65 class MemberIterator; 66 /// Iterates members of a type by initializer 67 class MemberIterator { 68 public: 69 virtual ~MemberIterator() {} 70 71 /// Internal set position based on iterator ranges 72 virtual void setPosition( 73 std::deque< ptr< Expr > >::const_iterator it, 74 std::deque< ptr< Expr > >::const_iterator end ) = 0; 75 76 /// walks the current object using the given designators as a guide 77 void setPosition( const std::deque< ptr< Expr > > & designators ) { 78 setPosition( designators.begin(), designators.end() ); 79 } 80 81 /// retrieve the list of possible (Type,Designation) pairs for the current position in the 82 /// current object 83 virtual std::deque< InitAlternative > operator* () const = 0; 84 85 /// true if the iterator is not currently at the end 86 virtual operator bool() const = 0; 87 88 /// moves the iterator by one member in the current object 89 virtual MemberIterator & bigStep() = 0; 90 91 /// moves the iterator by one member in the current subobject 92 virtual MemberIterator & smallStep() = 0; 93 94 /// the type of the current object 95 virtual const Type * getType() = 0; 96 97 /// the type of the current subobject 98 virtual const Type * getNext() = 0; 99 100 /// helper for operator*; aggregates must add designator to each init alternative, but 101 /// adding designators in operator* creates duplicates 102 virtual std::deque< InitAlternative > first() const = 0; 103 }; 66 104 67 105 /// Builds initializer lists in resolution … … 73 111 CurrentObject( const CodeLocation & loc, const Type * type ); 74 112 113 /// sets current position using the resolved designation 114 void setNext( const ast::Designation * designation ); 115 /// steps to next sub-object of current object 116 void increment(); 117 /// sets new current object for the duration of this brace-enclosed intializer-list 118 void enterListInit( const CodeLocation & loc ); 119 /// restores previous current object 120 void exitListInit(); 75 121 /// produces a list of alternatives (Type *, Designation *) for the current sub-object's 76 122 /// initializer. 77 std::vector< InitAlternative > getOptions(); 123 std::deque< InitAlternative > getOptions(); 124 /// produces the type of the current object but no subobjects 125 const Type * getCurrentType(); 78 126 }; 79 127 } // namespace ast -
src/ResolvExpr/Resolver.cc
r5684736 r60aaa51d 781 781 } 782 782 783 template< typename T > 784 bool isCharType( T t ) { 783 bool isCharType( Type * t ) { 785 784 if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) { 786 785 return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || … … 1071 1070 }; 1072 1071 1072 /// Swaps argument into expression pointer, saving original environment 1073 void swap_and_save_env( ast::ptr< ast::Expr > & expr, const ast::Expr * newExpr ) { 1074 ast::ptr< ast::TypeSubstitution > env = expr->env; 1075 expr.set_and_mutate( newExpr )->env = env; 1076 } 1077 1073 1078 /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts) 1074 1079 void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) { … … 1076 1081 if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) { 1077 1082 // cast is to the same type as its argument, remove it 1078 ast::ptr< ast::TypeSubstitution > env = castExpr->env; 1079 expr.set_and_mutate( castExpr->arg )->env = env; 1083 swap_and_save_env( expr, castExpr->arg ); 1080 1084 } 1081 1085 } … … 1175 1179 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); 1176 1180 } 1181 1182 /// check if a type is a character type 1183 bool isCharType( const ast::Type * t ) { 1184 if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) { 1185 return bt->kind == ast::BasicType::Char 1186 || bt->kind == ast::BasicType::SignedChar 1187 || bt->kind == ast::BasicType::UnsignedChar; 1188 } 1189 return false; 1190 } 1177 1191 } 1178 1192 … … 1213 1227 void previsit( const ast::WaitForStmt * ); 1214 1228 1215 voidprevisit( const ast::SingleInit * );1216 voidprevisit( const ast::ListInit * );1229 const ast::SingleInit * previsit( const ast::SingleInit * ); 1230 const ast::ListInit * previsit( const ast::ListInit * ); 1217 1231 void previsit( const ast::ConstructorInit * ); 1218 1232 }; … … 1363 1377 const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) { 1364 1378 if ( caseStmt->cond ) { 1365 std:: vector< ast::InitAlternative > initAlts = currentObject.getOptions();1379 std::deque< ast::InitAlternative > initAlts = currentObject.getOptions(); 1366 1380 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral " 1367 1381 "expression." ); … … 1374 1388 // whether it would perform a conversion. 1375 1389 if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) { 1376 ast::ptr< ast::TypeSubstitution > env = castExpr->env; 1377 newExpr.set_and_mutate( castExpr->arg )->env = env; 1390 swap_and_save_env( newExpr, castExpr->arg ); 1378 1391 } 1379 1392 … … 1438 1451 } 1439 1452 1440 void Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1441 #warning unimplemented; Resolver port in progress 1442 (void)singleInit; 1443 assert(false); 1444 } 1445 1446 void Resolver_new::previsit( const ast::ListInit * listInit ) { 1447 #warning unimplemented; Resolver port in progress 1448 (void)listInit; 1449 assert(false); 1453 1454 1455 const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1456 visit_children = false; 1457 // resolve initialization using the possibilities as determined by the `currentObject` 1458 // cursor. 1459 ast::Expr * untyped = new ast::UntypedInitExpr{ 1460 singleInit->location, singleInit->value, currentObject.getOptions() }; 1461 ast::ptr<ast::Expr> newExpr = findKindExpression( untyped, symtab ); 1462 const ast::InitExpr * initExpr = newExpr.strict_as< ast::InitExpr >(); 1463 1464 // move cursor to the object that is actually initialized 1465 currentObject.setNext( initExpr->designation ); 1466 1467 // discard InitExpr wrapper and retain relevant pieces. 1468 // `initExpr` may have inferred params in the case where the expression specialized a 1469 // function pointer, and newExpr may already have inferParams of its own, so a simple 1470 // swap is not sufficient 1471 ast::Expr::InferUnion inferred = initExpr->inferred; 1472 swap_and_save_env( newExpr, initExpr->expr ); 1473 newExpr.get_and_mutate()->inferred.splice( std::move(inferred) ); 1474 1475 // get the actual object's type (may not exactly match what comes back from the resolver 1476 // due to conversions) 1477 const ast::Type * initContext = currentObject.getCurrentType(); 1478 1479 removeExtraneousCast( newExpr, symtab ); 1480 1481 // check if actual object's type is char[] 1482 if ( auto at = dynamic_cast< const ast::ArrayType * >( initContext ) ) { 1483 if ( isCharType( at->base ) ) { 1484 // check if the resolved type is char* 1485 if ( auto pt = newExpr->result.as< ast::PointerType >() ) { 1486 if ( isCharType( pt->base ) ) { 1487 // strip cast if we're initializing a char[] with a char* 1488 // e.g. char x[] = "hello" 1489 if ( auto ce = newExpr.as< ast::CastExpr >() ) { 1490 swap_and_save_env( newExpr, ce->arg ); 1491 } 1492 } 1493 } 1494 } 1495 } 1496 1497 // move cursor to next object in preparation for next initializer 1498 currentObject.increment(); 1499 1500 // set initializer expression to resolved expression 1501 return ast::mutate_field( singleInit, &ast::SingleInit::value, std::move(newExpr) ); 1502 } 1503 1504 const ast::ListInit * Resolver_new::previsit( const ast::ListInit * listInit ) { 1505 // move cursor into brace-enclosed initializer-list 1506 currentObject.enterListInit( listInit->location ); 1507 1508 assert( listInit->designations.size() == listInit->initializers.size() ); 1509 for ( unsigned i = 0; i < listInit->designations.size(); ++i ) { 1510 // iterate designations and initializers in pairs, moving the cursor to the current 1511 // designated object and resolving the initializer against that object 1512 #warning unimplemented; Resolver port in progress 1513 assert(false); 1514 } 1515 1516 visit_children = false; 1517 return listInit; 1450 1518 } 1451 1519
Note: See TracChangeset
for help on using the changeset viewer.