Changes in / [05d55ff:be8518f]
- Location:
- src
- Files:
-
- 11 edited
-
AST/Convert.cpp (modified) (6 diffs)
-
AST/Expr.cpp (modified) (1 diff)
-
AST/Expr.hpp (modified) (5 diffs)
-
AST/GenericSubstitution.cpp (modified) (2 diffs)
-
AST/GenericSubstitution.hpp (modified) (1 diff)
-
AST/Init.hpp (modified) (2 diffs)
-
AST/Node.hpp (modified) (4 diffs)
-
AST/porting.md (modified) (1 diff)
-
ResolvExpr/CurrentObject.cc (modified) (5 diffs)
-
ResolvExpr/CurrentObject.h (modified) (4 diffs)
-
ResolvExpr/Resolver.cc (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r05d55ff rbe8518f 16 16 #include "Convert.hpp" 17 17 18 #include <deque>19 18 #include <unordered_map> 20 19 … … 576 575 577 576 if ( srcInferred.mode == ast::Expr::InferUnion::Params ) { 578 const ast::InferredParams &srcParams = srcInferred.inferParams ();577 const ast::InferredParams &srcParams = srcInferred.inferParamsConst(); 579 578 for (auto srcParam : srcParams) { 580 579 tgtInferParams[srcParam.first] = ParamEntry( … … 586 585 } 587 586 } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots ) { 588 const ast::ResnSlots &srcSlots = srcInferred.resnSlots ();587 const ast::ResnSlots &srcSlots = srcInferred.resnSlotsConst(); 589 588 for (auto srcSlot : srcSlots) { 590 589 tgtResnSlots.push_back(srcSlot); … … 1422 1421 # define GET_ACCEPT_V(child, type) \ 1423 1422 getAcceptV< ast::type, decltype( old->child ) >( old->child ) 1424 1425 template<typename NewT, typename OldC>1426 std::deque< ast::ptr<NewT> > getAcceptD( OldC& old ) {1427 std::deque< ast::ptr<NewT> > ret;1428 for ( auto a : old ) {1429 a->accept( *this );1430 ret.emplace_back( strict_dynamic_cast< NewT * >(node) );1431 node = nullptr;1432 }1433 return ret;1434 }1435 1436 # define GET_ACCEPT_D(child, type) \1437 getAcceptD< ast::type, decltype( old->child ) >( old->child )1438 1423 1439 1424 ast::Label make_label(Label* old) { … … 2477 2462 2478 2463 virtual void visit( UntypedInitExpr * old ) override final { 2479 std:: deque<ast::InitAlternative> initAlts;2464 std::vector<ast::InitAlternative> initAlts; 2480 2465 for (auto ia : old->initAlts) { 2481 2466 initAlts.push_back(ast::InitAlternative( … … 2742 2727 this->node = new ast::Designation( 2743 2728 old->location, 2744 GET_ACCEPT_ D(designators, Expr)2729 GET_ACCEPT_V(designators, Expr) 2745 2730 ); 2746 2731 } -
src/AST/Expr.cpp
r05d55ff rbe8518f 163 163 result = mem->get_type(); 164 164 // substitute aggregate generic parameters into member type 165 genericSubs titution( aggregate->result ).apply( result );165 genericSubsitution( aggregate->result ).apply( result ); 166 166 // ensure lvalue and appropriate restrictions from aggregate type 167 167 add_qualifiers( result, aggregate->result->qualifiers | CV::Lvalue ); -
src/AST/Expr.hpp
r05d55ff rbe8518f 17 17 18 18 #include <cassert> 19 #include <deque>20 19 #include <map> 21 20 #include <string> … … 112 111 } 113 112 114 const ResnSlots& resnSlots () const {113 const ResnSlots& resnSlotsConst() const { 115 114 if (mode == Slots) { 116 115 return data.resnSlots; … … 129 128 } 130 129 131 const InferredParams& inferParams () const {130 const InferredParams& inferParamsConst() const { 132 131 if (mode == Params) { 133 132 return data.inferParams; … … 135 134 assert(!"Mode was not already Params"); 136 135 return *((InferredParams*)nullptr); 137 }138 139 /// splices other InferUnion into this one. Will fail if one union is in `Slots` mode140 /// and the other is in `Params`.141 void splice( InferUnion && o ) {142 if ( o.mode == Empty ) return;143 if ( mode == Empty ) { init_from( o ); return; }144 assert( mode == o.mode && "attempt to splice incompatible InferUnion" );145 146 if ( mode == Slots ){147 data.resnSlots.insert(148 data.resnSlots.end(), o.data.resnSlots.begin(), o.data.resnSlots.end() );149 } else if ( mode == Params ) {150 for ( const auto & p : o.data.inferParams ) {151 data.inferParams[p.first] = std::move(p.second);152 }153 } else assert(!"invalid mode");154 136 } 155 137 }; … … 713 695 public: 714 696 ptr<Expr> expr; 715 std:: deque<InitAlternative> initAlts;716 717 UntypedInitExpr( const CodeLocation & loc, const Expr * e, std:: deque<InitAlternative> && as )697 std::vector<InitAlternative> initAlts; 698 699 UntypedInitExpr( const CodeLocation & loc, const Expr * e, std::vector<InitAlternative> && as ) 718 700 : Expr( loc ), expr( e ), initAlts( std::move(as) ) {} 719 701 -
src/AST/GenericSubstitution.cpp
r05d55ff rbe8518f 31 31 TypeSubstitution sub; 32 32 33 void previsit( const Type * ) {34 // allow empty substitution for non-generic type35 visit_children = false;33 void previsit( const Type * ty ) { 34 assertf( false, "Attempted generic substitution for non-aggregate type: %s", 35 toString( ty ).c_str() ); 36 36 } 37 37 … … 40 40 } 41 41 42 private: 43 // make substitution for generic type 44 void makeSub( const ReferenceToType * ty ) { 42 void previsit( const ReferenceToType * ty ) { 45 43 visit_children = false; 44 // build substitution from base parameters 46 45 const AggregateDecl * aggr = ty->aggr(); 47 46 sub = TypeSubstitution{ aggr->params.begin(), aggr->params.end(), ty->params.begin() }; 48 }49 50 public:51 void previsit( const StructInstType * ty ) {52 makeSub( ty );53 }54 55 void previsit( const UnionInstType * ty ) {56 makeSub( ty );57 47 } 58 48 }; 59 49 } 60 50 61 TypeSubstitution genericSubs titution( const Type * ty ) {51 TypeSubstitution genericSubsitution( const Type * ty ) { 62 52 Pass<GenericSubstitutionBuilder> builder; 63 53 maybe_accept( ty, builder ); -
src/AST/GenericSubstitution.hpp
r05d55ff rbe8518f 22 22 class Type; 23 23 24 TypeSubstitution genericSubs titution( const Type * );24 TypeSubstitution genericSubsitution( const Type * ); 25 25 26 26 } -
src/AST/Init.hpp
r05d55ff rbe8518f 16 16 #pragma once 17 17 18 #include <deque>19 18 #include <utility> // for move 20 19 #include <vector> … … 36 35 class Designation final : public ParseNode { 37 36 public: 38 std:: deque<ptr<Expr>> designators;37 std::vector<ptr<Expr>> designators; 39 38 40 Designation( const CodeLocation& loc, std:: deque<ptr<Expr>>&& ds = {} )39 Designation( const CodeLocation& loc, std::vector<ptr<Expr>>&& ds = {} ) 41 40 : ParseNode( loc ), designators( std::move(ds) ) {} 42 41 -
src/AST/Node.hpp
r05d55ff rbe8518f 154 154 155 155 template< enum Node::ref_type o_ref_t > 156 ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o. get()) {156 ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.node) { 157 157 if( node ) _inc(node); 158 158 } 159 159 160 160 template< enum Node::ref_type o_ref_t > 161 ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o. get()) {161 ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) { 162 162 if( node ) _inc(node); 163 163 } … … 184 184 template< enum Node::ref_type o_ref_t > 185 185 ptr_base & operator=( const ptr_base<node_t, o_ref_t> & o ) { 186 assign(o. get());186 assign(o.node); 187 187 return *this; 188 188 } … … 190 190 template< enum Node::ref_type o_ref_t > 191 191 ptr_base & operator=( ptr_base<node_t, o_ref_t> && o ) { 192 assign(o. get());192 assign(o.node); 193 193 return *this; 194 194 } … … 228 228 void _check() const; 229 229 230 protected: 230 231 const node_t * node; 231 232 }; -
src/AST/porting.md
r05d55ff rbe8518f 238 238 * also now returns `const AggregateDecl *` 239 239 * `genericSubstitution()` moved to own visitor in `AST/GenericSubstitution.hpp` 240 * subsumes old `makeGenericSubstitution()`241 240 242 241 `BasicType` -
src/ResolvExpr/CurrentObject.cc
r05d55ff rbe8518f 16 16 #include <stddef.h> // for size_t 17 17 #include <cassert> // for assertf, assert, safe_dynamic_... 18 #include <deque>19 18 #include <iostream> // for ostream, operator<<, basic_ost... 20 19 #include <stack> // for stack … … 22 21 23 22 #include "AST/Expr.hpp" // for InitAlternative 24 #include "AST/GenericSubstitution.hpp" // for genericSubstitution25 23 #include "AST/Init.hpp" // for Designation 26 24 #include "AST/Node.hpp" // for readonly 27 #include "AST/Type.hpp"28 25 #include "Common/Indenter.h" // for Indenter, operator<< 29 26 #include "Common/SemanticError.h" // for SemanticError … … 586 583 587 584 namespace ast { 588 /// create a new MemberIterator that traverses a type correctly 589 MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ); 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 }; 590 600 591 601 /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry … … 596 606 SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {} 597 607 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 { 608 std::vector< InitAlternative > operator* () const override { return first(); } 609 610 protected: 611 std::vector< InitAlternative > first() const override { 622 612 if ( type ) return { InitAlternative{ type, new Designation{ location } } }; 623 613 return {}; … … 625 615 }; 626 616 627 /// Iterates array types628 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 expressions660 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 end683 ) 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 debug738 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}Step743 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 end773 ) 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 types805 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 structure850 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 member888 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->members902 ) {}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 944 617 CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() { 945 618 objStack.emplace_back( new SimpleIterator{ loc, type } ); 946 619 } 947 620 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() { 621 std::vector< InitAlternative > CurrentObject::getOptions() { 980 622 PRINT( std::cerr << "____getting current options" << std::endl; ) 981 623 assertf( ! objStack.empty(), "objstack empty in getOptions" ); 982 624 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();989 625 } 990 626 } -
src/ResolvExpr/CurrentObject.h
r05d55ff rbe8518f 16 16 #pragma once 17 17 18 #include <deque>19 18 #include <list> // for list 20 19 #include <memory> // for unique_ptr … … 22 21 #include <vector> 23 22 24 #include "AST/Node.hpp" // for ptr25 23 #include "Common/CodeLocation.h" 26 24 … … 61 59 // AST class types 62 60 class Designation; 63 structInitAlternative;61 class InitAlternative; 64 62 class Type; 65 63 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 }; 64 // forward declaration of internal detail 65 class MemberIterator; 104 66 105 67 /// Builds initializer lists in resolution … … 111 73 CurrentObject( const CodeLocation & loc, const Type * type ); 112 74 113 /// sets current position using the resolved designation114 void setNext( const ast::Designation * designation );115 /// steps to next sub-object of current object116 void increment();117 /// sets new current object for the duration of this brace-enclosed intializer-list118 void enterListInit( const CodeLocation & loc );119 /// restores previous current object120 void exitListInit();121 75 /// produces a list of alternatives (Type *, Designation *) for the current sub-object's 122 76 /// initializer. 123 std::deque< InitAlternative > getOptions(); 124 /// produces the type of the current object but no subobjects 125 const Type * getCurrentType(); 77 std::vector< InitAlternative > getOptions(); 126 78 }; 127 79 } // namespace ast -
src/ResolvExpr/Resolver.cc
r05d55ff rbe8518f 781 781 } 782 782 783 bool isCharType( Type * t ) { 783 template< typename T > 784 bool isCharType( T t ) { 784 785 if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) { 785 786 return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || … … 1070 1071 }; 1071 1072 1072 /// Swaps argument into expression pointer, saving original environment1073 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 1078 1073 /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts) 1079 1074 void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) { … … 1081 1076 if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) { 1082 1077 // cast is to the same type as its argument, remove it 1083 swap_and_save_env( expr, castExpr->arg ); 1078 ast::ptr< ast::TypeSubstitution > env = castExpr->env; 1079 expr.set_and_mutate( castExpr->arg )->env = env; 1084 1080 } 1085 1081 } … … 1179 1175 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); 1180 1176 } 1181 1182 /// check if a type is a character type1183 bool isCharType( const ast::Type * t ) {1184 if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) {1185 return bt->kind == ast::BasicType::Char1186 || bt->kind == ast::BasicType::SignedChar1187 || bt->kind == ast::BasicType::UnsignedChar;1188 }1189 return false;1190 }1191 1177 } 1192 1178 … … 1227 1213 void previsit( const ast::WaitForStmt * ); 1228 1214 1229 const ast::SingleInit *previsit( const ast::SingleInit * );1230 const ast::ListInit *previsit( const ast::ListInit * );1215 void previsit( const ast::SingleInit * ); 1216 void previsit( const ast::ListInit * ); 1231 1217 void previsit( const ast::ConstructorInit * ); 1232 1218 }; … … 1377 1363 const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) { 1378 1364 if ( caseStmt->cond ) { 1379 std:: deque< ast::InitAlternative > initAlts = currentObject.getOptions();1365 std::vector< ast::InitAlternative > initAlts = currentObject.getOptions(); 1380 1366 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral " 1381 1367 "expression." ); … … 1388 1374 // whether it would perform a conversion. 1389 1375 if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) { 1390 swap_and_save_env( newExpr, castExpr->arg ); 1376 ast::ptr< ast::TypeSubstitution > env = castExpr->env; 1377 newExpr.set_and_mutate( castExpr->arg )->env = env; 1391 1378 } 1392 1379 … … 1451 1438 } 1452 1439 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; 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); 1518 1450 } 1519 1451
Note:
See TracChangeset
for help on using the changeset viewer.