Changeset db6cdc0


Ignore:
Timestamp:
Nov 14, 2022, 3:07:55 PM (3 years ago)
Author:
JiadaL <j82liang@…>
Branches:
ADT, ast-experimental, master
Children:
25b0fde
Parents:
e4d7c1c (diff), 1fb09eff (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
8 edited
8 moved

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    re4d7c1c rdb6cdc0  
    18761876                auto&& type = GET_ACCEPT_1(type, Type);
    18771877                auto&& attr = GET_ACCEPT_V(attributes, Attribute);
    1878  
     1878
    18791879                auto decl = new ast::InlineMemberDecl(
    18801880                        old->location,
  • src/AST/Decl.hpp

    re4d7c1c rdb6cdc0  
    398398};
    399399
     400/// Static Assertion `_Static_assert( ... , ... );`
    400401class StaticAssertDecl : public Decl {
    401402public:
     
    412413};
    413414
     415/// Inline Member Declaration `inline TypeName;`
    414416class InlineMemberDecl final : public DeclWithType {
    415417public:
     
    429431        MUTATE_FRIEND
    430432};
     433
    431434}
    432435
  • src/AST/Pass.hpp

    re4d7c1c rdb6cdc0  
    141141        const ast::DirectiveDecl *    visit( const ast::DirectiveDecl        * ) override final;
    142142        const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * ) override final;
    143         const ast::DeclWithType *     visit( const ast::InlineMemberDecl      * ) override final;
     143        const ast::DeclWithType *     visit( const ast::InlineMemberDecl     * ) override final;
    144144        const ast::CompoundStmt *     visit( const ast::CompoundStmt         * ) override final;
    145145        const ast::Stmt *             visit( const ast::ExprStmt             * ) override final;
  • src/AST/Pass.impl.hpp

    re4d7c1c rdb6cdc0  
    810810
    811811//--------------------------------------------------------------------------
    812 // DeclWithType
     812// InlineMemberDecl
    813813template< typename core_t >
    814814const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::InlineMemberDecl * node ) {
  • src/AST/Visitor.hpp

    re4d7c1c rdb6cdc0  
    3333    virtual const ast::DirectiveDecl *    visit( const ast::DirectiveDecl        * ) = 0;
    3434    virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * ) = 0;
    35     virtual const ast::DeclWithType *     visit( const ast::InlineMemberDecl      * ) = 0;
     35    virtual const ast::DeclWithType *     visit( const ast::InlineMemberDecl     * ) = 0;
    3636    virtual const ast::CompoundStmt *     visit( const ast::CompoundStmt         * ) = 0;
    3737    virtual const ast::Stmt *             visit( const ast::ExprStmt             * ) = 0;
  • src/Common/utility.h

    re4d7c1c rdb6cdc0  
    461461        Iterables iterables;
    462462
     463        // Getting the iterator and value types this way preserves const.
    463464        template<size_t I> using Iter = decltype(std::get<I>(iterables).begin());
    464465        template<size_t I> using Data = decltype(*std::get<I>(iterables).begin());
    465466        template<typename> struct base_iterator;
    466467
    467         template<std::size_t... Is>
    468         struct base_iterator<std::integer_sequence<std::size_t, Is...>> {
    469                 using value_type = std::tuple< Data<Is>... >;
    470                 std::tuple<Iter<Is>...> iterators;
    471 
    472                 base_iterator( Iter<Is>... is ) : iterators( is... ) {}
     468        // This inner template puts the sequence of `0, 1, ... sizeof...(Args)-1`
     469        // into a pack. These are the indexes into the tuples, so unpacking can
     470        // go over each element of the tuple.
     471        // The std::integer_sequence is just used to build that sequence.
     472        // A library reference will probably explain it better than I can.
     473        template<std::size_t... Indices>
     474        struct base_iterator<std::integer_sequence<std::size_t, Indices...>> {
     475                using value_type = std::tuple< Data<Indices>... >;
     476                std::tuple<Iter<Indices>...> iterators;
     477
     478                base_iterator( Iter<Indices>... is ) : iterators( is... ) {}
    473479                base_iterator operator++() {
    474                         return base_iterator( ++std::get<Is>( iterators )... );
     480                        return base_iterator( ++std::get<Indices>( iterators )... );
    475481                }
    476482                bool operator!=( const base_iterator& other ) const {
     
    478484                }
    479485                value_type operator*() const {
    480                         return std::tie( *std::get<Is>( iterators )... );
     486                        return std::tie( *std::get<Indices>( iterators )... );
    481487                }
    482488
    483489                static base_iterator make_begin( Iterables & data ) {
    484                         return base_iterator( std::get<Is>( data ).begin()... );
     490                        return base_iterator( std::get<Indices>( data ).begin()... );
    485491                }
    486492                static base_iterator make_end( Iterables & data ) {
    487                         return base_iterator( std::get<Is>( data ).end()... );
     493                        return base_iterator( std::get<Indices>( data ).end()... );
    488494                }
    489495        };
  • src/GenPoly/ErasableScopedMap.h

    re4d7c1c rdb6cdc0  
    2323
    2424namespace GenPoly {
    25         /// A map where the items are placed into nested scopes;
    26         /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward;
    27         /// erasing a key means that find() will no longer report any instance of the key in a scope further
    28         /// out, but the erasure itself is scoped. Key erasure works by inserting a sentinal value into the
    29         /// value field, and thus only works for Value types where a meaningful sentinal can be chosen.
    30         template<typename Key, typename Value>
    31         class ErasableScopedMap {
    32                 typedef std::map< Key, Value > Scope;
    33                 typedef std::vector< Scope > ScopeList;
    34 
    35                 ScopeList scopes; ///< scoped list of maps
    36                 Value erased;     ///< sentinal value for erased keys
    37         public:
    38                 typedef typename Scope::key_type key_type;
    39                 typedef typename Scope::mapped_type mapped_type;
    40                 typedef typename Scope::value_type value_type;
    41                 typedef typename ScopeList::size_type size_type;
    42                 typedef typename ScopeList::difference_type difference_type;
    43                 typedef typename Scope::reference reference;
    44                 typedef typename Scope::const_reference const_reference;
    45                 typedef typename Scope::pointer pointer;
    46                 typedef typename Scope::const_pointer const_pointer;
    47 
    48                 class iterator : public std::iterator< std::bidirectional_iterator_tag,
    49                                                        value_type > {
    50                 friend class ErasableScopedMap;
    51                 friend class const_iterator;
    52                         typedef typename std::map< Key, Value >::iterator wrapped_iterator;
    53                         typedef typename std::vector< std::map< Key, Value > > scope_list;
    54                         typedef typename scope_list::size_type size_type;
    55 
    56                         /// Checks if this iterator points to a valid item
    57                         bool is_valid() const {
    58                                 return it != map->scopes[i].end() && it->second != map->erased;
     25
     26/// A map where the items are placed into nested scopes.
     27/// Inserted items are placed into the innermost scope, lookup looks from the
     28/// innermost scope outward. Erasing a key means that find() will no longer
     29/// report any instance of the key in a scope further out, but the erasure
     30/// itself is scoped. Key erasure works by inserting a sentinal value into
     31/// the value field, and thus only works for Value types where a meaningful
     32/// sentinal can be chosen.
     33template<typename Key, typename Value>
     34class ErasableScopedMap {
     35        typedef std::map< Key, Value > Scope;
     36        typedef std::vector< Scope > ScopeList;
     37
     38        /// Scoped list of maps.
     39        ScopeList scopes;
     40        /// Sentinal value for erased keys.
     41        Value erased;
     42public:
     43        typedef typename Scope::key_type key_type;
     44        typedef typename Scope::mapped_type mapped_type;
     45        typedef typename Scope::value_type value_type;
     46        typedef typename ScopeList::size_type size_type;
     47        typedef typename ScopeList::difference_type difference_type;
     48        typedef typename Scope::reference reference;
     49        typedef typename Scope::const_reference const_reference;
     50        typedef typename Scope::pointer pointer;
     51        typedef typename Scope::const_pointer const_pointer;
     52
     53        // Both iterator types are complete bidirection iterators, defined below.
     54        class iterator;
     55        class const_iterator;
     56
     57        /// Starts a new scope
     58        void beginScope() {
     59                Scope scope;
     60                scopes.push_back(scope);
     61        }
     62
     63        /// Ends a scope; invalidates any iterators pointing to elements of that scope
     64        void endScope() {
     65                scopes.pop_back();
     66                assert( ! scopes.empty() );
     67        }
     68
     69        /// Default constructor initializes with one scope
     70        ErasableScopedMap( const Value &erased_ ) : erased( erased_ ) { beginScope(); }
     71
     72        iterator begin() { return iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); }
     73        const_iterator begin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); }
     74        const_iterator cbegin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); }
     75        iterator end() { return iterator(*this, scopes[0].end(), 0); }
     76        const_iterator end() const { return const_iterator(*this, scopes[0].end(), 0); }
     77        const_iterator cend() const { return const_iterator(*this, scopes[0].end(), 0); }
     78
     79        /// Gets the index of the current scope (counted from 1)
     80        size_type currentScope() const { return scopes.size(); }
     81
     82        /// Finds the given key in the outermost scope it occurs; returns end() for none such
     83        iterator find( const Key &key ) {
     84                for ( size_type i = scopes.size() - 1; ; --i ) {
     85                        typename Scope::iterator val = scopes[i].find( key );
     86                        if ( val != scopes[i].end() ) {
     87                                return val->second == erased ? end() : iterator( *this, val, i );
    5988                        }
    60 
    61                         /// Increments on invalid
    62                         iterator& next_valid() {
    63                                 if ( ! is_valid() ) { ++(*this); }
    64                                 return *this;
     89                        if ( i == 0 ) break;
     90                }
     91                return end();
     92        }
     93        const_iterator find( const Key &key ) const {
     94                return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->find( key ) );
     95        }
     96
     97        /// Finds the given key in the outermost scope inside the given scope where it occurs
     98        iterator findNext( const_iterator &it, const Key &key ) {
     99                if ( it.i == 0 ) return end();
     100                for ( size_type i = it.i - 1; ; --i ) {
     101                        typename Scope::iterator val = scopes[i].find( key );
     102                        if ( val != scopes[i].end() ) {
     103                                return val->second == erased ? end() : iterator( *this, val, i );
    65104                        }
    66 
    67                         /// Decrements on invalid
    68                         iterator& prev_valid() {
    69                                 if ( ! is_valid() ) { --(*this); }
    70                                 return *this;
    71                         }
    72                        
    73                         iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_iterator &_it, size_type _i)
    74                                         : map(&_map), it(_it), i(_i) {}
    75                        
    76                 public:
    77                         iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {}
    78                         iterator& operator= (const iterator &that) {
    79                                 map = that.map; i = that.i; it = that.it;
    80                                 return *this;
    81                         }
    82 
    83                         reference operator* () { return *it; }
    84                         pointer operator-> () { return it.operator->(); }
    85 
    86                         iterator& operator++ () {
    87                                 if ( it == map->scopes[i].end() ) {
    88                                         if ( i == 0 ) return *this;
    89                                         --i;
    90                                         it = map->scopes[i].begin();
    91                                 } else {
    92                                         ++it;
    93                                 }
    94                                 return next_valid();
    95                         }
    96                         iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
    97 
    98                         iterator& operator-- () {
    99                                 // may fail if this is the begin iterator; allowed by STL spec
    100                                 if ( it == map->scopes[i].begin() ) {
    101                                         ++i;
    102                                         it = map->scopes[i].end();
    103                                 }
    104                                 --it;
    105                                 return prev_valid();
    106                         }
    107                         iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
    108 
    109                         bool operator== (const iterator &that) {
    110                                 return map == that.map && i == that.i && it == that.it;
    111                         }
    112                         bool operator!= (const iterator &that) { return !( *this == that ); }
    113 
    114                 private:
    115                         ErasableScopedMap< Key, Value > const *map;
    116                         wrapped_iterator it;
    117                         size_type i;
    118                 };
    119 
    120                 class const_iterator : public std::iterator< std::bidirectional_iterator_tag,
    121                                                              value_type > {
    122                 friend class ErasableScopedMap;
    123                         typedef typename std::map< Key, Value >::iterator wrapped_iterator;
    124                         typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator;
    125                         typedef typename std::vector< std::map< Key, Value > > scope_list;
    126                         typedef typename scope_list::size_type size_type;
    127 
    128                         /// Checks if this iterator points to a valid item
    129                         bool is_valid() const {
    130                                 return it != map->scopes[i].end() && it->second != map->erased;
    131                         }
    132 
    133                         /// Increments on invalid
    134                         const_iterator& next_valid() {
    135                                 if ( ! is_valid() ) { ++(*this); }
    136                                 return *this;
    137                         }
    138 
    139                         /// Decrements on invalid
    140                         const_iterator& prev_valid() {
    141                                 if ( ! is_valid() ) { --(*this); }
    142                                 return *this;
    143                         }
    144                        
    145                         const_iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_const_iterator &_it, size_type _i)
    146                                         : map(&_map), it(_it), i(_i) {}
    147                 public:
    148                         const_iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {}
    149                         const_iterator(const const_iterator &that) : map(that.map), it(that.it), i(that.i) {}
    150                         const_iterator& operator= (const iterator &that) {
    151                                 map = that.map; i = that.i; it = that.it;
    152                                 return *this;
    153                         }
    154                         const_iterator& operator= (const const_iterator &that) {
    155                                 map = that.map; i = that.i; it = that.it;
    156                                 return *this;
    157                         }
    158 
    159                         const_reference operator* () { return *it; }
    160                         const_pointer operator-> () { return it.operator->(); }
    161 
    162                         const_iterator& operator++ () {
    163                                 if ( it == map->scopes[i].end() ) {
    164                                         if ( i == 0 ) return *this;
    165                                         --i;
    166                                         it = map->scopes[i].begin();
    167                                 } else {
    168                                         ++it;
    169                                 }
    170                                 return next_valid();
    171                         }
    172                         const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
    173 
    174                         const_iterator& operator-- () {
    175                                 // may fail if this is the begin iterator; allowed by STL spec
    176                                 if ( it == map->scopes[i].begin() ) {
    177                                         ++i;
    178                                         it = map->scopes[i].end();
    179                                 }
    180                                 --it;
    181                                 return prev_valid();
    182                         }
    183                         const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
    184 
    185                         bool operator== (const const_iterator &that) {
    186                                 return map == that.map && i == that.i && it == that.it;
    187                         }
    188                         bool operator!= (const const_iterator &that) { return !( *this == that ); }
    189 
    190                 private:
    191                         ErasableScopedMap< Key, Value > const *map;
    192                         wrapped_const_iterator it;
    193                         size_type i;
    194                 };
    195 
    196                 /// Starts a new scope
    197                 void beginScope() {
    198                         Scope scope;
    199                         scopes.push_back(scope);
    200                 }
    201 
    202                 /// Ends a scope; invalidates any iterators pointing to elements of that scope
    203                 void endScope() {
    204                         scopes.pop_back();
    205                         assert( ! scopes.empty() );
    206                 }
    207 
    208                 /// Default constructor initializes with one scope
    209                 ErasableScopedMap( const Value &erased_ ) : erased( erased_ ) { beginScope(); }
    210 
    211                 iterator begin() { return iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); }
    212                 const_iterator begin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); }
    213                 const_iterator cbegin() const { return const_iterator(*this, scopes.back().begin(), scopes.size()-1).next_valid(); }
    214                 iterator end() { return iterator(*this, scopes[0].end(), 0); }
    215                 const_iterator end() const { return const_iterator(*this, scopes[0].end(), 0); }
    216                 const_iterator cend() const { return const_iterator(*this, scopes[0].end(), 0); }
    217 
    218                 /// Gets the index of the current scope (counted from 1)
    219                 size_type currentScope() const { return scopes.size(); }
    220 
    221                 /// Finds the given key in the outermost scope it occurs; returns end() for none such
    222                 iterator find( const Key &key ) {
    223                         for ( size_type i = scopes.size() - 1; ; --i ) {
    224                                 typename Scope::iterator val = scopes[i].find( key );
    225                                 if ( val != scopes[i].end() ) {
    226                                         return val->second == erased ? end() : iterator( *this, val, i );
    227                                 }
    228                                 if ( i == 0 ) break;
    229                         }
    230                         return end();
    231                 }
    232                 const_iterator find( const Key &key ) const {
    233                                 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->find( key ) );
    234                 }
    235 
    236                 /// Finds the given key in the outermost scope inside the given scope where it occurs
    237                 iterator findNext( const_iterator &it, const Key &key ) {
    238                         if ( it.i == 0 ) return end();
    239                         for ( size_type i = it.i - 1; ; --i ) {
    240                                 typename Scope::iterator val = scopes[i].find( key );
    241                                 if ( val != scopes[i].end() ) {
    242                                         return val->second == erased ? end() : iterator( *this, val, i );
    243                                 }
    244                                 if ( i == 0 ) break;
    245                         }
    246                         return end();
    247                 }
    248                 const_iterator findNext( const_iterator &it, const Key &key ) const {
    249                                 return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->findNext( it, key ) );
    250                 }
    251 
    252                 /// Inserts the given key-value pair into the outermost scope
    253                 std::pair< iterator, bool > insert( const value_type &value ) {
    254                         std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value );
    255                         return std::make_pair( iterator(*this, res.first, scopes.size()-1), res.second );
    256                 }
    257                 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); }
    258 
    259                 /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise
    260                 size_type erase( const Key &key ) {
    261                         typename Scope::iterator val = scopes.back().find( key );
    262                         if ( val != scopes.back().end() ) {
    263                                 val->second = erased;
    264                                 return 1;
    265                         } else {
    266                                 scopes.back().insert( val, std::make_pair( key, erased ) );
    267                                 return 0;
    268                         }
    269                 }
    270 
    271                 Value& operator[] ( const Key &key ) {
    272                         iterator slot = find( key );
    273                         if ( slot != end() ) return slot->second;
    274                         return insert( key, Value() ).first->second;
    275                 }
    276         };
     105                        if ( i == 0 ) break;
     106                }
     107                return end();
     108        }
     109        const_iterator findNext( const_iterator &it, const Key &key ) const {
     110                return const_iterator( const_cast< ErasableScopedMap< Key, Value >* >(this)->findNext( it, key ) );
     111        }
     112
     113        /// Inserts the given key-value pair into the outermost scope
     114        std::pair< iterator, bool > insert( const value_type &value ) {
     115                std::pair< typename Scope::iterator, bool > res = scopes.back().insert( value );
     116                return std::make_pair( iterator(*this, res.first, scopes.size()-1), res.second );
     117        }
     118        std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); }
     119
     120        /// Marks the given element as erased from this scope inward; returns 1 for erased an element, 0 otherwise
     121        size_type erase( const Key &key ) {
     122                typename Scope::iterator val = scopes.back().find( key );
     123                if ( val != scopes.back().end() ) {
     124                        val->second = erased;
     125                        return 1;
     126                } else {
     127                        scopes.back().insert( val, std::make_pair( key, erased ) );
     128                        return 0;
     129                }
     130        }
     131
     132        Value& operator[] ( const Key &key ) {
     133                iterator slot = find( key );
     134                if ( slot != end() ) return slot->second;
     135                return insert( key, Value() ).first->second;
     136        }
     137};
     138
     139template<typename Key, typename Value>
     140class ErasableScopedMap<Key, Value>::iterator :
     141                public std::iterator< std::bidirectional_iterator_tag, value_type > {
     142        friend class ErasableScopedMap;
     143        typedef typename std::map< Key, Value >::iterator wrapped_iterator;
     144        typedef typename std::vector< std::map< Key, Value > > scope_list;
     145        typedef typename scope_list::size_type size_type;
     146
     147        /// Checks if this iterator points to a valid item
     148        bool is_valid() const {
     149                return it != map->scopes[i].end() && it->second != map->erased;
     150        }
     151
     152        /// Increments on invalid
     153        iterator& next_valid() {
     154                if ( ! is_valid() ) { ++(*this); }
     155                return *this;
     156        }
     157
     158        /// Decrements on invalid
     159        iterator& prev_valid() {
     160                if ( ! is_valid() ) { --(*this); }
     161                return *this;
     162        }
     163
     164        iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_iterator &_it, size_type _i)
     165                        : map(&_map), it(_it), i(_i) {}
     166
     167public:
     168        iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {}
     169        iterator& operator= (const iterator &that) {
     170                map = that.map; i = that.i; it = that.it;
     171                return *this;
     172        }
     173
     174        reference operator* () { return *it; }
     175        pointer operator-> () { return it.operator->(); }
     176
     177        iterator& operator++ () {
     178                if ( it == map->scopes[i].end() ) {
     179                        if ( i == 0 ) return *this;
     180                        --i;
     181                        it = map->scopes[i].begin();
     182                } else {
     183                        ++it;
     184                }
     185                return next_valid();
     186        }
     187
     188        iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
     189
     190        iterator& operator-- () {
     191                // may fail if this is the begin iterator; allowed by STL spec
     192                if ( it == map->scopes[i].begin() ) {
     193                        ++i;
     194                        it = map->scopes[i].end();
     195                }
     196                --it;
     197                return prev_valid();
     198        }
     199        iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
     200
     201        bool operator== (const iterator &that) {
     202                return map == that.map && i == that.i && it == that.it;
     203        }
     204        bool operator!= (const iterator &that) { return !( *this == that ); }
     205
     206private:
     207        ErasableScopedMap< Key, Value > const *map;
     208        wrapped_iterator it;
     209        size_type i;
     210};
     211
     212template<typename Key, typename Value>
     213class ErasableScopedMap<Key, Value>::const_iterator :
     214                public std::iterator< std::bidirectional_iterator_tag, value_type > {
     215        friend class ErasableScopedMap;
     216        typedef typename std::map< Key, Value >::iterator wrapped_iterator;
     217        typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator;
     218        typedef typename std::vector< std::map< Key, Value > > scope_list;
     219        typedef typename scope_list::size_type size_type;
     220
     221        /// Checks if this iterator points to a valid item
     222        bool is_valid() const {
     223                return it != map->scopes[i].end() && it->second != map->erased;
     224        }
     225
     226        /// Increments on invalid
     227        const_iterator& next_valid() {
     228                if ( ! is_valid() ) { ++(*this); }
     229                return *this;
     230        }
     231
     232        /// Decrements on invalid
     233        const_iterator& prev_valid() {
     234                if ( ! is_valid() ) { --(*this); }
     235                return *this;
     236        }
     237
     238        const_iterator(ErasableScopedMap< Key, Value > const &_map, const wrapped_const_iterator &_it, size_type _i)
     239                        : map(&_map), it(_it), i(_i) {}
     240public:
     241        const_iterator(const iterator &that) : map(that.map), it(that.it), i(that.i) {}
     242        const_iterator(const const_iterator &that) : map(that.map), it(that.it), i(that.i) {}
     243        const_iterator& operator= (const iterator &that) {
     244                map = that.map; i = that.i; it = that.it;
     245                return *this;
     246        }
     247        const_iterator& operator= (const const_iterator &that) {
     248                map = that.map; i = that.i; it = that.it;
     249                return *this;
     250        }
     251
     252        const_reference operator* () { return *it; }
     253        const_pointer operator-> () { return it.operator->(); }
     254
     255        const_iterator& operator++ () {
     256                if ( it == map->scopes[i].end() ) {
     257                        if ( i == 0 ) return *this;
     258                        --i;
     259                        it = map->scopes[i].begin();
     260                } else {
     261                        ++it;
     262                }
     263                return next_valid();
     264        }
     265        const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
     266
     267        const_iterator& operator-- () {
     268                // may fail if this is the begin iterator; allowed by STL spec
     269                if ( it == map->scopes[i].begin() ) {
     270                        ++i;
     271                        it = map->scopes[i].end();
     272                }
     273                --it;
     274                return prev_valid();
     275        }
     276        const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
     277
     278        bool operator== (const const_iterator &that) {
     279                return map == that.map && i == that.i && it == that.it;
     280        }
     281        bool operator!= (const const_iterator &that) { return !( *this == that ); }
     282
     283private:
     284        ErasableScopedMap< Key, Value > const *map;
     285        wrapped_const_iterator it;
     286        size_type i;
     287};
     288
    277289} // namespace GenPoly
    278290
  • src/Validate/EnumAndPointerDecay.cpp

    re4d7c1c rdb6cdc0  
    4141        auto mut = ast::mutate( decl );
    4242        std::vector<ast::ptr<ast::Decl>> buffer;
    43         for ( auto it = decl->members.begin(); it != decl->members.end(); ++it ) {
    44                 if ( ast::ObjectDecl const * object = (*it).as<ast::ObjectDecl>() ) {
    45                         buffer.push_back( ast::mutate_field( object, &ast::ObjectDecl::type, new ast::EnumInstType( decl, ast::CV::Const ) ) );
    46                 } else if ( ast::InlineMemberDecl const * value = (*it).as<ast::InlineMemberDecl>() ) {
     43        for ( auto member : decl->members ) {
     44                if ( ast::ObjectDecl const * object = member.as<ast::ObjectDecl>() ) {
     45                        buffer.push_back( ast::mutate_field( object,
     46                                &ast::ObjectDecl::type,
     47                                new ast::EnumInstType( decl, ast::CV::Const ) ) );
     48                } else if ( auto value = member.as<ast::InlineMemberDecl>() ) {
    4749                        if ( auto targetEnum = symtab.lookupEnum( value->name ) ) {
    48                                 for ( auto singleMember : targetEnum->members ) {
    49                                         auto copyingMember = singleMember.as<ast::ObjectDecl>();
     50                                for ( auto enumMember : targetEnum->members ) {
     51                                        auto enumObject = enumMember.strict_as<ast::ObjectDecl>();
    5052                                        buffer.push_back( new ast::ObjectDecl(
    51                                                 value->location, // use the "inline" location
    52                                                 copyingMember->name,
     53                                                // Get the location from the "inline" declaration.
     54                                                value->location,
     55                                                enumObject->name,
     56                                                // Construct a new EnumInstType as the type.
    5357                                                new ast::EnumInstType( decl, ast::CV::Const ),
    54                                                 // Construct a new EnumInstType as the type
    55                                                 copyingMember->init,
    56                                                 copyingMember->storage,
    57                                                 copyingMember->linkage,
    58                                                 copyingMember->bitfieldWidth,
     58                                                enumObject->init,
     59                                                enumObject->storage,
     60                                                enumObject->linkage,
     61                                                enumObject->bitfieldWidth,
    5962                                                {},
    60                                                 copyingMember->funcSpec
     63                                                enumObject->funcSpec
    6164                                        ) );
    6265                                }
Note: See TracChangeset for help on using the changeset viewer.