Changeset 181036c


Ignore:
Timestamp:
Aug 13, 2022, 1:30:37 PM (19 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation
Children:
3f1059e
Parents:
62c5a55 (diff), 082af5b (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:
16 edited

Legend:

Unmodified
Added
Removed
  • doc/bibliography/pl.bib

    r62c5a55 r181036c  
    78377837}
    78387838
     7839@misc{Tokio,
     7840    contributer = {pabuhr@plg},
     7841    key         = {Tokio},
     7842    title       = {{T}okio Asynchronous Runtime for {R}ust},
     7843    author      = {Tokio},
     7844    howpublished= {\href{https://tokio.rs}{https://\-tokio.rs}},
     7845}
     7846
    78397847@misc{Bumbulis90,
    78407848    keywords    = {parameter inference, ForceN},
     
    81528160    doi         = {10.1145/3379483},
    81538161    journal     = {Proc. ACM Meas. Anal. Comput. Syst.},
    8154     month       = mar,
     8162    month       = jun,
    81558163    numpages    = {30},
    81568164}
  • src/Common/Eval.cc

    r62c5a55 r181036c  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  1 08:41:03 2022
    13 // Update Count     : 117
     12// Last Modified On : Sat Aug  6 12:11:59 2022
     13// Update Count     : 119
    1414//
    1515
     
    217217                                value = arg1.first * arg2.first;
    218218                        } else if (fname == "?/?") {
    219                                 value = arg1.first / arg2.first;
     219                                if ( arg2.first ) value = arg1.first / arg2.first;
    220220                        } else if (fname == "?%?") {
    221                                 value = arg1.first % arg2.first;
     221                                if ( arg2.first ) value = arg1.first % arg2.first;
    222222                        } else if (fname == "?<<?") {
    223223                                value = arg1.first << arg2.first;
  • src/Common/ScopedMap.h

    r62c5a55 r181036c  
    1010// Created On       : Wed Dec 2 11:37:00 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 21 15:22:40 2018
    13 // Update Count     : 3
     12// Last Modified On : Tue Feb 15 08:41:28 2022
     13// Update Count     : 5
    1414//
    1515
     
    3636
    3737                template<typename N>
    38                 Scope(N&& n) : map(), note(std::forward<N>(n)) {}
     38                Scope(N && n) : map(), note(std::forward<N>(n)) {}
    3939               
    4040                Scope() = default;
    41                 Scope(const Scope&) = default;
    42                 Scope(Scope&&) = default;
    43                 Scope& operator= (const Scope&) = default;
    44                 Scope& operator= (Scope&&) = default;
     41                Scope(const Scope &) = default;
     42                Scope(Scope &&) = default;
     43                Scope & operator= (const Scope &) = default;
     44                Scope & operator= (Scope &&) = default;
    4545        };
    4646        typedef std::vector< Scope > ScopeList;
     
    5858        typedef typename MapType::const_pointer const_pointer;
    5959
    60         class iterator : public std::iterator< std::bidirectional_iterator_tag,
    61                                                value_type > {
     60        class iterator : public std::iterator< std::bidirectional_iterator_tag, value_type > {
    6261        friend class ScopedMap;
    6362        friend class const_iterator;
     
    7271
    7372                /// Increments on invalid
    74                 iterator& next_valid() {
     73                iterator & next_valid() {
    7574                        if ( ! is_valid() ) { ++(*this); }
    7675                        return *this;
     
    7877
    7978                /// Decrements on invalid
    80                 iterator& prev_valid() {
     79                iterator & prev_valid() {
    8180                        if ( ! is_valid() ) { --(*this); }
    8281                        return *this;
    8382                }
    8483
    85                 iterator(scope_list &_scopes, const wrapped_iterator &_it, size_type inLevel)
     84                iterator(scope_list & _scopes, const wrapped_iterator & _it, size_type inLevel)
    8685                        : scopes(&_scopes), it(_it), level(inLevel) {}
    8786        public:
    88                 iterator(const iterator &that) : scopes(that.scopes), it(that.it), level(that.level) {}
    89                 iterator& operator= (const iterator &that) {
     87                iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
     88                iterator & operator= (const iterator & that) {
    9089                        scopes = that.scopes; level = that.level; it = that.it;
    9190                        return *this;
     
    9594                pointer operator-> () const { return it.operator->(); }
    9695
    97                 iterator& operator++ () {
     96                iterator & operator++ () {
    9897                        if ( it == (*scopes)[level].map.end() ) {
    9998                                if ( level == 0 ) return *this;
     
    107106                iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
    108107
    109                 iterator& operator-- () {
     108                iterator & operator-- () {
    110109                        // may fail if this is the begin iterator; allowed by STL spec
    111110                        if ( it == (*scopes)[level].map.begin() ) {
     
    118117                iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
    119118
    120                 bool operator== (const iterator &that) const {
     119                bool operator== (const iterator & that) const {
    121120                        return scopes == that.scopes && level == that.level && it == that.it;
    122121                }
    123                 bool operator!= (const iterator &that) const { return !( *this == that ); }
     122                bool operator!= (const iterator & that) const { return !( *this == that ); }
    124123
    125124                size_type get_level() const { return level; }
    126125
    127                 Note& get_note() { return (*scopes)[level].note; }
    128                 const Note& get_note() const { return (*scopes)[level].note; }
     126                Note & get_note() { return (*scopes)[level].note; }
     127                const Note & get_note() const { return (*scopes)[level].note; }
    129128
    130129        private:
     
    148147
    149148                /// Increments on invalid
    150                 const_iterator& next_valid() {
     149                const_iterator & next_valid() {
    151150                        if ( ! is_valid() ) { ++(*this); }
    152151                        return *this;
     
    154153
    155154                /// Decrements on invalid
    156                 const_iterator& prev_valid() {
     155                const_iterator & prev_valid() {
    157156                        if ( ! is_valid() ) { --(*this); }
    158157                        return *this;
    159158                }
    160159
    161                 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type inLevel)
     160                const_iterator(scope_list const & _scopes, const wrapped_const_iterator & _it, size_type inLevel)
    162161                        : scopes(&_scopes), it(_it), level(inLevel) {}
    163162        public:
    164                 const_iterator(const iterator &that) : scopes(that.scopes), it(that.it), level(that.level) {}
    165                 const_iterator(const const_iterator &that) : scopes(that.scopes), it(that.it), level(that.level) {}
    166                 const_iterator& operator= (const iterator &that) {
     163                const_iterator(const iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
     164                const_iterator(const const_iterator & that) : scopes(that.scopes), it(that.it), level(that.level) {}
     165                const_iterator & operator= (const iterator & that) {
    167166                        scopes = that.scopes; level = that.level; it = that.it;
    168167                        return *this;
    169168                }
    170                 const_iterator& operator= (const const_iterator &that) {
     169                const_iterator & operator= (const const_iterator & that) {
    171170                        scopes = that.scopes; level = that.level; it = that.it;
    172171                        return *this;
     
    176175                const_pointer operator-> () { return it.operator->(); }
    177176
    178                 const_iterator& operator++ () {
     177                const_iterator & operator++ () {
    179178                        if ( it == (*scopes)[level].map.end() ) {
    180179                                if ( level == 0 ) return *this;
     
    188187                const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
    189188
    190                 const_iterator& operator-- () {
     189                const_iterator & operator-- () {
    191190                        // may fail if this is the begin iterator; allowed by STL spec
    192191                        if ( it == (*scopes)[level].map.begin() ) {
     
    199198                const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
    200199
    201                 bool operator== (const const_iterator &that) const {
     200                bool operator== (const const_iterator & that) const {
    202201                        return scopes == that.scopes && level == that.level && it == that.it;
    203202                }
    204                 bool operator!= (const const_iterator &that) const { return !( *this == that ); }
     203                bool operator!= (const const_iterator & that) const { return !( *this == that ); }
    205204
    206205                size_type get_level() const { return level; }
    207206
    208                 const Note& get_note() const { return (*scopes)[level].note; }
     207                const Note & get_note() const { return (*scopes)[level].note; }
    209208
    210209        private:
     
    221220        // Starts a new scope with the given note
    222221        template<typename N>
    223         void beginScope( N&& n ) {
     222        void beginScope( N && n ) {
    224223                scopes.emplace_back( std::forward<N>(n) );
    225224        }
     
    236235        /// Constructs with a given note on the outermost scope
    237236        template<typename N>
    238         ScopedMap( N&& n ) : scopes() { beginScope(std::forward<N>(n)); }
     237        ScopedMap( N && n ) : scopes() { beginScope(std::forward<N>(n)); }
    239238
    240239        iterator begin() { return iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); }
     
    249248
    250249        /// Gets the note at the given scope
    251         Note& getNote() { return scopes.back().note; }
    252         const Note& getNote() const { return scopes.back().note; }
    253         Note& getNote( size_type i ) { return scopes[i].note; }
    254         const Note& getNote( size_type i ) const { return scopes[i].note; }
     250        Note & getNote() { return scopes.back().note; }
     251        const Note & getNote() const { return scopes.back().note; }
     252        Note & getNote( size_type i ) { return scopes[i].note; }
     253        const Note & getNote( size_type i ) const { return scopes[i].note; }
    255254
    256255        /// Finds the given key in the outermost scope it occurs; returns end() for none such
    257         iterator find( const Key &key ) {
     256        iterator find( const Key & key ) {
    258257                for ( size_type i = scopes.size() - 1; ; --i ) {
    259258                        typename MapType::iterator val = scopes[i].map.find( key );
     
    263262                return end();
    264263        }
    265         const_iterator find( const Key &key ) const {
     264        const_iterator find( const Key & key ) const {
    266265                        return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->find( key ) );
    267266        }
    268267
    269268        /// Finds the given key in the provided scope; returns end() for none such
    270         iterator findAt( size_type scope, const Key& key ) {
     269        iterator findAt( size_type scope, const Key & key ) {
    271270                typename MapType::iterator val = scopes[scope].map.find( key );
    272271                if ( val != scopes[scope].map.end() ) return iterator( scopes, val, scope );
    273272                return end();
    274273        }
    275         const_iterator findAt( size_type scope, const Key& key ) const {
     274        const_iterator findAt( size_type scope, const Key & key ) const {
    276275                return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findAt( scope, key ) );
    277276        }
    278277
    279278        /// Finds the given key in the outermost scope inside the given scope where it occurs
    280         iterator findNext( const_iterator &it, const Key &key ) {
     279        iterator findNext( const_iterator & it, const Key & key ) {
    281280                if ( it.level == 0 ) return end();
    282281                for ( size_type i = it.level - 1; ; --i ) {
     
    287286                return end();
    288287        }
    289         const_iterator findNext( const_iterator &it, const Key &key ) const {
     288        const_iterator findNext( const_iterator & it, const Key & key ) const {
    290289                        return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findNext( it, key ) );
    291290        }
     
    293292        /// Inserts the given key-value pair into the outermost scope
    294293        template< typename value_type_t >
    295         std::pair< iterator, bool > insert( value_type_t&& value ) {
     294        std::pair< iterator, bool > insert( value_type_t && value ) {
    296295                std::pair< typename MapType::iterator, bool > res = scopes.back().map.insert( std::forward<value_type_t>( value ) );
    297296                return std::make_pair( iterator(scopes, std::move( res.first ), scopes.size()-1), std::move( res.second ) );
     
    299298
    300299        template< typename value_type_t >
    301         std::pair< iterator, bool > insert( iterator at, value_type_t&& value ) {
    302                 MapType& scope = (*at.scopes)[ at.level ].map;
     300        std::pair< iterator, bool > insert( iterator at, value_type_t && value ) {
     301                MapType & scope = (*at.scopes)[ at.level ].map;
    303302                std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );
    304303                return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) );
     
    306305
    307306        template< typename value_t >
    308         std::pair< iterator, bool > insert( const Key &key, value_t&& value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); }
     307        std::pair< iterator, bool > insert( const Key & key, value_t && value ) { return insert( std::make_pair( key, std::forward<value_t>( value ) ) ); }
    309308
    310309        template< typename value_type_t >
    311         std::pair< iterator, bool > insertAt( size_type scope, value_type_t&& value ) {
     310        std::pair< iterator, bool > insertAt( size_type scope, value_type_t && value ) {
    312311                std::pair< typename MapType::iterator, bool > res = scopes.at(scope).map.insert( std::forward<value_type_t>( value ) );
    313312                return std::make_pair( iterator(scopes, std::move( res.first ), scope), std::move( res.second ) );
     
    315314
    316315        template< typename value_t >
    317         std::pair< iterator, bool > insertAt( size_type scope, const Key& key, value_t&& value ) {
     316        std::pair< iterator, bool > insertAt( size_type scope, const Key & key, value_t && value ) {
    318317                return insertAt( scope, std::make_pair( key, std::forward<value_t>( value ) ) );
    319318        }
    320319
    321         Value& operator[] ( const Key &key ) {
     320        Value & operator[] ( const Key & key ) {
    322321                iterator slot = find( key );
    323322                if ( slot != end() ) return slot->second;
     
    326325
    327326        iterator erase( iterator pos ) {
    328                 MapType& scope = (*pos.scopes)[ pos.level ].map;
    329                 const typename iterator::wrapped_iterator& new_it = scope.erase( pos.it );
     327                MapType & scope = (*pos.scopes)[ pos.level ].map;
     328                const typename iterator::wrapped_iterator & new_it = scope.erase( pos.it );
    330329                iterator it( *pos.scopes, new_it, pos.level );
    331330                return it.next_valid();
    332331        }
    333332
    334         size_type count( const Key &key ) const {
     333        size_type count( const Key & key ) const {
    335334                size_type c = 0;
    336335                auto it = find( key );
     
    344343                return c;
    345344        }
    346 
    347345};
    348346
  • src/Parser/DeclarationNode.cc

    r62c5a55 r181036c  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 14 17:36:57 2021
    13 // Update Count     : 1154
     12// Last Modified On : Mon Aug  8 17:07:00 2022
     13// Update Count     : 1185
    1414//
    1515
     
    128128        if ( name ) {
    129129                os << *name << ": ";
    130         } else {
    131                 os << "unnamed: ";
    132130        } // if
    133131
     
    154152                initializer->printOneLine( os );
    155153                os << " maybe constructed? " << initializer->get_maybeConstructed();
    156 
    157         } // if
     154        } // if
     155
     156        for ( Attribute * attr: reverseIterate( attributes ) ) {
     157                os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str();
     158        } // for
    158159
    159160        os << endl;
     
    243244        newnode->type = new TypeData( TypeData::Aggregate );
    244245        newnode->type->aggregate.kind = kind;
    245         newnode->type->aggregate.name =  name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
     246        newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    246247        newnode->type->aggregate.actuals = actuals;
    247248        newnode->type->aggregate.fields = fields;
     
    518519        storageClasses |= q->storageClasses;
    519520
    520         for ( Attribute *attr: reverseIterate( q->attributes ) ) {
     521        for ( Attribute * attr: reverseIterate( q->attributes ) ) {
    521522                attributes.push_front( attr->clone() );
    522523        } // for
     
    683684        } // if
    684685        delete o;
     686
    685687        return this;
    686688}
  • src/Parser/TypeData.cc

    r62c5a55 r181036c  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:12:51 2015
    11 // Last Modified By : Henry Xue
    12 // Last Modified On : Tue Jul 20 04:10:50 2021
    13 // Update Count     : 673
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue May 10 22:36:52 2022
     13// Update Count     : 677
    1414//
    1515
     
    283283                if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " ";
    284284                if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " ";
    285                 if ( complextype == DeclarationNode::NoComplexType ) { // basic type
    286                         assert( basictype != DeclarationNode::NoBasicType );
    287                         os << DeclarationNode::basicTypeNames[ basictype ] << " ";
    288                 } else {                                                                                // complex type
    289                         // handle double _Complex
    290                         if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " ";
    291                         os << DeclarationNode::complexTypeNames[ complextype ] << " ";
    292                 } // if
     285                if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " ";
     286                if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " ";
    293287                break;
    294288          case Pointer:
     
    437431                        __attribute__((fallthrough));
    438432                #endif
     433                // FALL THROUGH
    439434          case Typeof:
    440435                os << "type-of expression ";
     
    442437                        typeexpr->print( os, indent + 2 );
    443438                } // if
     439                break;
     440          case Vtable:
     441                os << "vtable";
    444442                break;
    445443          case Builtin:
  • src/Parser/TypeData.h

    r62c5a55 r181036c  
    1010// Created On       : Sat May 16 15:18:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 14 17:44:05 2021
    13 // Update Count     : 202
     12// Last Modified On : Tue May 10 22:18:49 2022
     13// Update Count     : 203
    1414//
    1515
     
    2727struct TypeData {
    2828        enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
    29                                 SymbolicInst, Tuple, Typeof, Basetypeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };
     29                                SymbolicInst, Tuple, Basetypeof, Typeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };
    3030
    3131        struct Aggregate_t {
  • src/Parser/TypedefTable.cc

    r62c5a55 r181036c  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 19 08:30:14 2021
    13 // Update Count     : 262
     12// Last Modified On : Tue Feb 15 08:27:24 2022
     13// Update Count     : 275
    1414//
    1515
     
    1818#include <cassert>                                                                              // for assert
    1919#include <iostream>
     20using namespace std;
    2021
    2122#if 0
     
    2829
    2930debugPrint(
    30 static const char *kindName( int kind ) {
    31         switch ( kind ) {
    32           case IDENTIFIER: return "identifier";
    33           case TYPEDIMname: return "typedim";
    34           case TYPEDEFname: return "typedef";
    35           case TYPEGENname: return "typegen";
    36           default:
    37                 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
    38                 abort();
    39         } // switch
    40 } // kindName
    41 )
     31        static const char *kindName( int kind ) {
     32                switch ( kind ) {
     33                  case IDENTIFIER: return "identifier";
     34                  case TYPEDIMname: return "typedim";
     35                  case TYPEDEFname: return "typedef";
     36                  case TYPEGENname: return "typegen";
     37                  default:
     38                        cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;
     39                        abort();
     40                } // switch
     41        } // kindName
     42);
    4243
    4344TypedefTable::~TypedefTable() {
     
    8081
    8182void TypedefTable::addToScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
    82         auto scope = kindTable.currentScope();
     83        KindTable::size_type scope = kindTable.currentScope();
    8384        debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
    8485        kindTable.insertAt( scope, identifier, kind );
     
    8687
    8788void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
    88         auto scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level;
    89 //      auto scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level;
     89        KindTable::size_type scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level;
     90//      size_type scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level;
    9091        debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl );
    91         auto ret = kindTable.insertAt( scope, identifier, kind );
     92        pair< KindTable::iterator, bool > ret = kindTable.insertAt( scope, identifier, kind );
    9293        if ( ! ret.second ) ret.first->second = kind;           // exists => update
    9394} // TypedefTable::addToEnclosingScope
  • src/Parser/parser.yy

    r62c5a55 r181036c  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  1 15:35:08 2022
    13 // Update Count     : 5405
     12// Last Modified On : Fri Aug 12 07:59:58 2022
     13// Update Count     : 5649
    1414//
    1515
     
    5858
    5959// lex uses __null in a boolean context, it's fine.
    60 #pragma GCC diagnostic ignored "-Wparentheses-equality"
     60//#pragma GCC diagnostic ignored "-Wparentheses-equality"
    6161
    6262extern DeclarationNode * parseTree;
     
    197197} // fieldDecl
    198198
     199#define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
     200#define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
     201#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
     202
     203ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     204        if ( index->initializer ) {
     205                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     206        } // if
     207        if ( index->next ) {
     208                SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
     209        } // if
     210        return new ForCtrl( index->addInitializer( new InitializerNode( start ) ),
     211                // NULL comp/inc => leave blank
     212                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr,
     213                inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
     214                                                        OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr );
     215} // forCtrl
     216
    199217ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    200218        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
     
    206224                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
    207225                // NULL comp/inc => leave blank
    208                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,
     226                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr,
    209227                inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    210                                                         OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0 );
     228                                                        OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr );
    211229} // forCtrl
    212230
     
    346364%type<ifctl> conditional_declaration
    347365%type<fctl> for_control_expression              for_control_expression_list
    348 %type<compop> inclexcl
     366%type<compop> updown updowneq downupdowneq
    349367%type<en> subrange
    350368%type<decl> asm_name_opt
     
    12391257iteration_statement:
    12401258        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1241                 { $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); }
     1259                { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
    12421260        | WHILE '(' ')' statement ELSE statement                        // CFA
    12431261                {
    1244                         $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) );
     1262                        $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
    12451263                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12461264                }
     
    12501268                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
    12511269        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1252                 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }
     1270                { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
    12531271        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    12541272                {
    1255                         $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );
     1273                        $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
    12561274                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12571275                }
     
    13051323
    13061324        | comma_expression                                                                      // CFA
    1307                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    1308                                                 OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1309         | '=' comma_expression                                                          // CFA
    1310                 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    1311                                                 OperKinds::LEThan, $2->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1312         | comma_expression inclexcl comma_expression            // CFA
    1313                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1314         | comma_expression inclexcl comma_expression '~' comma_expression // CFA
    1315                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); }
    1316         | comma_expression ';'                                                          // CFA
    1317                 { $$ = forCtrl( new ExpressionNode( build_constantInteger( *new string( "0u" ) ) ), $1, nullptr, OperKinds::LThan, nullptr, nullptr ); }
     1325                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
     1326        | downupdowneq comma_expression                                         // CFA
     1327                { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
     1328
     1329        | comma_expression updowneq comma_expression            // CFA
     1330                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
     1331        | '@' updowneq comma_expression                                         // CFA
     1332                {
     1333                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1334                        else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
     1335                }
     1336        | comma_expression updowneq '@'                                         // CFA
     1337                {
     1338                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing comparison ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
     1339                        else { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1340                }
     1341        | comma_expression updowneq comma_expression '~' comma_expression // CFA
     1342                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
     1343        | '@' updowneq comma_expression '~' comma_expression // CFA
     1344                {
     1345                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1346                        else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
     1347                }
     1348        | comma_expression updowneq '@' '~' comma_expression // CFA
     1349                {
     1350                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing comparison ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
     1351                        else { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1352                }
     1353        | comma_expression updowneq comma_expression '~' '@' // CFA, error
     1354                { SemanticError( yylloc, "Missing increment ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
     1355        | '@' updowneq comma_expression '~' '@'                         // CFA, error
     1356                { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
     1357        | comma_expression updowneq '@' '~' '@'                         // CFA, error
     1358                { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
     1359        | '@' updowneq '@' '~' '@'                                                      // CFA, error
     1360                { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
     1361
    13181362        | comma_expression ';' comma_expression                         // CFA
    1319                 { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    1320                                                 OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1321         | comma_expression ';' '=' comma_expression                     // CFA
    1322                 { $$ = forCtrl( $4, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    1323                                                 OperKinds::LEThan, $4->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1324         | comma_expression ';' comma_expression inclexcl comma_expression // CFA
    1325                 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1326         | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
    1327                 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
     1363                { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1364        | comma_expression ';' downupdowneq comma_expression // CFA
     1365                { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
     1366
     1367        | comma_expression ';' comma_expression updowneq comma_expression // CFA
     1368                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
     1369        | comma_expression ';' '@' updowneq comma_expression // CFA
     1370                {
     1371                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1372                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1373                }
     1374        | comma_expression ';' comma_expression updowneq '@' // CFA
     1375                {
     1376                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1377                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
     1378                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
     1379                }
     1380        | comma_expression ';' '@' updowneq '@'                         // CFA, error
     1381                { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1382
     1383        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
     1384                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
     1385        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
     1386                {
     1387                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1388                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
     1389                }
     1390        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
     1391                {
     1392                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1393                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
     1394                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
     1395                }
     1396        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
     1397                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
     1398        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
     1399                {
     1400                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1401                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
     1402                }
     1403        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
     1404                {
     1405                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1406                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
     1407                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
     1408                }
     1409        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
     1410                { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1411
     1412        | declaration comma_expression                                          // CFA
     1413                { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1414        | declaration downupdowneq comma_expression                     // CFA
     1415                { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
     1416
     1417        | declaration comma_expression updowneq comma_expression // CFA
     1418                { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
     1419        | declaration '@' updowneq comma_expression                     // CFA
     1420                {
     1421                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1422                        else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
     1423                }
     1424        | declaration comma_expression updowneq '@'                     // CFA
     1425                {
     1426                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1427                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
     1428                        else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
     1429                }
     1430
     1431        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
     1432                { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
     1433        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
     1434                {
     1435                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1436                        else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
     1437                }
     1438        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
     1439                {
     1440                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1441                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
     1442                        else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
     1443                }
     1444        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
     1445                { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
     1446        | declaration '@' updowneq comma_expression '~' '@' // CFA
     1447                {
     1448                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1449                        else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
     1450                }
     1451        | declaration comma_expression updowneq '@' '~' '@'     // CFA
     1452                {
     1453                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1454                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
     1455                        else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
     1456                }
     1457        | declaration '@' updowneq '@' '~' '@'                          // CFA, error
     1458                { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    13281459
    13291460        | comma_expression ';' TYPEDEFname                                      // CFA, array type
    13301461                {
    1331                         SemanticError( yylloc, "Array interator is currently unimplemented." ); $$ = nullptr;
    1332                         $$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
    1333                 }
    1334 
    1335                 // There is a S/R conflicit if ~ and -~ are factored out.
    1336         | comma_expression ';' comma_expression '~' '@'         // CFA
    1337                 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1338         | comma_expression ';' comma_expression ErangeDown '@' // CFA
    1339                 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1340         | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
    1341                 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
    1342         | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA
    1343                 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); }
    1344         | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA
    1345                 { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); }
     1462                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
     1463                        //$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
     1464                }
     1465        | comma_expression ';' downupdowneq TYPEDEFname         // CFA, array type
     1466                {
     1467                        if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; }
     1468                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
     1469                }
    13461470        ;
    13471471
    1348 inclexcl:
     1472downupdowneq:
     1473        ErangeDown
     1474                { $$ = OperKinds::GThan; }
     1475        | ErangeUpEq
     1476                { $$ = OperKinds::LEThan; }
     1477        | ErangeDownEq
     1478                { $$ = OperKinds::GEThan; }
     1479        ;
     1480
     1481updown:
    13491482        '~'
    13501483                { $$ = OperKinds::LThan; }
     1484        | ErangeDown
     1485                { $$ = OperKinds::GThan; }
     1486        ;
     1487
     1488updowneq:
     1489        updown
    13511490        | ErangeUpEq
    13521491                { $$ = OperKinds::LEThan; }
    1353         | ErangeDown
    1354                 { $$ = OperKinds::GThan; }
    13551492        | ErangeDownEq
    13561493                { $$ = OperKinds::GEThan; }
     
    23952532          '{' enumerator_list comma_opt '}'
    23962533                { $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); }
     2534        | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
     2535                { SemanticError( yylloc, "Unvalued enumerated type is currently unimplemented." ); $$ = nullptr; }
    23972536        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    23982537                {
  • src/Virtual/ExpandCasts.cc

    r62c5a55 r181036c  
    1010// Created On       : Mon Jul 24 13:59:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 31 10:29:00 2020
    13 // Update Count     : 4
     12// Last Modified On : Thu Aug 11 12:06:00 2022
     13// Update Count     : 5
    1414//
    1515
     
    2020#include <string>                  // for string, allocator, operator==, ope...
    2121
     22#include "AST/Decl.hpp"
     23#include "AST/Expr.hpp"
     24#include "AST/Pass.hpp"
    2225#include "Common/PassVisitor.h"    // for PassVisitor
    2326#include "Common/ScopedMap.h"      // for ScopedMap
     
    3235namespace Virtual {
    3336
    34 static bool is_prefix( const std::string & prefix, const std::string& entire ) {
     37namespace {
     38
     39bool is_prefix( const std::string & prefix, const std::string& entire ) {
    3540        size_t const p_size = prefix.size();
    3641        return (p_size < entire.size() && prefix == entire.substr(0, p_size));
    3742}
    3843
    39 static bool is_type_id_object( const ObjectDecl * objectDecl ) {
     44bool is_type_id_object( const ObjectDecl * objectDecl ) {
    4045        const std::string & objectName = objectDecl->name;
    4146        return is_prefix( "__cfatid_", objectName );
     47}
     48
     49bool is_type_id_object( const ast::ObjectDecl * decl ) {
     50        return is_prefix( "__cfatid_", decl->name );
    4251}
    4352
     
    124133                }
    125134        }
    126 
    127         namespace {
    128135
    129136        /// Better error locations for generated casts.
     
    229236        }
    230237
    231         } // namespace
    232 
    233238        Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) {
    234239                assertf( castExpr->result, "Virtual Cast target not found before expansion." );
     
    265270        }
    266271
    267         void expandCasts( std::list< Declaration * > & translationUnit ) {
    268                 PassVisitor<VirtualCastCore> translator;
    269                 mutateAll( translationUnit, translator );
    270         }
    271 }
     272/// Better error locations for generated casts.
     273// TODO: Does the improved distribution of code locations make this unneeded?
     274CodeLocation castLocation( const ast::VirtualCastExpr * castExpr ) {
     275        if ( castExpr->location.isSet() ) {
     276                return castExpr->location;
     277        } else if ( castExpr->arg->location.isSet() ) {
     278                return castExpr->arg->location;
     279        } else {
     280                return CodeLocation();
     281        }
     282}
     283
     284[[noreturn]] void castError( ast::VirtualCastExpr const * castExpr, std::string const & message ) {
     285        SemanticError( castLocation( castExpr ), message );
     286}
     287
     288class TypeIdTable final {
     289        ScopedMap<std::string, ast::ObjectDecl const *> instances;
     290public:
     291        void enterScope() { instances.beginScope(); }
     292        void leaveScope() { instances.endScope(); }
     293
     294        // Attempt to insert an instance into the map. If there is a conflict,
     295        // returns the previous declaration for error messages.
     296        ast::ObjectDecl const * insert( ast::ObjectDecl const * typeIdDecl ) {
     297                std::string const & mangledName =
     298                                Mangle::mangle( typeIdDecl->type, Mangle::typeMode() );
     299                ast::ObjectDecl const *& value = instances[ mangledName ];
     300                if ( value ) {
     301                        if ( typeIdDecl->storage.is_extern ) {
     302                                return nullptr;
     303                        } else if ( !value->storage.is_extern ) {
     304                                return value;
     305                        }
     306                }
     307                value = typeIdDecl;
     308                return nullptr;
     309        }
     310
     311        ast::ObjectDecl const * lookup( ast::Type const * typeIdType ) {
     312                std::string const & mangledName =
     313                                Mangle::mangle( typeIdType, Mangle::typeMode() );
     314                auto const it = instances.find( mangledName );
     315                return ( instances.end() == it ) ? nullptr : it->second;
     316        }
     317};
     318
     319struct ExpandCastsCore {
     320        void previsit( ast::FunctionDecl const * decl );
     321        void previsit( ast::StructDecl const * decl );
     322        void previsit( ast::ObjectDecl const * decl );
     323        ast::Expr const * postvisit( ast::VirtualCastExpr const * expr );
     324
     325        ast::CastExpr const * cast_to_type_id(
     326                ast::Expr const * expr, unsigned int level_of_indirection );
     327
     328        ast::FunctionDecl const * vcast_decl = nullptr;
     329        ast::StructDecl const * info_decl = nullptr;
     330
     331        TypeIdTable symtab;
     332};
     333
     334void ExpandCastsCore::previsit( ast::FunctionDecl const * decl ) {
     335        if ( !vcast_decl && "__cfavir_virtual_cast" == decl->name ) {
     336                vcast_decl = decl;
     337        }
     338}
     339
     340void ExpandCastsCore::previsit( ast::StructDecl const * decl ) {
     341        if ( !info_decl && decl->body && "__cfavir_type_info" == decl->name ) {
     342                info_decl = decl;
     343        }
     344}
     345
     346void ExpandCastsCore::previsit( ast::ObjectDecl const * decl ) {
     347        if ( is_type_id_object( decl ) ) {
     348                // Multiple definitions should be fine because of linkonce.
     349                symtab.insert( decl );
     350        }
     351}
     352
     353/// Get the base type from a pointer or reference.
     354ast::Type const * getBaseType( ast::ptr<ast::Type> const & type ) {
     355        if ( auto target = type.as<ast::PointerType>() ) {
     356                return target->base.get();
     357        } else if ( auto target = type.as<ast::ReferenceType>() ) {
     358                return target->base.get();
     359        } else {
     360                return nullptr;
     361        }
     362}
     363
     364ast::StructInstType * polyCopy(
     365                ast::StructInstType const * oldType,
     366                ast::StructInstType const * newType ) {
     367        assert( oldType->params.size() == newType->params.size() );
     368        ast::StructInstType * retType = ast::deepCopy( newType );
     369        if ( ! oldType->params.empty() ) {
     370                retType->params.clear();
     371                for ( auto oldParams : oldType->params ) {
     372                        retType->params.push_back( ast::deepCopy( oldParams ) );
     373                }
     374        }
     375        return retType;
     376}
     377
     378/// Follow the "head" field of the structure to get the type that is pointed
     379/// to by that field.
     380ast::StructInstType const * followHeadPointerType(
     381                CodeLocation const & errorLocation,
     382                ast::StructInstType const * oldType,
     383                std::string const & fieldName ) {
     384        ast::StructDecl const * oldDecl = oldType->base;
     385        assert( oldDecl );
     386
     387        // Helper function for throwing semantic errors.
     388        auto throwError = [&fieldName, &errorLocation, &oldDecl](
     389                        std::string const & message ) {
     390                std::string const & context = "While following head pointer of " +
     391                        oldDecl->name + " named '" + fieldName + "': ";
     392                SemanticError( errorLocation, context + message );
     393        };
     394
     395        if ( oldDecl->members.empty() ) {
     396                throwError( "Type has no fields." );
     397        }
     398        ast::ptr<ast::Decl> const & memberDecl = oldDecl->members.front();
     399        assert( memberDecl );
     400        ast::ObjectDecl const * fieldDecl = memberDecl.as<ast::ObjectDecl>();
     401        assert( fieldDecl );
     402        if ( fieldName != fieldDecl->name ) {
     403                throwError( "Head field did not have expected name." );
     404        }
     405
     406        ast::ptr<ast::Type> const & fieldType = fieldDecl->type;
     407        if ( nullptr == fieldType ) {
     408                throwError( "Could not get head field." );
     409        }
     410        auto ptrType = fieldType.as<ast::PointerType>();
     411        if ( nullptr == ptrType ) {
     412                throwError( "First field is not a pointer type." );
     413        }
     414        assert( ptrType->base );
     415        auto newType = ptrType->base.as<ast::StructInstType>();
     416        if ( nullptr == newType ) {
     417                throwError( "First field does not point to a structure type." );
     418        }
     419
     420        return polyCopy( oldType, newType );
     421}
     422
     423/// Get the type-id type from a virtual type.
     424ast::StructInstType const * getTypeIdType(
     425                CodeLocation const & errorLocation,
     426                ast::Type const * type ) {
     427        auto typeInst = dynamic_cast<ast::StructInstType const *>( type );
     428        if ( nullptr == typeInst ) {
     429                return nullptr;
     430        }
     431        ast::ptr<ast::StructInstType> tableInst =
     432                followHeadPointerType( errorLocation, typeInst, "virtual_table" );
     433        if ( nullptr == tableInst ) {
     434                return nullptr;
     435        }
     436        ast::StructInstType const * typeIdInst =
     437                followHeadPointerType( errorLocation, tableInst, "__cfavir_typeid" );
     438        return typeIdInst;
     439}
     440
     441ast::Expr const * ExpandCastsCore::postvisit(
     442                ast::VirtualCastExpr const * expr ) {
     443        assertf( expr->result, "Virtual cast target not found before expansion." );
     444
     445        assert( vcast_decl );
     446        assert( info_decl );
     447
     448        ast::Type const * base_type = getBaseType( expr->result );
     449        if ( nullptr == base_type ) {
     450                castError( expr, "Virtual cast target must be a pointer or reference type." );
     451        }
     452        ast::StructInstType const * type_id_type =
     453                        getTypeIdType( castLocation( expr ), base_type );
     454        if ( nullptr == type_id_type ) {
     455                castError( expr, "Ill formed virtual cast target type." );
     456        }
     457        ast::ObjectDecl const * type_id = symtab.lookup( type_id_type );
     458        if ( nullptr == type_id ) {
     459                // I'm trying to give a different error for polymorpic types as
     460                // different things can go wrong there.
     461                if ( type_id_type->params.empty() ) {
     462                        castError( expr, "Virtual cast does not target a virtual type." );
     463                } else {
     464                        castError( expr, "Virtual cast does not target a type with a "
     465                                "type id (possible missing virtual table)." );
     466                }
     467        }
     468
     469        return new ast::CastExpr( expr->location,
     470                new ast::ApplicationExpr( expr->location,
     471                        ast::VariableExpr::functionPointer( expr->location, vcast_decl ),
     472                        {
     473                                cast_to_type_id(
     474                                        new ast::AddressExpr( expr->location,
     475                                                new ast::VariableExpr( expr->location, type_id ) ),
     476                                        1 ),
     477                                cast_to_type_id( expr->arg, 2 ),
     478                        }
     479                ),
     480                ast::deepCopy( expr->result )
     481        );
     482}
     483
     484ast::CastExpr const * ExpandCastsCore::cast_to_type_id(
     485                ast::Expr const * expr, unsigned int level_of_indirection ) {
     486        assert( info_decl );
     487        ast::Type * type = new ast::StructInstType( info_decl, ast::CV::Const );
     488        for ( unsigned int i = 0 ; i < level_of_indirection ; ++i ) {
     489                type = new ast::PointerType( type );
     490        }
     491        return new ast::CastExpr( expr->location, expr, type );
     492}
     493
     494} // namespace
     495
     496void expandCasts( std::list< Declaration * > & translationUnit ) {
     497        PassVisitor<VirtualCastCore> translator;
     498        mutateAll( translationUnit, translator );
     499}
     500
     501void expandCasts( ast::TranslationUnit & translationUnit ) {
     502        ast::Pass<ExpandCastsCore>::run( translationUnit );
     503}
     504
     505} // namespace Virtual
  • src/Virtual/ExpandCasts.h

    r62c5a55 r181036c  
    1010// Created On       : Mon Jul 24 13:54:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jul 25 14:51:00 2017
    13 // Update Count     : 0
     12// Last Modified On : Fri Jul 29 14:40:00 2022
     13// Update Count     : 1
    1414//
    1515
     
    1919
    2020class Declaration;
     21namespace ast {
     22        class TranslationUnit;
     23}
    2124
    2225namespace Virtual {
    23         void expandCasts( std::list< Declaration * > & translationUnit );
    24         // Breaks all virtual cast nodes up into translatable nodes.
     26void expandCasts( std::list< Declaration * > & translationUnit );
     27void expandCasts( ast::TranslationUnit & translationUnit );
     28// Breaks all virtual cast nodes up into translatable nodes.
    2529
    26         // Later this might just set some information so it can happen at CodeGen.
     30// Later this might just set some information so it can happen at CodeGen.
    2731
    2832}
  • src/main.cc

    r62c5a55 r181036c  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jul 18 11:08:00 2022
    13 // Update Count     : 676
     12// Last Modified On : Thu 11 12:18:00 2022
     13// Update Count     : 677
    1414//
    1515
     
    445445                        PASS( "Expand Tuples", Tuples::expandTuples( transUnit ) );
    446446
     447                        if ( tuplep ) {
     448                                dump( move( transUnit ) );
     449                                return EXIT_SUCCESS;
     450                        } // if
     451
     452                        // Must come after Translate Tries.
     453                        PASS( "Virtual Expand Casts", Virtual::expandCasts( transUnit ) );
     454
    447455                        translationUnit = convert( move( transUnit ) );
    448456                } else {
     
    520528                        PASS( "Convert Specializations",  GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded
    521529                        PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this?
     530
     531                        if ( tuplep ) {
     532                                dump( translationUnit );
     533                                return EXIT_SUCCESS;
     534                        } // if
     535
     536                        PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
    522537                }
    523 
    524                 if ( tuplep ) {
    525                         dump( translationUnit );
    526                         return EXIT_SUCCESS;
    527                 } // if
    528 
    529                 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
    530538
    531539                PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) );
  • tests/.expect/loop_else.txt

    r62c5a55 r181036c  
    33330 1 2 3 4 5 6 7 8 9 else
    34340 1 2 3 4 5 6 7 8 9 10 else
    35 10 9 8 7 6 5 4 3 2 1 else
     3510 9 8 7 6 5 4 3 2 1 0 else
    3636
    37373 6 9 else
    38 
    39 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else
    40 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else
    41 
    42 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else
    43 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else
    44 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)else
    45 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)else
    46 
    47 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)else
    48 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)else
    49 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else
    50 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else
    5138
    52390 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4 else
     
    63500 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 else
    64510 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5 else
     52(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else
     53(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else
     54
     55(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else
     56(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)else
     57(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)else
     58(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)else
     59
     60(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)else
     61(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)else
     62(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else
     63(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)else
     64
  • tests/.expect/loopctrl.txt

    r62c5a55 r181036c  
    31310 1 2 3 4 5 6 7 8 9
    32320 1 2 3 4 5 6 7 8 9 10
    33 10 9 8 7 6 5 4 3 2 1
     3310 9 8 7 6 5 4 3 2 1 0
    3434
    35353 6 9
    36 
    37 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)
    38 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)
    39 
    40 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)
    41 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)
    42 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)
    43 (0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)
    44 
    45 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)
    46 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)
    47 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)
    48 (10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)
    4936
    50370 -5 1 -4 2 -3 3 -2 4 -1 5 0 6 1 7 2 8 3 9 4
     
    61480 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5
    62490 -5 1.5 1 -7 2.5 2 -9 3.5 3 -11 4.5 4 -13 5.5 5 -15 6.5 6 -17 7.5 7 -19 8.5 8 -21 9.5 9 -23 10.5
     50(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)
     51(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)
     52
     53(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)
     54(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)
     55(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)
     56(0 0)(1 1)(2 2)(3 3)(4 4)(5 5)(6 6)(7 7)(8 8)(9 9)(10 10)
     57
     58(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)
     59(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)
     60(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)
     61(10 10)(9 9)(8 8)(7 7)(6 6)(5 5)(4 4)(3 3)(2 2)(1 1)(0 0)
     62
     63A A A A A A A A A A
     64B B B B B B B B B B B
     65C C C C C C C C C C
     66D D D D D D D D D D D
     67A A A A A A A A A A
     68B B B B B B B B B B B
     69C C C C C C C C C C
     70D D D D D D D D D D D
     71A A A A A
     72B B B B B B
     73C C C C C
     74D D D D D D
     750 1 2 3 4 5 6 7 8 9
     760 1 2 3 4 5 6 7 8 9 10
     7710 9 8 7 6 5 4 3 2 1
     7810 9 8 7 6 5 4 3 2 1 0
     790 1 2 3 4 5 6 7 8 9
     800 1 2 3 4 5 6 7 8 9 10
     8110 9 8 7 6 5 4 3 2 1
     8210 9 8 7 6 5 4 3 2 1 0
     830 2 4 6 8
     840 2 4 6 8 10
     8510 8 6 4 2
     8610 8 6 4 2 0
     870 1 2 3 4 5 6 7 8 9
     880 1 2 3 4 5 6 7 8 9
     890 1 2 3 4 5 6 7 8 9 10
     9010 9 8 7 6 5 4 3 2 1
     9110 9 8 7 6 5 4 3 2 1 0
     920 1 2 3 4 5 6 7 8 9
     930 1 2 3 4 5 6 7 8 9 10
     9410 9 8 7 6 5 4 3 2 1
     9510 9 8 7 6 5 4 3 2 1 0
     960 2 4 6 8
     970 2 4 6 8 10
     9810 8 6 4 2
     9910 8 6 4 2 0
     1000 1 2 3 4 5 6 7 8 9
     1010 -1 -2 -3 -4 -5 -6 -7 -8 -9
     1020 2 4 6 8
     1030 -2 -4 -6 -8
     1040 1 2 3 4 5 6 7 8 9
     1050 2 4 6 8
     1060 -2 -4 -6 -8
     1070 2 4 6 8
     1080 -2 -4 -6 -8
     1090 1 2 3 4 5 6 7 8 9
  • tests/heap.cfa

    r62c5a55 r181036c  
    1010// Created On       : Tue Nov  6 17:54:56 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec 15 12:11:51 2020
    13 // Update Count     : 79
     12// Last Modified On : Wed Aug 10 09:57:01 2022
     13// Update Count     : 86
    1414//
    1515
     
    2626//      return __CFA_DEFAULT_PREEMPTION__;
    2727// }
    28 
    29 size_t default_heap_expansion() {
    30         return 10 * 1024 * 1024;
    31 } // default_heap_expansion
    32 
    33 size_t default_mmap_start() {
    34         return 512 * 1024 + 1;
    35 } // default_mmap_start
    3628
    3729thread Worker {
     
    6658                        for ( k; i ) locns[i][k] = '\345';
    6759                } // for
    68                 for ( i; NoOfAllocs - 1 -~= 0 ) {
     60                for ( i; -~= NoOfAllocs - 1 ) {
    6961                        //sout | (void *)locns[i];
    7062                        for ( k; i ) if ( locns[i][k] != '\345' ) abort( "new/delete corrupt storage2" );
     
    9991
    10092        for ( i; NoOfMmaps ) {
    101                 size_t s = i + default_mmap_start();                    // cross over point
     93                size_t s = i + malloc_mmap_start();                     // cross over point
    10294                char * area = (char *)malloc( s );
    10395                area[0] = '\345'; area[s - 1] = '\345';                 // fill first/last
     
    10799
    108100        for ( i; NoOfMmaps ) {
    109                 size_t s = i + default_mmap_start();                    // cross over point
     101                size_t s = i + malloc_mmap_start();                     // cross over point
    110102                locns[i] = (char *)malloc( s );
    111103                locns[i][0] = '\345'; locns[i][s - 1] = '\345'; // fill first/last
     
    113105        } // for
    114106        for ( i; NoOfMmaps ) {
    115                 size_t s = i + default_mmap_start();                    // cross over point
     107                size_t s = i + malloc_mmap_start();                     // cross over point
    116108                if ( locns[i][0] != '\345' || locns[i][s - 1] != '\345' ||
    117109                         locns[i][malloc_usable_size( locns[i] ) - 1] != '\345' ) abort( "malloc/free corrupt storage" );
     
    151143
    152144        for ( i; NoOfMmaps ) {
    153                 size_t s = i + default_mmap_start();                    // cross over point
     145                size_t s = i + malloc_mmap_start();                     // cross over point
    154146                char * area = (char *)calloc( 1, s );
    155147                if ( area[0] != '\0' || area[s - 1] != '\0' ) abort( "calloc/free corrupt storage4.1" );
     
    162154
    163155        for ( i; NoOfMmaps ) {
    164                 size_t s = i + default_mmap_start();                    // cross over point
     156                size_t s = i + malloc_mmap_start();                     // cross over point
    165157                locns[i] = (char *)calloc( 1, s );
    166158                if ( locns[i][0] != '\0' || locns[i][s - 1] != '\0' ||
     
    171163        } // for
    172164        for ( i; NoOfMmaps ) {
    173                 size_t s = i + default_mmap_start();                    // cross over point
     165                size_t s = i + malloc_mmap_start();                     // cross over point
    174166                if ( locns[i][0] != '\345' || locns[i][s - 1] != '\345' ||
    175167                         locns[i][malloc_usable_size( locns[i] ) - 1] != '\345' ) abort( "calloc/free corrupt storage6" );
     
    198190                //sout | alignments[a];
    199191                for ( i; 1 ~ NoOfMmaps ) {
    200                         size_t s = i + default_mmap_start();            // cross over point
     192                        size_t s = i + malloc_mmap_start();             // cross over point
    201193                        char * area = (char *)memalign( a, s );
    202194                        //sout | i | area;
     
    232224        for ( i; 2 ~ NoOfAllocs ~ 12 ) {
    233225                // initial N byte allocation
    234                 size_t s = i + default_mmap_start();                    // cross over point
     226                size_t s = i + malloc_mmap_start();                     // cross over point
    235227                char * area = (char *)malloc( s );
    236228                area[0] = '\345'; area[s - 1] = '\345';                 // fill first/penultimate byte
     
    269261        for ( i; 2 ~ NoOfAllocs ~ 12 ) {
    270262                // initial N byte allocation
    271                 size_t s = i + default_mmap_start();                    // cross over point
     263                size_t s = i + malloc_mmap_start();                     // cross over point
    272264                char * area = (char *)malloc( s );
    273265                area[0] = '\345'; area[s - 1] = '\345';                 // fill first/penultimate byte
     
    307299        for ( i; 1 ~ 10_000 ~ 12 ) {
    308300                // initial N byte allocation
    309                 size_t s = i + default_mmap_start();                    // cross over point
     301                size_t s = i + malloc_mmap_start();                     // cross over point
    310302                char * area = (char *)calloc( 1, s );
    311303                if ( area[0] != '\0' || area[s - 1] != '\0' ||
     
    481473
    482474int main() {
    483         const unsigned int NoOfWorkers = 4;
     475        enum { NoOfWorkers = 4 };
    484476        {
    485477                processor processors[NoOfWorkers - 1] __attribute__(( unused )); // more than one processor
  • tests/loop_else.cfa

    r62c5a55 r181036c  
    2020
    2121int main() {
    22     sout | nlOff;                                                                               // turn off auto newline
    23         while () { sout | "empty"; break; } else { sout | "else"; }                                         sout | nl;
    24         do { sout | "empty"; break; } while () else { sout | "else"; }                              sout | nl;
    25         for () { sout | "empty"; break; } else { sout | "else"; }                                           sout | nl | nl;
     22        // Test some loop options.
    2623
    27     do { sout | "false"; } while (false) else { sout | "else"; }                                    sout | nl | nl;
     24        sout | nlOff;                                                                           // turn off auto newline
     25        while () { sout | "empty"; break; } else { sout | "else"; }                                             sout | nl;
     26        do { sout | "empty"; break; } while () else { sout | "else"; }                                  sout | nl;
     27        for () { sout | "empty"; break; } else { sout | "else"; }                                               sout | nl | nl;
    2828
    29         for ( 0 ) { sout | "A"; } else { sout | "else"; }                                                   sout | "zero" | nl;
     29        do { sout | "false"; } while (false) else { sout | "else"; }                                    sout | nl | nl;
     30
     31        for ( 0 ) { sout | "A"; } else { sout | "else"; }                                                               sout | "zero" | nl;
    3032        for ( 1 ) { sout | "A"; } else { sout | "else"; }                                                               sout | nl;
    31         for ( 10 ) { sout | "A"; } else { sout | "else"; }                                                          sout | nl;
    32         for ( = 10 ) { sout | "A"; } else { sout | "else"; }                                                    sout | nl;
     33        for ( 10 ) { sout | "A"; } else { sout | "else"; }                                                              sout | nl;
     34        for ( ~= 10 ) { sout | "A"; } else { sout | "else"; }                                                   sout | nl;
    3335        for ( 1 ~= 10 ~ 2 ) { sout | "B"; } else { sout | "else"; }                                             sout | nl;
    34         for ( 10 -~= 1 ~ 2 ) { sout | "C"; } else { sout | "else"; }                                    sout | nl;
     36        for ( 1 -~= 10 ~ 2 ) { sout | "C"; } else { sout | "else"; }                                    sout | nl;
    3537        for ( 0.5 ~ 5.5 ) { sout | "D"; } else { sout | "else"; }                                               sout | nl;
    36         for ( 5.5 -~ 0.5 ) { sout | "E"; } else { sout | "else"; }                                              sout | nl | nl;
     38        for ( 0.5 -~ 5.5 ) { sout | "E"; } else { sout | "else"; }                                              sout | nl | nl;
    3739
    3840        for ( i; 10 ) { sout | i; } else { sout | "else"; }                                                             sout | nl;
    39         for ( i; = 10 ) { sout | i; } else { sout | "else"; }                                                   sout | nl;
     41        for ( i; ~= 10 ) { sout | i; } else { sout | "else"; }                                                  sout | nl;
    4042        for ( i; 1 ~= 10 ~ 2 ) { sout | i; } else { sout | "else"; }                                    sout | nl;
    41         for ( i; 10 -~= 1 ~ 2 ) { sout | i; } else { sout | "else"; }                                   sout | nl;
     43        for ( i; 1 -~= 10 ~ 2 ) { sout | i; } else { sout | "else"; }                                   sout | nl;
    4244        for ( i; 0.5 ~ 5.5 ) { sout | i; } else { sout | "else"; }                                              sout | nl;
    43         for ( i; 5.5 -~ 0.5 ) { sout | i; } else { sout | "else"; }                                             sout | nl;
     45        for ( i; 0.5 -~ 5.5 ) { sout | i; } else { sout | "else"; }                                             sout | nl;
    4446        for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; } else { sout | "else"; }                               sout | nl;
    45         for ( ui; 10u -~= 2u ~ 2u ) { sout | ui; } else { sout | "else"; }                              sout | nl | nl;
     47        for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; } else { sout | "else"; }                              sout | nl | nl;
    4648
    4749        // @ means do nothing
     
    5052                sout | i;
    5153        } else { sout | "else"; }                                                                                                               sout | nl;
    52         for ( i; 10 -~ @ ) {
     54        for ( i; @ -~ 10 ) {
    5355          if ( i < 0 ) break;
    5456                sout | i;
     
    6365                i += 1.7;
    6466        } else { sout | "else"; }                                                                                                               sout | nl;
    65         for ( i; 10 -~ @ ~ 2 ) {
     67        for ( i; @ -~ 10 ~ 2 ) {
    6668          if ( i < 0 ) break;
    6769                sout | i;
     
    7678        for ( N ) { sout | "N"; } else { sout | "else"; }                                                       sout | nl;
    7779        for ( i; N ) { sout | i; } else { sout | "else"; }                                                      sout | nl;
    78         for ( i; = N ) { sout | i; } else { sout | "else"; }                                            sout | nl;
    79         for ( i; N -~ 0 ) { sout | i; } else { sout | "else"; }                                         sout | nl | nl;
     80        for ( i; ~= N ) { sout | i; } else { sout | "else"; }                                           sout | nl;
     81        for ( i; -~= N ) { sout | i; } else { sout | "else"; }                                          sout | nl | nl;
    8082
    8183        const int start = 3, comp = 10, inc = 2;
    8284        for ( i; start ~ comp ~ inc + 1 ) { sout | i; } else { sout | "else"; }         sout | nl | nl;
     85
     86        for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } else { sout | "else"; } sout | nl;
     87        for ( i; 10 : j; @ -~ -5 ) { sout | i | j; } else { sout | "else"; } sout | nl;
     88        for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } else { sout | "else"; } sout | nl;
     89        for ( i; 10 : j; @ -~ -5 ~ 2 ) { sout | i | j; } else { sout | "else"; } sout | nl | nl;
     90
     91        for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl;
     92        for ( j; @ -~ -5 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl;
     93        for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl;
     94        for ( j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl | nl;
     95
     96        for ( j; @ -~ -5 ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } else { sout | "else"; } sout | nl;
     97        for ( j; @ -~ -5 ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } else { sout | "else"; } sout | nl;
     98        for ( k; 1.5 ~ @ : j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j | k; } else { sout | "else"; } sout | nl;
    8399
    84100        for ( S s = (S){0}; s < (S){10,10}; s += (S){1} ) { sout | s; } else { sout | "else"; } sout | nl;
     
    90106        for ( s; (S){0} ~= (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl;
    91107        sout | nl;
    92         for ( s; (S){10,10} -~ (S){0} ) { sout | s; } else { sout | "else"; }            sout | nl;
    93         for ( s; (S){10,10} -~ (S){0} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl;
    94         for ( s; (S){10,10} -~= (S){0} ) { sout | s; } else { sout | "else"; }           sout | nl;
    95         for ( s; (S){10,10} -~= (S){0} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl | nl;
    96 
    97         for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } else { sout | "else"; } sout | nl;
    98         for ( i; 10 : j; -5 -~ @ ) { sout | i | j; } else { sout | "else"; } sout | nl;
    99         for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } else { sout | "else"; } sout | nl;
    100         for ( i; 10 : j; -5 -~ @ ~ 2 ) { sout | i | j; } else { sout | "else"; } sout | nl | nl;
    101 
    102         for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl;
    103         for ( j; -5 -~ @ : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl;
    104         for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl;
    105         for ( j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j; } else { sout | "else"; } sout | nl | nl;
    106 
    107         for ( j; -5 -~ @ ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } else { sout | "else"; } sout | nl;
    108         for ( j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } else { sout | "else"; } sout | nl;
    109         for ( k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j | k; } else { sout | "else"; } sout | nl;
     108        for ( s; (S){0} -~  (S){10,10} ) { sout | s; } else { sout | "else"; }           sout | nl;
     109        for ( s; (S){0} -~  (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl;
     110        for ( s; (S){0} -~= (S){10,10} ) { sout | s; } else { sout | "else"; }           sout | nl;
     111        for ( s; (S){0} -~= (S){10,10} ~ (S){1} ) { sout | s; } else { sout | "else"; } sout | nl | nl;
    110112}
  • tests/loopctrl.cfa

    r62c5a55 r181036c  
    1010// Created On       : Wed Aug  8 18:32:59 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Dec 12 17:55:26 2019
    13 // Update Count     : 108
     12// Last Modified On : Thu Aug 11 23:04:35 2022
     13// Update Count     : 160
    1414//
    1515
    1616#include <fstream.hfa>
     17
     18void fred() {
     19        // Test all possible loop syntax.
     20
     21        int s = 0, c = 10, i = 2;
     22
     23        for ( c ) { sout | "A"; }                                               sout | nl;
     24        for ( ~= c ) { sout | "B"; }                                    sout | nl;
     25        for ( -~ c ) { sout | "C"; }                                    sout | nl;
     26        for ( -~= c ) { sout | "D"; }                                   sout | nl;
     27
     28        for ( s ~ c ) { sout | "A"; }                                   sout | nl;
     29        for ( s ~= c ) { sout | "B"; }                                  sout | nl;
     30        for ( s -~ c ) { sout | "C"; }                                  sout | nl;
     31        for ( s -~= c ) { sout | "D"; }                                 sout | nl;
     32
     33        for ( s ~ c ~ i ) { sout | "A"; }                               sout | nl;
     34        for ( s ~= c ~ i ) { sout | "B"; }                              sout | nl;
     35        for ( s -~ c ~ i ) { sout | "C"; }                              sout | nl;
     36        for ( s -~= c ~ i ) { sout | "D"; }                             sout | nl;
     37
     38        for ( j; c ) { sout | j; }                                                      sout | nl;
     39        for ( j; ~= c ) { sout | j; }                                   sout | nl;
     40        for ( j; -~ c ) { sout | j; }                                   sout | nl;
     41        for ( j; -~= c ) { sout | j; }                                  sout | nl;
     42
     43        for ( j; s ~ c ) { sout | j; }                                  sout | nl;
     44        for ( j; s ~= c ) { sout | j; }                                 sout | nl;
     45        for ( j; s -~ c ) { sout | j; }                                 sout | nl;
     46        for ( j; s -~= c ) { sout | j; }                                sout | nl;
     47
     48        for ( j; s ~ c ~ i ) { sout | j; }                              sout | nl;
     49        for ( j; s ~= c ~ i ) { sout | j; }                             sout | nl;
     50        for ( j; s -~ c ~ i ) { sout | j; }                             sout | nl;
     51        for ( j; s -~= c ~ i ) { sout | j; }                    sout | nl;
     52
     53        // CANNOT DIRECTLY INITIALIZE INDEX VARIABLE, ONLY SINGLE LOOP INDEX VARIABLE IN DECLARATION
     54
     55        for ( j; c ) { sout | j; }                                              sout | nl;
     56        for ( int j; c ) { sout | j; }                                  sout | nl;
     57        for ( int j; ~= c ) { sout | j; }                               sout | nl;
     58        for ( int j; -~ c ) { sout | j; }                               sout | nl;
     59        for ( int j; -~= c ) { sout | j; }                              sout | nl;
     60
     61        for ( int j; s ~ c ) { sout | j; }                              sout | nl;
     62        for ( int j; s ~= c ) { sout | j; }                             sout | nl;
     63        for ( int j; s -~ c ) { sout | j; }                             sout | nl;
     64        for ( int j; s -~= c ) { sout | j; }                    sout | nl;
     65
     66        for ( int j; s ~ c ~ i ) { sout | j; }                  sout | nl;
     67        for ( int j; s ~= c ~ i ) { sout | j; }                 sout | nl;
     68        for ( int j; s -~ c ~ i ) { sout | j; }                 sout | nl;
     69        for ( int j; s -~= c ~ i ) { sout | j; }                sout | nl;
     70
     71        for ( j; s ~ @ ) { if ( j == 10 ) break; sout | j; }                            sout | nl;
     72        for ( j; @ -~ s ) { if ( j == -10 ) break; sout | j; }                          sout | nl;
     73        for ( j; s ~ @ ~ i ) { if ( j == 10 ) break; sout | j; }                        sout | nl;
     74        for ( j; @ -~ s ~ i ) { if ( j == -10 ) break; sout | j; }                      sout | nl;
     75        for ( j; s ~ @ ~ @ ) { if ( j == 10 ) break; sout | j; j += 1; }        sout | nl;
     76
     77        for ( int j; s ~ @ ) { if ( j == 10 ) break; sout | j; j += 1; }        sout | nl;
     78        for ( int j; @ -~ s ) { if ( j == -10 ) break; sout | j; j -= 1; }      sout | nl;
     79        for ( int j; s ~ @ ~ i ) { if ( j == 10 ) break; sout | j; }            sout | nl;
     80        for ( int j; @ -~ s ~ i ) { if ( j == -10 ) break; sout | j; }          sout | nl;
     81        for ( int j; s ~ @ ~ @ ) { if ( j == 10 ) break; sout | j; j += 1; } sout | nl;
     82
     83        // enum E { A, B, C, D };
     84        // for ( e; A ~= C ) { sout | j; }
     85        // for ( e; A ~= D ) { sout | j; }
     86        // for ( e; A -~= D ~ 2 ) { sout | j; }
     87        // for ( e; E ) { sout | j; }
     88        // for ( e; -~ E ) { sout | j; }
     89}
    1790
    1891struct S { int i, j; };
     
    35108
    36109int main() {
     110        // Test some loop options.
     111
    37112        sout | nlOff;                                                                           // turn off auto newline
    38113        while () { sout | "empty"; break; }                                     sout | nl;
     
    43118        for ( 1 ) { sout | "A"; }                                                       sout | nl;
    44119        for ( 10 ) { sout | "A"; }                                                      sout | nl;
    45         for ( = 10 ) { sout | "A"; }                                            sout | nl;
     120        for ( ~= 10 ) { sout | "A"; }                                           sout | nl;
    46121        for ( 1 ~= 10 ~ 2 ) { sout | "B"; }                                     sout | nl;
    47         for ( 10 -~= 1 ~ 2 ) { sout | "C"; }                            sout | nl;
     122        for ( 1 -~= 10 ~ 2 ) { sout | "C"; }                            sout | nl;
    48123        for ( 0.5 ~ 5.5 ) { sout | "D"; }                                       sout | nl;
    49         for ( 5.5 -~ 0.5 ) { sout | "E"; }                                      sout | nl | nl;
     124        for ( 0.5 -~ 5.5 ) { sout | "E"; }                                      sout | nl | nl;
    50125
    51126        for ( i; 10 ) { sout | i; }                                                     sout | nl;
    52         for ( i; = 10 ) { sout | i; }                                           sout | nl;
     127        for ( i; ~= 10 ) { sout | i; }                                          sout | nl;
    53128        for ( i; 1 ~= 10 ~ 2 ) { sout | i; }                            sout | nl;
    54         for ( i; 10 -~= 1 ~ 2 ) { sout | i; }                           sout | nl;
     129        for ( i; 1 -~= 10 ~ 2 ) { sout | i; }                           sout | nl;
    55130        for ( i; 0.5 ~ 5.5 ) { sout | i; }                                      sout | nl;
    56         for ( i; 5.5 -~ 0.5 ) { sout | i; }                                     sout | nl;
     131        for ( i; 0.5 -~ 5.5 ) { sout | i; }                                     sout | nl;
    57132        for ( ui; 2u ~= 10u ~ 2u ) { sout | ui; }                       sout | nl;
    58         for ( ui; 10u -~= 2u ~ 2u ) { sout | ui; }                      sout | nl | nl;
     133        for ( ui; 2u -~= 10u ~ 2u ) { sout | ui; }                      sout | nl | nl;
    59134
    60135        // @ means do nothing
     
    63138                sout | i;
    64139        }                                                                                                       sout | nl;
    65         for ( i; 10 -~ @ ) {
     140        for ( i; @ -~ 10 ) {
    66141          if ( i < 0 ) break;
    67142                sout | i;
     
    76151                i += 1.7;
    77152        }                                                                                                       sout | nl;
    78         for ( i; 10 -~ @ ~ 2 ) {
     153        for ( i; @ -~ 10 ~ 2 ) {
    79154          if ( i < 0 ) break;
    80155                sout | i;
     
    89164        for ( N ) { sout | "N"; }                                                       sout | nl;
    90165        for ( i; N ) { sout | i; }                                                      sout | nl;
    91         for ( i; = N ) { sout | i; }                                            sout | nl;
    92         for ( i; N -~ 0 ) { sout | i; }                                         sout | nl | nl;
     166        for ( i; ~= N ) { sout | i; }                                           sout | nl;
     167        for ( i; -~= N ) { sout | i; }                                          sout | nl | nl;
    93168
    94169        const int start = 3, comp = 10, inc = 2;
    95170        for ( i; start ~ comp ~ inc + 1 ) { sout | i; }         sout | nl | nl;
     171
     172        for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } sout | nl;
     173        for ( i; 10 : j; @ -~ -5 ) { sout | i | j; } sout | nl;
     174        for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } sout | nl;
     175        for ( i; 10 : j; @ -~ -5 ~ 2 ) { sout | i | j; } sout | nl | nl;
     176
     177        for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } sout | nl;
     178        for ( j; @ -~ -5 : i; 10 ) { sout | i | j; } sout | nl;
     179        for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl;
     180        for ( j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j; } sout | nl | nl;
     181
     182        for ( j; @ -~ -5 ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } sout | nl;
     183        for ( j; @ -~ -5 ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } sout | nl;
     184        for ( k; 1.5 ~ @ : j; @ -~ -5 ~ 2 : i; 10 ) { sout | i | j | k; } sout | nl;
    96185
    97186        for ( S s = (S){0}; s < (S){10,10}; s += (S){1} ) { sout | s; } sout | nl;
     
    103192        for ( s; (S){0} ~= (S){10,10} ~ (S){1} ) { sout | s; } sout | nl;
    104193        sout | nl;
    105         for ( s; (S){10,10} -~ (S){0} ) { sout | s; }            sout | nl;
    106         for ( s; (S){10,10} -~ (S){0} ~ (S){1} ) { sout | s; } sout | nl;
    107         for ( s; (S){10,10} -~= (S){0} ) { sout | s; }           sout | nl;
    108         for ( s; (S){10,10} -~= (S){0} ~ (S){1} ) { sout | s; } sout | nl | nl;
    109 
    110         for ( i; 10 : j; -5 ~ @ ) { sout | i | j; } sout | nl;
    111         for ( i; 10 : j; -5 -~ @ ) { sout | i | j; } sout | nl;
    112         for ( i; 10 : j; -5 ~ @ ~ 2 ) { sout | i | j; } sout | nl;
    113         for ( i; 10 : j; -5 -~ @ ~ 2 ) { sout | i | j; } sout | nl | nl;
    114 
    115         for ( j; -5 ~ @ : i; 10 ) { sout | i | j; } sout | nl;
    116         for ( j; -5 -~ @ : i; 10 ) { sout | i | j; } sout | nl;
    117         for ( j; -5 ~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl;
    118         for ( j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j; } sout | nl | nl;
    119 
    120         for ( j; -5 -~ @ ~ 2 : i; 10 : k; 1.5 ~ @ ) { sout | i | j | k; } sout | nl;
    121         for ( j; -5 -~ @ ~ 2 : k; 1.5 ~ @ : i; 10 ) { sout | i | j | k; } sout | nl;
    122         for ( k; 1.5 ~ @ : j; -5 -~ @ ~ 2 : i; 10 ) { sout | i | j | k; } sout | nl;
     194        for ( s; (S){0} -~  (S){10,10} ) { sout | s; }           sout | nl;
     195        for ( s; (S){0} -~  (S){10,10} ~ (S){1} ) { sout | s; } sout | nl;
     196        for ( s; (S){0} -~= (S){10,10} ) { sout | s; }           sout | nl;
     197        for ( s; (S){0} -~= (S){10,10} ~ (S){1} ) { sout | s; } sout | nl | nl;
     198
     199        fred();
    123200}
    124201
Note: See TracChangeset for help on using the changeset viewer.