Changes in / [05d55ff:be8518f]


Ignore:
Location:
src
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r05d55ff rbe8518f  
    1616#include "Convert.hpp"
    1717
    18 #include <deque>
    1918#include <unordered_map>
    2019
     
    576575
    577576                if ( srcInferred.mode == ast::Expr::InferUnion::Params ) {
    578                         const ast::InferredParams &srcParams = srcInferred.inferParams();
     577                        const ast::InferredParams &srcParams = srcInferred.inferParamsConst();
    579578                        for (auto srcParam : srcParams) {
    580579                                tgtInferParams[srcParam.first] = ParamEntry(
     
    586585                        }
    587586                } else if ( srcInferred.mode == ast::Expr::InferUnion::Slots  ) {
    588                         const ast::ResnSlots &srcSlots = srcInferred.resnSlots();
     587                        const ast::ResnSlots &srcSlots = srcInferred.resnSlotsConst();
    589588                        for (auto srcSlot : srcSlots) {
    590589                                tgtResnSlots.push_back(srcSlot);
     
    14221421#       define GET_ACCEPT_V(child, type) \
    14231422                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 )
    14381423
    14391424        ast::Label make_label(Label* old) {
     
    24772462
    24782463        virtual void visit( UntypedInitExpr * old ) override final {
    2479                 std::deque<ast::InitAlternative> initAlts;
     2464                std::vector<ast::InitAlternative> initAlts;
    24802465                for (auto ia : old->initAlts) {
    24812466                        initAlts.push_back(ast::InitAlternative(
     
    27422727                this->node = new ast::Designation(
    27432728                        old->location,
    2744                         GET_ACCEPT_D(designators, Expr)
     2729                        GET_ACCEPT_V(designators, Expr)
    27452730                );
    27462731        }
  • src/AST/Expr.cpp

    r05d55ff rbe8518f  
    163163        result = mem->get_type();
    164164        // substitute aggregate generic parameters into member type
    165         genericSubstitution( aggregate->result ).apply( result );
     165        genericSubsitution( 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

    r05d55ff rbe8518f  
    1717
    1818#include <cassert>
    19 #include <deque>
    2019#include <map>
    2120#include <string>
     
    112111                }
    113112
    114                 const ResnSlots& resnSlots() const {
     113                const ResnSlots& resnSlotsConst() const {
    115114                        if (mode == Slots) {
    116115                                return data.resnSlots;
     
    129128                }
    130129
    131                 const InferredParams& inferParams() const {
     130                const InferredParams& inferParamsConst() const {
    132131                        if (mode == Params) {
    133132                                return data.inferParams;
     
    135134                        assert(!"Mode was not already Params");
    136135                        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");
    154136                }
    155137        };
     
    713695public:
    714696        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 )
    718700        : Expr( loc ), expr( e ), initAlts( std::move(as) ) {}
    719701
  • src/AST/GenericSubstitution.cpp

    r05d55ff rbe8518f  
    3131                TypeSubstitution sub;
    3232
    33                 void previsit( const Type * ) {
    34                         // allow empty substitution for non-generic type
    35                         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() );
    3636                }
    3737
     
    4040                }
    4141
    42         private:
    43                 // make substitution for generic type
    44                 void makeSub( const ReferenceToType * ty ) {
     42                void previsit( const ReferenceToType * ty ) {
    4543                        visit_children = false;
     44                        // build substitution from base parameters
    4645                        const AggregateDecl * aggr = ty->aggr();
    4746                        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 );
    5747                }
    5848        };
    5949}
    6050
    61 TypeSubstitution genericSubstitution( const Type * ty ) {
     51TypeSubstitution genericSubsitution( const Type * ty ) {
    6252        Pass<GenericSubstitutionBuilder> builder;
    6353        maybe_accept( ty, builder );
  • src/AST/GenericSubstitution.hpp

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

    r05d55ff rbe8518f  
    1616#pragma once
    1717
    18 #include <deque>
    1918#include <utility>        // for move
    2019#include <vector>
     
    3635class Designation final : public ParseNode {
    3736public:
    38         std::deque<ptr<Expr>> designators;
     37        std::vector<ptr<Expr>> designators;
    3938
    40         Designation( const CodeLocation& loc, std::deque<ptr<Expr>>&& ds = {} )
     39        Designation( const CodeLocation& loc, std::vector<ptr<Expr>>&& ds = {} )
    4140        : ParseNode( loc ), designators( std::move(ds) ) {}
    4241
  • src/AST/Node.hpp

    r05d55ff rbe8518f  
    154154
    155155        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) {
    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.get()) {
     161        ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) {
    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.get());
     186                assign(o.node);
    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.get());
     192                assign(o.node);
    193193                return *this;
    194194        }
     
    228228        void _check() const;
    229229
     230protected:
    230231        const node_t * node;
    231232};
  • src/AST/porting.md

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

    r05d55ff rbe8518f  
    1616#include <stddef.h>                    // for size_t
    1717#include <cassert>                     // for assertf, assert, safe_dynamic_...
    18 #include <deque>
    1918#include <iostream>                    // for ostream, operator<<, basic_ost...
    2019#include <stack>                       // for stack
     
    2221
    2322#include "AST/Expr.hpp"                // for InitAlternative
    24 #include "AST/GenericSubstitution.hpp" // for genericSubstitution
    2523#include "AST/Init.hpp"                // for Designation
    2624#include "AST/Node.hpp"                // for readonly
    27 #include "AST/Type.hpp"
    2825#include "Common/Indenter.h"           // for Indenter, operator<<
    2926#include "Common/SemanticError.h"      // for SemanticError
     
    586583
    587584namespace 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        };
    590600
    591601        /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry
     
    596606                SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
    597607
    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 {
    622612                        if ( type ) return { InitAlternative{ type, new Designation{ location } } };
    623613                        return {};
     
    625615        };
    626616
    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 
    944617        CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() {
    945618                objStack.emplace_back( new SimpleIterator{ loc, type } );
    946619        }
    947620
    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() {
    980622                PRINT( std::cerr << "____getting current options" << std::endl; )
    981623                assertf( ! objStack.empty(), "objstack empty in getOptions" );
    982624                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();
    989625        }
    990626}
  • src/ResolvExpr/CurrentObject.h

    r05d55ff rbe8518f  
    1616#pragma once
    1717
    18 #include <deque>
    1918#include <list>   // for list
    2019#include <memory> // for unique_ptr
     
    2221#include <vector>
    2322
    24 #include "AST/Node.hpp"  // for ptr
    2523#include "Common/CodeLocation.h"
    2624
     
    6159        // AST class types
    6260        class Designation;
    63         struct InitAlternative;
     61        class InitAlternative;
    6462        class Type;
    6563
    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;
    10466
    10567        /// Builds initializer lists in resolution
     
    11173                CurrentObject( const CodeLocation & loc, const Type * type );
    11274
    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();
    12175                /// produces a list of alternatives (Type *, Designation *) for the current sub-object's
    12276                /// 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();
    12678        };
    12779} // namespace ast
  • src/ResolvExpr/Resolver.cc

    r05d55ff rbe8518f  
    781781        }
    782782
    783         bool isCharType( Type * t ) {
     783        template< typename T >
     784        bool isCharType( T t ) {
    784785                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    785786                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
     
    10701071                };
    10711072
    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 
    10781073                /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts)
    10791074                void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) {
     
    10811076                                if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) {
    10821077                                        // 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;
    10841080                                }
    10851081                        }
     
    11791175                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
    11801176                }
    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                 }
    11911177        }
    11921178
     
    12271213                void previsit( const ast::WaitForStmt * );
    12281214
    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 * );
    12311217                void previsit( const ast::ConstructorInit * );
    12321218        };
     
    13771363        const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    13781364                if ( caseStmt->cond ) {
    1379                         std::deque< ast::InitAlternative > initAlts = currentObject.getOptions();
     1365                        std::vector< ast::InitAlternative > initAlts = currentObject.getOptions();
    13801366                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
    13811367                                "expression." );
     
    13881374                        // whether it would perform a conversion.
    13891375                        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;
    13911378                        }
    13921379                       
     
    14511438        }
    14521439
    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);
    15181450        }
    15191451
Note: See TracChangeset for help on using the changeset viewer.