Changeset cde3891 for src/Parser


Ignore:
Timestamp:
Jan 23, 2019, 4:52:16 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
a200795
Parents:
9b086ca (diff), 1d832f4 (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 cleanup-dtors

Location:
src/Parser
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r9b086ca rcde3891  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 20 14:56:54 2018
    13 // Update Count     : 1107
     12// Last Modified On : Thu Nov  1 20:54:26 2018
     13// Update Count     : 1108
    1414//
    1515
     
    402402}
    403403
    404 DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr ) {
    405         DeclarationNode * newnode = new DeclarationNode;
    406         newnode->type = new TypeData( TypeData::Typeof );
     404DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr, bool basetypeof ) {
     405        DeclarationNode * newnode = new DeclarationNode;
     406        newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof );
    407407        newnode->type->typeexpr = expr;
    408408        return newnode;
  • src/Parser/LinkageSpec.cc

    r9b086ca rcde3891  
    1010// Created On       : Sat May 16 13:22:09 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul  7 11:11:00 2017
    13 // Update Count     : 25
     12// Last Modified On : Thr Spt 12 15:59:00 2018
     13// Update Count     : 26
    1414//
    1515
     
    2323
    2424namespace LinkageSpec {
    25 
    26 Spec linkageCheck( CodeLocation location, const string * spec ) {
    27         assert( spec );
    28         unique_ptr<const string> guard( spec ); // allocated by lexer
    29         if ( *spec == "\"Cforall\"" ) {
    30                 return Cforall;
    31         } else if ( *spec == "\"C\"" ) {
    32                 return C;
    33         } else if ( *spec == "\"BuiltinC\"" ) {
    34                 return BuiltinC;
    35         } else {
    36                 SemanticError( location, "Invalid linkage specifier " + *spec );
    37         } // if
    38 }
    3925
    4026Spec linkageUpdate( CodeLocation location, Spec old_spec, const string * cmd ) {
  • src/Parser/LinkageSpec.h

    r9b086ca rcde3891  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:24:28 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul  2 07:46:49 2018
    13 // Update Count     : 16
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Spt 13 15:59:00 2018
     13// Update Count     : 17
    1414//
    1515
     
    4141
    4242
    43         Spec linkageCheck( CodeLocation location, const std::string * );
    44         // Returns the Spec with the given name (limited to C, Cforall & BuiltinC)
    4543        Spec linkageUpdate( CodeLocation location, Spec old_spec, const std::string * cmd );
    4644        /* If cmd = "C" returns a Spec that is old_spec with is_mangled = false
  • src/Parser/ParseNode.h

    r9b086ca rcde3891  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug  4 09:39:40 2018
    13 // Update Count     : 853
     12// Last Modified On : Thu Nov  1 20:54:53 2018
     13// Update Count     : 854
    1414//
    1515
     
    249249        static DeclarationNode * newBitfield( ExpressionNode * size );
    250250        static DeclarationNode * newTuple( DeclarationNode * members );
    251         static DeclarationNode * newTypeof( ExpressionNode * expr );
     251        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
    252252        static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
    253253        static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
  • src/Parser/TypeData.cc

    r9b086ca rcde3891  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 20 14:39:31 2018
    13 // Update Count     : 622
     12// Last Modified On : Fri Nov  2 07:54:26 2018
     13// Update Count     : 624
    1414//
    1515
     
    9696                break;
    9797          case Typeof:
     98          case Basetypeof:
    9899                // typeexpr = new Typeof_t;
    99100                typeexpr = nullptr;
     
    166167                break;
    167168          case Typeof:
     169          case Basetypeof:
    168170                // delete typeexpr->expr;
    169171                delete typeexpr;
     
    245247                break;
    246248          case Typeof:
     249          case Basetypeof:
    247250                newtype->typeexpr = maybeClone( typeexpr );
    248251                break;
     
    319322                        function.params->printList( os, indent + 4 );
    320323                } else {
    321                         os << string( indent + 2, ' ' ) << "with no parameters " << endl;
     324                        os << string( indent + 2, ' ' ) << "with no parameters" << endl;
    322325                } // if
    323326                if ( function.idList ) {
     
    344347                os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl;
    345348                if ( aggregate.params ) {
    346                         os << string( indent + 2, ' ' ) << "with type parameters " << endl;
     349                        os << string( indent + 2, ' ' ) << "with type parameters" << endl;
    347350                        aggregate.params->printList( os, indent + 4 );
    348351                } // if
    349352                if ( aggregate.actuals ) {
    350                         os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
     353                        os << string( indent + 2, ' ' ) << "instantiated with actual parameters" << endl;
    351354                        aggregate.actuals->printList( os, indent + 4 );
    352355                } // if
    353356                if ( aggregate.fields ) {
    354                         os << string( indent + 2, ' ' ) << "with members " << endl;
     357                        os << string( indent + 2, ' ' ) << "with members" << endl;
    355358                        aggregate.fields->printList( os, indent + 4 );
    356359                } // if
    357360                if ( aggregate.body ) {
    358                         os << string( indent + 2, ' ' ) << " with body " << endl;
     361                        os << string( indent + 2, ' ' ) << " with body" << endl;
    359362                } // if
    360363                break;
     
    367370                } // if
    368371                if ( aggInst.params ) {
    369                         os << string( indent + 2, ' ' ) << "with parameters " << endl;
     372                        os << string( indent + 2, ' ' ) << "with parameters" << endl;
    370373                        aggInst.params->printList( os, indent + 2 );
    371374                } // if
     
    378381                } // if
    379382                if ( enumeration.body ) {
    380                         os << string( indent + 2, ' ' ) << " with body " << endl;
     383                        os << string( indent + 2, ' ' ) << " with body" << endl;
    381384                } // if
    382385                break;
     
    415418                os << "tuple ";
    416419                if ( tuple ) {
    417                         os << "with members " << endl;
     420                        os << "with members" << endl;
    418421                        tuple->printList( os, indent + 2 );
    419422                } // if
    420423                break;
     424          case Basetypeof:
     425                os << "base-";
     426                #if defined(__GNUC__) && __GNUC__ >= 7
     427                        __attribute__((fallthrough));
     428                #endif
    421429          case Typeof:
    422430                os << "type-of expression ";
     
    457465          case Tuple:
    458466          case Typeof:
     467          case Basetypeof:
    459468          case Builtin:
    460469                assertf(false, "Tried to get leaf name from kind without a name: %d", kind);
     
    513522        switch ( td->kind ) {
    514523          case TypeData::Unknown:
    515                 // fill in implicit int
    516                 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
     524                        // fill in implicit int
     525                        return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
    517526          case TypeData::Basic:
    518                 return buildBasicType( td );
     527                        return buildBasicType( td );
    519528          case TypeData::Pointer:
    520                 return buildPointer( td );
     529                        return buildPointer( td );
    521530          case TypeData::Array:
    522                 return buildArray( td );
     531                        return buildArray( td );
    523532          case TypeData::Reference:
    524                 return buildReference( td );
     533                        return buildReference( td );
    525534          case TypeData::Function:
    526                 return buildFunction( td );
     535                        return buildFunction( td );
    527536          case TypeData::AggregateInst:
    528                 return buildAggInst( td );
     537                        return buildAggInst( td );
    529538          case TypeData::EnumConstant:
    530                 // the name gets filled in later -- by SymTab::Validate
    531                 return new EnumInstType( buildQualifiers( td ), "" );
     539                        // the name gets filled in later -- by SymTab::Validate
     540                        return new EnumInstType( buildQualifiers( td ), "" );
    532541          case TypeData::SymbolicInst:
    533                 return buildSymbolicInst( td );
     542                        return buildSymbolicInst( td );
    534543          case TypeData::Tuple:
    535                 return buildTuple( td );
     544                        return buildTuple( td );
    536545          case TypeData::Typeof:
    537                 return buildTypeof( td );
     546          case TypeData::Basetypeof:
     547                        return buildTypeof( td );
    538548          case TypeData::Builtin:
    539                 if(td->builtintype == DeclarationNode::Zero) {
    540                         return new ZeroType( noQualifiers );
    541                 }
    542                 else if(td->builtintype == DeclarationNode::One) {
    543                         return new OneType( noQualifiers );
    544                 }
    545                 else {
    546                         return new VarArgsType( buildQualifiers( td ) );
    547                 }
     549                        if (td->builtintype == DeclarationNode::Zero) {
     550                                return new ZeroType( noQualifiers );
     551                        }
     552                        else if (td->builtintype == DeclarationNode::One) {
     553                                return new OneType( noQualifiers );
     554                        }
     555                        else {
     556                                return new VarArgsType( buildQualifiers( td ) );
     557                        }
    548558          case TypeData::GlobalScope:
    549                 return new GlobalScopeType();
     559                        return new GlobalScopeType();
    550560                case TypeData::Qualified:
    551                 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
     561                        return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
    552562          case TypeData::Symbolic:
    553563          case TypeData::Enum:
    554564          case TypeData::Aggregate:
    555                 assert( false );
     565                        assert( false );
    556566        } // switch
    557567
     
    929939
    930940TypeofType * buildTypeof( const TypeData * td ) {
    931         assert( td->kind == TypeData::Typeof );
     941        assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
    932942        assert( td->typeexpr );
    933943        // assert( td->typeexpr->expr );
    934         return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
     944        return new TypeofType{
     945                buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof };
    935946} // buildTypeof
    936947
  • src/Parser/TypeData.h

    r9b086ca rcde3891  
    1010// Created On       : Sat May 16 15:18:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 20 13:56:40 2018
    13 // Update Count     : 195
     12// Last Modified On : Thu Nov  1 20:56:46 2018
     13// Update Count     : 196
    1414//
    1515
     
    2727struct TypeData {
    2828        enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
    29                                 SymbolicInst, Tuple, Typeof, Builtin, GlobalScope, Qualified, Unknown };
     29                                SymbolicInst, Tuple, Typeof, Basetypeof, Builtin, GlobalScope, Qualified, Unknown };
    3030
    3131        struct Aggregate_t {
  • src/Parser/lex.ll

    r9b086ca rcde3891  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Wed Aug  8 17:23:17 2018
    13  * Update Count     : 685
     12 * Last Modified On : Thu Nov  1 20:57:35 2018
     13 * Update Count     : 687
    1414 */
    1515
     
    209209__attribute__   { KEYWORD_RETURN(ATTRIBUTE); }                  // GCC
    210210auto                    { KEYWORD_RETURN(AUTO); }
     211basetypeof              { KEYWORD_RETURN(BASETYPEOF); }                 // CFA
    211212_Bool                   { KEYWORD_RETURN(BOOL); }                               // C99
    212213break                   { KEYWORD_RETURN(BREAK); }
     
    410411">>="                   { NAMEDOP_RETURN(RSassign); }
    411412
    412 "~="                    { NAMEDOP_RETURN(Erange); }                             // CFA
    413413"@="                    { NAMEDOP_RETURN(ATassign); }                   // CFA
     414"~="                    { NAMEDOP_RETURN(ErangeUpEq); }                 // CFA
     415"-~"                    { NAMEDOP_RETURN(ErangeDown); }                 // CFA
     416"-~="                   { NAMEDOP_RETURN(ErangeDownEq); }               // CFA
    414417
    415418                                /* CFA, operator identifier */
  • src/Parser/parser.yy

    r9b086ca rcde3891  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug  8 17:50:07 2018
    13 // Update Count     : 3998
     12// Last Modified On : Thu Nov  8 18:08:23 2018
     13// Update Count     : 4052
    1414//
    1515
     
    187187
    188188ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     189        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->get_expr());
     190        if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
     191        type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
     192        } // if
    189193        return new ForCtrl(
    190                 distAttr( DeclarationNode::newTypeof( type ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
     194                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
    191195                new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ),
    192                 new ExpressionNode( build_binary_val( OperKinds::PlusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) );
     196                new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
     197                                                                                          OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) );
     198} // forCtrl
     199
     200ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     201        if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->get_expr()) ) {
     202                return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     203        } else {
     204                SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr;
     205        } // if
    193206} // forCtrl
    194207
     
    214227
    215228// Types declaration for productions
    216 %union
    217 {
     229%union {
    218230        Token tok;
    219231        ParseNode * pn;
     
    254266%token ZERO_T ONE_T                                                                             // CFA
    255267%token VALIST                                                                                   // GCC
    256 %token TYPEOF LABEL                                                                             // GCC
     268%token TYPEOF BASETYPEOF LABEL                                                  // GCC
    257269%token ENUM STRUCT UNION
    258270%token EXCEPTION                                                                                // CFA
     
    290302%token ANDassign        ERassign        ORassign                                // &=   ^=      |=
    291303
    292 %token Erange                                                                                   // ~=
     304%token ErangeUpEq       ErangeDown      ErangeDownEq                    // ~=   -~      -~=
    293305%token ATassign                                                                                 // @=
    294306
     
    629641                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    630642        | postfix_expression ARROW no_attr_identifier
    631                 {
    632                         $$ = new ExpressionNode( build_pfieldSel( $1, *$3 == "0" || *$3 == "1" ? build_constantInteger( *$3 ) : build_varref( $3 ) ) );
    633                 }
     643                { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
    634644        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    635645                { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
     
    11301140        | FOR '(' push for_control_expression ')' statement pop
    11311141                { $$ = new StatementNode( build_for( $4, $6 ) ); }
     1142        | FOR '(' ')' statement                                                         // CFA => for ( ;; )
     1143                { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), $4 ) ); }
    11321144        ;
    11331145
    11341146for_control_expression:
    1135         comma_expression_opt                                                            // CFA
    1136                 {
    1137                         if ( ! $1 ) {                                                           // => for ( ;; )
    1138                                 $$ = new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr );
    1139                         } else {
    1140                                 $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), OperKinds::LThan, $1->clone(),
    1141                                                          new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) );
    1142                         } // if
    1143                 }
     1147        comma_expression                                                                        // CFA
     1148                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1149                                                OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    11441150        | constant_expression inclexcl constant_expression      // CFA
    11451151                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    11461152        | constant_expression inclexcl constant_expression '~' constant_expression // CFA
    11471153                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); }
    1148         | comma_expression_opt ';' comma_expression                     // CFA
    1149                 {
    1150                         if ( ! $1 ) {
    1151                                 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr;
    1152                         } else if ( ! $3 ) {
    1153                                 SemanticError( yylloc, "Missing loop range." ); $$ = nullptr;
    1154                         } else {
    1155                                 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) {
    1156                                         $$ = forCtrl( $3, new string( identifier->name ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), OperKinds::LThan, $3->clone(),
    1157                                                                  new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) );
    1158                                 } else {
    1159                                         SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr;
    1160                                 } // if
    1161                         } // if
    1162                 }
    1163         | comma_expression_opt ';' constant_expression inclexcl constant_expression // CFA
    1164                 {
    1165                         if ( ! $1 ) {
    1166                                 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr;
    1167                         } else {
    1168                                 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) {
    1169                                         $$ = forCtrl( $3, new string( identifier->name ), $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) );
    1170                                 } else {
    1171                                         SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr;
    1172                                 } // if
    1173                         } // if
    1174                 }
    1175         | comma_expression_opt ';' constant_expression inclexcl constant_expression '~' constant_expression // CFA
    1176                 {
    1177                         if ( ! $1 ) {
    1178                                 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr;
    1179                         } else {
    1180                                 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) {
    1181                                         $$ = forCtrl( $3, new string( identifier->name ), $3->clone(), $4, $5, $7 );
    1182                                 } else {
    1183                                         SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr;
    1184                                 } // if
    1185                         } // if
    1186                 }
    1187         | comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt
     1154        | comma_expression ';' comma_expression                         // CFA
     1155                { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1156                                                OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1157        | comma_expression ';' constant_expression inclexcl constant_expression // CFA
     1158                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1159        | comma_expression ';' constant_expression inclexcl constant_expression '~' constant_expression // CFA
     1160                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
     1161        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    11881162                { $$ = new ForCtrl( $1, $3, $5 ); }
     1163        | ';' comma_expression_opt ';' comma_expression_opt
     1164                { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
    11891165        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    11901166                { $$ = new ForCtrl( $1, $2, $4 ); }
     
    11941170        '~'
    11951171                { $$ = OperKinds::LThan; }
    1196         | Erange
     1172        | ErangeUpEq
    11971173                { $$ = OperKinds::LEThan; }
     1174        | ErangeDown
     1175                { $$ = OperKinds::GThan; }
     1176        | ErangeDownEq
     1177                { $$ = OperKinds::GEThan; }
    11981178        ;
    11991179
     
    18441824
    18451825indirect_type:
    1846         TYPEOF '(' type ')'                                                                     // GCC: typeof(x) y;
     1826        TYPEOF '(' type ')'                                                                     // GCC: typeof( x ) y;
    18471827                { $$ = $3; }
    1848         | TYPEOF '(' comma_expression ')'                                       // GCC: typeof(a+b) y;
     1828        | TYPEOF '(' comma_expression ')'                                       // GCC: typeof( a+b ) y;
    18491829                { $$ = DeclarationNode::newTypeof( $3 ); }
    1850         | ATTR_TYPEGENname '(' type ')'                                         // CFA: e.g., @type(x) y;
     1830        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
     1831                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
     1832        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
     1833                { $$ = DeclarationNode::newTypeof( $3, true ); }
     1834        | ATTR_TYPEGENname '(' type ')'                                         // CFA: e.g., @type( x ) y;
    18511835                { $$ = DeclarationNode::newAttr( $1, $3 ); }
    1852         | ATTR_TYPEGENname '(' comma_expression ')'                     // CFA: e.g., @type(a+b) y;
     1836        | ATTR_TYPEGENname '(' comma_expression ')'                     // CFA: e.g., @type( a+b ) y;
    18531837                { $$ = DeclarationNode::newAttr( $1, $3 ); }
    18541838        | ZERO_T                                                                                        // CFA
Note: See TracChangeset for help on using the changeset viewer.