Changes in / [4bf5298:b1a6d6b]
- Files:
-
- 1 added
- 24 edited
-
ChangeLog (added)
-
LICENSE (modified) (2 diffs)
-
driver/cc1.cc (modified) (1 diff)
-
libcfa/prelude.cf (modified) (1 diff)
-
translator/CodeGen/CodeGenerator2.cc (modified) (1 diff)
-
translator/ControlStruct/ForExprMutator.cc (modified) (2 diffs)
-
translator/Parser/DeclarationNode.cc (modified) (2 diffs)
-
translator/Parser/ParseNode.h (modified) (1 diff)
-
translator/Parser/TypeData.cc (modified) (1 diff)
-
translator/Parser/cfa.y (modified) (125 diffs)
-
translator/ResolvExpr/CastCost.cc (modified) (2 diffs)
-
translator/ResolvExpr/PtrsAssignable.cc (modified) (5 diffs)
-
translator/ResolvExpr/Resolver.cc (modified) (3 diffs)
-
translator/SymTab/Validate.cc (modified) (1 diff)
-
translator/SynTree/CompoundStmt.cc (modified) (1 diff)
-
translator/SynTree/Declaration.h (modified) (2 diffs)
-
translator/SynTree/FunctionDecl.cc (modified) (6 diffs)
-
translator/SynTree/Statement.cc (modified) (14 diffs)
-
translator/SynTree/Statement.h (modified) (1 diff)
-
translator/SynTree/Type.h (modified) (4 diffs)
-
translator/examples/identity.c (modified) (1 diff)
-
translator/examples/min.c (modified) (2 diffs)
-
translator/examples/s.c (modified) (1 diff)
-
translator/examples/square.c (modified) (1 diff)
-
translator/examples/swap.c (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
LICENSE
r4bf5298 rb1a6d6b 1 BSD Licence 1 This software Cforall is published under the BSD license as listed below. 2 2 3 Copyright (c) 2015 University of Waterloo.3 Copyright (c) 2015 Huawei Technologies Co., Ltd and University of Waterloo. 4 4 All rights reserved. 5 5 … … 8 8 9 9 1. Redistributions of source code must retain the above copyright notice, this 10 list of conditions and the following disclaimer.10 list of conditions and the following disclaimer. 11 11 12 12 2. Redistributions in binary form must reproduce the above copyright notice, 13 this list of conditions and the following disclaimer in the documentation14 and/or other materials provided with the distribution.13 this list of conditions and the following disclaimer in the documentation 14 and/or other materials provided with the distribution. 15 15 16 3. Neither the name of the copyright holder nor the names of its contributors 17 may be used to endorse or promote products derived from this software without 18 specific prior written permission. 16 3. Neither the name of Huawei Technologies Co., Ltd., nor University of 17 Waterloo, nor the names of the contributors to Cfoall may be used to endorse 18 or promote products derived from this software without specific prior 19 written permission. 19 20 20 21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 21 22 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 22 23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 24 25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -
driver/cc1.cc
r4bf5298 rb1a6d6b 8 8 // Created On : Fri Aug 26 14:23:51 2005 9 9 // Last Modified By : Peter A. Buhr 10 // Last Modified On : Thu May 14 13:24:45201511 // Update Count : 4310 // Last Modified On : Mon Apr 27 23:11:52 2015 11 // Update Count : 39 12 12 // 13 13 -
libcfa/prelude.cf
r4bf5298 rb1a6d6b 8 8 // Created On : Sat Nov 29 07:23:41 2014 9 9 // Last Modified By : Peter A. Buhr 10 // Last Modified On : Mon May 4 17:21:02201511 // Update Count : 7010 // Last Modified On : Wed Mar 18 11:36:59 2015 11 // Update Count : 69 12 12 // 13 13 -
translator/CodeGen/CodeGenerator2.cc
r4bf5298 rb1a6d6b 631 631 case Declaration::NoStorageClass: 632 632 break; 633 case Declaration::Auto: 634 break; 635 case Declaration::Static: 636 before << "static "; 637 break; 633 638 case Declaration::Extern: 634 639 before << "extern "; 635 640 break; 636 case Declaration::Static:637 before << "static ";638 break;639 case Declaration::Auto:640 // silently drop storage class641 break;642 641 case Declaration::Register: 643 642 before << "register "; 644 643 break; 645 case Declaration::Inline:646 before << "inline ";647 break;648 644 case Declaration::Fortran: 649 645 before << "fortran "; -
translator/ControlStruct/ForExprMutator.cc
r4bf5298 rb1a6d6b 5 5 namespace ControlStruct { 6 6 Statement *ForExprMutator::mutate( ForStmt *forStmt ) { 7 // recurse down all nest for loops to hoist any initializer declarations to make them C89 (rather than C99)8 7 forStmt->set_body( forStmt->get_body()->acceptMutator( *this ) ); 9 8 if ( DeclStmt *decl = dynamic_cast< DeclStmt * > ( forStmt->get_initialization() ) ) { 10 // create compound statement, move initializerdeclaration outside, leave _for_ as-is9 // create compound statement, move declaration outside, leave _for_ as-is 11 10 CompoundStmt *block = new CompoundStmt( std::list< Label >() ); 12 11 std::list<Statement *> &stmts = block->get_kids(); … … 18 17 return block; 19 18 } // if 20 21 return forStmt; 19 // ForStmt still needs to be fixed 20 else 21 return forStmt; 22 22 } 23 23 } // namespace ControlStruct -
translator/Parser/DeclarationNode.cc
r4bf5298 rb1a6d6b 50 50 const char *storageClassName[] = { 51 51 // order must correspond with DeclarationNode::StorageClass 52 "extern",53 52 "static", 54 53 "auto", 54 "extern", 55 55 "register", 56 56 "inline", … … 880 880 Declaration::StorageClass DeclarationNode::buildStorageClass() const { 881 881 static const Declaration::StorageClass scMap[] = { 882 Declaration::Extern,883 882 Declaration::Static, 884 883 Declaration::Auto, 884 Declaration::Extern, 885 885 Declaration::Register, 886 Declaration:: Inline,886 Declaration::NoStorageClass, // inline 887 887 Declaration::Fortran 888 888 }; -
translator/Parser/ParseNode.h
r4bf5298 rb1a6d6b 262 262 class DeclarationNode : public ParseNode { 263 263 public: 264 enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic , Attribute};265 enum StorageClass { Extern, Static, Auto, Register, Inline, Fortran };264 enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic }; 265 enum StorageClass { Static, Auto, Extern, Register, Inline, Fortran }; 266 266 enum BasicType { Char, Int, Float, Double, Void, Bool, Complex, Imaginary }; 267 267 enum Modifier { Signed, Unsigned, Short, Long }; -
translator/Parser/TypeData.cc
r4bf5298 rb1a6d6b 544 544 case DeclarationNode::Atomic: 545 545 q.isAtomic = true; 546 break;547 case DeclarationNode::Attribute:548 q.isAttribute = true;549 546 break; 550 547 } -
translator/Parser/cfa.y
r4bf5298 rb1a6d6b 1 // -*- Mode: C++ -*- 2 // 3 // CForall Grammar Version 1.0, Copyright (C) Peter A. Buhr 2001 4 // 5 // cfa.y -- 6 // 7 // Author : Peter A. Buhr 8 // Created On : Sat Sep 1 20:22:55 2001 9 // Last Modified By : Peter A. Buhr 10 // Last Modified On : Tue May 12 17:24:53 2015 11 // Update Count : 963 12 // 13 14 // This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C 15 // grammar by James A. Roskind, specifically parts of DECLARATIONS and EXTERNAL DEFINITIONS. While parts have been 16 // copied, important changes have been made in all sections; these changes are sufficient to constitute a new grammar. 17 // In particular, this grammar attempts to be more syntactically precise, i.e., it parses less incorrect language syntax 18 // that must be subsequently rejected by semantic checks. Nevertheless, there are still several semantic checks 19 // required and many are noted in the grammar. Finally, the grammar is extended with GCC and CFA language extensions. 20 21 // Acknowledgments to Richard Bilson, Glen Ditchfield, and Rodolfo Gabriel Esteves who all helped when I got stuck with 22 // the grammar. 23 24 // The root language for this grammar is ANSI99/11 C. All of ANSI99/11 is parsed, except for: 25 // 26 // 1. designation with '=' (use ':' instead) 27 // 28 // Most of the syntactic extensions from ANSI90 to ANSI11 C are marked with the comment "C99/C11". This grammar also has 29 // two levels of extensions. The first extensions cover most of the GCC C extensions, except for: 30 // 31 // 1. nested functions 32 // 2. generalized lvalues 33 // 3. designation with and without '=' (use ':' instead) 34 // 4. attributes not allowed in parenthesis of declarator 35 // 36 // All of the syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for Cforall 37 // (CFA), which fixes several of C's outstanding problems and extends C with many modern language concepts. All of the 38 // syntactic extensions for CFA C are marked with the comment "CFA". As noted above, there is one unreconcileable 39 // parsing problem between C99 and CFA with respect to designators; this is discussed in detail before the "designation" 40 // grammar rule. 1 /* -*- Mode: C -*- 2 * 3 * CForall Grammar Version 1.0, Copyright (C) Peter A. Buhr 2001 -- Permission is granted to copy this 4 * grammar and to use it within software systems. THIS GRAMMAR IS PROVIDED "AS IS" AND WITHOUT 5 * ANY EXPRESS OR IMPLIED WARRANTIES. 6 * 7 * cfa.y -- 8 * 9 * Author : Peter A. Buhr 10 * Created On : Sat Sep 1 20:22:55 2001 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Wed Apr 15 15:11:16 2015 13 * Update Count : 913 14 */ 15 16 /* This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on 17 the C grammar by James A. Roskind, specifically parts of DECLARATIONS and EXTERNAL DEFINITIONS. While 18 parts have been copied, important changes have been made in all sections; these changes are sufficient to 19 constitute a new grammar. In particular, this grammar attempts to be more syntactically precise, i.e., it 20 parses less incorrect language syntax that must be subsequently rejected by semantic checks. Nevertheless, 21 there are still several semantic checks required and many are noted in the grammar. Finally, the grammar is 22 extended with GCC and CFA language extensions. */ 23 24 /* Acknowledgments to Richard Bilson, Glen Ditchfield, and Rodolfo Gabriel Esteves who all helped when I got 25 stuck with the grammar. */ 26 27 /* The root language for this grammar is ANSI99/11 C. All of ANSI99/11 is parsed, except for: 28 29 1. designation with '=' (use ':' instead) 30 31 Most of the syntactic extensions from ANSI90 to ANSI11 C are marked with the comment "C99/C11". This grammar 32 also has two levels of extensions. The first extensions cover most of the GCC C extensions, except for: 33 34 1. nested functions 35 2. generalized lvalues 36 3. designation with and without '=' (use ':' instead) 37 4. attributes not allowed in parenthesis of declarator 38 39 All of the syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for 40 Cforall (CFA), which fixes several of C's outstanding problems and extends C with many modern language 41 concepts. All of the syntactic extensions for CFA C are marked with the comment "CFA". As noted above, 42 there is one unreconcileable parsing problem between C99 and CFA with respect to designators; this is 43 discussed in detail before the "designation" grammar rule. */ 41 44 42 45 %{ 43 #define YYDEBUG_LEXER_TEXT (yylval) / / lexer loads this up each time44 #define YYDEBUG 1 / / get the pretty debugging code to compile46 #define YYDEBUG_LEXER_TEXT (yylval) /* lexer loads this up each time */ 47 #define YYDEBUG 1 /* get the pretty debugging code to compile*/ 45 48 46 49 #undef __GNUC_MINOR__ … … 53 56 #include "LinkageSpec.h" 54 57 55 DeclarationNode *theTree = 0; / / the resulting parse tree58 DeclarationNode *theTree = 0; /* the resulting parse tree */ 56 59 LinkageSpec::Type linkage = LinkageSpec::Cforall; 57 60 std::stack< LinkageSpec::Type > linkageStack; … … 59 62 %} 60 63 61 / /************************* TERMINAL TOKENS ********************************62 63 / / keywords64 /************************* TERMINAL TOKENS ********************************/ 65 66 /* keywords */ 64 67 %token TYPEDEF 65 68 %token AUTO EXTERN REGISTER STATIC 66 %token INLINE / / C9967 %token FORTRAN / / C99, extension ISO/IEC 9899:1999 Section J.5.9(1)69 %token INLINE /* C99 */ 70 %token FORTRAN /* C99, extension ISO/IEC 9899:1999 Section J.5.9(1) */ 68 71 %token CONST VOLATILE 69 %token RESTRICT / / C9970 %token FORALL LVALUE / / CFA72 %token RESTRICT /* C99 */ 73 %token FORALL LVALUE /* CFA */ 71 74 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED 72 %token BOOL COMPLEX IMAGINARY / / C9973 %token TYPEOF LABEL / / GCC75 %token BOOL COMPLEX IMAGINARY /* C99 */ 76 %token TYPEOF LABEL /* GCC */ 74 77 %token ENUM STRUCT UNION 75 %token TYPE FTYPE DTYPE CONTEXT / / CFA78 %token TYPE FTYPE DTYPE CONTEXT /* CFA */ 76 79 %token SIZEOF 77 %token ATTRIBUTE EXTENSION / / GCC80 %token ATTRIBUTE EXTENSION /* GCC */ 78 81 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN 79 %token CHOOSE FALLTHRU TRY CATCH FINALLY THROW / / CFA80 %token ASM / / C99, extension ISO/IEC 9899:1999 Section J.5.10(1)81 %token ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATICASSERT THREADLOCAL / / C1182 83 / / names and constants: lexer differentiates between identifier and typedef names82 %token CHOOSE FALLTHRU TRY CATCH FINALLY THROW /* CFA */ 83 %token ASM /* C99, extension ISO/IEC 9899:1999 Section J.5.10(1) */ 84 %token ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATICASSERT THREADLOCAL /* C11 */ 85 86 /* names and constants: lexer differentiates between identifier and typedef names */ 84 87 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDEFname TYPEGENname 85 88 %token<tok> ATTR_IDENTIFIER ATTR_TYPEDEFname ATTR_TYPEGENname 86 89 %token<tok> INTEGERconstant FLOATINGconstant CHARACTERconstant STRINGliteral 87 %token<tok> ZERO ONE / / CFA88 89 / / multi-character operators90 %token<tok> ZERO ONE /* CFA */ 91 92 /* multi-character operators */ 90 93 %token ARROW /* -> */ 91 94 %token ICR DECR /* ++ -- */ … … 100 103 %token ANDassign ERassign ORassign /* &= ^= |= */ 101 104 102 / / Types declaration105 /* Types declaration */ 103 106 %union 104 107 { 105 Token tok;106 ParseNode *pn;107 ExpressionNode *en;108 DeclarationNode *decl;109 DeclarationNode::TyCon aggKey;110 DeclarationNode::TypeClass tclass;111 StatementNode *sn;112 ConstantNode *constant;113 InitializerNode *in;108 Token tok; 109 ParseNode *pn; 110 ExpressionNode *en; 111 DeclarationNode *decl; 112 DeclarationNode::TyCon aggKey; 113 DeclarationNode::TypeClass tclass; 114 StatementNode *sn; 115 ConstantNode *constant; 116 InitializerNode *in; 114 117 } 115 118 … … 118 121 %type<constant> string_literal_list 119 122 120 / / expressions123 /* expressions */ 121 124 %type<constant> constant 122 125 %type<en> tuple tuple_expression_list … … 131 134 %type<en> subrange 132 135 133 / / statements136 /* statements */ 134 137 %type<sn> labeled_statement compound_statement expression_statement selection_statement 135 138 %type<sn> iteration_statement jump_statement exception_statement asm_statement … … 143 146 %type<pn> handler_list handler_clause finally_clause 144 147 145 / / declarations148 /* declarations */ 146 149 %type<decl> abstract_array abstract_declarator abstract_function abstract_parameter_array 147 150 %type<decl> abstract_parameter_declaration abstract_parameter_declarator abstract_parameter_function … … 225 228 %type<decl> variable_abstract_ptr variable_array variable_declarator variable_function variable_ptr 226 229 227 / / initializers230 /* initializers */ 228 231 %type<in> initializer initializer_list initializer_opt 229 232 230 / / designators233 /* designators */ 231 234 %type<en> designator designator_list designation 232 235 233 236 234 / / Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string is235 //ambiguous:236 //.---------. matches IF '(' comma_expression ')' statement237 //if ( C ) S1 else S2238 //`-----------------' matches IF '(' comma_expression ')' statement ELSE statement */239 240 %nonassoc THEN / / rule precedence for IF '(' comma_expression ')' statement241 %nonassoc ELSE / / token precedence for start of else clause in IF statement242 243 %start translation_unit / / parse-tree root237 /* Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string 238 is ambiguous: 239 .---------. matches IF '(' comma_expression ')' statement 240 if ( C ) S1 else S2 241 `-----------------' matches IF '(' comma_expression ')' statement ELSE statement */ 242 243 %nonassoc THEN /* rule precedence for IF '(' comma_expression ')' statement */ 244 %nonassoc ELSE /* token precedence for start of else clause in IF statement */ 245 246 %start translation_unit /* parse-tree root */ 244 247 245 248 %% 246 //************************* Namespace Management ******************************** 247 248 // The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal symbols 249 // "identifier" and "TYPEDEFname" that are lexically identical. While it is possible to write a purely context-free 250 // grammar, such a grammar would obscure the relationship between syntactic and semantic constructs. Hence, this 251 // grammar uses the ANSI style. 252 // 253 // Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, those 254 // introduced through "forall" qualifiers), and by introducing "type generators" -- parametrized types. This latter 255 // type name creates a third class of identifiers that must be distinguished by the scanner. 256 // 257 // Since the scanner cannot distinguish among the different classes of identifiers without some context information, it 258 // accesses a data structure (the TypedefTable) to allow classification of an identifier that it has just read. 259 // Semantic actions during the parser update this data structure when the class of identifiers change. 260 // 261 // Because the Cforall language is block-scoped, there is the possibility that an identifier can change its class in a 262 // local scope; it must revert to its original class at the end of the block. Since type names can be local to a 263 // particular declaration, each declaration is itself a scope. This requires distinguishing between type names that are 264 // local to the current declaration scope and those that persist past the end of the declaration (i.e., names defined in 265 // "typedef" or "type" declarations). 266 // 267 // The non-terminals "push" and "pop" derive the empty string; their only use is to denote the opening and closing of 268 // scopes. Every push must have a matching pop, although it is regrettable the matching pairs do not always occur 269 // within the same rule. These non-terminals may appear in more contexts than strictly necessary from a semantic point 270 // of view. Unfortunately, these extra rules are necessary to prevent parsing conflicts -- the parser may not have 271 // enough context and look-ahead information to decide whether a new scope is necessary, so the effect of these extra 272 // rules is to open a new scope unconditionally. As the grammar evolves, it may be neccesary to add or move around 273 // "push" and "pop" nonterminals to resolve conflicts of this sort. 249 /************************* Namespace Management ********************************/ 250 251 /* The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal 252 symbols "identifier" and "TYPEDEFname" that are lexically identical. While it is possible to write a 253 purely context-free grammar, such a grammar would obscure the relationship between syntactic and semantic 254 constructs. Hence, this grammar uses the ANSI style. 255 256 Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, 257 those introduced through "forall" qualifiers), and by introducing "type generators" -- parametrized types. 258 This latter type name creates a third class of identifiers that must be distinguished by the scanner. 259 260 Since the scanner cannot distinguish among the different classes of identifiers without some context 261 information, it accesses a data structure (the TypedefTable) to allow classification of an identifier that 262 it has just read. Semantic actions during the parser update this data structure when the class of 263 identifiers change. 264 265 Because the Cforall language is block-scoped, there is the possibility that an identifier can change its 266 class in a local scope; it must revert to its original class at the end of the block. Since type names can 267 be local to a particular declaration, each declaration is itself a scope. This requires distinguishing 268 between type names that are local to the current declaration scope and those that persist past the end of 269 the declaration (i.e., names defined in "typedef" or "type" declarations). 270 271 The non-terminals "push" and "pop" derive the empty string; their only use is to denote the opening and 272 closing of scopes. Every push must have a matching pop, although it is regrettable the matching pairs do 273 not always occur within the same rule. These non-terminals may appear in more contexts than strictly 274 necessary from a semantic point of view. Unfortunately, these extra rules are necessary to prevent parsing 275 conflicts -- the parser may not have enough context and look-ahead information to decide whether a new 276 scope is necessary, so the effect of these extra rules is to open a new scope unconditionally. As the 277 grammar evolves, it may be neccesary to add or move around "push" and "pop" nonterminals to resolve 278 conflicts of this sort. */ 274 279 275 280 push: … … 285 290 ; 286 291 287 / /************************* CONSTANTS ********************************292 /************************* CONSTANTS ********************************/ 288 293 289 294 constant: 290 / / ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration291 // constant".295 /* ENUMERATIONconstant is not included here; it is treated as a variable with type 296 "enumeration constant". */ 292 297 INTEGERconstant { $$ = new ConstantNode(ConstantNode::Integer, $1); } 293 298 | FLOATINGconstant { $$ = new ConstantNode(ConstantNode::Float, $1); } … … 297 302 identifier: 298 303 IDENTIFIER 299 | ATTR_IDENTIFIER / / CFA300 | zero_one / / CFA304 | ATTR_IDENTIFIER /* CFA */ 305 | zero_one /* CFA */ 301 306 ; 302 307 303 308 no_01_identifier: 304 309 IDENTIFIER 305 | ATTR_IDENTIFIER / / CFA310 | ATTR_IDENTIFIER /* CFA */ 306 311 ; 307 312 … … 310 315 ; 311 316 312 zero_one: / / CFA317 zero_one: /* CFA */ 313 318 ZERO 314 319 | ONE 315 320 ; 316 321 317 string_literal_list: / / juxtaposed strings are concatenated322 string_literal_list: /* juxtaposed strings are concatenated */ 318 323 STRINGliteral { $$ = new ConstantNode(ConstantNode::String, $1); } 319 324 | string_literal_list STRINGliteral { $$ = $1->append( $2 ); } 320 325 ; 321 326 322 / /************************* EXPRESSIONS ********************************327 /************************* EXPRESSIONS ********************************/ 323 328 324 329 primary_expression: 325 IDENTIFIER / / typedef name cannot be used as a variable name330 IDENTIFIER /* typedef name cannot be used as a variable name */ 326 331 { $$ = new VarRefNode($1); } 327 332 | zero_one … … 333 338 | '(' comma_expression ')' 334 339 { $$ = $2; } 335 | '(' compound_statement ')' / / GCC, lambda expression340 | '(' compound_statement ')' /* GCC, lambda expression */ 336 341 { $$ = new ValofExprNode($2); } 337 342 ; … … 340 345 primary_expression 341 346 | postfix_expression '[' push assignment_expression pop ']' 342 //CFA, comma_expression disallowed in the context because it results in a commom user error:343 //subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards344 // compatible, there seems to be little advantage to this feature and many disadvantages. It is345 // possible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j].347 /* CFA, comma_expression disallowed in the context because it results in a commom user error: 348 subscripting a matrix with x[i,j] instead of x[i][j]. While this change is not backwards 349 compatible, there seems to be little advantage to this feature and many disadvantages. It 350 is possible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j]. */ 346 351 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Index), $1, $4); } 347 352 | postfix_expression '(' argument_expression_list ')' … … 349 354 | postfix_expression '.' no_attr_identifier 350 355 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), $1, new VarRefNode($3)); } 351 | postfix_expression '.' '[' push field_list pop ']' / / CFA, tuple field selector356 | postfix_expression '.' '[' push field_list pop ']' /* CFA, tuple field selector */ 352 357 | postfix_expression ARROW no_attr_identifier 353 358 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), $1, new VarRefNode($3)); } 354 | postfix_expression ARROW '[' push field_list pop ']' / / CFA, tuple field selector359 | postfix_expression ARROW '[' push field_list pop ']' /* CFA, tuple field selector */ 355 360 | postfix_expression ICR 356 361 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost), $1); } 357 362 | postfix_expression DECR 358 363 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost), $1); } 359 / / GCC has priority: cast_expression360 | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' / / C99364 /* GCC has priority: cast_expression */ 365 | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' /* C99 */ 361 366 { $$ = 0; } 362 367 ; … … 369 374 370 375 argument_expression: 371 / / empty372 { $$ = 0; } // use default argument376 /* empty */ /* use default argument */ 377 { $$ = 0; } 373 378 | assignment_expression 374 379 | no_attr_identifier ':' assignment_expression 375 380 { $$ = $3->set_asArgName($1); } 376 / / Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However, there is377 // insufficient look ahead to distinguish between this list of parameter names and a tuple, so the378 // tuple form must be used with an appropriate semantic check.381 /* Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However, there 382 is insufficient look ahead to distinguish between this list of parameter names and a tuple, 383 so the tuple form must be used with an appropriate semantic check. */ 379 384 | '[' push assignment_expression pop ']' ':' assignment_expression 380 { $$ = $7->set_asArgName($3); }385 { $$ = $7->set_asArgName($3); } 381 386 | '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression 382 { $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); }383 ; 384 385 field_list: / / CFA, tuple field selector387 { $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); } 388 ; 389 390 field_list: /* CFA, tuple field selector */ 386 391 field 387 392 | field_list ',' field { $$ = (ExpressionNode *)$1->set_link( $3 ); } 388 393 ; 389 394 390 field: / / CFA, tuple field selector395 field: /* CFA, tuple field selector */ 391 396 no_attr_identifier 392 397 { $$ = new VarRefNode( $1 ); } … … 407 412 | DECR unary_expression 408 413 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr), $2); } 409 | EXTENSION cast_expression / / GCC414 | EXTENSION cast_expression /* GCC */ 410 415 { $$ = $2; } 411 416 | unary_operator cast_expression … … 413 418 | '!' cast_expression 414 419 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg), $2); } 415 | '*' cast_expression / / CFA420 | '*' cast_expression /* CFA */ 416 421 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo), $2); } 417 / /'*' is is separated from unary_operator because of shift/reduce conflict in:418 //{ * X; } // dereference X419 //{ * int X; } // CFA declaration of pointer to int420 // '&' must be moved here if C++ reference variables are supported.422 /* '*' is is separated from unary_operator because of shift/reduce conflict in: 423 { * X; } // dereference X 424 { * int X; } // CFA declaration of pointer to int 425 '&' must be moved here if C++ reference variables are supported. */ 421 426 | SIZEOF unary_expression 422 427 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), $2); } … … 429 434 | ATTR_IDENTIFIER '(' argument_expression ')' 430 435 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), $3); } 431 | ALIGNOF unary_expression / / GCC, variable alignment436 | ALIGNOF unary_expression /* GCC, variable alignment */ 432 437 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), $2); } 433 | ALIGNOF '(' type_name_no_function ')' / / GCC, type alignment438 | ALIGNOF '(' type_name_no_function ')' /* GCC, type alignment */ 434 439 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), new TypeValueNode($3)); } 435 | ANDAND no_attr_identifier / / GCC, address of label440 | ANDAND no_attr_identifier /* GCC, address of label */ 436 441 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress), new VarRefNode($2, true)); } 437 442 ; … … 533 538 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), 534 539 (ExpressionNode *)mkList((*$1,*$3,*$5))); } 535 | logical_OR_expression '?' /* empty */ ':' conditional_expression / / GCC, omitted first operand540 | logical_OR_expression '?' /* empty */ ':' conditional_expression /* GCC, omitted first operand */ 536 541 { $$=new CompositeExprNode(new OperatorNode(OperatorNode::NCond),$1,$4); } 537 | logical_OR_expression '?' comma_expression ':' tuple / / CFA, tuple expression542 | logical_OR_expression '?' comma_expression ':' tuple /* CFA, tuple expression */ 538 543 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), 539 544 (ExpressionNode *)mkList(( *$1, *$3, *$5 ))); } … … 545 550 546 551 assignment_expression: 547 // CFA, assignment is separated from assignment_operator to ensure no assignment operations for tuples 552 /* CFA, assignment is separated from assignment_operator to ensure no assignment operations 553 for tuples */ 548 554 conditional_expression 549 555 | unary_expression '=' assignment_expression … … 551 557 | unary_expression assignment_operator assignment_expression 552 558 { $$ =new CompositeExprNode($2, $1, $3); } 553 | tuple assignment_opt / / CFA, tuple expression559 | tuple assignment_opt /* CFA, tuple expression */ 554 560 { 555 561 if ( $2 == 0 ) { … … 562 568 563 569 assignment_expression_opt: 564 / / empty570 /* empty */ 565 571 { $$ = new NullExprNode; } 566 572 | assignment_expression 567 573 ; 568 574 569 tuple: // CFA, tuple 570 // CFA, one assignment_expression is factored out of comma_expression to eliminate a shift/reduce 571 // conflict with comma_expression in new_identifier_parameter_array and new_abstract_array 575 tuple: /* CFA, tuple */ 576 /* CFA, one assignment_expression is factored out of comma_expression to eliminate a 577 shift/reduce conflict with comma_expression in new_identifier_parameter_array and 578 new_abstract_array */ 572 579 '[' push pop ']' 573 580 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); } … … 601 608 comma_expression: 602 609 assignment_expression 603 | comma_expression ',' assignment_expression / / { $$ = (ExpressionNode *)$1->add_to_list($3); }610 | comma_expression ',' assignment_expression /* { $$ = (ExpressionNode *)$1->add_to_list($3); } */ 604 611 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma),$1,$3); } 605 612 ; 606 613 607 614 comma_expression_opt: 608 // empty 609 { $$ = 0; } 615 /* empty */ { $$ = 0; } 610 616 | comma_expression 611 617 ; 612 618 613 / /*************************** STATEMENTS *******************************619 /*************************** STATEMENTS *******************************/ 614 620 615 621 statement: … … 633 639 { $$ = new CompoundStmtNode( (StatementNode *)0 ); } 634 640 | '{' 635 / / Two scopes are necessary because the block itself has a scope, but every declaration within the block636 // also requires its own scope641 /* Two scopes are necessary because the block itself has a scope, but every declaration within 642 the block also requires its own scope */ 637 643 push push 638 label_declaration_opt / / GCC, local labels639 block_item_list pop '}' / / C99, intermix declarations and statements644 label_declaration_opt /* GCC, local labels */ 645 block_item_list pop '}' /* C99, intermix declarations and statements */ 640 646 { $$ = new CompoundStmtNode( $5 ); } 641 647 ; 642 648 643 block_item_list: / / C99649 block_item_list: /* C99 */ 644 650 block_item 645 651 | block_item_list push block_item … … 648 654 649 655 block_item: 650 declaration / / CFA, new & old style declarations656 declaration /* CFA, new & old style declarations */ 651 657 { $$ = new StatementNode( $1 ); } 652 | EXTENSION declaration / / GCC658 | EXTENSION declaration /* GCC */ 653 659 { $$ = new StatementNode( $2 ); } 654 660 | statement pop … … 668 674 selection_statement: 669 675 IF '(' comma_expression ')' statement %prec THEN 670 / / explicitly deal with the shift/reduce conflict on if/else676 /* explicitly deal with the shift/reduce conflict on if/else */ 671 677 { $$ = new StatementNode(StatementNode::If, $3, $5); } 672 678 | IF '(' comma_expression ')' statement ELSE statement 673 679 { $$ = new StatementNode(StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7)) ); } 674 | SWITCH '(' comma_expression ')' case_clause / / CFA680 | SWITCH '(' comma_expression ')' case_clause /* CFA */ 675 681 { $$ = new StatementNode(StatementNode::Switch, $3, $5); } 676 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' / / CFA682 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' /* CFA */ 677 683 { $$ = new StatementNode(StatementNode::Switch, $3, $8); /* xxx */ } 678 / / The semantics of the declaration list is changed to include any associated initialization, which is679 // performed *before* the transfer to the appropriate case clause. Statements after the initial680 // declaration list can never be executed, and therefore, are removed from the grammar even though C681 // allows it.682 | CHOOSE '(' comma_expression ')' case_clause / / CFA684 /* The semantics of the declaration list is changed to include any associated initialization, 685 which is performed *before* the transfer to the appropriate case clause. Statements after 686 the initial declaration list can never be executed, and therefore, are removed from the 687 grammar even though C allows it. */ 688 | CHOOSE '(' comma_expression ')' case_clause /* CFA */ 683 689 { $$ = new StatementNode(StatementNode::Choose, $3, $5); } 684 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' / / CFA690 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' /* CFA */ 685 691 { $$ = new StatementNode(StatementNode::Choose, $3, $8); } 686 692 ; 687 693 688 / / CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case689 // clause allows a list of values and subranges. 690 691 case_value: / / CFA694 /* CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a 695 case clause allows a list of values and subranges. */ 696 697 case_value: /* CFA */ 692 698 constant_expression { $$ = $1; } 693 | constant_expression ELLIPSIS constant_expression / / GCC, subrange699 | constant_expression ELLIPSIS constant_expression /* GCC, subrange */ 694 700 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range),$1,$3); } 695 | subrange / / CFA, subrange696 ; 697 698 case_value_list: / / CFA701 | subrange /* CFA, subrange */ 702 ; 703 704 case_value_list: /* CFA */ 699 705 case_value 700 706 | case_value_list ',' case_value … … 702 708 ; 703 709 704 case_label: / / CFA710 case_label: /* CFA */ 705 711 CASE case_value_list ':' { $$ = new StatementNode(StatementNode::Case, $2, 0); } 706 712 | DEFAULT ':' { $$ = new StatementNode(StatementNode::Default); } 707 // A semantic check is required to ensure only one default clause per switch/choose statement. 708 ; 709 710 case_label_list: // CFA 713 /* A semantic check is required to ensure only one default clause per switch/choose 714 statement. */ 715 ; 716 717 case_label_list: /* CFA */ 711 718 case_label 712 719 | case_label_list case_label { $$ = (StatementNode *)($1->set_link($2)); } 713 720 ; 714 721 715 case_clause: / / CFA722 case_clause: /* CFA */ 716 723 case_label_list statement { $$ = $1->append_last_case($2); } 717 724 ; 718 725 719 switch_clause_list_opt: // CFA 720 // empty 721 { $$ = 0; } 726 switch_clause_list_opt: /* CFA */ 727 /* empty */ { $$ = 0; } 722 728 | switch_clause_list 723 729 ; 724 730 725 switch_clause_list: / / CFA731 switch_clause_list: /* CFA */ 726 732 case_label_list statement_list 727 733 { $$ = $1->append_last_case($2); } … … 730 736 ; 731 737 732 choose_clause_list_opt: // CFA 733 // empty 734 { $$ = 0; } 738 choose_clause_list_opt: /* CFA */ 739 /* empty */ { $$ = 0; } 735 740 | choose_clause_list 736 741 ; 737 742 738 choose_clause_list: / / CFA743 choose_clause_list: /* CFA */ 739 744 case_label_list fall_through 740 { $$ = $1->append_last_case($2); }745 { $$ = $1->append_last_case($2); } 741 746 | case_label_list statement_list fall_through_opt 742 { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); }747 { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); } 743 748 | choose_clause_list case_label_list fall_through 744 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); }749 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); } 745 750 | choose_clause_list case_label_list statement_list fall_through_opt 746 { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); } 747 ; 748 749 fall_through_opt: // CFA 750 // empty 751 { $$ = 0; } 751 { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); } 752 ; 753 754 fall_through_opt: /* CFA */ 755 /* empty */ { $$ = 0; } 752 756 | fall_through 753 757 ; 754 758 755 fall_through: / / CFA759 fall_through: /* CFA */ 756 760 FALLTHRU { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); } 757 761 | FALLTHRU ';' { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); } … … 770 774 comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt 771 775 { $$ = new ForCtlExprNode($1, $4, $6); } 772 | declaration comma_expression_opt ';' comma_expression_opt / / C99773 / / Like C++, the loop index can be declared local to the loop.776 | declaration comma_expression_opt ';' comma_expression_opt /* C99 */ 777 /* Like C++, the loop index can be declared local to the loop. */ 774 778 { $$ = new ForCtlExprNode($1, $2, $4); } 775 779 ; … … 778 782 GOTO no_attr_identifier ';' 779 783 { $$ = new StatementNode(StatementNode::Goto, $2); } 780 | GOTO '*' comma_expression ';' / / GCC, computed goto781 / / The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; =>782 // goto *(i+3); whereas normal operator precedence yields goto (*i)+3;784 | GOTO '*' comma_expression ';' /* GCC, computed goto */ 785 /* The syntax for the GCC computed goto violates normal expression precedence, e.g., 786 goto *i+3; => goto *(i+3); whereas normal operator precedence yields goto (*i)+3; */ 783 787 { $$ = new StatementNode(StatementNode::Goto, $3); } 784 788 | CONTINUE ';' 785 / / A semantic check is required to ensure this statement appears only in the body of an iteration786 // statement.789 /* A semantic check is required to ensure this statement appears only in the body of an 790 iteration statement. */ 787 791 { $$ = new StatementNode(StatementNode::Continue, 0, 0); } 788 | CONTINUE no_attr_identifier ';' // CFA, multi-level continue 789 // A semantic check is required to ensure this statement appears only in the body of an iteration 790 // statement, and the target of the transfer appears only at the start of an iteration statement. 792 | CONTINUE no_attr_identifier ';' /* CFA, multi-level continue */ 793 /* A semantic check is required to ensure this statement appears only in the body of an 794 iteration statement, and the target of the transfer appears only at the start of an 795 iteration statement. */ 791 796 { $$ = new StatementNode(StatementNode::Continue, $2); } 792 797 | BREAK ';' 793 / / A semantic check is required to ensure this statement appears only in the body of an iteration794 // statement.798 /* A semantic check is required to ensure this statement appears only in the body of an 799 iteration statement. */ 795 800 { $$ = new StatementNode(StatementNode::Break, 0, 0); } 796 | BREAK no_attr_identifier ';' // CFA, multi-level exit 797 // A semantic check is required to ensure this statement appears only in the body of an iteration 798 // statement, and the target of the transfer appears only at the start of an iteration statement. 801 | BREAK no_attr_identifier ';' /* CFA, multi-level exit */ 802 /* A semantic check is required to ensure this statement appears only in the body of an 803 iteration statement, and the target of the transfer appears only at the start of an 804 iteration statement. */ 799 805 { $$ = new StatementNode(StatementNode::Break, $2 ); } 800 806 | RETURN comma_expression_opt ';' … … 819 825 820 826 handler_list: 821 / / There must be at least one catch clause827 /* There must be at least one catch clause */ 822 828 handler_clause 823 / / ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for its try824 // block.829 /* ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for 830 its try block. */ 825 831 | CATCH '(' ELLIPSIS ')' compound_statement 826 832 { $$ = StatementNode::newCatchStmt( 0, $5, true ); } … … 844 850 845 851 exception_declaration: 846 / /A semantic check is required to ensure type_specifier does not create a new type, e.g.:847 // 848 //catch ( struct { int i; } x ) ...849 // 850 // This new type cannot catch any thrown type because of name equivalence among types.852 /* A semantic check is required to ensure type_specifier does not create a new type, e.g.: 853 854 catch ( struct { int i; } x ) ... 855 856 This new type cannot catch any thrown type because of name equivalence among types. */ 851 857 type_specifier 852 858 | type_specifier declarator … … 857 863 | type_specifier variable_abstract_declarator 858 864 { $$ = $2->addType( $1 ); } 859 | new_abstract_declarator_tuple no_attr_identifier / / CFA865 | new_abstract_declarator_tuple no_attr_identifier /* CFA */ 860 866 { 861 867 typedefTable.addToEnclosingScope( TypedefTable::ID ); 862 868 $$ = $1->addName( $2 ); 863 869 } 864 | new_abstract_declarator_tuple / / CFA870 | new_abstract_declarator_tuple /* CFA */ 865 871 ; 866 872 … … 868 874 ASM type_qualifier_list_opt '(' constant_expression ')' ';' 869 875 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 870 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' / / remaining GCC876 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' /* remaining GCC */ 871 877 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 872 878 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ')' ';' … … 877 883 ; 878 884 879 asm_operands_opt: / / GCC880 / / empty885 asm_operands_opt: /* GCC */ 886 /* empty */ 881 887 | asm_operands_list 882 888 ; 883 889 884 asm_operands_list: / / GCC890 asm_operands_list: /* GCC */ 885 891 asm_operand 886 892 | asm_operands_list ',' asm_operand 887 893 ; 888 894 889 asm_operand: / / GCC895 asm_operand: /* GCC */ 890 896 STRINGliteral '(' constant_expression ')' {} 891 897 ; 892 898 893 asm_clobbers_list: / / GCC899 asm_clobbers_list: /* GCC */ 894 900 STRINGliteral {} 895 901 | asm_clobbers_list ',' STRINGliteral 896 902 ; 897 903 898 / /******************************* DECLARATIONS *********************************899 900 declaration_list_opt: / / used at beginning of switch statement904 /******************************* DECLARATIONS *********************************/ 905 906 declaration_list_opt: /* used at beginning of switch statement */ 901 907 pop 902 908 { $$ = 0; } … … 910 916 ; 911 917 912 old_declaration_list_opt: / / used to declare parameter types in K&R style functions918 old_declaration_list_opt: /* used to declare parameter types in K&R style functions */ 913 919 pop 914 920 { $$ = 0; } … … 922 928 ; 923 929 924 label_declaration_opt: / / GCC, local label925 / / empty930 label_declaration_opt: /* GCC, local label */ 931 /* empty */ 926 932 | label_declaration_list 927 933 ; 928 934 929 label_declaration_list: / / GCC, local label935 label_declaration_list: /* GCC, local label */ 930 936 LABEL label_list ';' 931 937 | label_declaration_list LABEL label_list ';' 932 938 ; 933 939 934 label_list: / / GCC, local label940 label_list: /* GCC, local label */ 935 941 no_attr_identifier_or_typedef_name {} 936 942 | label_list ',' no_attr_identifier_or_typedef_name {} 937 943 ; 938 944 939 declaration: / / CFA, new & old style declarations945 declaration: /* CFA, new & old style declarations */ 940 946 new_declaration 941 947 | old_declaration 942 948 ; 943 949 944 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function 945 // declarations. CFA declarations use the same declaration tokens as in C; however, CFA places declaration modifiers to 946 // the left of the base type, while C declarations place modifiers to the right of the base type. CFA declaration 947 // modifiers are interpreted from left to right and the entire type specification is distributed across all variables in 948 // the declaration list (as in Pascal). ANSI C and the new CFA declarations may appear together in the same program 949 // block, but cannot be mixed within a specific declaration. 950 // 951 // CFA C 952 // [10] int x; int x[10]; // array of 10 integers 953 // [10] * char y; char *y[10]; // array of 10 pointers to char 954 955 new_declaration: // CFA 950 /* C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and 951 function declarations. CFA declarations use the same declaration tokens as in C; however, CFA places 952 declaration modifiers to the left of the base type, while C declarations place modifiers to the right of 953 the base type. CFA declaration modifiers are interpreted from left to right and the entire type 954 specification is distributed across all variables in the declaration list (as in Pascal). ANSI C and the 955 new CFA declarations may appear together in the same program block, but cannot be mixed within a specific 956 declaration. 957 958 CFA C 959 [10] int x; int x[10]; // array of 10 integers 960 [10] * char y; char *y[10]; // array of 10 pointers to char 961 */ 962 963 new_declaration: /* CFA */ 956 964 new_variable_declaration pop ';' 957 965 | new_typedef_declaration pop ';' … … 961 969 ; 962 970 963 new_variable_declaration: / / CFA971 new_variable_declaration: /* CFA */ 964 972 new_variable_specifier initializer_opt 965 973 { 966 typedefTable.addToEnclosingScope( TypedefTable::ID );974 typedefTable.addToEnclosingScope( TypedefTable::ID); 967 975 $$ = $1; 968 976 } 969 977 | declaration_qualifier_list new_variable_specifier initializer_opt 970 / / declaration_qualifier_list also includes type_qualifier_list, so a semantic check is necessary to971 // preclude them as a type_qualifier cannot appear in that context.972 { 973 typedefTable.addToEnclosingScope( TypedefTable::ID );978 /* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is 979 necessary to preclude them as a type_qualifier cannot appear in that context. */ 980 { 981 typedefTable.addToEnclosingScope( TypedefTable::ID); 974 982 $$ = $2->addQualifiers( $1 ); 975 983 } 976 984 | new_variable_declaration pop ',' push identifier_or_typedef_name initializer_opt 977 985 { 978 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );986 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID); 979 987 $$ = $1->appendList( $1->cloneType( $5 ) ); 980 988 } 981 989 ; 982 990 983 new_variable_specifier: / / CFA984 / / A semantic check is required to ensure asm_name only appears on declarations with implicit or985 // explicit static storage-class991 new_variable_specifier: /* CFA */ 992 /* A semantic check is required to ensure asm_name only appears on declarations with implicit 993 or explicit static storage-class */ 986 994 new_abstract_declarator_no_tuple identifier_or_typedef_name asm_name_opt 987 995 { … … 1001 1009 ; 1002 1010 1003 new_function_declaration: / / CFA1011 new_function_declaration: /* CFA */ 1004 1012 new_function_specifier 1005 1013 { 1006 typedefTable.addToEnclosingScope( TypedefTable::ID );1014 typedefTable.addToEnclosingScope( TypedefTable::ID); 1007 1015 $$ = $1; 1008 1016 } 1009 1017 | declaration_qualifier_list new_function_specifier 1010 / / declaration_qualifier_list also includes type_qualifier_list, so a semantic check is necessary to1011 // preclude them as a type_qualifier cannot appear in this context.1012 { 1013 typedefTable.addToEnclosingScope( TypedefTable::ID );1018 /* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is 1019 necessary to preclude them as a type_qualifier cannot appear in this context. */ 1020 { 1021 typedefTable.addToEnclosingScope( TypedefTable::ID); 1014 1022 $$ = $2->addQualifiers( $1 ); 1015 1023 } 1016 1024 | new_function_declaration pop ',' push identifier_or_typedef_name 1017 1025 { 1018 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );1026 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID); 1019 1027 $$ = $1->appendList( $1->cloneType( $5 ) ); 1020 1028 } 1021 1029 ; 1022 1030 1023 new_function_specifier: / / CFA1031 new_function_specifier: /* CFA */ 1024 1032 '[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')' 1025 1033 { … … 1052 1060 ; 1053 1061 1054 new_function_return: / / CFA1062 new_function_return: /* CFA */ 1055 1063 '[' push new_parameter_list pop ']' 1056 1064 { $$ = DeclarationNode::newTuple( $3 ); } … … 1061 1069 ; 1062 1070 1063 new_typedef_declaration: / / CFA1071 new_typedef_declaration: /* CFA */ 1064 1072 TYPEDEF new_variable_specifier 1065 1073 { … … 1094 1102 $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() ); 1095 1103 } 1096 | type_qualifier_list TYPEDEF type_specifier declarator / / remaining OBSOLESCENT (see 2)1104 | type_qualifier_list TYPEDEF type_specifier declarator /* remaining OBSOLESCENT (see 2) */ 1097 1105 { 1098 1106 typedefTable.addToEnclosingScope( TypedefTable::TD); … … 1111 1119 ; 1112 1120 1113 typedef_expression: / / GCC, naming expression type1121 typedef_expression: /* GCC, naming expression type */ 1114 1122 TYPEDEF no_attr_identifier '=' assignment_expression 1115 1123 { … … 1127 1135 declaring_list pop ';' 1128 1136 | typedef_declaration pop ';' 1129 | typedef_expression pop ';' / / GCC, naming expression type1137 | typedef_expression pop ';' /* GCC, naming expression type */ 1130 1138 | sue_declaration_specifier pop ';' 1131 1139 ; … … 1141 1149 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 1142 1150 { 1143 typedefTable.addToEnclosingScope( TypedefTable::ID );1151 typedefTable.addToEnclosingScope( TypedefTable::ID); 1144 1152 $$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) ); 1145 1153 } 1146 1154 ; 1147 1155 1148 declaration_specifier: / / type specifier + storage class1156 declaration_specifier: /* type specifier + storage class */ 1149 1157 basic_declaration_specifier 1150 1158 | sue_declaration_specifier … … 1153 1161 ; 1154 1162 1155 type_specifier: / / declaration specifier - storage class1163 type_specifier: /* declaration specifier - storage class */ 1156 1164 basic_type_specifier 1157 1165 | sue_type_specifier … … 1160 1168 ; 1161 1169 1162 type_qualifier_list_opt: / / GCC, used in asm_statement1163 / / empty1170 type_qualifier_list_opt: /* GCC, used in asm_statement */ 1171 /* empty */ 1164 1172 { $$ = 0; } 1165 1173 | type_qualifier_list … … 1181 1189 type_qualifier_name 1182 1190 | attribute 1183 { $$ = DeclarationNode::newQualifier( DeclarationNode:: Attribute); }1191 { $$ = DeclarationNode::newQualifier( DeclarationNode::Const ); } 1184 1192 ; 1185 1193 … … 1191 1199 | VOLATILE 1192 1200 { $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile ); } 1193 | LVALUE / / CFA1201 | LVALUE /* CFA */ 1194 1202 { $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); } 1195 1203 | ATOMIC 1196 1204 { $$ = DeclarationNode::newQualifier( DeclarationNode::Atomic ); } 1197 | FORALL '(' 1205 | FORALL '(' 1198 1206 { 1199 1207 typedefTable.enterScope(); 1200 1208 } 1201 type_parameter_list ')' / / CFA1209 type_parameter_list ')' /* CFA */ 1202 1210 { 1203 1211 typedefTable.leaveScope(); … … 1208 1216 declaration_qualifier_list: 1209 1217 storage_class_list 1210 | type_qualifier_list storage_class_list / / remaining OBSOLESCENT (see 2)1218 | type_qualifier_list storage_class_list /* remaining OBSOLESCENT (see 2) */ 1211 1219 { $$ = $1->addQualifiers( $2 ); } 1212 1220 | declaration_qualifier_list type_qualifier_list storage_class_list … … 1231 1239 1232 1240 storage_class_name: 1233 EXTERN 1241 AUTO 1242 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); } 1243 | EXTERN 1234 1244 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); } 1245 | REGISTER 1246 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); } 1235 1247 | STATIC 1236 1248 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); } 1237 | AUTO 1238 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); } 1239 | REGISTER 1240 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); } 1241 | INLINE // C99 1242 // INLINE is essentially a storage class specifier for functions, and hence, belongs here. 1249 | INLINE /* C99 */ 1250 /* INLINE is essentially a storage class specifier for functions, and hence, belongs here. */ 1243 1251 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline ); } 1244 | FORTRAN / / C991252 | FORTRAN /* C99 */ 1245 1253 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); } 1246 1254 ; … … 1265 1273 | VOID 1266 1274 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } 1267 | BOOL / / C991275 | BOOL /* C99 */ 1268 1276 { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 1269 | COMPLEX / / C991277 | COMPLEX /* C99 */ 1270 1278 { $$ = DeclarationNode::newBasicType( DeclarationNode::Complex ); } 1271 | IMAGINARY / / C991279 | IMAGINARY /* C99 */ 1272 1280 { $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); } 1273 1281 ; 1274 1282 1275 1283 basic_declaration_specifier: 1276 / / A semantic check is necessary for conflicting storage classes.1284 /* A semantic check is necessary for conflicting storage classes. */ 1277 1285 basic_type_specifier 1278 1286 | declaration_qualifier_list basic_type_specifier 1279 1287 { $$ = $2->addQualifiers( $1 ); } 1280 | basic_declaration_specifier storage_class / / remaining OBSOLESCENT (see 2)1288 | basic_declaration_specifier storage_class /* remaining OBSOLESCENT (see 2) */ 1281 1289 { $$ = $1->addQualifiers( $2 ); } 1282 1290 | basic_declaration_specifier storage_class type_qualifier_list … … 1293 1301 1294 1302 direct_type_name: 1295 / / A semantic check is necessary for conflicting type qualifiers.1303 /* A semantic check is necessary for conflicting type qualifiers. */ 1296 1304 basic_type_name 1297 1305 | type_qualifier_list basic_type_name … … 1304 1312 1305 1313 indirect_type_name: 1306 TYPEOF '(' type_name ')' / / GCC: typeof(x) y;1314 TYPEOF '(' type_name ')' /* GCC: typeof(x) y; */ 1307 1315 { $$ = $3; } 1308 | TYPEOF '(' comma_expression ')' / / GCC: typeof(a+b) y;1316 | TYPEOF '(' comma_expression ')' /* GCC: typeof(a+b) y; */ 1309 1317 { $$ = DeclarationNode::newTypeof( $3 ); } 1310 | ATTR_TYPEGENname '(' type_name ')' / / CFA: e.g., @type(x) y;1318 | ATTR_TYPEGENname '(' type_name ')' /* CFA: e.g., @type(x) y; */ 1311 1319 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1312 | ATTR_TYPEGENname '(' comma_expression ')' / / CFA: e.g., @type(a+b) y;1320 | ATTR_TYPEGENname '(' comma_expression ')' /* CFA: e.g., @type(a+b) y; */ 1313 1321 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1314 1322 ; … … 1318 1326 | declaration_qualifier_list sue_type_specifier 1319 1327 { $$ = $2->addQualifiers( $1 ); } 1320 | sue_declaration_specifier storage_class / / remaining OBSOLESCENT (see 2)1328 | sue_declaration_specifier storage_class /* remaining OBSOLESCENT (see 2) */ 1321 1329 { $$ = $1->addQualifiers( $2 ); } 1322 1330 | sue_declaration_specifier storage_class type_qualifier_list … … 1325 1333 1326 1334 sue_type_specifier: 1327 elaborated_type_name / / struct, union, enum1335 elaborated_type_name /* struct, union, enum */ 1328 1336 | type_qualifier_list elaborated_type_name 1329 1337 { $$ = $2->addQualifiers( $1 ); } … … 1336 1344 | declaration_qualifier_list typedef_type_specifier 1337 1345 { $$ = $2->addQualifiers( $1 ); } 1338 | typedef_declaration_specifier storage_class / / remaining OBSOLESCENT (see 2)1346 | typedef_declaration_specifier storage_class /* remaining OBSOLESCENT (see 2) */ 1339 1347 { $$ = $1->addQualifiers( $2 ); } 1340 1348 | typedef_declaration_specifier storage_class type_qualifier_list … … 1342 1350 ; 1343 1351 1344 typedef_type_specifier: / / typedef types1352 typedef_type_specifier: /* typedef types */ 1345 1353 TYPEDEFname 1346 1354 { $$ = DeclarationNode::newFromTypedef( $1 ); } … … 1363 1371 | aggregate_key no_attr_identifier_or_typedef_name '{' field_declaration_list '}' 1364 1372 { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); } 1365 | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' / / CFA1373 | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' /* CFA */ 1366 1374 { $$ = DeclarationNode::newAggregate( $1, 0, $4, 0, $8 ); } 1367 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name / / CFA1375 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name /* CFA */ 1368 1376 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); } 1369 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' / / CFA1377 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' /* CFA */ 1370 1378 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); } 1371 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' / / CFA1379 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' /* CFA */ 1372 1380 { $$ = DeclarationNode::newAggregate( $1, 0, $4, $8, $11 ); } 1373 | aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name / / CFA1374 / / push and pop are only to prevent S/R conflicts1381 | aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name /* CFA */ 1382 /* push and pop are only to prevent S/R conflicts */ 1375 1383 { $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); } 1376 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' / / CFA1384 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' /* CFA */ 1377 1385 { $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); } 1378 1386 ; … … 1393 1401 1394 1402 field_declaration: 1395 new_field_declaring_list ';' / / CFA, new style field declaration1396 | EXTENSION new_field_declaring_list ';' / / GCC1403 new_field_declaring_list ';' /* CFA, new style field declaration */ 1404 | EXTENSION new_field_declaring_list ';' /* GCC */ 1397 1405 { $$ = $2; } 1398 1406 | field_declaring_list ';' 1399 | EXTENSION field_declaring_list ';' / / GCC1400 { $$ = $2; } 1401 ; 1402 1403 new_field_declaring_list: / / CFA, new style field declaration1404 new_abstract_declarator_tuple / / CFA, no field name1407 | EXTENSION field_declaring_list ';' /* GCC */ 1408 { $$ = $2; } 1409 ; 1410 1411 new_field_declaring_list: /* CFA, new style field declaration */ 1412 new_abstract_declarator_tuple /* CFA, no field name */ 1405 1413 | new_abstract_declarator_tuple no_attr_identifier_or_typedef_name 1406 1414 { $$ = $1->addName( $2 ); } 1407 1415 | new_field_declaring_list ',' no_attr_identifier_or_typedef_name 1408 1416 { $$ = $1->appendList( $1->cloneType( $3 ) ); } 1409 | new_field_declaring_list ',' / / CFA, no field name1417 | new_field_declaring_list ',' /* CFA, no field name */ 1410 1418 { $$ = $1->appendList( $1->cloneType( 0 ) ); } 1411 1419 ; … … 1419 1427 1420 1428 field_declarator: 1421 / / empty1422 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name1423 | bit_subrange_size / / no field name1429 /* empty */ /* CFA, no field name */ 1430 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } 1431 | bit_subrange_size /* no field name */ 1424 1432 { $$ = DeclarationNode::newBitfield( $1 ); } 1425 1433 | variable_declarator bit_subrange_size_opt 1426 / / A semantic check is required to ensure bit_subrange only appears on base type int.1434 /* A semantic check is required to ensure bit_subrange only appears on base type int. */ 1427 1435 { $$ = $1->addBitfield( $2 ); } 1428 1436 | typedef_redeclarator bit_subrange_size_opt 1429 / / A semantic check is required to ensure bit_subrange only appears on base type int.1437 /* A semantic check is required to ensure bit_subrange only appears on base type int. */ 1430 1438 { $$ = $1->addBitfield( $2 ); } 1431 | variable_abstract_declarator / / CFA, no field name1439 | variable_abstract_declarator /* CFA, no field name */ 1432 1440 ; 1433 1441 1434 1442 bit_subrange_size_opt: 1435 / / empty1443 /* empty */ 1436 1444 { $$ = 0; } 1437 1445 | bit_subrange_size … … 1465 1473 1466 1474 enumerator_value_opt: 1467 / / empty1475 /* empty */ 1468 1476 { $$ = 0; } 1469 1477 | '=' constant_expression … … 1471 1479 ; 1472 1480 1473 / / Minimum of one parameter after which ellipsis is allowed only at the end.1474 1475 new_parameter_type_list_opt: / / CFA1476 / / empty1481 /* Minimum of one parameter after which ellipsis is allowed only at the end. */ 1482 1483 new_parameter_type_list_opt: /* CFA */ 1484 /* empty */ 1477 1485 { $$ = 0; } 1478 1486 | new_parameter_type_list 1479 1487 ; 1480 1488 1481 new_parameter_type_list: / / CFA, abstract + real1489 new_parameter_type_list: /* CFA, abstract + real */ 1482 1490 new_abstract_parameter_list 1483 1491 | new_parameter_list … … 1490 1498 ; 1491 1499 1492 new_parameter_list: / / CFA1493 / /To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last1494 //new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules1495 // to get lookahead to the ']'.1500 new_parameter_list: /* CFA */ 1501 /* To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last 1502 new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules 1503 to get lookahead to the ']'. */ 1496 1504 new_parameter_declaration 1497 1505 | new_abstract_parameter_list pop ',' push new_parameter_declaration … … 1503 1511 ; 1504 1512 1505 new_abstract_parameter_list: / / CFA, new & old style abstract1513 new_abstract_parameter_list: /* CFA, new & old style abstract */ 1506 1514 new_abstract_parameter_declaration 1507 1515 | new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration … … 1510 1518 1511 1519 parameter_type_list_opt: 1512 / / empty1520 /* empty */ 1513 1521 { $$ = 0; } 1514 1522 | parameter_type_list … … 1521 1529 ; 1522 1530 1523 parameter_list: / / abstract + real1531 parameter_list: /* abstract + real */ 1524 1532 abstract_parameter_declaration 1525 1533 | parameter_declaration … … 1530 1538 ; 1531 1539 1532 / /Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different1533 //semantics for typedef name by using typedef_parameter_redeclarator instead of typedef_redeclarator, and1534 // function prototypes. 1535 1536 new_parameter_declaration: / / CFA, new & old style parameter declaration1540 /* Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different 1541 semantics for typedef name by using typedef_parameter_redeclarator instead of typedef_redeclarator, and 1542 function prototypes. */ 1543 1544 new_parameter_declaration: /* CFA, new & old style parameter declaration */ 1537 1545 parameter_declaration 1538 1546 | new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt 1539 1547 { $$ = $1->addName( $2 ); } 1540 1548 | new_abstract_tuple identifier_or_typedef_name assignment_opt 1541 / / To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).1549 /* To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). */ 1542 1550 { $$ = $1->addName( $2 ); } 1543 1551 | type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt … … 1546 1554 ; 1547 1555 1548 new_abstract_parameter_declaration: / / CFA, new & old style parameter declaration1556 new_abstract_parameter_declaration: /* CFA, new & old style parameter declaration */ 1549 1557 abstract_parameter_declaration 1550 1558 | new_identifier_parameter_declarator_no_tuple 1551 1559 | new_abstract_tuple 1552 / / To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator).1560 /* To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). */ 1553 1561 | type_qualifier_list new_abstract_tuple 1554 1562 { $$ = $2->addQualifiers( $1 ); } … … 1559 1567 declaration_specifier identifier_parameter_declarator assignment_opt 1560 1568 { 1561 typedefTable.addToEnclosingScope( TypedefTable::ID );1569 typedefTable.addToEnclosingScope( TypedefTable::ID); 1562 1570 $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) ); 1563 1571 } 1564 1572 | declaration_specifier typedef_parameter_redeclarator assignment_opt 1565 1573 { 1566 typedefTable.addToEnclosingScope( TypedefTable::ID );1574 typedefTable.addToEnclosingScope( TypedefTable::ID); 1567 1575 $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) ); 1568 1576 } … … 1575 1583 ; 1576 1584 1577 / /ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a1578 //parameter." Because the scope of the K&R-style parameter-list sees the typedef first, the following is1579 // based only on identifiers. The ANSI-style parameter-list can redefine a typedef name. 1580 1581 identifier_list: / / K&R-style parameter list => no types1585 /* ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a 1586 parameter." Because the scope of the K&R-style parameter-list sees the typedef first, the following is 1587 based only on identifiers. The ANSI-style parameter-list can redefine a typedef name. */ 1588 1589 identifier_list: /* K&R-style parameter list => no types */ 1582 1590 no_attr_identifier 1583 1591 { $$ = DeclarationNode::newName( $1 ); } … … 1604 1612 ; 1605 1613 1606 type_name_no_function: / / sizeof, alignof, cast (constructor)1607 new_abstract_declarator_tuple / / CFA1614 type_name_no_function: /* sizeof, alignof, cast (constructor) */ 1615 new_abstract_declarator_tuple /* CFA */ 1608 1616 | type_specifier 1609 1617 | type_specifier variable_abstract_declarator … … 1611 1619 ; 1612 1620 1613 type_name: / / typeof, assertion1614 new_abstract_declarator_tuple / / CFA1615 | new_abstract_function / / CFA1621 type_name: /* typeof, assertion */ 1622 new_abstract_declarator_tuple /* CFA */ 1623 | new_abstract_function /* CFA */ 1616 1624 | type_specifier 1617 1625 | type_specifier abstract_declarator … … 1637 1645 ; 1638 1646 1639 / /There is an unreconcileable parsing problem between C99 and CFA with respect to designators. The problem1640 //is use of '=' to separator the designator from the initializer value, as in:1641 // 1642 //int x[10] = { [1] = 3 };1643 // 1644 //The string "[1] = 3" can be parsed as a designator assignment or a tuple assignment. To disambiguate this1645 //case, CFA changes the syntax from "=" to ":" as the separator between the designator and initializer. GCC1646 //does uses ":" for field selection. The optional use of the "=" in GCC, or in this case ":", cannot be1647 // supported either due to shift/reduce conflicts 1647 /* There is an unreconcileable parsing problem between C99 and CFA with respect to designators. The problem 1648 is use of '=' to separator the designator from the initializer value, as in: 1649 1650 int x[10] = { [1] = 3 }; 1651 1652 The string "[1] = 3" can be parsed as a designator assignment or a tuple assignment. To disambiguate this 1653 case, CFA changes the syntax from "=" to ":" as the separator between the designator and initializer. GCC 1654 does uses ":" for field selection. The optional use of the "=" in GCC, or in this case ":", cannot be 1655 supported either due to shift/reduce conflicts */ 1648 1656 1649 1657 designation: 1650 designator_list ':' / / C99, CFA uses ":" instead of "="1651 | no_attr_identifier_or_typedef_name ':' / / GCC, field name1658 designator_list ':' /* C99, CFA uses ":" instead of "=" */ 1659 | no_attr_identifier_or_typedef_name ':' /* GCC, field name */ 1652 1660 { $$ = new VarRefNode( $1 ); } 1653 1661 ; 1654 1662 1655 designator_list: / / C991663 designator_list: /* C99 */ 1656 1664 designator 1657 1665 | designator_list designator { $$ = (ExpressionNode *)($1->set_link( $2 )); } … … 1659 1667 1660 1668 designator: 1661 '.' no_attr_identifier_or_typedef_name / / C99, field name1669 '.' no_attr_identifier_or_typedef_name /* C99, field name */ 1662 1670 { $$ = new VarRefNode( $2 ); } 1663 | '[' push assignment_expression pop ']' / / C99, single array element1671 | '[' push assignment_expression pop ']' /* C99, single array element */ 1664 1672 /* assignment_expression used instead of constant_expression because of shift/reduce conflicts 1665 1673 with tuple. */ 1666 1674 { $$ = $3; } 1667 | '[' push subrange pop ']' / / CFA, multiple array elements1675 | '[' push subrange pop ']' /* CFA, multiple array elements */ 1668 1676 { $$ = $3; } 1669 | '[' push constant_expression ELLIPSIS constant_expression pop ']' / / GCC, multiple array elements1677 | '[' push constant_expression ELLIPSIS constant_expression pop ']' /* GCC, multiple array elements */ 1670 1678 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $3, $5); } 1671 | '.' '[' push field_list pop ']' / / CFA, tuple field selector1679 | '.' '[' push field_list pop ']' /* CFA, tuple field selector */ 1672 1680 { $$ = $4; } 1673 1681 ; 1674 1682 1675 / /The CFA type system is based on parametric polymorphism, the ability to declare functions with type1676 //parameters, rather than an object-oriented type system. This required four groups of extensions:1677 // 1678 //Overloading: function, data, and operator identifiers may be overloaded.1679 // 1680 //Type declarations: "type" is used to generate new types for declaring objects. Similarly, "dtype" is used1681 //for object and incomplete types, and "ftype" is used for function types. Type declarations with1682 //initializers provide definitions of new types. Type declarations with storage class "extern" provide1683 //opaque types.1684 // 1685 //Polymorphic functions: A forall clause declares a type parameter. The corresponding argument is inferred at1686 //the call site. A polymorphic function is not a template; it is a function, with an address and a type.1687 // 1688 //Specifications and Assertions: Specifications are collections of declarations parameterized by one or more1689 //types. They serve many of the purposes of abstract classes, and specification hierarchies resemble1690 //subclass hierarchies. Unlike classes, they can define relationships between types. Assertions declare1691 //that a type or types provide the operations declared by a specification. Assertions are normally used1692 // to declare requirements on type arguments of polymorphic functions. 1693 1694 typegen_declaration_specifier: / / CFA1683 /* The CFA type system is based on parametric polymorphism, the ability to declare functions with type 1684 parameters, rather than an object-oriented type system. This required four groups of extensions: 1685 1686 Overloading: function, data, and operator identifiers may be overloaded. 1687 1688 Type declarations: "type" is used to generate new types for declaring objects. Similarly, "dtype" is used 1689 for object and incomplete types, and "ftype" is used for function types. Type declarations with 1690 initializers provide definitions of new types. Type declarations with storage class "extern" provide 1691 opaque types. 1692 1693 Polymorphic functions: A forall clause declares a type parameter. The corresponding argument is inferred at 1694 the call site. A polymorphic function is not a template; it is a function, with an address and a type. 1695 1696 Specifications and Assertions: Specifications are collections of declarations parameterized by one or more 1697 types. They serve many of the purposes of abstract classes, and specification hierarchies resemble 1698 subclass hierarchies. Unlike classes, they can define relationships between types. Assertions declare 1699 that a type or types provide the operations declared by a specification. Assertions are normally used 1700 to declare requirements on type arguments of polymorphic functions. */ 1701 1702 typegen_declaration_specifier: /* CFA */ 1695 1703 typegen_type_specifier 1696 1704 | declaration_qualifier_list typegen_type_specifier 1697 1705 { $$ = $2->addQualifiers( $1 ); } 1698 | typegen_declaration_specifier storage_class / / remaining OBSOLESCENT (see 2)1706 | typegen_declaration_specifier storage_class /* remaining OBSOLESCENT (see 2) */ 1699 1707 { $$ = $1->addQualifiers( $2 ); } 1700 1708 | typegen_declaration_specifier storage_class type_qualifier_list … … 1702 1710 ; 1703 1711 1704 typegen_type_specifier: / / CFA1712 typegen_type_specifier: /* CFA */ 1705 1713 TYPEGENname '(' type_name_list ')' 1706 1714 { $$ = DeclarationNode::newFromTypeGen( $1, $3 ); } … … 1711 1719 ; 1712 1720 1713 type_parameter_list: / / CFA1721 type_parameter_list: /* CFA */ 1714 1722 type_parameter assignment_opt 1715 1723 | type_parameter_list ',' type_parameter assignment_opt … … 1717 1725 ; 1718 1726 1719 type_parameter: / / CFA1727 type_parameter: /* CFA */ 1720 1728 type_class no_attr_identifier_or_typedef_name 1721 1729 { typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); } … … 1725 1733 ; 1726 1734 1727 type_class: / / CFA1735 type_class: /* CFA */ 1728 1736 TYPE 1729 1737 { $$ = DeclarationNode::Type; } … … 1734 1742 ; 1735 1743 1736 assertion_list_opt: / / CFA1737 / / empty1744 assertion_list_opt: /* CFA */ 1745 /* empty */ 1738 1746 { $$ = 0; } 1739 1747 | assertion_list_opt assertion … … 1741 1749 ; 1742 1750 1743 assertion: / / CFA1751 assertion: /* CFA */ 1744 1752 '|' no_attr_identifier_or_typedef_name '(' type_name_list ')' 1745 1753 { … … 1753 1761 ; 1754 1762 1755 type_name_list: / / CFA1763 type_name_list: /* CFA */ 1756 1764 type_name 1757 1765 { $$ = new TypeValueNode( $1 ); } … … 1763 1771 ; 1764 1772 1765 type_declaring_list: / / CFA1773 type_declaring_list: /* CFA */ 1766 1774 TYPE type_declarator 1767 1775 { $$ = $2; } … … 1772 1780 ; 1773 1781 1774 type_declarator: / / CFA1782 type_declarator: /* CFA */ 1775 1783 type_declarator_name assertion_list_opt 1776 1784 { $$ = $1->addAssertions( $2 ); } … … 1779 1787 ; 1780 1788 1781 type_declarator_name: / / CFA1789 type_declarator_name: /* CFA */ 1782 1790 no_attr_identifier_or_typedef_name 1783 1791 { … … 1792 1800 ; 1793 1801 1794 context_specifier: / / CFA1802 context_specifier: /* CFA */ 1795 1803 CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}' 1796 1804 { 1797 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );1805 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID); 1798 1806 $$ = DeclarationNode::newContext( $2, $5, 0 ); 1799 1807 } … … 1806 1814 { 1807 1815 typedefTable.leaveContext(); 1808 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );1816 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID); 1809 1817 $$ = DeclarationNode::newContext( $2, $5, $10 ); 1810 1818 } 1811 1819 ; 1812 1820 1813 context_declaration_list: / / CFA1821 context_declaration_list: /* CFA */ 1814 1822 context_declaration 1815 1823 | context_declaration_list push context_declaration … … 1817 1825 ; 1818 1826 1819 context_declaration: / / CFA1827 context_declaration: /* CFA */ 1820 1828 new_context_declaring_list pop ';' 1821 1829 | context_declaring_list pop ';' 1822 1830 ; 1823 1831 1824 new_context_declaring_list: / / CFA1832 new_context_declaring_list: /* CFA */ 1825 1833 new_variable_specifier 1826 1834 { … … 1840 1848 ; 1841 1849 1842 context_declaring_list: / / CFA1850 context_declaring_list: /* CFA */ 1843 1851 type_specifier declarator 1844 1852 { 1845 typedefTable.addToEnclosingScope2( TypedefTable::ID );1853 typedefTable.addToEnclosingScope2( TypedefTable::ID); 1846 1854 $$ = $2->addType( $1 ); 1847 1855 } 1848 1856 | context_declaring_list pop ',' push declarator 1849 1857 { 1850 typedefTable.addToEnclosingScope2( TypedefTable::ID );1858 typedefTable.addToEnclosingScope2( TypedefTable::ID); 1851 1859 $$ = $1->appendList( $1->cloneBaseType( $5 ) ); 1852 1860 } 1853 1861 ; 1854 1862 1855 / /***************************** EXTERNAL DEFINITIONS *****************************1863 /***************************** EXTERNAL DEFINITIONS *****************************/ 1856 1864 1857 1865 translation_unit: 1858 / / empty1859 {} // empty input file1866 /* empty */ /* empty input file */ 1867 {} 1860 1868 | external_definition_list 1861 1869 { … … 1872 1880 | external_definition_list push external_definition 1873 1881 { 1874 if ( $1 ) {1875 $$ = $1->appendList( $3 );1876 } else {1877 $$ = $3;1878 }1882 if ( $1 ) { 1883 $$ = $1->appendList( $3 ); 1884 } else { 1885 $$ = $3; 1886 } 1879 1887 } 1880 1888 ; 1881 1889 1882 1890 external_definition_list_opt: 1883 // empty 1884 { $$ = 0; } 1891 /* empty */ 1892 { 1893 $$ = 0; 1894 } 1885 1895 | external_definition_list 1886 1896 ; … … 1889 1899 declaration 1890 1900 | function_definition 1891 | asm_statement / / GCC, global assembler statement1901 | asm_statement /* GCC, global assembler statement */ 1892 1902 {} 1893 1903 | EXTERN STRINGliteral … … 1896 1906 linkage = LinkageSpec::fromString( *$2 ); 1897 1907 } 1898 '{' external_definition_list_opt '}' / / C++-style linkage specifier1908 '{' external_definition_list_opt '}' /* C++-style linkage specifier */ 1899 1909 { 1900 1910 linkage = linkageStack.top(); … … 1907 1917 1908 1918 function_definition: 1909 new_function_specifier compound_statement / / CFA1919 new_function_specifier compound_statement /* CFA */ 1910 1920 { 1911 1921 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 1913 1923 $$ = $1->addFunctionBody( $2 ); 1914 1924 } 1915 | declaration_qualifier_list new_function_specifier compound_statement / / CFA1916 / /declaration_qualifier_list also includes type_qualifier_list, so a semantic check is1917 // necessary to preclude them as a type_qualifier cannot appear in this context.1925 | declaration_qualifier_list new_function_specifier compound_statement /* CFA */ 1926 /* declaration_qualifier_list also includes type_qualifier_list, so a semantic check is 1927 necessary to preclude them as a type_qualifier cannot appear in this context. */ 1918 1928 { 1919 1929 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 1929 1939 } 1930 1940 1931 / /These rules are a concession to the "implicit int" type_specifier because there is a1932 //significant amount of code with functions missing a type-specifier on the return type.1933 //Parsing is possible because function_definition does not appear in the context of an1934 //expression (nested functions would preclude this concession). A function prototype1935 // declaration must still have a type_specifier. OBSOLESCENT (see 1)1941 /* These rules are a concession to the "implicit int" type_specifier because there is a 1942 significant amount of code with functions missing a type-specifier on the return type. 1943 Parsing is possible because function_definition does not appear in the context of an 1944 expression (nested functions would preclude this concession). A function prototype 1945 declaration must still have a type_specifier. OBSOLESCENT (see 1) */ 1936 1946 | function_declarator compound_statement 1937 1947 { … … 1959 1969 } 1960 1970 1961 / / Old-style K&R function definition, OBSOLESCENT (see 4)1971 /* Old-style K&R function definition, OBSOLESCENT (see 4) */ 1962 1972 | declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement 1963 1973 { … … 1979 1989 } 1980 1990 1981 / / Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4)1991 /* Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4) */ 1982 1992 | declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement 1983 1993 { … … 2002 2012 2003 2013 subrange: 2004 constant_expression '~' constant_expression / / CFA, integer subrange2014 constant_expression '~' constant_expression /* CFA, integer subrange */ 2005 2015 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $1, $3); } 2006 2016 ; 2007 2017 2008 asm_name_opt: / / GCC2009 / / empty2018 asm_name_opt: /* GCC */ 2019 /* empty */ 2010 2020 | ASM '(' string_literal_list ')' attribute_list_opt 2011 2021 ; 2012 2022 2013 attribute_list_opt: / / GCC2014 / / empty2023 attribute_list_opt: /* GCC */ 2024 /* empty */ 2015 2025 | attribute_list 2016 2026 ; 2017 2027 2018 attribute_list: / / GCC2028 attribute_list: /* GCC */ 2019 2029 attribute 2020 2030 | attribute_list attribute 2021 2031 ; 2022 2032 2023 attribute: / / GCC2033 attribute: /* GCC */ 2024 2034 ATTRIBUTE '(' '(' attribute_parameter_list ')' ')' 2025 2035 ; 2026 2036 2027 attribute_parameter_list: / / GCC2037 attribute_parameter_list: /* GCC */ 2028 2038 attrib 2029 2039 | attribute_parameter_list ',' attrib 2030 2040 ; 2031 2041 2032 attrib: / / GCC2033 / / empty2042 attrib: /* GCC */ 2043 /* empty */ 2034 2044 | any_word 2035 2045 | any_word '(' comma_expression_opt ')' 2036 2046 ; 2037 2047 2038 any_word: / / GCC2048 any_word: /* GCC */ 2039 2049 identifier_or_typedef_name {} 2040 2050 | storage_class_name {} … … 2043 2053 ; 2044 2054 2045 / /============================================================================2046 //The following sections are a series of grammar patterns used to parse declarators. Multiple patterns are2047 //necessary because the type of an identifier in wrapped around the identifier in the same form as its usage2048 //in an expression, as in:2049 // 2050 //int (*f())[10] { ... };2051 //... (*f())[3] += 1; // definition mimics usage2052 // 2053 //Because these patterns are highly recursive, changes at a lower level in the recursion require copying some2054 //or all of the pattern. Each of these patterns has some subtle variation to ensure correct syntax in a2055 //particular context.2056 // ============================================================================ 2057 2058 / /----------------------------------------------------------------------------2059 //The set of valid declarators before a compound statement for defining a function is less than the set of2060 //declarators to define a variable or function prototype, e.g.:2061 // 2062 //valid declaration invalid definition2063 //----------------- ------------------2064 //int f; int f {}2065 //int *f; int *f {}2066 //int f[10]; int f[10] {}2067 //int (*f)(int); int (*f)(int) {}2068 // 2069 //To preclude this syntactic anomaly requires separating the grammar rules for variable and function2070 //declarators, hence variable_declarator and function_declarator.2071 // ---------------------------------------------------------------------------- 2072 2073 / /This pattern parses a declaration of a variable that is not redefining a typedef name. The pattern2074 // precludes declaring an array of functions versus a pointer to an array of functions. 2055 /* ============================================================================ 2056 The following sections are a series of grammar patterns used to parse declarators. Multiple patterns are 2057 necessary because the type of an identifier in wrapped around the identifier in the same form as its usage 2058 in an expression, as in: 2059 2060 int (*f())[10] { ... }; 2061 ... (*f())[3] += 1; // definition mimics usage 2062 2063 Because these patterns are highly recursive, changes at a lower level in the recursion require copying some 2064 or all of the pattern. Each of these patterns has some subtle variation to ensure correct syntax in a 2065 particular context. 2066 ============================================================================ */ 2067 2068 /* ---------------------------------------------------------------------------- 2069 The set of valid declarators before a compound statement for defining a function is less than the set of 2070 declarators to define a variable or function prototype, e.g.: 2071 2072 valid declaration invalid definition 2073 ----------------- ------------------ 2074 int f; int f {} 2075 int *f; int *f {} 2076 int f[10]; int f[10] {} 2077 int (*f)(int); int (*f)(int) {} 2078 2079 To preclude this syntactic anomaly requires separating the grammar rules for variable and function 2080 declarators, hence variable_declarator and function_declarator. 2081 ---------------------------------------------------------------------------- */ 2082 2083 /* This pattern parses a declaration of a variable that is not redefining a typedef name. The pattern 2084 precludes declaring an array of functions versus a pointer to an array of functions. */ 2075 2085 2076 2086 variable_declarator: … … 2087 2097 $$ = DeclarationNode::newName( $1 ); 2088 2098 } 2089 | '(' paren_identifier ')' / / redundant parenthesis2099 | '(' paren_identifier ')' /* redundant parenthesis */ 2090 2100 { $$ = $2; } 2091 2101 ; … … 2105 2115 | '(' variable_ptr ')' array_dimension 2106 2116 { $$ = $2->addArray( $4 ); } 2107 | '(' variable_array ')' multi_array_dimension / / redundant parenthesis2117 | '(' variable_array ')' multi_array_dimension /* redundant parenthesis */ 2108 2118 { $$ = $2->addArray( $4 ); } 2109 | '(' variable_array ')' / / redundant parenthesis2119 | '(' variable_array ')' /* redundant parenthesis */ 2110 2120 { $$ = $2; } 2111 2121 ; 2112 2122 2113 2123 variable_function: 2114 '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2124 '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2115 2125 { $$ = $2->addParamList( $6 ); } 2116 | '(' variable_function ')' / / redundant parenthesis2117 { $$ = $2; } 2118 ; 2119 2120 / /This pattern parses a function declarator that is not redefining a typedef name. Because functions cannot2121 //be nested, there is no context where a function definition can redefine a typedef name. To allow nested2122 //functions requires further separation of variable and function declarators in typedef_redeclarator. The2123 // pattern precludes returning arrays and functions versus pointers to arrays and functions. 2126 | '(' variable_function ')' /* redundant parenthesis */ 2127 { $$ = $2; } 2128 ; 2129 2130 /* This pattern parses a function declarator that is not redefining a typedef name. Because functions cannot 2131 be nested, there is no context where a function definition can redefine a typedef name. To allow nested 2132 functions requires further separation of variable and function declarators in typedef_redeclarator. The 2133 pattern precludes returning arrays and functions versus pointers to arrays and functions. */ 2124 2134 2125 2135 function_declarator: … … 2130 2140 2131 2141 function_no_ptr: 2132 paren_identifier '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2142 paren_identifier '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2133 2143 { $$ = $1->addParamList( $4 ); } 2134 2144 | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')' 2135 2145 { $$ = $2->addParamList( $6 ); } 2136 | '(' function_no_ptr ')' / / redundant parenthesis2146 | '(' function_no_ptr ')' /* redundant parenthesis */ 2137 2147 { $$ = $2; } 2138 2148 ; … … 2150 2160 '(' function_ptr ')' array_dimension 2151 2161 { $$ = $2->addArray( $4 ); } 2152 | '(' function_array ')' multi_array_dimension / / redundant parenthesis2162 | '(' function_array ')' multi_array_dimension /* redundant parenthesis */ 2153 2163 { $$ = $2->addArray( $4 ); } 2154 | '(' function_array ')' / / redundant parenthesis2155 { $$ = $2; } 2156 ; 2157 2158 / /This pattern parses an old-style K&R function declarator (OBSOLESCENT, see 4) that is not redefining a2159 //typedef name (see function_declarator for additional comments). The pattern precludes returning arrays and2160 // functions versus pointers to arrays and functions. 2164 | '(' function_array ')' /* redundant parenthesis */ 2165 { $$ = $2; } 2166 ; 2167 2168 /* This pattern parses an old-style K&R function declarator (OBSOLESCENT, see 4) that is not redefining a 2169 typedef name (see function_declarator for additional comments). The pattern precludes returning arrays and 2170 functions versus pointers to arrays and functions. */ 2161 2171 2162 2172 old_function_declarator: … … 2167 2177 2168 2178 old_function_no_ptr: 2169 paren_identifier '(' identifier_list ')' / / function_declarator handles empty parameter2179 paren_identifier '(' identifier_list ')' /* function_declarator handles empty parameter */ 2170 2180 { $$ = $1->addIdList( $3 ); } 2171 2181 | '(' old_function_ptr ')' '(' identifier_list ')' 2172 2182 { $$ = $2->addIdList( $5 ); } 2173 | '(' old_function_no_ptr ')' / / redundant parenthesis2183 | '(' old_function_no_ptr ')' /* redundant parenthesis */ 2174 2184 { $$ = $2; } 2175 2185 ; … … 2187 2197 '(' old_function_ptr ')' array_dimension 2188 2198 { $$ = $2->addArray( $4 ); } 2189 | '(' old_function_array ')' multi_array_dimension / / redundant parenthesis2199 | '(' old_function_array ')' multi_array_dimension /* redundant parenthesis */ 2190 2200 { $$ = $2->addArray( $4 ); } 2191 | '(' old_function_array ')' / / redundant parenthesis2192 { $$ = $2; } 2193 ; 2194 2195 / /This pattern parses a declaration for a variable or function prototype that redefines a typedef name, e.g.:2196 // 2197 //typedef int foo;2198 //{2199 //int foo; // redefine typedef name in new scope2200 //}2201 // 2202 //The pattern precludes declaring an array of functions versus a pointer to an array of functions, and2203 // returning arrays and functions versus pointers to arrays and functions. 2201 | '(' old_function_array ')' /* redundant parenthesis */ 2202 { $$ = $2; } 2203 ; 2204 2205 /* This pattern parses a declaration for a variable or function prototype that redefines a typedef name, e.g.: 2206 2207 typedef int foo; 2208 { 2209 int foo; // redefine typedef name in new scope 2210 } 2211 2212 The pattern precludes declaring an array of functions versus a pointer to an array of functions, and 2213 returning arrays and functions versus pointers to arrays and functions. */ 2204 2214 2205 2215 typedef_redeclarator: … … 2234 2244 | '(' typedef_ptr ')' array_dimension 2235 2245 { $$ = $2->addArray( $4 ); } 2236 | '(' typedef_array ')' multi_array_dimension / / redundant parenthesis2246 | '(' typedef_array ')' multi_array_dimension /* redundant parenthesis */ 2237 2247 { $$ = $2->addArray( $4 ); } 2238 | '(' typedef_array ')' / / redundant parenthesis2248 | '(' typedef_array ')' /* redundant parenthesis */ 2239 2249 { $$ = $2; } 2240 2250 ; 2241 2251 2242 2252 typedef_function: 2243 paren_typedef '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2253 paren_typedef '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2244 2254 { $$ = $1->addParamList( $4 ); } 2245 | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2255 | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2246 2256 { $$ = $2->addParamList( $6 ); } 2247 | '(' typedef_function ')' / / redundant parenthesis2248 { $$ = $2; } 2249 ; 2250 2251 / /This pattern parses a declaration for a parameter variable or function prototype that is not redefining a2252 //typedef name and allows the C99 array options, which can only appear in a parameter list. The pattern2253 //precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays2254 // and functions versus pointers to arrays and functions. 2257 | '(' typedef_function ')' /* redundant parenthesis */ 2258 { $$ = $2; } 2259 ; 2260 2261 /* This pattern parses a declaration for a parameter variable or function prototype that is not redefining a 2262 typedef name and allows the C99 array options, which can only appear in a parameter list. The pattern 2263 precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 2264 and functions versus pointers to arrays and functions. */ 2255 2265 2256 2266 identifier_parameter_declarator: … … 2275 2285 | '(' identifier_parameter_ptr ')' array_dimension 2276 2286 { $$ = $2->addArray( $4 ); } 2277 | '(' identifier_parameter_array ')' multi_array_dimension / / redundant parenthesis2287 | '(' identifier_parameter_array ')' multi_array_dimension /* redundant parenthesis */ 2278 2288 { $$ = $2->addArray( $4 ); } 2279 | '(' identifier_parameter_array ')' / / redundant parenthesis2289 | '(' identifier_parameter_array ')' /* redundant parenthesis */ 2280 2290 { $$ = $2; } 2281 2291 ; 2282 2292 2283 2293 identifier_parameter_function: 2284 paren_identifier '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2294 paren_identifier '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2285 2295 { $$ = $1->addParamList( $4 ); } 2286 | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2296 | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2287 2297 { $$ = $2->addParamList( $6 ); } 2288 | '(' identifier_parameter_function ')' / / redundant parenthesis2289 { $$ = $2; } 2290 ; 2291 2292 / / This pattern parses a declaration for a parameter variable or function prototype that is redefining a typedef name,2293 //e.g.:2294 // 2295 //typedef int foo;2296 //int f( int foo ); // redefine typedef name in new scope2297 // 2298 // and allows the C99 array options, which can only appear in a parameter list. In addition, the pattern handles the 2299 //special meaning of parenthesis around a typedef name:2300 // 2301 //ISO/IEC 9899:1999 Section 6.7.5.3(11) : "In a parameter declaration, a single typedef name in2302 //parentheses is taken to be an abstract declarator that specifies a function with a single parameter,2303 //not as redundant parentheses around the identifier."2304 // 2305 //which precludes the following cases:2306 // 2307 //typedef float T;2308 //int f( int ( T [5] ) ); // see abstract_parameter_declarator2309 //int g( int ( T ( int ) ) ); // see abstract_parameter_declarator2310 //int f( int f1( T a[5] ) ); // see identifier_parameter_declarator2311 //int g( int g1( T g2( int p ) ) ); // see identifier_parameter_declarator2312 // 2313 // In essence, a '(' immediately to the left of typedef name, T, is interpreted as starting a parameter type list, and 2314 // not as redundant parentheses around a redeclaration of T. Finally, the pattern also precludes declaring an array of 2315 // functions versus a pointer to an array of functions, and returning arrays and functions versus pointers toarrays and2316 // functions. 2298 | '(' identifier_parameter_function ')' /* redundant parenthesis */ 2299 { $$ = $2; } 2300 ; 2301 2302 /* This pattern parses a declaration for a parameter variable or function prototype that is redefining a 2303 typedef name, e.g.: 2304 2305 typedef int foo; 2306 int f( int foo ); // redefine typedef name in new scope 2307 2308 and allows the C99 array options, which can only appear in a parameter list. In addition, the pattern 2309 handles the special meaning of parenthesis around a typedef name: 2310 2311 ISO/IEC 9899:1999 Section 6.7.5.3(11) : "In a parameter declaration, a single typedef name in 2312 parentheses is taken to be an abstract declarator that specifies a function with a single parameter, 2313 not as redundant parentheses around the identifier." 2314 2315 which precludes the following cases: 2316 2317 typedef float T; 2318 int f( int ( T [5] ) ); // see abstract_parameter_declarator 2319 int g( int ( T ( int ) ) ); // see abstract_parameter_declarator 2320 int f( int f1( T a[5] ) ); // see identifier_parameter_declarator 2321 int g( int g1( T g2( int p ) ) ); // see identifier_parameter_declarator 2322 2323 In essence, a '(' immediately to the left of typedef name, T, is interpreted as starting a parameter type 2324 list, and not as redundant parentheses around a redeclaration of T. Finally, the pattern also precludes 2325 declaring an array of functions versus a pointer to an array of functions, and returning arrays and 2326 functions versus pointers to arrays and functions. */ 2317 2327 2318 2328 typedef_parameter_redeclarator: … … 2348 2358 2349 2359 typedef_parameter_function: 2350 typedef '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2360 typedef '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2351 2361 { $$ = $1->addParamList( $4 ); } 2352 | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2362 | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2353 2363 { $$ = $2->addParamList( $6 ); } 2354 2364 ; 2355 2365 2356 / / This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no identifier to2357 //which the type applies, e.g.:2358 // 2359 //sizeof( int );2360 //sizeof( int [10] );2361 // 2362 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 2363 // and functions versus pointers to arrays and functions. 2366 /* This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no 2367 identifier to which the type applies, e.g.: 2368 2369 sizeof( int ); 2370 sizeof( int [10] ); 2371 2372 The pattern precludes declaring an array of functions versus a pointer to an array of functions, and 2373 returning arrays and functions versus pointers to arrays and functions. */ 2364 2374 2365 2375 abstract_declarator: … … 2386 2396 | '(' abstract_ptr ')' array_dimension 2387 2397 { $$ = $2->addArray( $4 ); } 2388 | '(' abstract_array ')' multi_array_dimension / / redundant parenthesis2398 | '(' abstract_array ')' multi_array_dimension /* redundant parenthesis */ 2389 2399 { $$ = $2->addArray( $4 ); } 2390 | '(' abstract_array ')' / / redundant parenthesis2400 | '(' abstract_array ')' /* redundant parenthesis */ 2391 2401 { $$ = $2; } 2392 2402 ; 2393 2403 2394 2404 abstract_function: 2395 '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2405 '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2396 2406 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); } 2397 | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2407 | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2398 2408 { $$ = $2->addParamList( $6 ); } 2399 | '(' abstract_function ')' / / redundant parenthesis2409 | '(' abstract_function ')' /* redundant parenthesis */ 2400 2410 { $$ = $2; } 2401 2411 ; 2402 2412 2403 2413 array_dimension: 2404 / / Only the first dimension can be empty.2414 /* Only the first dimension can be empty. */ 2405 2415 '[' push pop ']' 2406 2416 { $$ = DeclarationNode::newArray( 0, 0, false ); } … … 2413 2423 '[' push assignment_expression pop ']' 2414 2424 { $$ = DeclarationNode::newArray( $3, 0, false ); } 2415 | '[' push '*' pop ']' / / C992425 | '[' push '*' pop ']' /* C99 */ 2416 2426 { $$ = DeclarationNode::newVarArray( 0 ); } 2417 2427 | multi_array_dimension '[' push assignment_expression pop ']' 2418 2428 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); } 2419 | multi_array_dimension '[' push '*' pop ']' / / C992429 | multi_array_dimension '[' push '*' pop ']' /* C99 */ 2420 2430 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); } 2421 2431 ; 2422 2432 2423 / /This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no2424 //identifier to which the type applies, e.g.:2425 // 2426 //int f( int ); // abstract variable parameter; no parameter name specified2427 //int f( int (int) ); // abstract function-prototype parameter; no parameter name specified2428 // 2429 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 2430 //and functions versus pointers to arrays and functions. */2433 /* This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no 2434 identifier to which the type applies, e.g.: 2435 2436 int f( int ); // abstract variable parameter; no parameter name specified 2437 int f( int (int) ); // abstract function-prototype parameter; no parameter name specified 2438 2439 The pattern precludes declaring an array of functions versus a pointer to an array of functions, and 2440 returning arrays and functions versus pointers to arrays and functions. */ 2431 2441 2432 2442 abstract_parameter_declarator: … … 2453 2463 | '(' abstract_parameter_ptr ')' array_parameter_dimension 2454 2464 { $$ = $2->addArray( $4 ); } 2455 | '(' abstract_parameter_array ')' multi_array_dimension / / redundant parenthesis2465 | '(' abstract_parameter_array ')' multi_array_dimension /* redundant parenthesis */ 2456 2466 { $$ = $2->addArray( $4 ); } 2457 | '(' abstract_parameter_array ')' / / redundant parenthesis2467 | '(' abstract_parameter_array ')' /* redundant parenthesis */ 2458 2468 { $$ = $2; } 2459 2469 ; 2460 2470 2461 2471 abstract_parameter_function: 2462 '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2472 '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2463 2473 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); } 2464 | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2474 | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2465 2475 { $$ = $2->addParamList( $6 ); } 2466 | '(' abstract_parameter_function ')' / / redundant parenthesis2476 | '(' abstract_parameter_function ')' /* redundant parenthesis */ 2467 2477 { $$ = $2; } 2468 2478 ; 2469 2479 2470 2480 array_parameter_dimension: 2471 / / Only the first dimension can be empty or have qualifiers.2481 /* Only the first dimension can be empty or have qualifiers. */ 2472 2482 array_parameter_1st_dimension 2473 2483 | array_parameter_1st_dimension multi_array_dimension … … 2476 2486 ; 2477 2487 2478 // The declaration of an array parameter has additional syntax over arrays in normal variable declarations: 2479 // 2480 // ISO/IEC 9899:1999 Section 6.7.5.2(1) : "The optional type qualifiers and the keyword static shall appear only in 2481 // a declaration of a function parameter with an array type, and then only in the outermost array type derivation." 2488 /* The declaration of an array parameter has additional syntax over arrays in normal variable declarations: 2489 2490 ISO/IEC 9899:1999 Section 6.7.5.2(1) : "The optional type qualifiers and the keyword static shall 2491 appear only in a declaration of a function parameter with an array type, and then only in the 2492 outermost array type derivation." */ 2482 2493 2483 2494 array_parameter_1st_dimension: … … 2485 2496 { $$ = DeclarationNode::newArray( 0, 0, false ); } 2486 2497 // multi_array_dimension handles the '[' '*' ']' case 2487 | '[' push type_qualifier_list '*' pop ']' / / remaining C992498 | '[' push type_qualifier_list '*' pop ']' /* remaining C99 */ 2488 2499 { $$ = DeclarationNode::newVarArray( $3 ); } 2489 2500 | '[' push type_qualifier_list pop ']' … … 2498 2509 ; 2499 2510 2500 / / This pattern parses a declaration of an abstract variable, i.e., there is no identifier to which the type applies,2501 //e.g.:2502 // 2503 //sizeof( int ); // abstract variable; no identifier name specified2504 // 2505 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 2506 //and functions versus pointers to arrays and functions. */2511 /* This pattern parses a declaration of an abstract variable, i.e., there is no identifier to which the type 2512 applies, e.g.: 2513 2514 sizeof( int ); // abstract variable; no identifier name specified 2515 2516 The pattern precludes declaring an array of functions versus a pointer to an array of functions, and 2517 returning arrays and functions versus pointers to arrays and functions. */ 2507 2518 2508 2519 variable_abstract_declarator: … … 2529 2540 | '(' variable_abstract_ptr ')' array_dimension 2530 2541 { $$ = $2->addArray( $4 ); } 2531 | '(' variable_abstract_array ')' multi_array_dimension / / redundant parenthesis2542 | '(' variable_abstract_array ')' multi_array_dimension /* redundant parenthesis */ 2532 2543 { $$ = $2->addArray( $4 ); } 2533 | '(' variable_abstract_array ')' / / redundant parenthesis2544 | '(' variable_abstract_array ')' /* redundant parenthesis */ 2534 2545 { $$ = $2; } 2535 2546 ; 2536 2547 2537 2548 variable_abstract_function: 2538 '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' / / empty parameter list OBSOLESCENT (see 3)2549 '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' /* empty parameter list OBSOLESCENT (see 3) */ 2539 2550 { $$ = $2->addParamList( $6 ); } 2540 | '(' variable_abstract_function ')' // redundant parenthesis 2541 { $$ = $2; } 2542 ; 2543 2544 // This pattern parses a new-style declaration for a parameter variable or function prototype that is either an 2545 // identifier or typedef name and allows the C99 array options, which can only appear in a parameter list. 2546 2547 new_identifier_parameter_declarator_tuple: // CFA 2551 | '(' variable_abstract_function ')' /* redundant parenthesis */ 2552 { $$ = $2; } 2553 ; 2554 2555 /* This pattern parses a new-style declaration for a parameter variable or function prototype that is either 2556 an identifier or typedef name and allows the C99 array options, which can only appear in a parameter 2557 list. */ 2558 2559 new_identifier_parameter_declarator_tuple: /* CFA */ 2548 2560 new_identifier_parameter_declarator_no_tuple 2549 2561 | new_abstract_tuple … … 2552 2564 ; 2553 2565 2554 new_identifier_parameter_declarator_no_tuple: / / CFA2566 new_identifier_parameter_declarator_no_tuple: /* CFA */ 2555 2567 new_identifier_parameter_ptr 2556 2568 | new_identifier_parameter_array 2557 2569 ; 2558 2570 2559 new_identifier_parameter_ptr: / / CFA2571 new_identifier_parameter_ptr: /* CFA */ 2560 2572 '*' type_specifier 2561 2573 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } … … 2572 2584 ; 2573 2585 2574 new_identifier_parameter_array: / / CFA2575 / / Only the first dimension can be empty or have qualifiers. Empty dimension must be factored out due to2576 //shift/reduce conflict with new-style empty (void) function return type. */2586 new_identifier_parameter_array: /* CFA */ 2587 /* Only the first dimension can be empty or have qualifiers. Empty dimension must be factored 2588 out due to shift/reduce conflict with new-style empty (void) function return type. */ 2577 2589 '[' push pop ']' type_specifier 2578 2590 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } … … 2598 2610 2599 2611 new_array_parameter_1st_dimension: 2600 '[' push type_qualifier_list '*' pop ']' / / remaining C992612 '[' push type_qualifier_list '*' pop ']' /* remaining C99 */ 2601 2613 { $$ = DeclarationNode::newVarArray( $3 ); } 2602 2614 | '[' push type_qualifier_list assignment_expression pop ']' 2603 2615 { $$ = DeclarationNode::newArray( $4, $3, false ); } 2604 2616 | '[' push declaration_qualifier_list assignment_expression pop ']' 2605 / / declaration_qualifier_list must be used because of shift/reduce conflict with assignment_expression,2606 // so a semantic check is necessary to preclude them as a type_qualifier cannot appear in this2607 // context.2617 /* declaration_qualifier_list must be used because of shift/reduce conflict with 2618 assignment_expression, so a semantic check is necessary to preclude them as a 2619 type_qualifier cannot appear in this context. */ 2608 2620 { $$ = DeclarationNode::newArray( $4, $3, true ); } 2609 2621 | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']' … … 2611 2623 ; 2612 2624 2613 / / This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is no2614 //identifier to which the type applies, e.g.:2615 // 2616 //[int] f( int ); // abstract variable parameter; no parameter name specified2617 //[int] f( [int] (int) ); // abstract function-prototype parameter; no parameter name specified2618 // 2619 //These rules need LR(3):2620 // 2621 //new_abstract_tuple identifier_or_typedef_name2622 //'[' new_parameter_list ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'2623 // 2624 //since a function return type can be syntactically identical to a tuple type:2625 // 2626 //[int, int] t;2627 //[int, int] f( int );2628 // 2629 //Therefore, it is necessary to look at the token after identifier_or_typedef_name to know when to reduce2630 // new_abstract_tuple. To make this LR(1), several rules have to be flattened (lengthened) to allow the necessary 2631 // lookahead. To accomplish this, new_abstract_declarator has an entry point without tuple, and tuple declarations are 2632 // duplicated when appearing with new_function_specifier. 2633 2634 new_abstract_declarator_tuple: / / CFA2625 /* This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is 2626 no identifier to which the type applies, e.g.: 2627 2628 [int] f( int ); // abstract variable parameter; no parameter name specified 2629 [int] f( [int] (int) ); // abstract function-prototype parameter; no parameter name specified 2630 2631 These rules need LR(3): 2632 2633 new_abstract_tuple identifier_or_typedef_name 2634 '[' new_parameter_list ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')' 2635 2636 since a function return type can be syntactically identical to a tuple type: 2637 2638 [int, int] t; 2639 [int, int] f( int ); 2640 2641 Therefore, it is necessary to look at the token after identifier_or_typedef_name to know when to reduce 2642 new_abstract_tuple. To make this LR(1), several rules have to be flattened (lengthened) to allow 2643 the necessary lookahead. To accomplish this, new_abstract_declarator has an entry point without tuple, and 2644 tuple declarations are duplicated when appearing with new_function_specifier. */ 2645 2646 new_abstract_declarator_tuple: /* CFA */ 2635 2647 new_abstract_tuple 2636 2648 | type_qualifier_list new_abstract_tuple … … 2639 2651 ; 2640 2652 2641 new_abstract_declarator_no_tuple: / / CFA2653 new_abstract_declarator_no_tuple: /* CFA */ 2642 2654 new_abstract_ptr 2643 2655 | new_abstract_array 2644 2656 ; 2645 2657 2646 new_abstract_ptr: / / CFA2658 new_abstract_ptr: /* CFA */ 2647 2659 '*' type_specifier 2648 2660 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } … … 2659 2671 ; 2660 2672 2661 new_abstract_array: / / CFA2662 / / Only the first dimension can be empty. Empty dimension must be factored out due to shift/reduce2663 // conflict with empty (void) function return type.2673 new_abstract_array: /* CFA */ 2674 /* Only the first dimension can be empty. Empty dimension must be factored out due to 2675 shift/reduce conflict with empty (void) function return type. */ 2664 2676 '[' push pop ']' type_specifier 2665 2677 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } … … 2676 2688 ; 2677 2689 2678 new_abstract_tuple: / / CFA2690 new_abstract_tuple: /* CFA */ 2679 2691 '[' push new_abstract_parameter_list pop ']' 2680 2692 { $$ = DeclarationNode::newTuple( $3 ); } 2681 2693 ; 2682 2694 2683 new_abstract_function: / / CFA2695 new_abstract_function: /* CFA */ 2684 2696 '[' push pop ']' '(' new_parameter_type_list_opt ')' 2685 2697 { $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); } … … 2690 2702 ; 2691 2703 2692 // 1) ISO/IEC 9899:1999 Section 6.7.2(2) : "At least one type specifier shall be given in the declaration specifiers in 2693 // each declaration, and in the specifier-qualifier list in each structure declaration and type name." 2694 // 2695 // 2) ISO/IEC 9899:1999 Section 6.11.5(1) : "The placement of a storage-class specifier other than at the beginning of 2696 // the declaration specifiers in a declaration is an obsolescent feature." 2697 // 2698 // 3) ISO/IEC 9899:1999 Section 6.11.6(1) : "The use of function declarators with empty parentheses (not 2699 // prototype-format parameter type declarators) is an obsolescent feature." 2700 // 2701 // 4) ISO/IEC 9899:1999 Section 6.11.7(1) : "The use of function definitions with separate parameter identifier and 2702 // declaration lists (not prototype-format parameter type and identifier declarators) is an obsolescent feature. 2703 2704 //************************* MISCELLANEOUS ******************************** 2705 2706 comma_opt: // redundant comma 2707 // empty 2704 /* 1) ISO/IEC 9899:1999 Section 6.7.2(2) : "At least one type specifier shall be given in the declaration 2705 specifiers in each declaration, and in the specifier-qualifier list in each structure declaration and 2706 type name." 2707 2708 2) ISO/IEC 9899:1999 Section 6.11.5(1) : "The placement of a storage-class specifier other than at the 2709 beginning of the declaration specifiers in a declaration is an obsolescent feature." 2710 2711 3) ISO/IEC 9899:1999 Section 6.11.6(1) : "The use of function declarators with empty parentheses (not 2712 prototype-format parameter type declarators) is an obsolescent feature." 2713 2714 4) ISO/IEC 9899:1999 Section 6.11.7(1) : "The use of function definitions with separate parameter 2715 identifier and declaration lists (not prototype-format parameter type and identifier declarators) is 2716 an obsolescent feature." */ 2717 2718 /************************* MISCELLANEOUS ********************************/ 2719 2720 comma_opt: /* redundant comma */ 2721 /* empty */ 2708 2722 | ',' 2709 2723 ; 2710 2724 2711 2725 assignment_opt: 2712 / / empty2726 /* empty */ 2713 2727 { $$ = 0; } 2714 2728 | '=' assignment_expression … … 2717 2731 2718 2732 %% 2719 / / ----end of grammar----2733 /* ----end of grammar----*/ 2720 2734 2721 2735 void yyerror( char *string ) { … … 2729 2743 } 2730 2744 2731 / / Local Variables: //2732 / / fill-column: 110 //2733 / / compile-command: "make install" //2734 / / End: //2745 /* Local Variables: */ 2746 /* fill-column: 110 */ 2747 /* compile-command: "make install" */ 2748 /* End: */ -
translator/ResolvExpr/CastCost.cc
r4bf5298 rb1a6d6b 1 /* 2 * This file is part of the Cforall project 3 * 4 * $Id: CastCost.cc,v 1.11 2005/08/29 20:14:15 rcbilson Exp $ 5 * 6 */ 7 1 8 #include "typeops.h" 2 9 #include "Cost.h" … … 8 15 9 16 namespace ResolvExpr { 10 class CastCost : public ConversionCost { 11 public: 12 CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 17 18 class CastCost : public ConversionCost 19 { 20 public: 21 CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 13 22 14 virtual void visit( BasicType *basicType);15 virtual void visit( PointerType *pointerType);16 };23 virtual void visit(BasicType *basicType); 24 virtual void visit(PointerType *pointerType); 25 }; 17 26 18 Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 19 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 20 EqvClass eqvClass; 21 NamedTypeDecl *namedType; 22 if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { 23 return castCost( src, eqvClass.type, indexer, env ); 24 } else if ( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) { 25 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); 26 // all typedefs should be gone by this point 27 assert( type ); 28 if ( type->get_base() ) { 29 return castCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 ); 30 } // if 31 } // if 32 } // if 33 if ( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 34 return Cost( 0, 0, 0 ); 35 } else if ( dynamic_cast< VoidType* >( dest ) ) { 36 return Cost( 0, 0, 1 ); 37 } else { 38 CastCost converter( dest, indexer, env ); 39 src->accept( converter ); 40 if ( converter.get_cost() == Cost::infinity ) { 41 return Cost::infinity; 42 } else { 43 return converter.get_cost() + Cost( 0, 0, 0 ); 44 } // if 45 } // if 27 Cost 28 castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) 29 { 30 // std::cout << "casting" << std::endl; 31 // src->print( std::cout, 8 ); 32 // std::cout << std::endl << "to" << std::endl; 33 // dest->print( std::cout, 8 ); 34 if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 35 EqvClass eqvClass; 36 NamedTypeDecl *namedType; 37 if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { 38 return castCost( src, eqvClass.type, indexer, env ); 39 } else if( ( namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) ) { 40 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType ); 41 // all typedefs should be gone by this point 42 assert( type ); 43 if( type->get_base() ) { 44 return castCost( src, type->get_base(), indexer, env ) + Cost( 0, 0, 1 ); 45 } 46 46 } 47 } 48 if( typesCompatibleIgnoreQualifiers( src, dest, indexer, env ) ) { 49 // std::cout << "types are compatible" << std::endl; 50 return Cost( 0, 0, 0 ); 51 } else if( dynamic_cast< VoidType* >( dest ) ) { 52 // std::cout << "destination is void" << std::endl; 53 return Cost( 0, 0, 1 ); 54 } else { 55 CastCost converter( dest, indexer, env ); 56 src->accept( converter ); 57 // std::cout << "cost is " << converter.get_cost() << std::endl; 58 if( converter.get_cost() == Cost::infinity ) { 59 return Cost::infinity; 60 } else { 61 return converter.get_cost() + Cost( 0, 0, 0 ); 62 } 63 } 64 } 47 65 48 CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) 49 : ConversionCost( dest, indexer, env ) { 66 CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) 67 : ConversionCost( dest, indexer, env ) 68 { 69 } 70 71 void 72 CastCost::visit(BasicType *basicType) 73 { 74 if( dynamic_cast< PointerType* >( dest ) ) { 75 cost = Cost( 1, 0, 0 ); 76 } else { 77 ConversionCost::visit( basicType ); 78 } 79 } 80 81 void 82 CastCost::visit(PointerType *pointerType) 83 { 84 if( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) { 85 if( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) { 86 cost = Cost( 0, 0, 1 ); 87 } else if( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) { 88 if( destAsBasic->isInteger() ) { 89 cost = Cost( 1, 0, 0 ); 90 } 91 } else { 92 TypeEnvironment newEnv( env ); 93 newEnv.add( pointerType->get_forall() ); 94 newEnv.add( pointerType->get_base()->get_forall() ); 95 int assignResult = ptrsCastable( pointerType->get_base(), destAsPtr->get_base(), newEnv, indexer ); 96 if( assignResult > 0 ) { 97 cost = Cost( 0, 0, 1 ); 98 } else if( assignResult < 0 ) { 99 cost = Cost( 1, 0, 0 ); 100 } 50 101 } 102 } 103 } 51 104 52 void CastCost::visit( BasicType *basicType ) {53 if ( dynamic_cast< PointerType* >( dest ) ) {54 cost = Cost( 1, 0, 0 );55 } else {56 ConversionCost::visit( basicType );57 } // if58 }59 60 void CastCost::visit( PointerType *pointerType ) {61 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {62 if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->get_base(), destAsPtr->get_base(), indexer, env ) ) {63 cost = Cost( 0, 0, 1 );64 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {65 if ( destAsBasic->isInteger() ) {66 cost = Cost( 1, 0, 0 );67 }68 } else {69 TypeEnvironment newEnv( env );70 newEnv.add( pointerType->get_forall() );71 newEnv.add( pointerType->get_base()->get_forall() );72 int assignResult = ptrsCastable( pointerType->get_base(), destAsPtr->get_base(), newEnv, indexer );73 if ( assignResult > 0 ) {74 cost = Cost( 0, 0, 1 );75 } else if ( assignResult < 0 ) {76 cost = Cost( 1, 0, 0 );77 } // if78 } // if79 } // if80 }81 105 } // namespace ResolvExpr -
translator/ResolvExpr/PtrsAssignable.cc
r4bf5298 rb1a6d6b 1 /* 2 * This file is part of the Cforall project 3 * 4 * $Id: PtrsAssignable.cc,v 1.3 2005/08/29 20:14:16 rcbilson Exp $ 5 * 6 */ 7 1 8 #include "typeops.h" 2 9 #include "SynTree/Type.h" … … 6 13 7 14 namespace ResolvExpr { 8 class PtrsAssignable : public Visitor { 9 public: 10 PtrsAssignable( Type *dest, const TypeEnvironment &env ); 15 16 class PtrsAssignable : public Visitor 17 { 18 public: 19 PtrsAssignable( Type *dest, const TypeEnvironment &env ); 11 20 12 int get_result() const { return result; }21 int get_result() const { return result; } 13 22 14 virtual void visit(VoidType *voidType); 15 virtual void visit(BasicType *basicType); 16 virtual void visit(PointerType *pointerType); 17 virtual void visit(ArrayType *arrayType); 18 virtual void visit(FunctionType *functionType); 19 virtual void visit(StructInstType *inst); 20 virtual void visit(UnionInstType *inst); 21 virtual void visit(EnumInstType *inst); 22 virtual void visit(ContextInstType *inst); 23 virtual void visit(TypeInstType *inst); 24 virtual void visit(TupleType *tupleType); 25 private: 26 Type *dest; 27 int result; 28 const TypeEnvironment &env; 29 }; 23 virtual void visit(VoidType *voidType); 24 virtual void visit(BasicType *basicType); 25 virtual void visit(PointerType *pointerType); 26 virtual void visit(ArrayType *arrayType); 27 virtual void visit(FunctionType *functionType); 28 virtual void visit(StructInstType *inst); 29 virtual void visit(UnionInstType *inst); 30 virtual void visit(EnumInstType *inst); 31 virtual void visit(ContextInstType *inst); 32 virtual void visit(TypeInstType *inst); 33 virtual void visit(TupleType *tupleType); 30 34 31 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) { 32 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 33 EqvClass eqvClass; 34 if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { 35 return ptrsAssignable( src, eqvClass.type, env ); 36 } 37 } 38 if ( dynamic_cast< VoidType* >( dest ) ) { 39 return 1; 40 } else { 41 PtrsAssignable ptrs( dest, env ); 42 src->accept( ptrs ); 43 return ptrs.get_result(); 44 } 35 private: 36 Type *dest; 37 int result; 38 const TypeEnvironment &env; 39 }; 40 41 int 42 ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) 43 { 44 if( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) { 45 EqvClass eqvClass; 46 if( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { 47 return ptrsAssignable( src, eqvClass.type, env ); 45 48 } 49 } 50 if( dynamic_cast< VoidType* >( dest ) ) { 51 return 1; 52 } else { 53 PtrsAssignable ptrs( dest, env ); 54 src->accept( ptrs ); 55 return ptrs.get_result(); 56 } 57 } 46 58 47 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) { 48 } 59 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) 60 : dest( dest ), result( 0 ), env( env ) 61 { 62 } 49 63 50 void PtrsAssignable::visit(VoidType *voidType) { 51 if ( dynamic_cast< FunctionType* >( dest ) ) { 52 result = 0; 53 } else { 54 result = -1; 55 } 56 } 64 void 65 PtrsAssignable::visit(VoidType *voidType) 66 { 67 if( dynamic_cast< FunctionType* >( dest ) ) { 68 result = 0; 69 } else { 70 result = -1; 71 } 72 } 57 73 58 void PtrsAssignable::visit( BasicType *basicType ) { 59 } 74 void 75 PtrsAssignable::visit(BasicType *basicType) 76 { 77 } 60 78 61 void PtrsAssignable::visit( PointerType *pointerType ) { 62 } 79 void 80 PtrsAssignable::visit(PointerType *pointerType) 81 { 82 } 63 83 64 void PtrsAssignable::visit( ArrayType *arrayType ) { 65 } 84 void 85 PtrsAssignable::visit(ArrayType *arrayType) 86 { 87 } 66 88 67 void PtrsAssignable::visit( FunctionType *functionType ) { 68 result = -1; 69 } 89 void 90 PtrsAssignable::visit(FunctionType *functionType) 91 { 92 result = -1; 93 } 70 94 71 void PtrsAssignable::visit( StructInstType *inst ) { 72 // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong 73 } 95 void 96 PtrsAssignable::visit(StructInstType *inst) 97 { 98 // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong 99 } 74 100 75 void PtrsAssignable::visit( UnionInstType *inst ) { 76 // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong 77 } 101 void 102 PtrsAssignable::visit(UnionInstType *inst) 103 { 104 // I don't think we should be doing anything here, but I'm willing to admit that I might be wrong 105 } 78 106 79 void PtrsAssignable::visit( EnumInstType *inst ) { 80 if ( dynamic_cast< EnumInstType* >( inst ) ) { 81 result = 1; 82 } else if ( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) { 83 result = bt->get_kind() == BasicType::SignedInt; 84 } 85 } 107 void 108 PtrsAssignable::visit(EnumInstType *inst) 109 { 110 if( dynamic_cast< EnumInstType* >( inst ) ) { 111 result = 1; 112 } else if( BasicType *bt = dynamic_cast< BasicType* >( inst ) ) { 113 result = bt->get_kind() == BasicType::SignedInt; 114 } 115 } 86 116 87 void PtrsAssignable::visit( ContextInstType *inst ) { 88 // I definitely don't think we should be doing anything here 89 } 117 void 118 PtrsAssignable::visit(ContextInstType *inst) 119 { 120 // I definitely don't think we should be doing anything here 121 } 90 122 91 void PtrsAssignable::visit( TypeInstType *inst ) { 92 EqvClass eqvClass; 93 if ( env.lookup( inst->get_name(), eqvClass ) ) { 94 result = ptrsAssignable( eqvClass.type, dest, env ); 95 } else { 96 result = 0; 97 } 98 } 123 void 124 PtrsAssignable::visit(TypeInstType *inst) 125 { 126 EqvClass eqvClass; 127 if( env.lookup( inst->get_name(), eqvClass ) ) { 128 result = ptrsAssignable( eqvClass.type, dest, env ); 129 } else { 130 result = 0; 131 } 132 } 99 133 100 void PtrsAssignable::visit( TupleType *tupleType ) { 134 void 135 PtrsAssignable::visit(TupleType *tupleType) 136 { 101 137 /// // This code doesn't belong here, but it might be useful somewhere else 102 /// if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {138 /// if( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) { 103 139 /// int ret = 0; 104 140 /// std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin(); … … 106 142 /// while( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) { 107 143 /// int assignResult = ptrsAssignable( *srcIt++, *destIt++ ); 108 /// if ( assignResult == 0 ) {144 /// if( assignResult == 0 ) { 109 145 /// result = assignResult; 110 146 /// return; … … 115 151 /// } 116 152 /// } 117 /// if ( srcIt == tupleType->get_types().end() && destIt == destAsTuple->get_types().end() ) {153 /// if( srcIt == tupleType->get_types().end() && destIt == destAsTuple->get_types().end() ) { 118 154 /// result = ret; 119 155 /// } else { … … 121 157 /// } 122 158 /// } 123 } 159 } 160 124 161 } // namespace ResolvExpr -
translator/ResolvExpr/Resolver.cc
r4bf5298 rb1a6d6b 98 98 return bt->isInteger(); 99 99 } else { 100 return false;100 return true; 101 101 } // if 102 102 } … … 121 121 if ( i->expr->get_results().size() == 1 && isIntegralType( i->expr->get_results().front() ) ) { 122 122 if ( newExpr ) { 123 throw SemanticError( "Too many interpretations for casecontrol expression", untyped );123 throw SemanticError( "Too many interpretations for switch control expression", untyped ); 124 124 } else { 125 125 newExpr = i->expr->clone(); … … 128 128 } // if 129 129 } // for 130 if ( ! newExpr ) {131 throw SemanticError( " No interpretations for casecontrol expression", untyped );130 if ( !newExpr ) { 131 throw SemanticError( "Too many interpretations for switch control expression", untyped ); 132 132 } // if 133 133 finishExpr( newExpr, *newEnv ); -
translator/SymTab/Validate.cc
r4bf5298 rb1a6d6b 278 278 ObjectDecl *obj = dynamic_cast< ObjectDecl * >( *i ); 279 279 assert( obj ); 280 obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false , false), enumDecl->get_name() ) );280 obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false ), enumDecl->get_name() ) ); 281 281 } // for 282 282 Parent::visit( enumDecl ); -
translator/SynTree/CompoundStmt.cc
r4bf5298 rb1a6d6b 11 11 #include <functional> 12 12 13 using std::string; 14 using std::endl;13 #include <iostream> 14 using namespace std; 15 15 16 CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) { 16 CompoundStmt::CompoundStmt( std::list<Label> labels ) 17 : Statement( labels ) 18 { 17 19 } 18 20 19 CompoundStmt::CompoundStmt( const CompoundStmt &other ) : Statement( other ) { 21 CompoundStmt::CompoundStmt( const CompoundStmt &other ) 22 : Statement( other ) 23 { 20 24 cloneAll( other.kids, kids ); 21 25 } 22 26 23 CompoundStmt::~CompoundStmt() { 27 CompoundStmt::~CompoundStmt() 28 { 24 29 deleteAll( kids ); 25 30 } 26 31 27 void CompoundStmt::print( std::ostream &os, int indent ) { 32 void 33 CompoundStmt::print( std::ostream &os, int indent ) 34 { 28 35 os << "\r" << string(indent, ' ') << "CompoundStmt" << endl ; 29 36 printAll( kids, os, indent+2 ); -
translator/SynTree/Declaration.h
r4bf5298 rb1a6d6b 12 12 enum StorageClass { 13 13 NoStorageClass, 14 Auto, 15 Static, 14 16 Extern, 15 Static,16 Auto,17 17 Register, 18 Inline, 19 Fortran, 18 Fortran 20 19 }; 21 20 … … 109 108 CompoundStmt *get_statements() const { return statements; } 110 109 void set_statements( CompoundStmt *newValue ) { statements = newValue; } 111 //bool get_isInline() const { return isInline; }112 //void set_isInline( bool newValue ) { isInline = newValue; }110 bool get_isInline() const { return isInline; } 111 void set_isInline( bool newValue ) { isInline = newValue; } 113 112 std::list< std::string >& get_oldIdents() { return oldIdents; } 114 113 std::list< Declaration* >& get_oldDecls() { return oldDecls; } -
translator/SynTree/FunctionDecl.cc
r4bf5298 rb1a6d6b 1 /* 2 * This file is part of the Cforall project 3 * 4 * $Id: FunctionDecl.cc,v 1.15 2005/08/29 20:59:25 rcbilson Exp $ 5 * 6 */ 7 1 8 #include <cassert> 2 9 … … 7 14 8 15 9 FunctionDecl::FunctionDecl( const std::string &name, StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline ) 10 : Parent( name, sc, linkage ), type( type ), statements( statements ), isInline( isInline ) { 11 // this is a brazen hack to force the function "main" to have C linkage 12 if ( name == "main" ) { 16 FunctionDecl::FunctionDecl( const std::string &name, StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, 17 CompoundStmt *statements, bool isInline ) 18 : Parent( name, sc, linkage ), type( type ), statements( statements ), isInline( isInline ) 19 { 20 // this is a pretty brazen hack to force the function "main" to have C linkage 21 if( name == "main" ) { 13 22 set_linkage( LinkageSpec::C ); 14 23 } … … 16 25 17 26 FunctionDecl::FunctionDecl( const FunctionDecl &other ) 18 : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), isInline( other.isInline ) { 27 : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), 28 isInline( other.isInline ) 29 { 19 30 } 20 31 21 FunctionDecl::~FunctionDecl() { 32 FunctionDecl::~FunctionDecl() 33 { 22 34 delete type; 23 35 delete statements; 24 36 } 25 37 26 Type * FunctionDecl::get_type() const { 38 Type* 39 FunctionDecl::get_type() const 40 { 27 41 return type; 28 42 } 29 43 30 void FunctionDecl::set_type( Type *t ) { 44 void 45 FunctionDecl::set_type(Type *t) 46 { 31 47 type = dynamic_cast< FunctionType* >( t ); 32 48 assert( type ); 33 49 } 34 50 35 void FunctionDecl::print( std::ostream &os, int indent ) const { 51 void 52 FunctionDecl::print( std::ostream &os, int indent ) const 53 { 36 54 using std::endl; 37 55 using std::string; 38 56 39 if ( get_name() != "" ) {57 if( get_name() != "" ) { 40 58 os << get_name() << ": a "; 41 59 } 42 if ( get_linkage() != LinkageSpec::Cforall ) {60 if( get_linkage() != LinkageSpec::Cforall ) { 43 61 os << LinkageSpec::toString( get_linkage() ) << " "; 44 62 } 45 if ( isInline ) {63 if( isInline ) { 46 64 os << "inline "; 47 65 } 48 if ( get_storageClass() != NoStorageClass ) {66 if( get_storageClass() != NoStorageClass ) { 49 67 os << storageClassName[ get_storageClass() ] << ' '; 50 68 } 51 if ( get_type() ) {69 if( get_type() ) { 52 70 get_type()->print( os, indent ); 53 71 } else { 54 72 os << "untyped entity "; 55 73 } 56 if ( !oldIdents.empty() ) {74 if( !oldIdents.empty() ) { 57 75 os << string( indent+2, ' ' ) << "with parameter names" << endl; 58 76 for( std::list< std::string >::const_iterator i = oldIdents.begin(); i != oldIdents.end(); ++i ) { … … 60 78 } 61 79 } 62 if ( !oldDecls.empty() ) {80 if( !oldDecls.empty() ) { 63 81 os << string( indent+2, ' ' ) << "with parameter declarations" << endl; 64 82 printAll( oldDecls, os, indent+4 ); 65 83 } 66 if ( statements ) {84 if( statements ) { 67 85 os << string( indent+2, ' ' ) << "with body " << endl; 68 86 statements->print( os, indent+4 ); … … 70 88 } 71 89 72 void FunctionDecl::printShort( std::ostream &os, int indent ) const { 90 void 91 FunctionDecl::printShort( std::ostream &os, int indent ) const 92 { 73 93 using std::endl; 74 94 using std::string; 75 95 76 if ( get_name() != "" ) {96 if( get_name() != "" ) { 77 97 os << get_name() << ": a "; 78 98 } 79 if ( isInline ) {99 if( isInline ) { 80 100 os << "inline "; 81 101 } 82 if ( get_storageClass() != NoStorageClass ) {102 if( get_storageClass() != NoStorageClass ) { 83 103 os << storageClassName[ get_storageClass() ] << ' '; 84 104 } 85 if ( get_type() ) {105 if( get_type() ) { 86 106 get_type()->print( os, indent ); 87 107 } else { … … 89 109 } 90 110 } 111 -
translator/SynTree/Statement.cc
r4bf5298 rb1a6d6b 14 14 15 15 16 // *** Statement 16 17 Statement::Statement(std::list<Label> _labels): 17 18 labels(_labels) {} … … 21 22 Statement::~Statement() {} 22 23 24 //*** ExprStmt 23 25 ExprStmt::ExprStmt( std::list<Label> _labels, Expression *_expr ): 24 26 Statement(_labels), expr(_expr) {} … … 31 33 } 32 34 35 //*** BranchStmt 33 36 const char *BranchStmt::brType[] = { "Goto", "Break", "Continue" }; 34 37 … … 54 57 } 55 58 59 //*** ReturnStmt 56 60 ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *_expr, bool throwP ) : 57 61 Statement( labels ), expr( _expr ), isThrow( throwP ) {} … … 68 72 69 73 74 // *** IfStmt 70 75 IfStmt::IfStmt( std::list<Label> _labels, Expression *_condition, Statement *_thenPart, Statement *_elsePart ): 71 76 Statement(_labels), condition(_condition), thenPart(_thenPart), elsePart(_elsePart) {} … … 86 91 } 87 92 93 // *** SwitchStmt 88 94 SwitchStmt::SwitchStmt(std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_branches): 89 95 Statement(_labels), condition(_condition), branches(_branches) … … 110 116 } 111 117 118 // *** CaseStmt 112 119 CaseStmt::CaseStmt( std::list<Label> _labels, Expression *_condition, 113 120 std::list<Statement *> &_statements, bool deflt ) … … 140 147 } 141 148 149 //*** ChooseStmt 142 150 //ChooseStmt::ChooseStmt( std::list<Label> labels, Expression *condition, Statement *body ) {} 143 151 ChooseStmt::ChooseStmt(std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_branches): … … 164 172 } 165 173 174 //*** FallthruStmt 166 175 void FallthruStmt::print(std::ostream &os, int indent) { 167 176 os << "\r" << string(indent, ' ') << "Fall-through statement" << endl; 168 177 } 169 178 179 //*** WhileStmt 170 180 WhileStmt::WhileStmt( std::list<Label> labels, Expression *condition_, 171 181 Statement *body_, bool isDoWhile_ ): … … 186 196 } 187 197 198 //*** ForStmt 188 199 ForStmt::ForStmt( std::list<Label> labels, Statement *initialization_, 189 200 Expression *condition_, Expression *increment_, Statement *body_ ): … … 222 233 } 223 234 235 //*** TryStmt 224 236 TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &_handlers, FinallyStmt *_finallyBlock ) : 225 237 Statement( labels ), block( tryBlock ), handlers( _handlers ), finallyBlock( _finallyBlock ) … … 254 266 } 255 267 268 //*** CatchStmt 256 269 CatchStmt::CatchStmt( std::list<Label> labels, Declaration *_decl, Statement *_body, bool isCatchRest ) : 257 270 Statement( labels ), decl ( _decl ), body( _body ), catchRest ( isCatchRest ) … … 277 290 278 291 292 //*** FinallyStmt 279 293 FinallyStmt::FinallyStmt( std::list<Label> labels, CompoundStmt *_block ) : 280 294 Statement( labels ), block( _block ) … … 293 307 } 294 308 309 //*** NullStmt 295 310 NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {} 296 311 NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {} -
translator/SynTree/Statement.h
r4bf5298 rb1a6d6b 1 /* 2 * This file is part of the Cforall project 3 * 4 * $Id: Statement.h,v 1.18 2005/08/29 20:59:26 rcbilson Exp $ 5 * 6 */ 7 1 8 #ifndef STATEMENT_H 2 9 #define STATEMENT_H -
translator/SynTree/Type.h
r4bf5298 rb1a6d6b 10 10 public: 11 11 struct Qualifiers { 12 Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ), isAtomic( false ) , isAttribute( false ){}13 Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue, bool isAtomic , bool isAttribute): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ), isAtomic( isAtomic ), isAttribute( isAttribute) {}12 Qualifiers(): isConst( false ), isVolatile( false ), isRestrict( false ), isLvalue( false ), isAtomic( false ) {} 13 Qualifiers( bool isConst, bool isVolatile, bool isRestrict, bool isLvalue, bool isAtomic ): isConst( isConst ), isVolatile( isVolatile ), isRestrict( isRestrict ), isLvalue( isLvalue ), isAtomic( isAtomic ) {} 14 14 15 15 Qualifiers &operator+=( const Qualifiers &other ); … … 28 28 bool isLvalue; 29 29 bool isAtomic; 30 bool isAttribute;31 30 }; 32 31 … … 41 40 bool get_isLvalue() { return tq.isLvalue; } 42 41 bool get_isAtomic() { return tq.isAtomic; } 43 bool get_isAttribute() { return tq.isAttribute; }44 42 void set_isConst( bool newValue ) { tq.isConst = newValue; } 45 43 void set_iisVolatile( bool newValue ) { tq.isVolatile = newValue; } … … 47 45 void set_isLvalue( bool newValue ) { tq.isLvalue = newValue; } 48 46 void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; } 49 void set_isAttribute( bool newValue ) { tq.isAttribute = newValue; }50 47 std::list<TypeDecl*>& get_forall() { return forall; } 51 48 -
translator/examples/identity.c
r4bf5298 rb1a6d6b 9 9 ofstream *sout = ofstream_stdout(); 10 10 char c = 'a'; 11 c = identity( c );12 11 sout << c << ' ' << identity( c ) << '\n'; 13 12 int i = 5; 14 i = identity( i );15 13 sout << i << ' ' << identity( i ) << '\n'; 16 14 double d = 3.2; 17 d = identity( d );18 15 sout << d << ' ' << identity( d ) << '\n'; 19 16 } -
translator/examples/min.c
r4bf5298 rb1a6d6b 1 1 extern "C" { 2 2 int printf( const char *, ... ); 3 //#include <stdio.h>4 3 } 5 4 … … 11 10 int main() { 12 11 char c; 13 //c = min( 'z', 'a' );14 //printf( "minimum %d\n", c );12 c = min( 'z', 'a' ); 13 printf( "minimum %d\n", c ); 15 14 int i; 16 15 i = min( 4, 3 ); -
translator/examples/s.c
r4bf5298 rb1a6d6b 1 //int ?!=?( int, int ); 1 int ?!=?( int, int ); 2 int 0; 2 3 3 void f() { 4 // int a; 5 // a ? 4 : 5; 6 1 ? 4 : 5; 4 void f() 5 { 7 6 0 ? 4 : 5; 8 7 } -
translator/examples/square.c
r4bf5298 rb1a6d6b 1 // './cfa square.c' 2 1 3 extern "C" { 2 4 #include <stdio.h> -
translator/examples/swap.c
r4bf5298 rb1a6d6b 5 5 forall( type T ) 6 6 void swap( T *left, T *right ) { 7 T temp = *left; 7 T temp; 8 temp = *left; 8 9 *left = *right; 9 10 *right = temp;
Note:
See TracChangeset
for help on using the changeset viewer.