Changeset 60aaa51d


Ignore:
Timestamp:
Jun 7, 2019, 4:14:48 PM (3 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
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)
Message:

More resolver porting; mostly CurrentObject?

Location:
src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r5684736 r60aaa51d  
    1616#include "Convert.hpp"
    1717
     18#include <deque>
    1819#include <unordered_map>
    1920
     
    575576
    576577                if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
    577                         const ast::InferredParams &srcParams = srcInferred.inferParamsConst();
     578                        const ast::InferredParams &srcParams = srcInferred.inferParams();
    578579                        for (auto srcParam : srcParams) {
    579580                                tgtInferParams[srcParam.first] = ParamEntry(
     
    585586                        }
    586587                } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
    587                         const ast::ResnSlots &srcSlots = srcInferred.resnSlotsConst();
     588                        const ast::ResnSlots &srcSlots = srcInferred.resnSlots();
    588589                        for (auto srcSlot : srcSlots) {
    589590                                tgtResnSlots.push_back(srcSlot);
     
    14131414#       define GET_ACCEPT_V(child, type) \
    14141415                getAcceptV< ast::type, decltype( old->child ) >( old->child )
     1416       
     1417        template<typename NewT, typename OldC>
     1418        std::deque< ast::ptr<NewT> > getAcceptD( OldC& old ) {
     1419                std::deque< ast::ptr<NewT> > ret;
     1420                for ( auto a : old ) {
     1421                        a->accept( *this );
     1422                        ret.emplace_back( strict_dynamic_cast< NewT * >(node) );
     1423                        node = nullptr;
     1424                }
     1425                return ret;
     1426        }
     1427
     1428#       define GET_ACCEPT_D(child, type) \
     1429                getAcceptD< ast::type, decltype( old->child ) >( old->child )
    14151430
    14161431        ast::Label make_label(Label* old) {
     
    24492464
    24502465        virtual void visit( UntypedInitExpr * old ) override final {
    2451                 std::vector<ast::InitAlternative> initAlts;
     2466                std::deque<ast::InitAlternative> initAlts;
    24522467                for (auto ia : old->initAlts) {
    24532468                        initAlts.push_back(ast::InitAlternative(
     
    27142729                this->node = new ast::Designation(
    27152730                        old->location,
    2716                         GET_ACCEPT_V(designators, Expr)
     2731                        GET_ACCEPT_D(designators, Expr)
    27172732                );
    27182733        }
  • src/AST/Expr.cpp

    r5684736 r60aaa51d  
    163163        result = mem->get_type();
    164164        // substitute aggregate generic parameters into member type
    165         genericSubsitution( aggregate->result ).apply( result );
     165        genericSubstitution( aggregate->result ).apply( result );
    166166        // ensure lvalue and appropriate restrictions from aggregate type
    167167        add_qualifiers( result, aggregate->result->qualifiers | CV::Lvalue );
  • src/AST/Expr.hpp

    r5684736 r60aaa51d  
    1717
    1818#include <cassert>
     19#include <deque>
    1920#include <map>
    2021#include <string>
     
    111112                }
    112113
    113                 const ResnSlots& resnSlotsConst() const {
     114                const ResnSlots& resnSlots() const {
    114115                        if (mode == Slots) {
    115116                                return data.resnSlots;
     
    128129                }
    129130
    130                 const InferredParams& inferParamsConst() const {
     131                const InferredParams& inferParams() const {
    131132                        if (mode == Params) {
    132133                                return data.inferParams;
     
    134135                        assert(!"Mode was not already Params");
    135136                        return *((InferredParams*)nullptr);
     137                }
     138
     139                /// splices other InferUnion into this one. Will fail if one union is in `Slots` mode
     140                /// 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");
    136154                }
    137155        };
     
    695713public:
    696714        ptr<Expr> expr;
    697         std::vector<InitAlternative> initAlts;
    698 
    699         UntypedInitExpr( const CodeLocation & loc, const Expr * e, std::vector<InitAlternative> && as )
     715        std::deque<InitAlternative> initAlts;
     716
     717        UntypedInitExpr( const CodeLocation & loc, const Expr * e, std::deque<InitAlternative> && as )
    700718        : Expr( loc ), expr( e ), initAlts( std::move(as) ) {}
    701719
  • src/AST/GenericSubstitution.cpp

    r5684736 r60aaa51d  
    3131                TypeSubstitution sub;
    3232
    33                 void previsit( const Type * ty ) {
    34                         assertf( false, "Attempted generic substitution for non-aggregate type: %s",
    35                                 toString( ty ).c_str() );
     33                void previsit( const Type * ) {
     34                        // allow empty substitution for non-generic type
     35                        visit_children = false;
    3636                }
    3737
     
    4040                }
    4141
    42                 void previsit( const ReferenceToType * ty ) {
     42        private:
     43                // make substitution for generic type
     44                void makeSub( const ReferenceToType * ty ) {
    4345                        visit_children = false;
    44                         // build substitution from base parameters
    4546                        const AggregateDecl * aggr = ty->aggr();
    4647                        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 );
    4757                }
    4858        };
    4959}
    5060
    51 TypeSubstitution genericSubsitution( const Type * ty ) {
     61TypeSubstitution genericSubstitution( const Type * ty ) {
    5262        Pass<GenericSubstitutionBuilder> builder;
    5363        maybe_accept( ty, builder );
  • src/AST/GenericSubstitution.hpp

    r5684736 r60aaa51d  
    2222class Type;
    2323
    24 TypeSubstitution genericSubsitution( const Type * );
     24TypeSubstitution genericSubstitution( const Type * );
    2525
    2626}
  • src/AST/Init.hpp

    r5684736 r60aaa51d  
    1616#pragma once
    1717
     18#include <deque>
    1819#include <utility>        // for move
    1920#include <vector>
     
    3536class Designation final : public ParseNode {
    3637public:
    37         std::vector<ptr<Expr>> designators;
     38        std::deque<ptr<Expr>> designators;
    3839
    39         Designation( const CodeLocation& loc, std::vector<ptr<Expr>>&& ds = {} )
     40        Designation( const CodeLocation& loc, std::deque<ptr<Expr>>&& ds = {} )
    4041        : ParseNode( loc ), designators( std::move(ds) ) {}
    4142
  • src/AST/Node.hpp

    r5684736 r60aaa51d  
    154154
    155155        template< enum Node::ref_type o_ref_t >
    156         ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.node) {
     156        ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.get()) {
    157157                if( node ) _inc(node);
    158158        }
    159159
    160160        template< enum Node::ref_type o_ref_t >
    161         ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) {
     161        ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.get()) {
    162162                if( node ) _inc(node);
    163163        }
     
    184184        template< enum Node::ref_type o_ref_t >
    185185        ptr_base & operator=( const ptr_base<node_t, o_ref_t> & o ) {
    186                 assign(o.node);
     186                assign(o.get());
    187187                return *this;
    188188        }
     
    190190        template< enum Node::ref_type o_ref_t >
    191191        ptr_base & operator=( ptr_base<node_t, o_ref_t> && o ) {
    192                 assign(o.node);
     192                assign(o.get());
    193193                return *this;
    194194        }
     
    228228        void _check() const;
    229229
    230 protected:
    231230        const node_t * node;
    232231};
  • src/AST/porting.md

    r5684736 r60aaa51d  
    238238    * also now returns `const AggregateDecl *`
    239239* `genericSubstitution()` moved to own visitor in `AST/GenericSubstitution.hpp`
     240  * subsumes old `makeGenericSubstitution()`
    240241
    241242`BasicType`
  • src/ResolvExpr/CurrentObject.cc

    r5684736 r60aaa51d  
    1616#include <stddef.h>                    // for size_t
    1717#include <cassert>                     // for assertf, assert, safe_dynamic_...
     18#include <deque>
    1819#include <iostream>                    // for ostream, operator<<, basic_ost...
    1920#include <stack>                       // for stack
     
    2122
    2223#include "AST/Expr.hpp"                // for InitAlternative
     24#include "AST/GenericSubstitution.hpp" // for genericSubstitution
    2325#include "AST/Init.hpp"                // for Designation
    2426#include "AST/Node.hpp"                // for readonly
     27#include "AST/Type.hpp"
    2528#include "Common/Indenter.h"           // for Indenter, operator<<
    2629#include "Common/SemanticError.h"      // for SemanticError
     
    583586
    584587namespace 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 );
    600590
    601591        /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry
     
    606596                SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
    607597
    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 {
    612622                        if ( type ) return { InitAlternative{ type, new Designation{ location } } };
    613623                        return {};
     
    615625        };
    616626
     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
    617944        CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() {
    618945                objStack.emplace_back( new SimpleIterator{ loc, type } );
    619946        }
    620947
    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() {
    622980                PRINT( std::cerr << "____getting current options" << std::endl; )
    623981                assertf( ! objStack.empty(), "objstack empty in getOptions" );
    624982                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();
    625989        }
    626990}
  • src/ResolvExpr/CurrentObject.h

    r5684736 r60aaa51d  
    1616#pragma once
    1717
     18#include <deque>
    1819#include <list>   // for list
    1920#include <memory> // for unique_ptr
     
    2122#include <vector>
    2223
     24#include "AST/Node.hpp"  // for ptr
    2325#include "Common/CodeLocation.h"
    2426
     
    5961        // AST class types
    6062        class Designation;
    61         class InitAlternative;
     63        struct InitAlternative;
    6264        class Type;
    6365
    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        };
    66104
    67105        /// Builds initializer lists in resolution
     
    73111                CurrentObject( const CodeLocation & loc, const Type * type );
    74112
     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();
    75121                /// produces a list of alternatives (Type *, Designation *) for the current sub-object's
    76122                /// 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();
    78126        };
    79127} // namespace ast
  • src/ResolvExpr/Resolver.cc

    r5684736 r60aaa51d  
    781781        }
    782782
    783         template< typename T >
    784         bool isCharType( T t ) {
     783        bool isCharType( Type * t ) {
    785784                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    786785                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
     
    10711070                };
    10721071
     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
    10731078                /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts)
    10741079                void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) {
     
    10761081                                if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) {
    10771082                                        // 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 );
    10801084                                }
    10811085                        }
     
    11751179                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
    11761180                }
     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                }
    11771191        }
    11781192
     
    12131227                void previsit( const ast::WaitForStmt * );
    12141228
    1215                 void previsit( const ast::SingleInit * );
    1216                 void previsit( const ast::ListInit * );
     1229                const ast::SingleInit * previsit( const ast::SingleInit * );
     1230                const ast::ListInit * previsit( const ast::ListInit * );
    12171231                void previsit( const ast::ConstructorInit * );
    12181232        };
     
    13631377        const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    13641378                if ( caseStmt->cond ) {
    1365                         std::vector< ast::InitAlternative > initAlts = currentObject.getOptions();
     1379                        std::deque< ast::InitAlternative > initAlts = currentObject.getOptions();
    13661380                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
    13671381                                "expression." );
     
    13741388                        // whether it would perform a conversion.
    13751389                        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 );
    13781391                        }
    13791392                       
     
    14381451        }
    14391452
    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;
    14501518        }
    14511519
Note: See TracChangeset for help on using the changeset viewer.