Changeset cd28605 for src


Ignore:
Timestamp:
Feb 6, 2025, 3:42:32 PM (8 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
eca364f7
Parents:
a8e2215
Message:

first attempt at generalizing attributes to statements

Location:
src/Parser
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/StatementNode.cpp

    ra8e2215 rcd28605  
    1010// Author           : Rodolfo G. Esteves
    1111// Created On       : Sat May 16 14:59:41 2015
    12 // Last Modified By : Kyoung Seo
    13 // Last Modified On : Thd Jan 16 13:05:00 2025
    14 // Update Count     : 433
     12// Last Modified By : Peter A. Buhr
     13// Last Modified On : Thu Feb  6 11:38:39 2025
     14// Update Count     : 434
    1515//
    1616
     
    7070        stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) );
    7171} // StatementNode::StatementNode
     72
     73StatementNode * StatementNode::addQualifiers( DeclarationNode * attr ) {
     74        if ( ! attr ) { return this; }                                          // empty attribute list
     75        attributes.insert( attributes.end(), attr->attributes.begin(), attr->attributes.end() );
     76        return this;
     77}
    7278
    7379StatementNode * StatementNode::add_label(
  • src/Parser/StatementNode.hpp

    ra8e2215 rcd28605  
    1010// Created On       : Wed Apr  5 11:42:00 2023
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 23 22:43:05 2024
    13 // Update Count     : 3
     12// Last Modified On : Thu Feb  6 11:39:26 2025
     13// Update Count     : 6
    1414//
    1515
     
    2727        ast::Stmt * build() { return stmt.release(); }
    2828
     29        StatementNode * addQualifiers( DeclarationNode * );
    2930        StatementNode * add_label(
    3031                        const CodeLocation & location,
     
    3637        }
    3738
     39        std::vector<ast::ptr<ast::Attribute>> attributes;
    3840        std::unique_ptr<ast::Stmt> stmt;
    3941}; // StatementNode
  • src/Parser/parser.yy

    ra8e2215 rcd28605  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jan 17 14:35:08 2025
    13 // Update Count     : 6935
     12// Last Modified On : Thu Feb  6 11:40:06 2025
     13// Update Count     : 7236
    1414//
    1515
     
    5454#include "Common/SemanticError.hpp"                     // error_str
    5555#include "Common/Utility.hpp"                           // for maybeMoveBuild, maybeBuild, CodeLo...
     56#include "AST/Attribute.hpp"         // for Attribute
     57#include "AST/Print.hpp"             // for print
     58#include "Common/Iterate.hpp"        // for reverseIterate
    5659
    5760// lex uses __null in a boolean context, it's fine.
     
    98101} // appendStr
    99102
    100 DeclarationNode * distAttr( DeclarationNode * typeSpec, DeclarationNode * declList ) {
     103DeclarationNode * distTypeSpec( DeclarationNode * typeSpec, DeclarationNode * declList ) {
    101104        // Distribute type specifier across all declared variables, e.g., static, const, __attribute__.
    102105        assert( declList );
     
    132135        declList->addType( cl, copyattr );                                      // cl IS DELETED!!!
    133136        return declList;
     137} // distTypeSpec
     138
     139void distAttr( DeclarationNode * attributes, DeclarationNode * declaration ) {
     140        // distribute attributes across all declaring list
     141        for ( DeclarationNode * attr = attributes; attr != nullptr ; attr = attr->next ) {
     142                for ( DeclarationNode * decl = declaration ; decl != nullptr ; decl = decl->next ) {
     143                        decl->attributes.insert( decl->attributes.begin(), attr->attributes.begin(), attr->attributes.end() );
     144                } // for
     145        } // for
    134146} // distAttr
    135147
    136148void distExt( DeclarationNode * declaration ) {
    137149        // distribute EXTENSION across all declarations
    138         for ( DeclarationNode *iter = declaration ; iter != nullptr ; iter = iter->next ) {
    139                 iter->set_extension( true );
     150        for ( DeclarationNode * decl = declaration ; decl != nullptr ; decl = decl->next ) {
     151                decl->set_extension( true );
    140152        } // for
    141153} // distExt
     
    143155void distInl( DeclarationNode * declaration ) {
    144156        // distribute INLINE across all declarations
    145         for ( DeclarationNode *iter = declaration ; iter != nullptr ; iter = iter->next ) {
    146                 iter->set_inLine( true );
     157        for ( DeclarationNode *decl = declaration ; decl != nullptr ; decl = decl->next ) {
     158                decl->set_inLine( true );
    147159        } // for
    148160} // distInl
     
    150162void distQual( DeclarationNode * declaration, DeclarationNode * qualifiers ) {
    151163        // distribute qualifiers across all non-variable declarations in a distribution statemement
    152         for ( DeclarationNode * iter = declaration ; iter != nullptr ; iter = iter->next ) {
     164        for ( DeclarationNode * decl = declaration ; decl != nullptr ; decl = decl->next ) {
    153165                // SKULLDUGGERY: Distributions are parsed inside out, so qualifiers are added to declarations inside out. Since
    154166                // addQualifiers appends to the back of the list, the forall clauses are in the wrong order (right to left). To
     
    157169                DeclarationNode * clone = qualifiers->clone();
    158170                if ( qualifiers->type ) {                                               // forall clause ? (handles SC)
    159                         if ( iter->type->kind == TypeData::Aggregate ) { // struct/union ?
    160                                 swap( clone->type->forall, iter->type->aggregate.params );
    161                                 iter->addQualifiers( clone );
    162                         } else if ( iter->type->kind == TypeData::AggregateInst && iter->type->aggInst.aggregate->aggregate.body ) { // struct/union ?
     171                        if ( decl->type->kind == TypeData::Aggregate ) { // struct/union ?
     172                                swap( clone->type->forall, decl->type->aggregate.params );
     173                                decl->addQualifiers( clone );
     174                        } else if ( decl->type->kind == TypeData::AggregateInst && decl->type->aggInst.aggregate->aggregate.body ) { // struct/union ?
    163175                                // Create temporary node to hold aggregate, call addQualifiers as above, then put nodes back together.
    164176                                DeclarationNode newnode;
    165                                 swap( newnode.type, iter->type->aggInst.aggregate );
     177                                swap( newnode.type, decl->type->aggInst.aggregate );
    166178                                swap( clone->type->forall, newnode.type->aggregate.params );
    167179                                newnode.addQualifiers( clone );
    168                                 swap( newnode.type, iter->type->aggInst.aggregate );
    169                         } else if ( iter->type->kind == TypeData::Function ) { // routines ?
    170                                 swap( clone->type->forall, iter->type->forall );
    171                                 iter->addQualifiers( clone );
     180                                swap( newnode.type, decl->type->aggInst.aggregate );
     181                        } else if ( decl->type->kind == TypeData::Function ) { // routines ?
     182                                swap( clone->type->forall, decl->type->forall );
     183                                decl->addQualifiers( clone );
    172184                        } // if
    173185                } else {                                                                                // just SC qualifiers
    174                         iter->addQualifiers( clone );
     186                        decl->addQualifiers( clone );
    175187                } // if
    176188        } // for
     
    210222
    211223        // printf( "fieldDecl3 typeSpec %p\n", typeSpec ); typeSpec->print( std::cout, 0 );
    212         DeclarationNode * temp = distAttr( typeSpec, fieldList ); // mark all fields in list
     224        DeclarationNode * temp = distTypeSpec( typeSpec, fieldList ); // mark all fields in list
    213225        // printf( "fieldDecl4 temp %p\n", temp ); temp->print( std::cout, 0 );
    214226        return temp;
     
    253265                type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicKind::SignedInt ) ) );
    254266        } // if
    255         DeclarationNode * initDecl = distAttr(
     267        DeclarationNode * initDecl = distTypeSpec(
    256268                DeclarationNode::newTypeof( type, true ),
    257269                DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) )
     
    434446%type<decl> asm_name_opt
    435447%type<expr> asm_operands_opt                    asm_operands_list                       asm_operand
    436 %type<labels> label_list
     448%type<labels> asm_label_list
    437449%type<expr> asm_clobbers_list_opt
    438450%type<is_volatile> asm_volatile_opt
     
    441453
    442454// statements
    443 %type<stmt> statement                                   labeled_statement                       compound_statement
     455%type<stmt> statement                                   labelled_statement                      compound_statement
    444456%type<stmt> statement_decl                              statement_decl_list                     statement_list_nodecl
    445457%type<stmt> selection_statement
     
    926938        | SIZEOF '(' type_no_function ')'
    927939                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
     940        | SIZEOF '(' attribute_list type_no_function ')'
     941                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $4->addQualifiers( $3 ) ) ) ); }
    928942        | ALIGNOF unary_expression                                                      // GCC, variable alignment
    929943                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, new ast::TypeofType( maybeMoveBuild( $2 ) ) ) ); }
     
    12021216
    12031217statement:
    1204         labeled_statement
     1218        labelled_statement
    12051219        | compound_statement
    12061220        | expression_statement
     
    12201234        | DIRECTIVE
    12211235                { $$ = new StatementNode( build_directive( yylloc, $1 ) ); }
    1222 //      | attribute ';'
    1223 //              { $$ = new StatementNode( $1 ); }
    1224         ;
    1225 
    1226 labeled_statement:
     1236        ;
     1237
     1238labelled_statement:
    12271239                // labels cannot be identifiers 0 or 1
    12281240        identifier_or_type_name ':' attribute_list_opt statement
     
    12541266
    12551267statement_decl:
    1256         declaration                                                                                     // CFA, new & old style declarations
    1257                 { $$ = new StatementNode( $1 ); }
    1258         | EXTENSION declaration                                                         // GCC
    1259                 { distExt( $2 ); $$ = new StatementNode( $2 ); }
    1260         | function_definition
    1261                 { $$ = new StatementNode( $1 ); }
    1262         | EXTENSION function_definition                                         // GCC
    1263                 { distExt( $2 ); $$ = new StatementNode( $2 ); }
    1264         | statement
     1268        attribute_list_opt declaration                                          // CFA, new & old style declarations
     1269                { distAttr( $1, $2 ); $$ = new StatementNode( $2 ); }
     1270        | attribute_list_opt EXTENSION declaration                      // GCC
     1271                { distAttr( $1, $3 ); distExt( $3 ); $$ = new StatementNode( $3 ); }
     1272        | attribute_list_opt function_definition
     1273                { distAttr( $1, $2 ); $$ = new StatementNode( $2 ); }
     1274        | attribute_list_opt EXTENSION function_definition      // GCC
     1275                { distAttr( $1, $3 ); distExt( $3 ); $$ = new StatementNode( $3 ); }
     1276        | attribute_list_opt statement                                          // FIX ME!
     1277                { $$ = $2->addQualifiers( $1 ); }
    12651278        ;
    12661279
    12671280statement_list_nodecl:
    1268         statement
    1269         | statement_list_nodecl statement
    1270                 { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
     1281        attribute_list_opt statement
     1282                { $$ = $2->addQualifiers( $1 ); }                                                                       // FIX ME!
     1283        | statement_list_nodecl attribute_list_opt statement
     1284                { assert( $1 ); $1->set_last( $3->addQualifiers( $2 ) ); $$ = $1; }     // FIX ME!
    12711285        | statement_list_nodecl error                                           // invalid syntax rule
    12721286                { SemanticError( yylloc, "illegal syntax, declarations only allowed at the start of the switch body,"
     
    12741288        ;
    12751289
    1276 expression_statement:
     1290expression_statement:                                                                   // expression or null statement
    12771291        comma_expression_opt ';'
    12781292                { $$ = new StatementNode( build_expr( yylloc, $1 ) ); }
     
    19031917        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';'
    19041918                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
    1905         | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';'
     1919        | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' asm_label_list ')' ';'
    19061920                { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
    19071921        ;
     
    19451959        ;
    19461960
    1947 label_list:
    1948         identifier
    1949                 {
    1950                         $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
    1951                         delete $1;                                                                      // allocated by lexer
    1952                 }
    1953         | label_list ',' identifier
    1954                 {
    1955                         $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
    1956                         delete $3;                                                                      // allocated by lexer
    1957                 }
     1961asm_label_list:
     1962        identifier_or_type_name
     1963                { $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 ); delete $1; } // allocated by lexer
     1964        | asm_label_list ',' identifier_or_type_name
     1965                { $$ = $1; $1->labels.emplace_back( yylloc, *$3 ); delete $3; } // allocated by lexer
    19581966        ;
    19591967
     
    19671975
    19681976declaration_list:
    1969         declaration
     1977        attribute_list_opt declaration
     1978                { $$ = $2->addQualifiers( $1 ); }
    19701979        | declaration_list declaration
    19711980                { $$ = $1->set_last( $2 ); }
     
    21422151                        } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
    21432152                }
     2153        | TYPEDEF attribute_list type_specifier declarator
     2154                {
     2155                        typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname, "typedef_declaration 1" );
     2156                        if ( $3->type->forall || ($3->type->kind == TypeData::Aggregate && $3->type->aggregate.params) ) {
     2157                                SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr;
     2158                        } else $$ = $4->addType( $3 )->addTypedef()->addQualifiers( $2 ); // watchout frees $3 and $4
     2159                }
    21442160        | typedef_declaration ',' declarator
    21452161                {
     
    21692185c_declaration:
    21702186        declaration_specifier declaring_list
    2171                 { $$ = distAttr( $1, $2 ); }
     2187                { $$ = distTypeSpec( $1, $2 ); }
    21722188        | typedef_declaration
    21732189        | typedef_expression                                                            // deprecated GCC, naming expression type
     
    22652281                // specifier-qualifier-list, either directly or via one or more typedefs, the behavior is the same as if it
    22662282                // appeared only once.
    2267         type_qualifier
    2268         | type_qualifier_list type_qualifier
     2283        type_qualifier attribute_list_opt
    22692284                { $$ = $1->addQualifiers( $2 ); }
     2285        | type_qualifier_list type_qualifier attribute_list_opt
     2286                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    22702287        ;
    22712288
     
    22732290        type_qualifier_name
    22742291                { $$ = DeclarationNode::newFromTypeData( $1 ); }
    2275         | attribute                                                                                     // trick handles most attribute locations
    22762292        ;
    22772293
     
    23012317declaration_qualifier_list:
    23022318        storage_class_list
    2303         | type_qualifier_list storage_class_list                        // remaining OBSOLESCENT (see 2 )
     2319        | type_qualifier_list storage_class_list
    23042320                { $$ = $1->addQualifiers( $2 ); }
    23052321        | declaration_qualifier_list type_qualifier_list storage_class_list
     
    23132329                // ISO/IEC 9899:1999 Section 6.7.1(2) : At most, one storage-class specifier may be given in the declaration
    23142330                // specifiers in a declaration.
    2315         storage_class
    2316         | storage_class_list storage_class
     2331        storage_class attribute_list_opt
    23172332                { $$ = $1->addQualifiers( $2 ); }
     2333        | storage_class_list storage_class attribute_list_opt
     2334                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    23182335        ;
    23192336
     
    24402457        | declaration_qualifier_list basic_type_specifier
    24412458                { $$ = $2->addQualifiers( $1 ); }
    2442         | basic_declaration_specifier storage_class                     // remaining OBSOLESCENT (see 2)
    2443                 { $$ = $1->addQualifiers( $2 ); }
     2459        | basic_declaration_specifier storage_class attribute_list_opt // remaining OBSOLESCENT (see 2)
     2460                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    24442461        | basic_declaration_specifier storage_class type_qualifier_list
    24452462                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
     
    24492466
    24502467basic_type_specifier:
    2451         direct_type
     2468        direct_type attribute_list_opt
     2469                { $$ = $1->addQualifiers( $2 ); }
    24522470                // Cannot have type modifiers, e.g., short, long, etc.
     2471        | type_qualifier_list_opt indirect_type attribute_list
     2472                { $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); }
    24532473        | type_qualifier_list_opt indirect_type type_qualifier_list_opt
    24542474                { $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); }
     
    25222542
    25232543type_declaration_specifier:
    2524         type_type_specifier
    2525         | declaration_qualifier_list type_type_specifier
    2526                 { $$ = $2->addQualifiers( $1 ); }
    2527         | type_declaration_specifier storage_class                      // remaining OBSOLESCENT (see 2)
     2544        type_type_specifier attribute_list_opt
    25282545                { $$ = $1->addQualifiers( $2 ); }
     2546        | declaration_qualifier_list type_type_specifier attribute_list_opt
     2547                { $$ = $2->addQualifiers( $1 )->addQualifiers( $3 ); }
     2548        | type_declaration_specifier storage_class attribute_list_opt // remaining OBSOLESCENT (see 2)
     2549                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
    25292550        | type_declaration_specifier storage_class type_qualifier_list
    25302551                { $$ = $1->addQualifiers( $2 )->addQualifiers( $3 ); }
     
    25782599        aggregate_key attribute_list_opt
    25792600                { forall = false; }                                                             // reset
    2580           '{' field_declaration_list_opt '}' type_parameters_opt
    2581                 { $$ = DeclarationNode::newAggregate( $1, nullptr, $7, $5, true )->addQualifiers( $2 ); }
    2582         | aggregate_key attribute_list_opt identifier
     2601          '{' field_declaration_list_opt '}' type_parameters_opt attribute_list_opt
     2602                { $$ = DeclarationNode::newAggregate( $1, nullptr, $7, $5, true )->addQualifiers( $2 )->addQualifiers( $8 ); }
     2603        | aggregate_key attribute_list_opt identifier attribute_list_opt
    25832604                {
    25842605                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname, "aggregate_type: 1" );
    25852606                        forall = false;                                                         // reset
    25862607                }
    2587           '{' field_declaration_list_opt '}' type_parameters_opt
    2588                 {
    2589                         $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
    2590                 }
    2591         | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
     2608          '{' field_declaration_list_opt '}' type_parameters_opt attribute_list_opt
     2609                {
     2610                        $$ = DeclarationNode::newAggregate( $1, $3, $9, $7, true )->addQualifiers( $2 )->addQualifiers( $4 )->addQualifiers( $10 );
     2611                }
     2612        | aggregate_key attribute_list_opt TYPEDEFname attribute_list_opt // unqualified type name
    25922613                {
    25932614                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname, "aggregate_type: 2" );
    25942615                        forall = false;                                                         // reset
    25952616                }
    2596           '{' field_declaration_list_opt '}' type_parameters_opt
     2617          '{' field_declaration_list_opt '}' type_parameters_opt attribute_list_opt
    25972618                {
    25982619                        DeclarationNode::newFromTypeData( build_typedef( $3 ) );
    2599                         $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
    2600                 }
    2601         | aggregate_key attribute_list_opt TYPEGENname          // unqualified type name
     2620                        $$ = DeclarationNode::newAggregate( $1, $3, $9, $7, true )->addQualifiers( $2 )->addQualifiers( $4 )->addQualifiers( $10 );
     2621                }
     2622        | aggregate_key attribute_list_opt TYPEGENname attribute_list_opt // unqualified type name
    26022623                {
    26032624                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname, "aggregate_type: 3" );
    26042625                        forall = false;                                                         // reset
    26052626                }
    2606           '{' field_declaration_list_opt '}' type_parameters_opt
     2627          '{' field_declaration_list_opt '}' type_parameters_opt attribute_list_opt
    26072628                {
    26082629                        DeclarationNode::newFromTypeData( build_type_gen( $3, nullptr ) );
    2609                         $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 );
     2630                        $$ = DeclarationNode::newAggregate( $1, $3, $9, $7, true )->addQualifiers( $2 )->addQualifiers( $10 );
    26102631                }
    26112632        | aggregate_type_nobody
     
    26862707
    26872708field_declaration_list_opt:
    2688         // empty
     2709        // empty => struct S { /* no fields */ };
    26892710                { $$ = nullptr; }
    2690         | field_declaration_list_opt field_declaration
    2691                 { $$ = $1 ? $1->set_last( $2 ) : $2; }
     2711        | field_declaration_list_opt attribute_list_opt field_declaration
     2712                { distAttr( $2, $3 ); $$ = $1 ? $1->set_last( $3 ) : $3; }
    26922713        ;
    26932714
    26942715field_declaration:
    26952716        type_specifier field_declaring_list_opt ';'
    2696                 {
    2697                         $$ = fieldDecl( $1, $2 );
    2698                 }
     2717                { $$ = fieldDecl( $1, $2 ); }
    26992718        | type_specifier field_declaring_list_opt '}'           // invalid syntax rule
    27002719                {
     
    27062725        | STATIC type_specifier field_declaring_list_opt ';' // CFA
    27072726                { SemanticError( yylloc, "STATIC aggregate field qualifier currently unimplemented." ); $$ = nullptr; }
    2708         | INLINE type_specifier field_abstract_list_opt ';'     // CFA
    2709                 {
    2710                         if ( ! $3 ) {                                                           // field declarator ?
    2711                                 $3 = DeclarationNode::newName( nullptr );
     2727        | INLINE attribute_list_opt type_specifier field_abstract_list_opt ';'  // CFA
     2728                {
     2729                        if ( ! $4 ) {                                                           // field declarator ?
     2730                                $4 = DeclarationNode::newName( nullptr );
    27122731                        } // if
    2713                         $3->inLine = true;
    2714                         $$ = distAttr( $2, $3 );                                        // mark all fields in list
    2715                         distInl( $3 );
    2716                 }
    2717         | INLINE aggregate_control ';'                                          // CFA
     2732                        $4->inLine = true;
     2733                        $$ = distTypeSpec( $3, $4 );                            // mark all fields in list
     2734                        distInl( $4 );
     2735                }
     2736        | INLINE attribute_list_opt aggregate_control ';'                                               // CFA
    27182737                { SemanticError( yylloc, "INLINE aggregate control currently unimplemented." ); $$ = nullptr; }
    27192738        | typedef_declaration ';'                                                       // CFA
     
    27212740        | EXTENSION cfa_field_declaring_list ';'                        // GCC
    27222741                { distExt( $2 ); $$ = $2; }                                             // mark all fields in list
    2723         | INLINE cfa_field_abstract_list ';'                            // CFA, new style field declaration
    2724                 { $$ = $2; }                                                                    // mark all fields in list
     2742        | INLINE attribute_list_opt cfa_field_abstract_list ';' // CFA, new style field declaration
     2743                { $$ = $3->addQualifiers( $2 ); }                               // mark all fields in list
    27252744        | cfa_typedef_declaration ';'                                           // CFA
    27262745        | static_assert ';'                                                                     // C11
     
    27622781
    27632782field_abstract:
    2764                 //      no bit fields
    2765         variable_abstract_declarator
     2783        variable_abstract_declarator                                            //      no bit fields
    27662784        ;
    27672785
     
    27962814enum_type:
    27972815                // anonymous, no type name
    2798         ENUM attribute_list_opt hide_opt '{' enumerator_list comma_opt '}'
     2816        ENUM attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' attribute_list_opt
    27992817                {
    28002818                        if ( $3 == EnumHiding::Hide ) {
    28012819                                SemanticError( yylloc, "illegal syntax, hiding ('!') the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr;
    28022820                        } // if
    2803                         $$ = DeclarationNode::newEnum( nullptr, $5, true, false )->addQualifiers( $2 );
    2804                 }
    2805         | ENUM enumerator_type attribute_list_opt hide_opt '{' enumerator_list comma_opt '}'
     2821                        $$ = DeclarationNode::newEnum( nullptr, $5, true, false )->addQualifiers( $2 )->addQualifiers( $8 );
     2822                }
     2823        | ENUM enumerator_type attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' attribute_list_opt
    28062824                {
    28072825                        if ( $2 && ($2->storageClasses.val != 0 || $2->type->qualifiers.any()) ) {
     
    28112829                                SemanticError( yylloc, "illegal syntax, hiding ('!') the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr;
    28122830                        } // if
    2813                         $$ = DeclarationNode::newEnum( nullptr, $6, true, true, $2 )->addQualifiers( $3 );
     2831                        $$ = DeclarationNode::newEnum( nullptr, $6, true, true, $2 )->addQualifiers( $3 )->addQualifiers( $9 );
    28142832                }
    28152833
    28162834                // named type
    2817         | ENUM attribute_list_opt identifier
     2835        | ENUM attribute_list_opt identifier attribute_list_opt
    28182836                { typedefTable.makeTypedef( *$3, "enum_type 1" ); }
    2819           hide_opt '{' enumerator_list comma_opt '}'
    2820                 { $$ = DeclarationNode::newEnum( $3, $7, true, false, nullptr, $5 )->addQualifiers( $2 ); }
    2821         | ENUM attribute_list_opt typedef_name hide_opt '{' enumerator_list comma_opt '}' // unqualified type name
    2822                 { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
     2837          hide_opt '{' enumerator_list comma_opt '}' attribute_list_opt
     2838                { $$ = DeclarationNode::newEnum( $3, $8, true, false, nullptr, $6 )->addQualifiers( $2 ->addQualifiers( $4 ))->addQualifiers( $11 ); }
     2839        | ENUM attribute_list_opt typedef_name attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' attribute_list_opt // unqualified type name
     2840                { $$ = DeclarationNode::newEnum( $3->name, $7, true, false, nullptr, $5 )->addQualifiers( $2 )->addQualifiers( $4 )->addQualifiers( $10 ); }
    28232841        | ENUM enumerator_type attribute_list_opt identifier attribute_list_opt
    28242842                {
     
    28282846                        typedefTable.makeTypedef( *$4, "enum_type 2" );
    28292847                }
    2830           hide_opt '{' enumerator_list comma_opt '}'
    2831                 { $$ = DeclarationNode::newEnum( $4, $9, true, true, $2, $7 )->addQualifiers( $3 )->addQualifiers( $5 ); }
    2832         | ENUM enumerator_type attribute_list_opt typedef_name attribute_list_opt hide_opt '{' enumerator_list comma_opt '}'
    2833                 { $$ = DeclarationNode::newEnum( $4->name, $8, true, true, $2, $6 )->addQualifiers( $3 )->addQualifiers( $5 ); }
     2848          hide_opt '{' enumerator_list comma_opt '}' attribute_list_opt
     2849                { $$ = DeclarationNode::newEnum( $4, $9, true, true, $2, $7 )->addQualifiers( $3 )->addQualifiers( $5 )->addQualifiers( $12 ); }
     2850        | ENUM enumerator_type attribute_list_opt typedef_name attribute_list_opt hide_opt '{' enumerator_list comma_opt '}' attribute_list_opt
     2851                { $$ = DeclarationNode::newEnum( $4->name, $8, true, true, $2, $6 )->addQualifiers( $3 )->addQualifiers( $5 )->addQualifiers( $11 ); }
    28342852
    28352853                // forward declaration
     
    29102928parameter_list:                                                                                 // abstract + real
    29112929        parameter_declaration
     2930        | attribute_list parameter_declaration
     2931                { $$ = $2->addQualifiers( $1 ); }
    29122932        | abstract_parameter_declaration
    2913         | parameter_list ',' parameter_declaration
    2914                 { $$ = $1->set_last( $3 ); }
    2915         | parameter_list ',' abstract_parameter_declaration
    2916                 { $$ = $1->set_last( $3 ); }
     2933        | attribute_list abstract_parameter_declaration
     2934                { $$ = $2->addQualifiers( $1 ); }
     2935        | parameter_list ',' attribute_list_opt parameter_declaration
     2936                { $4->addQualifiers( $3 ); $$ = $1->set_last( $4 ); }
     2937        | parameter_list ',' attribute_list_opt abstract_parameter_declaration
     2938                { $4->addQualifiers( $3 ); $$ = $1->set_last( $4 ); }
    29172939        ;
    29182940
     
    30023024
    30033025type_no_function:                                                                               // sizeof, alignof, cast (constructor)
    3004         cfa_abstract_declarator_tuple                                           // CFA
    3005         | type_specifier                                                                        // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
     3026        type_specifier                                                                          // cannot be type_specifier_nobody, e.g., (struct S {}){} is a thing
    30063027        | type_specifier abstract_declarator
    30073028                { $$ = $2->addType( $1 ); }
     3029        | cfa_abstract_declarator_tuple                                         // CFA
    30083030        ;
    30093031
    30103032type:                                                                                                   // typeof, assertion
    30113033        type_no_function
     3034        | attribute_list type_no_function
     3035                { $$ = $2->addQualifiers( $1 ); }
    30123036        | cfa_abstract_function                                                         // CFA
     3037        | attribute_list cfa_abstract_function                          // CFA
     3038                { $$ = $2->addQualifiers( $1 ); }
    30133039        ;
    30143040
     
    32683294        ;
    32693295
    3270 external_definition_list:
    3271         push external_definition pop
    3272                 { $$ = $2; }
    3273         | external_definition_list push external_definition pop
    3274                 { $$ = $1 ? $1->set_last( $3 ) : $3; }
    3275         ;
    3276 
    32773296external_definition_list_opt:
    32783297        // empty
    32793298                { $$ = nullptr; }
    32803299        | external_definition_list
     3300        ;
     3301
     3302external_definition_list:
     3303        attribute_list_opt push external_definition pop
     3304                { distAttr( $1, $3 ); $$ = $3; }
     3305        | external_definition_list attribute_list_opt push external_definition pop
     3306                { distAttr( $2, $4 ); $$ = $1 ? $1->set_last( $4 ) : $4->addQualifiers( $2 ); }
    32813307        ;
    32823308
     
    35873613        ptrref_operator variable_declarator
    35883614                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3615        | ptrref_operator attribute_list variable_declarator
     3616                { $$ = $3->addPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    35893617        | ptrref_operator type_qualifier_list variable_declarator
    35903618                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    36513679        ptrref_operator function_declarator
    36523680                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3681        | ptrref_operator attribute_list function_declarator
     3682                { $$ = $3->addPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    36533683        | ptrref_operator type_qualifier_list function_declarator
    36543684                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    37033733        ptrref_operator KR_function_declarator
    37043734                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3735        | ptrref_operator attribute_list KR_function_declarator
     3736                { $$ = $3->addPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    37053737        | ptrref_operator type_qualifier_list KR_function_declarator
    37063738                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    37563788        ptrref_operator variable_type_redeclarator
    37573789                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3790        | ptrref_operator attribute_list variable_type_redeclarator
     3791                { $$ = $3->addPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    37583792        | ptrref_operator type_qualifier_list variable_type_redeclarator
    37593793                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38203854        ptrref_operator function_type_redeclarator
    38213855                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3856        | ptrref_operator attribute_list function_type_redeclarator
     3857                { $$ = $3->addPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    38223858        | ptrref_operator type_qualifier_list function_type_redeclarator
    38233859                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    38643900        ptrref_operator identifier_parameter_declarator
    38653901                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3902        | ptrref_operator attribute_list identifier_parameter_declarator
     3903                { $$ = $3->addPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    38663904        | ptrref_operator type_qualifier_list identifier_parameter_declarator
    38673905                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    39223960        ptrref_operator type_parameter_redeclarator
    39233961                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     3962        | ptrref_operator attribute_list type_parameter_redeclarator
     3963                { $$ = $3->addPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    39243964        | ptrref_operator type_qualifier_list type_parameter_redeclarator
    39253965                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    39634003
    39644004abstract_ptr:
    3965         ptrref_operator
    3966                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     4005        ptrref_operator attribute_list_opt
     4006                { $$ = DeclarationNode::newPointer( nullptr, $1 )->addQualifiers( $2 ); }
    39674007        | ptrref_operator type_qualifier_list
    39684008                { $$ = DeclarationNode::newPointer( $2, $1 ); }
    39694009        | ptrref_operator abstract_declarator
    39704010                { $$ = $2->addPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     4011        | ptrref_operator attribute_list abstract_declarator
     4012                { $$ = $3->addPointer( DeclarationNode::newPointer( nullptr, $1 )->addQualifiers( $2 ) ); }
    39714013        | ptrref_operator type_qualifier_list abstract_declarator
    39724014                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
     
    40964138
    40974139abstract_parameter_ptr:
    4098         ptrref_operator
    4099                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     4140        ptrref_operator attribute_list_opt
     4141                { $$ = DeclarationNode::newPointer( nullptr, $1 )->addQualifiers( $2 ); }
    41004142        | ptrref_operator type_qualifier_list
    41014143                { $$ = DeclarationNode::newPointer( $2, $1 ); }
     
    41754217
    41764218variable_abstract_ptr:
    4177         ptrref_operator
    4178                 { $$ = DeclarationNode::newPointer( nullptr, $1 ); }
     4219        ptrref_operator attribute_list_opt
     4220                { $$ = DeclarationNode::newPointer( nullptr, $1 )->addQualifiers( $2 ); }
    41794221        | ptrref_operator type_qualifier_list
    41804222                { $$ = DeclarationNode::newPointer( $2, $1 ); }
     
    42234265cfa_identifier_parameter_ptr:                                                   // CFA
    42244266                // No SUE declaration in parameter list.
    4225         ptrref_operator type_specifier_nobody
     4267        ptrref_operator type_specifier_nobody
    42264268                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     4269        | ptrref_operator attribute_list type_specifier_nobody
     4270                { $$ = $3->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    42274271        | type_qualifier_list ptrref_operator type_specifier_nobody
    42284272                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
     
    43234367        ptrref_operator type_specifier
    43244368                { $$ = $2->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) ); }
     4369        | ptrref_operator attribute_list type_specifier
     4370                { $$ = $3->addNewPointer( DeclarationNode::newPointer( nullptr, $1 ) )->addQualifiers( $2 ); }
    43254371        | type_qualifier_list ptrref_operator type_specifier
    43264372                { $$ = $3->addNewPointer( DeclarationNode::newPointer( $1, $2 ) ); }
Note: See TracChangeset for help on using the changeset viewer.