Changeset 7f6a7c9 for src/Parser


Ignore:
Timestamp:
Sep 21, 2022, 11:02:15 AM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation
Children:
95dab9e
Parents:
428adbc (diff), 0bd46fd (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' into pthread-emulation

Location:
src/Parser
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r428adbc r7f6a7c9  
    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;
     
    253254} // DeclarationNode::newAggregate
    254255
    255 DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, DeclarationNode * base) {
     256DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base) {
    256257        DeclarationNode * newnode = new DeclarationNode;
    257258        newnode->type = new TypeData( TypeData::Enum );
     
    260261        newnode->type->enumeration.body = body;
    261262        newnode->type->enumeration.anon = name == nullptr;
     263        newnode->type->enumeration.typed = typed;
    262264        if ( base && base->type)  {
    263                 newnode->type->base = base->type;       
    264         } // if
    265 
    266         // Check: if base has TypeData
     265                newnode->type->base = base->type;
     266        } // if
     267
    267268        return newnode;
    268269} // DeclarationNode::newEnum
     
    284285
    285286DeclarationNode * DeclarationNode::newEnumValueGeneric( const string * name, InitializerNode * init ) {
    286         if ( init ) { // list init {} or a singleInit
    287                 if ( init->get_expression() ) { // singleInit
     287        if ( init ) {
     288                if ( init->get_expression() ) {
    288289                        return newEnumConstant( name, init->get_expression() );
    289                 } else { // TODO: listInit
     290                } else {
    290291                        DeclarationNode * newnode = newName( name );
    291292                        newnode->initializer = init;
     
    293294                } // if
    294295        } else {
    295                 return newName( name ); // Not explicitly inited enum value;
     296                return newName( name );
    296297        } // if
    297298} // DeclarationNode::newEnumValueGeneric
     
    504505                        } // for
    505506                        // src is the new item being added and has a single bit
    506                 } else if ( ! src->storageClasses.is_threadlocal ) { // conflict ?
     507                } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ?
    507508                        appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] +
    508509                                                 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] );
     
    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/ExpressionNode.cc

    r428adbc r7f6a7c9  
    509509} // build_varref
    510510
     511QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) {
     512        Declaration * newDecl = maybeBuild< Declaration >(decl_node);
     513        if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) {
     514                const Type * t = newDeclWithType->get_type();
     515                if ( t ) {
     516                        if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) {
     517                                newDecl= new EnumDecl( typeInst->name );
     518                        }
     519                }
     520        }
     521        auto ret =  new QualifiedNameExpr( newDecl, name->name );
     522        if ( auto e = dynamic_cast<EnumDecl*>(newDecl) ) {
     523                auto enumInst = new EnumInstType( Type::Qualifiers(), e );
     524                auto obj = new ObjectDecl( name->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, enumInst, nullptr );
     525                ret->set_var( obj );
     526        }
     527        return ret;
     528}
     529
     530QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) {
     531        EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node );
     532        return new QualifiedNameExpr( newDecl, name->name );
     533}
     534
    511535DimensionExpr * build_dimensionref( const string * name ) {
    512536        DimensionExpr * expr = new DimensionExpr( *name );
  • src/Parser/ParseNode.h

    r428adbc r7f6a7c9  
    183183
    184184NameExpr * build_varref( const std::string * name );
     185QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
     186QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
    185187DimensionExpr * build_dimensionref( const std::string * name );
    186188
     
    235237        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    236238        static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
    237         static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, DeclarationNode * base = nullptr );
     239        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr );
    238240        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
    239241        static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
  • src/Parser/TypeData.cc

    r428adbc r7f6a7c9  
    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:
     
    548546                return buildAggInst( td );
    549547          case TypeData::EnumConstant:
    550                 // the name gets filled in later -- by SymTab::Validate
    551548                return new EnumInstType( buildQualifiers( td ), "" );
    552549          case TypeData::SymbolicInst:
     
    923920        assert( td->kind == TypeData::Enum );
    924921        Type * baseType = td->base ? typebuild(td->base) : nullptr;
    925         EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, linkage, baseType );
     922        EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType );
    926923        buildList( td->enumeration.constants, ret->get_members() );
    927924        list< Declaration * >::iterator members = ret->get_members().begin();
    928925        for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
    929                 if ( cur->has_enumeratorValue() ) {
     926                if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
     927                        SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
     928                } else if ( cur->has_enumeratorValue() ) {
    930929                        ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
    931930                        member->set_init( new SingleInit( maybeMoveBuild< Expression >( cur->consume_enumeratorValue() ) ) );
    932931                } else if ( !cur->initializer ) {
    933932                        if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isWholeNumber())) {
    934                                 SemanticError( td->location, "A non whole number enum value decl must be explicitly initialized." );
     933                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
    935934                        }
    936935                }
  • src/Parser/TypeData.h

    r428adbc r7f6a7c9  
    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 {
     
    5959                bool body;
    6060                bool anon;
     61                bool typed;
    6162        };
    6263
  • src/Parser/TypedefTable.cc

    r428adbc r7f6a7c9  
    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/lex.ll

    r428adbc r7f6a7c9  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Sun Jun 20 18:41:09 2021
    13  * Update Count     : 759
     12 * Last Modified On : Tue Sep 20 21:18:55 2022
     13 * Update Count     : 762
    1414 */
    1515
     
    2424
    2525//**************************** Includes and Defines ****************************
     26
     27#ifdef __clang__
     28#pragma GCC diagnostic ignored "-Wnull-conversion"
     29#endif
    2630
    2731// trigger before each matching rule's action
     
    8286// Stop warning due to incorrectly generated flex code.
    8387#pragma GCC diagnostic ignored "-Wsign-compare"
    84 
    85 // lex uses __null in a boolean context, it's fine.
    86 #pragma GCC diagnostic ignored "-Wnull-conversion"
    8788%}
    8889
     
    314315switch                  { KEYWORD_RETURN(SWITCH); }
    315316thread                  { KEYWORD_RETURN(THREAD); }                             // C11
    316 _Thread_local   { KEYWORD_RETURN(THREADLOCAL); }                // C11
     317__thread                { KEYWORD_RETURN(THREADLOCALGCC); }             // GCC
     318_Thread_local   { KEYWORD_RETURN(THREADLOCALC11); }             // C11
    317319throw                   { KEYWORD_RETURN(THROW); }                              // CFA
    318320throwResume             { KEYWORD_RETURN(THROWRESUME); }                // CFA
  • src/Parser/parser.yy

    r428adbc r7f6a7c9  
    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 : Sat Aug 27 13:21:28 2022
     13// Update Count     : 5661
    1414//
    1515
     
    5858
    5959// lex uses __null in a boolean context, it's fine.
     60#ifdef __clang__
    6061#pragma GCC diagnostic ignored "-Wparentheses-equality"
     62#endif
    6163
    6264extern DeclarationNode * parseTree;
     
    197199} // fieldDecl
    198200
     201#define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
     202#define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
     203#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
     204#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     205#define MISSING_LOW "Missing low value for up-to range so index is uninitialized."
     206#define MISSING_HIGH "Missing high value for down-to range so index is uninitialized."
     207
     208ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     209        if ( index->initializer ) {
     210                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     211        } // if
     212        if ( index->next ) {
     213                SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
     214        } // if
     215        return new ForCtrl( index->addInitializer( new InitializerNode( start ) ),
     216                // NULL comp/inc => leave blank
     217                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr,
     218                inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
     219                                                        OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr );
     220} // forCtrl
     221
    199222ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    200223        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
     
    206229                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
    207230                // NULL comp/inc => leave blank
    208                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,
     231                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr,
    209232                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 );
     233                                                        OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr );
    211234} // forCtrl
    212235
     
    272295%token TYPEDEF
    273296%token EXTERN STATIC AUTO REGISTER
    274 %token THREADLOCAL                                                                              // C11
     297%token THREADLOCALGCC THREADLOCALC11                                            // GCC, C11
    275298%token INLINE FORTRAN                                                                   // C99, extension ISO/IEC 9899:1999 Section J.5.9(1)
    276299%token NORETURN                                                                                 // C11
     
    346369%type<ifctl> conditional_declaration
    347370%type<fctl> for_control_expression              for_control_expression_list
    348 %type<compop> inclexcl
     371%type<compop> updown updowneq downupdowneq
    349372%type<en> subrange
    350373%type<decl> asm_name_opt
     
    614637                { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild<Statement>($2) ) ) ); }
    615638        | type_name '.' identifier                                                      // CFA, nested type
    616                 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     639                { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
    617640        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    618641                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    12391262iteration_statement:
    12401263        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 ) ) ); }
     1264                { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
    12421265        | WHILE '(' ')' statement ELSE statement                        // CFA
    12431266                {
    1244                         $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) );
     1267                        $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
    12451268                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12461269                }
     
    12501273                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
    12511274        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1252                 { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }
     1275                { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
    12531276        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    12541277                {
    1255                         $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );
     1278                        $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
    12561279                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12571280                }
     
    13041327                { $$ = new ForCtrl( $1, $2, $4 ); }
    13051328
    1306         | 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 ); }
     1329        | '@' ';' comma_expression                                                      // CFA, empty loop-index
     1330                { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, nullptr ); }
     1331        | '@' ';' comma_expression ';' comma_expression         // CFA, empty loop-index
     1332                { $$ = new ForCtrl( (ExpressionNode *)nullptr, $3, $5 ); }
     1333
     1334        | comma_expression                                                                      // CFA, anonymous loop-index
     1335                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
     1336        | downupdowneq comma_expression                                         // CFA, anonymous loop-index
     1337                { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
     1338
     1339        | comma_expression updowneq comma_expression            // CFA, anonymous loop-index
     1340                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
     1341        | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
     1342                {
     1343                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     1344                        else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
     1345                }
     1346        | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
     1347                {
     1348                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
     1349                        else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
     1350                }
     1351        | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
     1352                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
     1353        | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
     1354                {
     1355                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     1356                        else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
     1357                }
     1358        | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
     1359                {
     1360                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
     1361                        else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
     1362                }
     1363        | comma_expression updowneq comma_expression '~' '@' // CFA, error
     1364                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
     1365        | '@' updowneq '@'                                                                      // CFA, error
     1366                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
     1367        | '@' updowneq comma_expression '~' '@'                         // CFA, error
     1368                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
     1369        | comma_expression updowneq '@' '~' '@'                         // CFA, error
     1370                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
     1371        | '@' updowneq '@' '~' '@'                                                      // CFA, error
     1372                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
     1373
    13181374        | 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 ); }
     1375                { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1376        | comma_expression ';' downupdowneq comma_expression // CFA
     1377                { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
     1378
     1379        | comma_expression ';' comma_expression updowneq comma_expression // CFA
     1380                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
     1381        | comma_expression ';' '@' updowneq comma_expression // CFA
     1382                {
     1383                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     1384                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1385                }
     1386        | comma_expression ';' comma_expression updowneq '@' // CFA
     1387                {
     1388                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
     1389                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1390                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
     1391                }
     1392        | comma_expression ';' '@' updowneq '@'                         // CFA, error
     1393                { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1394
     1395        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
     1396                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
     1397        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
     1398                {
     1399                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     1400                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
     1401                }
     1402        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
     1403                {
     1404                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
     1405                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1406                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
     1407                }
     1408        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
     1409                { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
     1410        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
     1411                {
     1412                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     1413                        else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
     1414                }
     1415        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
     1416                {
     1417                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
     1418                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1419                        else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
     1420                }
     1421        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
     1422                { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
     1423
     1424        | declaration comma_expression                                          // CFA
     1425                { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1426        | declaration downupdowneq comma_expression                     // CFA
     1427                { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
     1428
     1429        | declaration comma_expression updowneq comma_expression // CFA
     1430                { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
     1431        | declaration '@' updowneq comma_expression                     // CFA
     1432                {
     1433                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     1434                        else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
     1435                }
     1436        | declaration comma_expression updowneq '@'                     // CFA
     1437                {
     1438                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
     1439                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1440                        else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
     1441                }
     1442
     1443        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
     1444                { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
     1445        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
     1446                {
     1447                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     1448                        else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
     1449                }
     1450        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
     1451                {
     1452                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
     1453                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1454                        else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
     1455                }
     1456        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
     1457                { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
     1458        | declaration '@' updowneq comma_expression '~' '@' // CFA
     1459                {
     1460                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     1461                        else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
     1462                }
     1463        | declaration comma_expression updowneq '@' '~' '@'     // CFA
     1464                {
     1465                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
     1466                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
     1467                        else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
     1468                }
     1469        | declaration '@' updowneq '@' '~' '@'                          // CFA, error
     1470                { SemanticError( yylloc, "Missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    13281471
    13291472        | comma_expression ';' TYPEDEFname                                      // CFA, array type
    13301473                {
    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 ); }
     1474                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
     1475                        //$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
     1476                }
     1477        | comma_expression ';' downupdowneq TYPEDEFname         // CFA, array type
     1478                {
     1479                        if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; }
     1480                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
     1481                }
    13461482        ;
    13471483
    1348 inclexcl:
     1484downupdowneq:
     1485        ErangeDown
     1486                { $$ = OperKinds::GThan; }
     1487        | ErangeUpEq
     1488                { $$ = OperKinds::LEThan; }
     1489        | ErangeDownEq
     1490                { $$ = OperKinds::GEThan; }
     1491        ;
     1492
     1493updown:
    13491494        '~'
    13501495                { $$ = OperKinds::LThan; }
     1496        | ErangeDown
     1497                { $$ = OperKinds::GThan; }
     1498        ;
     1499
     1500updowneq:
     1501        updown
    13511502        | ErangeUpEq
    13521503                { $$ = OperKinds::LEThan; }
    1353         | ErangeDown
    1354                 { $$ = OperKinds::GThan; }
    13551504        | ErangeDownEq
    13561505                { $$ = OperKinds::GEThan; }
     
    19352084        | REGISTER
    19362085                { $$ = DeclarationNode::newStorageClass( Type::Register ); }
    1937         | THREADLOCAL                                                                           // C11
    1938                 { $$ = DeclarationNode::newStorageClass( Type::Threadlocal ); }
     2086        | THREADLOCALGCC                                                                                // GCC
     2087                { $$ = DeclarationNode::newStorageClass( Type::ThreadlocalGcc ); }
     2088        | THREADLOCALC11                                                                                // C11
     2089                { $$ = DeclarationNode::newStorageClass( Type::ThreadlocalC11 ); }
    19392090                // Put function specifiers here to simplify parsing rules, but separate them semantically.
    19402091        | INLINE                                                                                        // C99
     
    23872538enum_type:
    23882539        ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
    2389                 { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }
     2540                { $$ = DeclarationNode::newEnum( nullptr, $4, true, false )->addQualifiers( $2 ); }
    23902541        | ENUM attribute_list_opt identifier
    23912542                { typedefTable.makeTypedef( *$3 ); }
    23922543          '{' enumerator_list comma_opt '}'
    2393                 { $$ = DeclarationNode::newEnum( $3, $6, true )->addQualifiers( $2 ); }
     2544                { $$ = DeclarationNode::newEnum( $3, $6, true, false )->addQualifiers( $2 ); }
    23942545        | ENUM attribute_list_opt typedef_name                          // unqualified type name
    23952546          '{' enumerator_list comma_opt '}'
    2396                 { $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); }
     2547                { $$ = DeclarationNode::newEnum( $3->name, $5, true, false )->addQualifiers( $2 ); }
    23972548        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    23982549                {
     
    24002551                        { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    24012552
    2402                         $$ = DeclarationNode::newEnum( nullptr, $7, true, $3 )->addQualifiers( $5 );
     2553                        $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 );
     2554                }
     2555        | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
     2556                {
     2557                        $$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 );
    24032558                }
    24042559        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
     
    24092564          '{' enumerator_list comma_opt '}'
    24102565                {
    2411                         $$ = DeclarationNode::newEnum( $6, $10, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
     2566                        $$ = DeclarationNode::newEnum( $6, $10, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
     2567                }
     2568        | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt
     2569          '{' enumerator_list comma_opt '}'
     2570                {
     2571                        $$ = DeclarationNode::newEnum( $5, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );
    24122572                }
    24132573        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}'
    24142574                {
    2415                         if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }
    2416                         typedefTable.makeTypedef( *$6->name );
    2417                         $$ = DeclarationNode::newEnum( $6->name, $9, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
     2575                        $$ = DeclarationNode::newEnum( $6->name, $9, true, true, $3 )->addQualifiers( $5 )->addQualifiers( $7 );
     2576                }
     2577        | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}'
     2578                {
     2579                        $$ = DeclarationNode::newEnum( $5->name, $8, true, true, nullptr )->addQualifiers( $4 )->addQualifiers( $6 );
    24182580                }
    24192581        | enum_type_nobody
     
    24222584enum_type_nobody:                                                                               // enum - {...}
    24232585        ENUM attribute_list_opt identifier
    2424                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 ); }
    2425         | ENUM attribute_list_opt type_name                                     // qualified type name
    2426                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 ); }
     2586                { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false, false )->addQualifiers( $2 ); }
     2587        | ENUM attribute_list_opt type_name
     2588                { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false, false )->addQualifiers( $2 ); }
    24272589        ;
    24282590
Note: See TracChangeset for help on using the changeset viewer.