Changeset c11e31c
- Timestamp:
- May 14, 2015, 1:44:55 PM (10 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
- Children:
- 4bf5298
- Parents:
- d4778a6
- Files:
-
- 1 deleted
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
LICENSE
rd4778a6 rc11e31c 1 This software Cforall is published under the BSD license as listed below. 1 BSD Licence 2 2 3 Copyright (c) 2015 Huawei Technologies Co., Ltd andUniversity of Waterloo.3 Copyright (c) 2015 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 10 list of conditions and the following disclaimer. 11 11 12 12 2. Redistributions in binary form must reproduce the above copyright notice, 13 14 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 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. 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. 20 19 21 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 22 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE23 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -
driver/cc1.cc
rd4778a6 rc11e31c 8 8 // Created On : Fri Aug 26 14:23:51 2005 9 9 // Last Modified By : Peter A. Buhr 10 // Last Modified On : Mon Apr 27 23:11:52201511 // Update Count : 3910 // Last Modified On : Thu May 14 13:24:45 2015 11 // Update Count : 43 12 12 // 13 13 -
libcfa/prelude.cf
rd4778a6 rc11e31c 8 8 // Created On : Sat Nov 29 07:23:41 2014 9 9 // Last Modified By : Peter A. Buhr 10 // Last Modified On : Wed Mar 18 11:36:59201511 // Update Count : 6910 // Last Modified On : Mon May 4 17:21:02 2015 11 // Update Count : 70 12 12 // 13 13 -
translator/CodeGen/CodeGenerator2.cc
rd4778a6 rc11e31c 631 631 case Declaration::NoStorageClass: 632 632 break; 633 case Declaration::Auto: 633 case Declaration::Extern: 634 before << "extern "; 634 635 break; 635 636 case Declaration::Static: 636 637 before << "static "; 637 638 break; 638 case Declaration:: Extern:639 before << "extern ";639 case Declaration::Auto: 640 // silently drop storage class 640 641 break; 641 642 case Declaration::Register: 642 643 before << "register "; 643 644 break; 645 case Declaration::Inline: 646 before << "inline "; 647 break; 644 648 case Declaration::Fortran: 645 649 before << "fortran "; -
translator/ControlStruct/ForExprMutator.cc
rd4778a6 rc11e31c 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) 7 8 forStmt->set_body( forStmt->get_body()->acceptMutator( *this ) ); 8 9 if ( DeclStmt *decl = dynamic_cast< DeclStmt * > ( forStmt->get_initialization() ) ) { 9 // create compound statement, move declaration outside, leave _for_ as-is10 // create compound statement, move initializer declaration outside, leave _for_ as-is 10 11 CompoundStmt *block = new CompoundStmt( std::list< Label >() ); 11 12 std::list<Statement *> &stmts = block->get_kids(); … … 17 18 return block; 18 19 } // if 19 // ForStmt still needs to be fixed 20 else 21 return forStmt; 20 21 return forStmt; 22 22 } 23 23 } // namespace ControlStruct -
translator/Parser/DeclarationNode.cc
rd4778a6 rc11e31c 50 50 const char *storageClassName[] = { 51 51 // order must correspond with DeclarationNode::StorageClass 52 "extern", 52 53 "static", 53 54 "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, 882 883 Declaration::Static, 883 884 Declaration::Auto, 884 Declaration::Extern,885 885 Declaration::Register, 886 Declaration:: NoStorageClass, // inline886 Declaration::Inline, 887 887 Declaration::Fortran 888 888 }; -
translator/Parser/ParseNode.h
rd4778a6 rc11e31c 262 262 class DeclarationNode : public ParseNode { 263 263 public: 264 enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic };265 enum StorageClass { Static, Auto, Extern, Register, Inline, Fortran };264 enum Qualifier { Const, Restrict, Volatile, Lvalue, Atomic, Attribute }; 265 enum StorageClass { Extern, Static, Auto, 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
rd4778a6 rc11e31c 544 544 case DeclarationNode::Atomic: 545 545 q.isAtomic = true; 546 break; 547 case DeclarationNode::Attribute: 548 q.isAttribute = true; 546 549 break; 547 550 } -
translator/Parser/cfa.y
rd4778a6 rc11e31c 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. */ 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. 44 41 45 42 %{ 46 #define YYDEBUG_LEXER_TEXT (yylval) / * lexer loads this up each time */47 #define YYDEBUG 1 / * get the pretty debugging code to compile*/43 #define YYDEBUG_LEXER_TEXT (yylval) // lexer loads this up each time 44 #define YYDEBUG 1 // get the pretty debugging code to compile 48 45 49 46 #undef __GNUC_MINOR__ … … 56 53 #include "LinkageSpec.h" 57 54 58 DeclarationNode *theTree = 0; / * the resulting parse tree */55 DeclarationNode *theTree = 0; // the resulting parse tree 59 56 LinkageSpec::Type linkage = LinkageSpec::Cforall; 60 57 std::stack< LinkageSpec::Type > linkageStack; … … 62 59 %} 63 60 64 / ************************* TERMINAL TOKENS ********************************/65 66 / * keywords */61 //************************* TERMINAL TOKENS ******************************** 62 63 // keywords 67 64 %token TYPEDEF 68 65 %token AUTO EXTERN REGISTER STATIC 69 %token INLINE / * C99 */70 %token FORTRAN / * C99, extension ISO/IEC 9899:1999 Section J.5.9(1) */66 %token INLINE // C99 67 %token FORTRAN // C99, extension ISO/IEC 9899:1999 Section J.5.9(1) 71 68 %token CONST VOLATILE 72 %token RESTRICT / * C99 */73 %token FORALL LVALUE / * CFA */69 %token RESTRICT // C99 70 %token FORALL LVALUE // CFA 74 71 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED 75 %token BOOL COMPLEX IMAGINARY / * C99 */76 %token TYPEOF LABEL / * GCC */72 %token BOOL COMPLEX IMAGINARY // C99 73 %token TYPEOF LABEL // GCC 77 74 %token ENUM STRUCT UNION 78 %token TYPE FTYPE DTYPE CONTEXT / * CFA */75 %token TYPE FTYPE DTYPE CONTEXT // CFA 79 76 %token SIZEOF 80 %token ATTRIBUTE EXTENSION / * GCC */77 %token ATTRIBUTE EXTENSION // GCC 81 78 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN 82 %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 */79 %token CHOOSE FALLTHRU TRY CATCH FINALLY THROW // CFA 80 %token ASM // C99, extension ISO/IEC 9899:1999 Section J.5.10(1) 81 %token ALIGNAS ALIGNOF ATOMIC GENERIC NORETURN STATICASSERT THREADLOCAL // C11 82 83 // names and constants: lexer differentiates between identifier and typedef names 87 84 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDEFname TYPEGENname 88 85 %token<tok> ATTR_IDENTIFIER ATTR_TYPEDEFname ATTR_TYPEGENname 89 86 %token<tok> INTEGERconstant FLOATINGconstant CHARACTERconstant STRINGliteral 90 %token<tok> ZERO ONE / * CFA */91 92 / * multi-character operators */87 %token<tok> ZERO ONE // CFA 88 89 // multi-character operators 93 90 %token ARROW /* -> */ 94 91 %token ICR DECR /* ++ -- */ … … 103 100 %token ANDassign ERassign ORassign /* &= ^= |= */ 104 101 105 / * Types declaration */102 // Types declaration 106 103 %union 107 104 { 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;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; 117 114 } 118 115 … … 121 118 %type<constant> string_literal_list 122 119 123 / * expressions */120 // expressions 124 121 %type<constant> constant 125 122 %type<en> tuple tuple_expression_list … … 134 131 %type<en> subrange 135 132 136 / * statements */133 // statements 137 134 %type<sn> labeled_statement compound_statement expression_statement selection_statement 138 135 %type<sn> iteration_statement jump_statement exception_statement asm_statement … … 146 143 %type<pn> handler_list handler_clause finally_clause 147 144 148 / * declarations */145 // declarations 149 146 %type<decl> abstract_array abstract_declarator abstract_function abstract_parameter_array 150 147 %type<decl> abstract_parameter_declaration abstract_parameter_declarator abstract_parameter_function … … 228 225 %type<decl> variable_abstract_ptr variable_array variable_declarator variable_function variable_ptr 229 226 230 / * initializers */227 // initializers 231 228 %type<in> initializer initializer_list initializer_opt 232 229 233 / * designators */230 // designators 234 231 %type<en> designator designator_list designation 235 232 236 233 237 / * Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string238 isambiguous:239 240 241 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 */234 // Handle single shift/reduce conflict for dangling else by shifting the ELSE token. For example, this string is 235 // ambiguous: 236 // .---------. matches IF '(' comma_expression ')' statement 237 // if ( C ) S1 else S2 238 // `-----------------' matches IF '(' comma_expression ')' statement ELSE statement */ 239 240 %nonassoc THEN // rule precedence for IF '(' comma_expression ')' statement 241 %nonassoc ELSE // token precedence for start of else clause in IF statement 242 243 %start translation_unit // parse-tree root 247 244 248 245 %% 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. */ 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. 279 274 280 275 push: … … 290 285 ; 291 286 292 / ************************* CONSTANTS ********************************/287 //************************* CONSTANTS ******************************** 293 288 294 289 constant: 295 / * ENUMERATIONconstant is not included here; it is treated as a variable with type296 "enumeration constant". */290 // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration 291 // constant". 297 292 INTEGERconstant { $$ = new ConstantNode(ConstantNode::Integer, $1); } 298 293 | FLOATINGconstant { $$ = new ConstantNode(ConstantNode::Float, $1); } … … 302 297 identifier: 303 298 IDENTIFIER 304 | ATTR_IDENTIFIER / * CFA */305 | zero_one / * CFA */299 | ATTR_IDENTIFIER // CFA 300 | zero_one // CFA 306 301 ; 307 302 308 303 no_01_identifier: 309 304 IDENTIFIER 310 | ATTR_IDENTIFIER / * CFA */305 | ATTR_IDENTIFIER // CFA 311 306 ; 312 307 … … 315 310 ; 316 311 317 zero_one: / * CFA */312 zero_one: // CFA 318 313 ZERO 319 314 | ONE 320 315 ; 321 316 322 string_literal_list: / * juxtaposed strings are concatenated */317 string_literal_list: // juxtaposed strings are concatenated 323 318 STRINGliteral { $$ = new ConstantNode(ConstantNode::String, $1); } 324 319 | string_literal_list STRINGliteral { $$ = $1->append( $2 ); } 325 320 ; 326 321 327 / ************************* EXPRESSIONS ********************************/322 //************************* EXPRESSIONS ******************************** 328 323 329 324 primary_expression: 330 IDENTIFIER / * typedef name cannot be used as a variable name */325 IDENTIFIER // typedef name cannot be used as a variable name 331 326 { $$ = new VarRefNode($1); } 332 327 | zero_one … … 338 333 | '(' comma_expression ')' 339 334 { $$ = $2; } 340 | '(' compound_statement ')' / * GCC, lambda expression */335 | '(' compound_statement ')' // GCC, lambda expression 341 336 { $$ = new ValofExprNode($2); } 342 337 ; … … 345 340 primary_expression 346 341 | postfix_expression '[' push assignment_expression pop ']' 347 /*CFA, comma_expression disallowed in the context because it results in a commom user error:348 349 compatible, there seems to be little advantage to this feature and many disadvantages. It350 is possible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j]. */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 backwards 344 // compatible, there seems to be little advantage to this feature and many disadvantages. It is 345 // possible to write x[(i,j)] in CFA, which is equivalent to the old x[i,j]. 351 346 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Index), $1, $4); } 352 347 | postfix_expression '(' argument_expression_list ')' … … 354 349 | postfix_expression '.' no_attr_identifier 355 350 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::FieldSel), $1, new VarRefNode($3)); } 356 | postfix_expression '.' '[' push field_list pop ']' / * CFA, tuple field selector */351 | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector 357 352 | postfix_expression ARROW no_attr_identifier 358 353 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PFieldSel), $1, new VarRefNode($3)); } 359 | postfix_expression ARROW '[' push field_list pop ']' / * CFA, tuple field selector */354 | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector 360 355 | postfix_expression ICR 361 356 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::IncrPost), $1); } 362 357 | postfix_expression DECR 363 358 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::DecrPost), $1); } 364 / * GCC has priority: cast_expression */365 | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' / * C99 */359 // GCC has priority: cast_expression 360 | '(' type_name_no_function ')' '{' initializer_list comma_opt '}' // C99 366 361 { $$ = 0; } 367 362 ; … … 374 369 375 370 argument_expression: 376 / * empty */ /* use default argument */377 { $$ = 0; } 371 // empty 372 { $$ = 0; } // use default argument 378 373 | assignment_expression 379 374 | no_attr_identifier ':' assignment_expression 380 375 { $$ = $3->set_asArgName($1); } 381 / * Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However, there382 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. */376 // Only a list of no_attr_identifier_or_typedef_name is allowed in this context. However, there is 377 // insufficient look ahead to distinguish between this list of parameter names and a tuple, so the 378 // tuple form must be used with an appropriate semantic check. 384 379 | '[' push assignment_expression pop ']' ':' assignment_expression 385 { $$ = $7->set_asArgName($3); }380 { $$ = $7->set_asArgName($3); } 386 381 | '[' push assignment_expression ',' tuple_expression_list pop ']' ':' assignment_expression 387 { $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); }388 ; 389 390 field_list: / * CFA, tuple field selector */382 { $$ = $9->set_asArgName(new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ), (ExpressionNode *)$3->set_link( flattenCommas( $5 )))); } 383 ; 384 385 field_list: // CFA, tuple field selector 391 386 field 392 387 | field_list ',' field { $$ = (ExpressionNode *)$1->set_link( $3 ); } 393 388 ; 394 389 395 field: / * CFA, tuple field selector */390 field: // CFA, tuple field selector 396 391 no_attr_identifier 397 392 { $$ = new VarRefNode( $1 ); } … … 412 407 | DECR unary_expression 413 408 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Decr), $2); } 414 | EXTENSION cast_expression / * GCC */409 | EXTENSION cast_expression // GCC 415 410 { $$ = $2; } 416 411 | unary_operator cast_expression … … 418 413 | '!' cast_expression 419 414 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Neg), $2); } 420 | '*' cast_expression / * CFA */415 | '*' cast_expression // CFA 421 416 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::PointTo), $2); } 422 / *'*' is is separated from unary_operator because of shift/reduce conflict in:423 { * X; } // dereference X424 { * int X; } // CFA declaration of pointer to int425 '&' must be moved here if C++ reference variables are supported. */417 // '*' is is separated from unary_operator because of shift/reduce conflict in: 418 // { * X; } // dereference X 419 // { * int X; } // CFA declaration of pointer to int 420 // '&' must be moved here if C++ reference variables are supported. 426 421 | SIZEOF unary_expression 427 422 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::SizeOf), $2); } … … 434 429 | ATTR_IDENTIFIER '(' argument_expression ')' 435 430 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Attr), new VarRefNode($1), $3); } 436 | ALIGNOF unary_expression / * GCC, variable alignment */431 | ALIGNOF unary_expression // GCC, variable alignment 437 432 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), $2); } 438 | ALIGNOF '(' type_name_no_function ')' / * GCC, type alignment */433 | ALIGNOF '(' type_name_no_function ')' // GCC, type alignment 439 434 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::AlignOf), new TypeValueNode($3)); } 440 | ANDAND no_attr_identifier / * GCC, address of label */435 | ANDAND no_attr_identifier // GCC, address of label 441 436 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::LabelAddress), new VarRefNode($2, true)); } 442 437 ; … … 538 533 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), 539 534 (ExpressionNode *)mkList((*$1,*$3,*$5))); } 540 | logical_OR_expression '?' /* empty */ ':' conditional_expression / * GCC, omitted first operand */535 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 541 536 { $$=new CompositeExprNode(new OperatorNode(OperatorNode::NCond),$1,$4); } 542 | logical_OR_expression '?' comma_expression ':' tuple / * CFA, tuple expression */537 | logical_OR_expression '?' comma_expression ':' tuple // CFA, tuple expression 543 538 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Cond), 544 539 (ExpressionNode *)mkList(( *$1, *$3, *$5 ))); } … … 550 545 551 546 assignment_expression: 552 /* CFA, assignment is separated from assignment_operator to ensure no assignment operations 553 for tuples */ 547 // CFA, assignment is separated from assignment_operator to ensure no assignment operations for tuples 554 548 conditional_expression 555 549 | unary_expression '=' assignment_expression … … 557 551 | unary_expression assignment_operator assignment_expression 558 552 { $$ =new CompositeExprNode($2, $1, $3); } 559 | tuple assignment_opt / * CFA, tuple expression */553 | tuple assignment_opt // CFA, tuple expression 560 554 { 561 555 if ( $2 == 0 ) { … … 568 562 569 563 assignment_expression_opt: 570 / * empty */564 // empty 571 565 { $$ = new NullExprNode; } 572 566 | assignment_expression 573 567 ; 574 568 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 */ 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 579 572 '[' push pop ']' 580 573 { $$ = new CompositeExprNode( new OperatorNode( OperatorNode::TupleC ) ); } … … 608 601 comma_expression: 609 602 assignment_expression 610 | comma_expression ',' assignment_expression / * { $$ = (ExpressionNode *)$1->add_to_list($3); } */603 | comma_expression ',' assignment_expression // { $$ = (ExpressionNode *)$1->add_to_list($3); } 611 604 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Comma),$1,$3); } 612 605 ; 613 606 614 607 comma_expression_opt: 615 /* empty */ { $$ = 0; } 608 // empty 609 { $$ = 0; } 616 610 | comma_expression 617 611 ; 618 612 619 / *************************** STATEMENTS *******************************/613 //*************************** STATEMENTS ******************************* 620 614 621 615 statement: … … 639 633 { $$ = new CompoundStmtNode( (StatementNode *)0 ); } 640 634 | '{' 641 / * Two scopes are necessary because the block itself has a scope, but every declaration within642 the block also requires its own scope */635 // Two scopes are necessary because the block itself has a scope, but every declaration within the block 636 // also requires its own scope 643 637 push push 644 label_declaration_opt / * GCC, local labels */645 block_item_list pop '}' / * C99, intermix declarations and statements */638 label_declaration_opt // GCC, local labels 639 block_item_list pop '}' // C99, intermix declarations and statements 646 640 { $$ = new CompoundStmtNode( $5 ); } 647 641 ; 648 642 649 block_item_list: / * C99 */643 block_item_list: // C99 650 644 block_item 651 645 | block_item_list push block_item … … 654 648 655 649 block_item: 656 declaration / * CFA, new & old style declarations */650 declaration // CFA, new & old style declarations 657 651 { $$ = new StatementNode( $1 ); } 658 | EXTENSION declaration / * GCC */652 | EXTENSION declaration // GCC 659 653 { $$ = new StatementNode( $2 ); } 660 654 | statement pop … … 674 668 selection_statement: 675 669 IF '(' comma_expression ')' statement %prec THEN 676 / * explicitly deal with the shift/reduce conflict on if/else */670 // explicitly deal with the shift/reduce conflict on if/else 677 671 { $$ = new StatementNode(StatementNode::If, $3, $5); } 678 672 | IF '(' comma_expression ')' statement ELSE statement 679 673 { $$ = new StatementNode(StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7)) ); } 680 | SWITCH '(' comma_expression ')' case_clause / * CFA */674 | SWITCH '(' comma_expression ')' case_clause // CFA 681 675 { $$ = new StatementNode(StatementNode::Switch, $3, $5); } 682 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' / * CFA */676 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA 683 677 { $$ = new StatementNode(StatementNode::Switch, $3, $8); /* xxx */ } 684 / * 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 after686 the initial declaration list can never be executed, and therefore, are removed from the687 grammar even though C allows it. */688 | CHOOSE '(' comma_expression ')' case_clause / * CFA */678 // The semantics of the declaration list is changed to include any associated initialization, which is 679 // performed *before* the transfer to the appropriate case clause. Statements after the initial 680 // declaration list can never be executed, and therefore, are removed from the grammar even though C 681 // allows it. 682 | CHOOSE '(' comma_expression ')' case_clause // CFA 689 683 { $$ = new StatementNode(StatementNode::Choose, $3, $5); } 690 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' / * CFA */684 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA 691 685 { $$ = new StatementNode(StatementNode::Choose, $3, $8); } 692 686 ; 693 687 694 / * CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a695 case clause allows a list of values and subranges. */ 696 697 case_value: / * CFA */688 // CASE and DEFAULT clauses are only allowed in the SWITCH statement, precluding Duff's device. In addition, a case 689 // clause allows a list of values and subranges. 690 691 case_value: // CFA 698 692 constant_expression { $$ = $1; } 699 | constant_expression ELLIPSIS constant_expression / * GCC, subrange */693 | constant_expression ELLIPSIS constant_expression // GCC, subrange 700 694 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range),$1,$3); } 701 | subrange / * CFA, subrange */702 ; 703 704 case_value_list: / * CFA */695 | subrange // CFA, subrange 696 ; 697 698 case_value_list: // CFA 705 699 case_value 706 700 | case_value_list ',' case_value … … 708 702 ; 709 703 710 case_label: / * CFA */704 case_label: // CFA 711 705 CASE case_value_list ':' { $$ = new StatementNode(StatementNode::Case, $2, 0); } 712 706 | DEFAULT ':' { $$ = new StatementNode(StatementNode::Default); } 713 /* A semantic check is required to ensure only one default clause per switch/choose 714 statement. */ 715 ; 716 717 case_label_list: /* CFA */ 707 // A semantic check is required to ensure only one default clause per switch/choose statement. 708 ; 709 710 case_label_list: // CFA 718 711 case_label 719 712 | case_label_list case_label { $$ = (StatementNode *)($1->set_link($2)); } 720 713 ; 721 714 722 case_clause: / * CFA */715 case_clause: // CFA 723 716 case_label_list statement { $$ = $1->append_last_case($2); } 724 717 ; 725 718 726 switch_clause_list_opt: /* CFA */ 727 /* empty */ { $$ = 0; } 719 switch_clause_list_opt: // CFA 720 // empty 721 { $$ = 0; } 728 722 | switch_clause_list 729 723 ; 730 724 731 switch_clause_list: / * CFA */725 switch_clause_list: // CFA 732 726 case_label_list statement_list 733 727 { $$ = $1->append_last_case($2); } … … 736 730 ; 737 731 738 choose_clause_list_opt: /* CFA */ 739 /* empty */ { $$ = 0; } 732 choose_clause_list_opt: // CFA 733 // empty 734 { $$ = 0; } 740 735 | choose_clause_list 741 736 ; 742 737 743 choose_clause_list: / * CFA */738 choose_clause_list: // CFA 744 739 case_label_list fall_through 745 740 { $$ = $1->append_last_case($2); } 746 741 | case_label_list statement_list fall_through_opt 747 742 { $$ = $1->append_last_case((StatementNode *)mkList((*$2,*$3))); } 748 743 | choose_clause_list case_label_list fall_through 749 744 { $$ = (StatementNode *)($1->set_link($2->append_last_case($3))); } 750 745 | choose_clause_list case_label_list statement_list fall_through_opt 751 { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); } 752 ; 753 754 fall_through_opt: /* CFA */ 755 /* empty */ { $$ = 0; } 746 { $$ = (StatementNode *)($1->set_link($2->append_last_case((StatementNode *)mkList((*$3,*$4))))); } 747 ; 748 749 fall_through_opt: // CFA 750 // empty 751 { $$ = 0; } 756 752 | fall_through 757 753 ; 758 754 759 fall_through: / * CFA */755 fall_through: // CFA 760 756 FALLTHRU { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); } 761 757 | FALLTHRU ';' { $$ = new StatementNode(StatementNode::Fallthru, 0, 0); } … … 774 770 comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt 775 771 { $$ = new ForCtlExprNode($1, $4, $6); } 776 | declaration comma_expression_opt ';' comma_expression_opt / * C99 */777 / * Like C++, the loop index can be declared local to the loop. */772 | declaration comma_expression_opt ';' comma_expression_opt // C99 773 // Like C++, the loop index can be declared local to the loop. 778 774 { $$ = new ForCtlExprNode($1, $2, $4); } 779 775 ; … … 782 778 GOTO no_attr_identifier ';' 783 779 { $$ = new StatementNode(StatementNode::Goto, $2); } 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; */780 | GOTO '*' comma_expression ';' // GCC, computed goto 781 // 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; 787 783 { $$ = new StatementNode(StatementNode::Goto, $3); } 788 784 | CONTINUE ';' 789 / * A semantic check is required to ensure this statement appears only in the body of an790 iteration statement. */785 // A semantic check is required to ensure this statement appears only in the body of an iteration 786 // statement. 791 787 { $$ = new StatementNode(StatementNode::Continue, 0, 0); } 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. */ 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. 796 791 { $$ = new StatementNode(StatementNode::Continue, $2); } 797 792 | BREAK ';' 798 / * A semantic check is required to ensure this statement appears only in the body of an799 iteration statement. */793 // A semantic check is required to ensure this statement appears only in the body of an iteration 794 // statement. 800 795 { $$ = new StatementNode(StatementNode::Break, 0, 0); } 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. */ 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. 805 799 { $$ = new StatementNode(StatementNode::Break, $2 ); } 806 800 | RETURN comma_expression_opt ';' … … 825 819 826 820 handler_list: 827 / * There must be at least one catch clause */821 // There must be at least one catch clause 828 822 handler_clause 829 / * ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for830 its try block. */823 // ISO/IEC 9899:1999 Section 15.3(6) If present, a "..." handler shall be the last handler for its try 824 // block. 831 825 | CATCH '(' ELLIPSIS ')' compound_statement 832 826 { $$ = StatementNode::newCatchStmt( 0, $5, true ); } … … 850 844 851 845 exception_declaration: 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. */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. 857 851 type_specifier 858 852 | type_specifier declarator … … 863 857 | type_specifier variable_abstract_declarator 864 858 { $$ = $2->addType( $1 ); } 865 | new_abstract_declarator_tuple no_attr_identifier / * CFA */859 | new_abstract_declarator_tuple no_attr_identifier // CFA 866 860 { 867 861 typedefTable.addToEnclosingScope( TypedefTable::ID ); 868 862 $$ = $1->addName( $2 ); 869 863 } 870 | new_abstract_declarator_tuple / * CFA */864 | new_abstract_declarator_tuple // CFA 871 865 ; 872 866 … … 874 868 ASM type_qualifier_list_opt '(' constant_expression ')' ';' 875 869 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 876 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' / * remaining GCC */870 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ')' ';' // remaining GCC 877 871 { $$ = new StatementNode(StatementNode::Asm, 0, 0); } 878 872 | ASM type_qualifier_list_opt '(' constant_expression ':' asm_operands_opt ':' asm_operands_opt ')' ';' … … 883 877 ; 884 878 885 asm_operands_opt: / * GCC */886 / * empty */879 asm_operands_opt: // GCC 880 // empty 887 881 | asm_operands_list 888 882 ; 889 883 890 asm_operands_list: / * GCC */884 asm_operands_list: // GCC 891 885 asm_operand 892 886 | asm_operands_list ',' asm_operand 893 887 ; 894 888 895 asm_operand: / * GCC */889 asm_operand: // GCC 896 890 STRINGliteral '(' constant_expression ')' {} 897 891 ; 898 892 899 asm_clobbers_list: / * GCC */893 asm_clobbers_list: // GCC 900 894 STRINGliteral {} 901 895 | asm_clobbers_list ',' STRINGliteral 902 896 ; 903 897 904 / ******************************* DECLARATIONS *********************************/905 906 declaration_list_opt: / * used at beginning of switch statement */898 //******************************* DECLARATIONS ********************************* 899 900 declaration_list_opt: // used at beginning of switch statement 907 901 pop 908 902 { $$ = 0; } … … 916 910 ; 917 911 918 old_declaration_list_opt: / * used to declare parameter types in K&R style functions */912 old_declaration_list_opt: // used to declare parameter types in K&R style functions 919 913 pop 920 914 { $$ = 0; } … … 928 922 ; 929 923 930 label_declaration_opt: / * GCC, local label */931 / * empty */924 label_declaration_opt: // GCC, local label 925 // empty 932 926 | label_declaration_list 933 927 ; 934 928 935 label_declaration_list: / * GCC, local label */929 label_declaration_list: // GCC, local label 936 930 LABEL label_list ';' 937 931 | label_declaration_list LABEL label_list ';' 938 932 ; 939 933 940 label_list: / * GCC, local label */934 label_list: // GCC, local label 941 935 no_attr_identifier_or_typedef_name {} 942 936 | label_list ',' no_attr_identifier_or_typedef_name {} 943 937 ; 944 938 945 declaration: / * CFA, new & old style declarations */939 declaration: // CFA, new & old style declarations 946 940 new_declaration 947 941 | old_declaration 948 942 ; 949 943 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 */ 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 964 956 new_variable_declaration pop ';' 965 957 | new_typedef_declaration pop ';' … … 969 961 ; 970 962 971 new_variable_declaration: / * CFA */963 new_variable_declaration: // CFA 972 964 new_variable_specifier initializer_opt 973 965 { 974 typedefTable.addToEnclosingScope( TypedefTable::ID );966 typedefTable.addToEnclosingScope( TypedefTable::ID ); 975 967 $$ = $1; 976 968 } 977 969 | declaration_qualifier_list new_variable_specifier initializer_opt 978 / * declaration_qualifier_list also includes type_qualifier_list, so a semantic check is979 necessary to preclude them as a type_qualifier cannot appear in that context. */980 { 981 typedefTable.addToEnclosingScope( TypedefTable::ID );970 // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is necessary to 971 // preclude them as a type_qualifier cannot appear in that context. 972 { 973 typedefTable.addToEnclosingScope( TypedefTable::ID ); 982 974 $$ = $2->addQualifiers( $1 ); 983 975 } 984 976 | new_variable_declaration pop ',' push identifier_or_typedef_name initializer_opt 985 977 { 986 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );978 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID ); 987 979 $$ = $1->appendList( $1->cloneType( $5 ) ); 988 980 } 989 981 ; 990 982 991 new_variable_specifier: / * CFA */992 / * A semantic check is required to ensure asm_name only appears on declarations with implicit993 or explicit static storage-class */983 new_variable_specifier: // CFA 984 // A semantic check is required to ensure asm_name only appears on declarations with implicit or 985 // explicit static storage-class 994 986 new_abstract_declarator_no_tuple identifier_or_typedef_name asm_name_opt 995 987 { … … 1009 1001 ; 1010 1002 1011 new_function_declaration: / * CFA */1003 new_function_declaration: // CFA 1012 1004 new_function_specifier 1013 1005 { 1014 typedefTable.addToEnclosingScope( TypedefTable::ID );1006 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1015 1007 $$ = $1; 1016 1008 } 1017 1009 | declaration_qualifier_list new_function_specifier 1018 / * declaration_qualifier_list also includes type_qualifier_list, so a semantic check is1019 necessary to preclude them as a type_qualifier cannot appear in this context. */1020 { 1021 typedefTable.addToEnclosingScope( TypedefTable::ID );1010 // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is necessary to 1011 // preclude them as a type_qualifier cannot appear in this context. 1012 { 1013 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1022 1014 $$ = $2->addQualifiers( $1 ); 1023 1015 } 1024 1016 | new_function_declaration pop ',' push identifier_or_typedef_name 1025 1017 { 1026 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID );1018 typedefTable.addToEnclosingScope( *$5, TypedefTable::ID ); 1027 1019 $$ = $1->appendList( $1->cloneType( $5 ) ); 1028 1020 } 1029 1021 ; 1030 1022 1031 new_function_specifier: / * CFA */1023 new_function_specifier: // CFA 1032 1024 '[' push pop ']' identifier '(' push new_parameter_type_list_opt pop ')' 1033 1025 { … … 1060 1052 ; 1061 1053 1062 new_function_return: / * CFA */1054 new_function_return: // CFA 1063 1055 '[' push new_parameter_list pop ']' 1064 1056 { $$ = DeclarationNode::newTuple( $3 ); } … … 1069 1061 ; 1070 1062 1071 new_typedef_declaration: / * CFA */1063 new_typedef_declaration: // CFA 1072 1064 TYPEDEF new_variable_specifier 1073 1065 { … … 1102 1094 $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() ); 1103 1095 } 1104 | type_qualifier_list TYPEDEF type_specifier declarator / * remaining OBSOLESCENT (see 2) */1096 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2) 1105 1097 { 1106 1098 typedefTable.addToEnclosingScope( TypedefTable::TD); … … 1119 1111 ; 1120 1112 1121 typedef_expression: / * GCC, naming expression type */1113 typedef_expression: // GCC, naming expression type 1122 1114 TYPEDEF no_attr_identifier '=' assignment_expression 1123 1115 { … … 1135 1127 declaring_list pop ';' 1136 1128 | typedef_declaration pop ';' 1137 | typedef_expression pop ';' / * GCC, naming expression type */1129 | typedef_expression pop ';' // GCC, naming expression type 1138 1130 | sue_declaration_specifier pop ';' 1139 1131 ; … … 1149 1141 | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 1150 1142 { 1151 typedefTable.addToEnclosingScope( TypedefTable::ID );1143 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1152 1144 $$ = $1->appendList( $1->cloneBaseType( $4->addInitializer($6) ) ); 1153 1145 } 1154 1146 ; 1155 1147 1156 declaration_specifier: / * type specifier + storage class */1148 declaration_specifier: // type specifier + storage class 1157 1149 basic_declaration_specifier 1158 1150 | sue_declaration_specifier … … 1161 1153 ; 1162 1154 1163 type_specifier: / * declaration specifier - storage class */1155 type_specifier: // declaration specifier - storage class 1164 1156 basic_type_specifier 1165 1157 | sue_type_specifier … … 1168 1160 ; 1169 1161 1170 type_qualifier_list_opt: / * GCC, used in asm_statement */1171 / * empty */1162 type_qualifier_list_opt: // GCC, used in asm_statement 1163 // empty 1172 1164 { $$ = 0; } 1173 1165 | type_qualifier_list … … 1189 1181 type_qualifier_name 1190 1182 | attribute 1191 { $$ = DeclarationNode::newQualifier( DeclarationNode:: Const); }1183 { $$ = DeclarationNode::newQualifier( DeclarationNode::Attribute ); } 1192 1184 ; 1193 1185 … … 1199 1191 | VOLATILE 1200 1192 { $$ = DeclarationNode::newQualifier( DeclarationNode::Volatile ); } 1201 | LVALUE / * CFA */1193 | LVALUE // CFA 1202 1194 { $$ = DeclarationNode::newQualifier( DeclarationNode::Lvalue ); } 1203 1195 | ATOMIC 1204 1196 { $$ = DeclarationNode::newQualifier( DeclarationNode::Atomic ); } 1205 | FORALL '(' 1197 | FORALL '(' 1206 1198 { 1207 1199 typedefTable.enterScope(); 1208 1200 } 1209 type_parameter_list ')' / * CFA */1201 type_parameter_list ')' // CFA 1210 1202 { 1211 1203 typedefTable.leaveScope(); … … 1216 1208 declaration_qualifier_list: 1217 1209 storage_class_list 1218 | type_qualifier_list storage_class_list / * remaining OBSOLESCENT (see 2) */1210 | type_qualifier_list storage_class_list // remaining OBSOLESCENT (see 2) 1219 1211 { $$ = $1->addQualifiers( $2 ); } 1220 1212 | declaration_qualifier_list type_qualifier_list storage_class_list … … 1239 1231 1240 1232 storage_class_name: 1241 AUTO 1233 EXTERN 1234 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); } 1235 | STATIC 1236 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); } 1237 | AUTO 1242 1238 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Auto ); } 1243 | EXTERN1244 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Extern ); }1245 1239 | REGISTER 1246 1240 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Register ); } 1247 | STATIC 1248 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Static ); } 1249 | INLINE /* C99 */ 1250 /* INLINE is essentially a storage class specifier for functions, and hence, belongs here. */ 1241 | INLINE // C99 1242 // INLINE is essentially a storage class specifier for functions, and hence, belongs here. 1251 1243 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Inline ); } 1252 | FORTRAN / * C99 */1244 | FORTRAN // C99 1253 1245 { $$ = DeclarationNode::newStorageClass( DeclarationNode::Fortran ); } 1254 1246 ; … … 1273 1265 | VOID 1274 1266 { $$ = DeclarationNode::newBasicType( DeclarationNode::Void ); } 1275 | BOOL / * C99 */1267 | BOOL // C99 1276 1268 { $$ = DeclarationNode::newBasicType( DeclarationNode::Bool ); } 1277 | COMPLEX / * C99 */1269 | COMPLEX // C99 1278 1270 { $$ = DeclarationNode::newBasicType( DeclarationNode::Complex ); } 1279 | IMAGINARY / * C99 */1271 | IMAGINARY // C99 1280 1272 { $$ = DeclarationNode::newBasicType( DeclarationNode::Imaginary ); } 1281 1273 ; 1282 1274 1283 1275 basic_declaration_specifier: 1284 / * A semantic check is necessary for conflicting storage classes. */1276 // A semantic check is necessary for conflicting storage classes. 1285 1277 basic_type_specifier 1286 1278 | declaration_qualifier_list basic_type_specifier 1287 1279 { $$ = $2->addQualifiers( $1 ); } 1288 | basic_declaration_specifier storage_class / * remaining OBSOLESCENT (see 2) */1280 | basic_declaration_specifier storage_class // remaining OBSOLESCENT (see 2) 1289 1281 { $$ = $1->addQualifiers( $2 ); } 1290 1282 | basic_declaration_specifier storage_class type_qualifier_list … … 1301 1293 1302 1294 direct_type_name: 1303 / * A semantic check is necessary for conflicting type qualifiers. */1295 // A semantic check is necessary for conflicting type qualifiers. 1304 1296 basic_type_name 1305 1297 | type_qualifier_list basic_type_name … … 1312 1304 1313 1305 indirect_type_name: 1314 TYPEOF '(' type_name ')' / * GCC: typeof(x) y; */1306 TYPEOF '(' type_name ')' // GCC: typeof(x) y; 1315 1307 { $$ = $3; } 1316 | TYPEOF '(' comma_expression ')' / * GCC: typeof(a+b) y; */1308 | TYPEOF '(' comma_expression ')' // GCC: typeof(a+b) y; 1317 1309 { $$ = DeclarationNode::newTypeof( $3 ); } 1318 | ATTR_TYPEGENname '(' type_name ')' / * CFA: e.g., @type(x) y; */1310 | ATTR_TYPEGENname '(' type_name ')' // CFA: e.g., @type(x) y; 1319 1311 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1320 | ATTR_TYPEGENname '(' comma_expression ')' / * CFA: e.g., @type(a+b) y; */1312 | ATTR_TYPEGENname '(' comma_expression ')' // CFA: e.g., @type(a+b) y; 1321 1313 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1322 1314 ; … … 1326 1318 | declaration_qualifier_list sue_type_specifier 1327 1319 { $$ = $2->addQualifiers( $1 ); } 1328 | sue_declaration_specifier storage_class / * remaining OBSOLESCENT (see 2) */1320 | sue_declaration_specifier storage_class // remaining OBSOLESCENT (see 2) 1329 1321 { $$ = $1->addQualifiers( $2 ); } 1330 1322 | sue_declaration_specifier storage_class type_qualifier_list … … 1333 1325 1334 1326 sue_type_specifier: 1335 elaborated_type_name / * struct, union, enum */1327 elaborated_type_name // struct, union, enum 1336 1328 | type_qualifier_list elaborated_type_name 1337 1329 { $$ = $2->addQualifiers( $1 ); } … … 1344 1336 | declaration_qualifier_list typedef_type_specifier 1345 1337 { $$ = $2->addQualifiers( $1 ); } 1346 | typedef_declaration_specifier storage_class / * remaining OBSOLESCENT (see 2) */1338 | typedef_declaration_specifier storage_class // remaining OBSOLESCENT (see 2) 1347 1339 { $$ = $1->addQualifiers( $2 ); } 1348 1340 | typedef_declaration_specifier storage_class type_qualifier_list … … 1350 1342 ; 1351 1343 1352 typedef_type_specifier: / * typedef types */1344 typedef_type_specifier: // typedef types 1353 1345 TYPEDEFname 1354 1346 { $$ = DeclarationNode::newFromTypedef( $1 ); } … … 1371 1363 | aggregate_key no_attr_identifier_or_typedef_name '{' field_declaration_list '}' 1372 1364 { $$ = DeclarationNode::newAggregate( $1, $2, 0, 0, $4 ); } 1373 | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' / * CFA */1365 | aggregate_key '(' push type_parameter_list pop ')' '{' field_declaration_list '}' // CFA 1374 1366 { $$ = DeclarationNode::newAggregate( $1, 0, $4, 0, $8 ); } 1375 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name / * CFA */1367 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name // CFA 1376 1368 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, 0 ); } 1377 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' / * CFA */1369 | aggregate_key '(' push type_parameter_list pop ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA 1378 1370 { $$ = DeclarationNode::newAggregate( $1, $7, $4, 0, $9 ); } 1379 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' / * CFA */1371 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' '{' field_declaration_list '}' // CFA 1380 1372 { $$ = DeclarationNode::newAggregate( $1, 0, $4, $8, $11 ); } 1381 | 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 */1373 | aggregate_key '(' push type_name_list pop ')' no_attr_identifier_or_typedef_name // CFA 1374 // push and pop are only to prevent S/R conflicts 1383 1375 { $$ = DeclarationNode::newAggregate( $1, $7, 0, $4, 0 ); } 1384 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' / * CFA */1376 | aggregate_key '(' push type_parameter_list pop ')' '(' type_name_list ')' no_attr_identifier_or_typedef_name '{' field_declaration_list '}' // CFA 1385 1377 { $$ = DeclarationNode::newAggregate( $1, $10, $4, $8, $12 ); } 1386 1378 ; … … 1401 1393 1402 1394 field_declaration: 1403 new_field_declaring_list ';' / * CFA, new style field declaration */1404 | EXTENSION new_field_declaring_list ';' / * GCC */1395 new_field_declaring_list ';' // CFA, new style field declaration 1396 | EXTENSION new_field_declaring_list ';' // GCC 1405 1397 { $$ = $2; } 1406 1398 | field_declaring_list ';' 1407 | 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 */1399 | EXTENSION field_declaring_list ';' // GCC 1400 { $$ = $2; } 1401 ; 1402 1403 new_field_declaring_list: // CFA, new style field declaration 1404 new_abstract_declarator_tuple // CFA, no field name 1413 1405 | new_abstract_declarator_tuple no_attr_identifier_or_typedef_name 1414 1406 { $$ = $1->addName( $2 ); } 1415 1407 | new_field_declaring_list ',' no_attr_identifier_or_typedef_name 1416 1408 { $$ = $1->appendList( $1->cloneType( $3 ) ); } 1417 | new_field_declaring_list ',' / * CFA, no field name */1409 | new_field_declaring_list ',' // CFA, no field name 1418 1410 { $$ = $1->appendList( $1->cloneType( 0 ) ); } 1419 1411 ; … … 1427 1419 1428 1420 field_declarator: 1429 / * empty */ /* CFA, no field name */1430 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } 1431 | bit_subrange_size / * no field name */1421 // empty 1422 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name 1423 | bit_subrange_size // no field name 1432 1424 { $$ = DeclarationNode::newBitfield( $1 ); } 1433 1425 | variable_declarator bit_subrange_size_opt 1434 / * A semantic check is required to ensure bit_subrange only appears on base type int. */1426 // A semantic check is required to ensure bit_subrange only appears on base type int. 1435 1427 { $$ = $1->addBitfield( $2 ); } 1436 1428 | typedef_redeclarator bit_subrange_size_opt 1437 / * A semantic check is required to ensure bit_subrange only appears on base type int. */1429 // A semantic check is required to ensure bit_subrange only appears on base type int. 1438 1430 { $$ = $1->addBitfield( $2 ); } 1439 | variable_abstract_declarator / * CFA, no field name */1431 | variable_abstract_declarator // CFA, no field name 1440 1432 ; 1441 1433 1442 1434 bit_subrange_size_opt: 1443 / * empty */1435 // empty 1444 1436 { $$ = 0; } 1445 1437 | bit_subrange_size … … 1473 1465 1474 1466 enumerator_value_opt: 1475 / * empty */1467 // empty 1476 1468 { $$ = 0; } 1477 1469 | '=' constant_expression … … 1479 1471 ; 1480 1472 1481 / * Minimum of one parameter after which ellipsis is allowed only at the end. */1482 1483 new_parameter_type_list_opt: / * CFA */1484 / * empty */1473 // Minimum of one parameter after which ellipsis is allowed only at the end. 1474 1475 new_parameter_type_list_opt: // CFA 1476 // empty 1485 1477 { $$ = 0; } 1486 1478 | new_parameter_type_list 1487 1479 ; 1488 1480 1489 new_parameter_type_list: / * CFA, abstract + real */1481 new_parameter_type_list: // CFA, abstract + real 1490 1482 new_abstract_parameter_list 1491 1483 | new_parameter_list … … 1498 1490 ; 1499 1491 1500 new_parameter_list: / * CFA */1501 / *To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last1502 1503 to get lookahead to the ']'. */1492 new_parameter_list: // CFA 1493 // To obtain LR(1) between new_parameter_list and new_abstract_tuple, the last 1494 // new_abstract_parameter_list is factored out from new_parameter_list, flattening the rules 1495 // to get lookahead to the ']'. 1504 1496 new_parameter_declaration 1505 1497 | new_abstract_parameter_list pop ',' push new_parameter_declaration … … 1511 1503 ; 1512 1504 1513 new_abstract_parameter_list: / * CFA, new & old style abstract */1505 new_abstract_parameter_list: // CFA, new & old style abstract 1514 1506 new_abstract_parameter_declaration 1515 1507 | new_abstract_parameter_list pop ',' push new_abstract_parameter_declaration … … 1518 1510 1519 1511 parameter_type_list_opt: 1520 / * empty */1512 // empty 1521 1513 { $$ = 0; } 1522 1514 | parameter_type_list … … 1529 1521 ; 1530 1522 1531 parameter_list: / * abstract + real */1523 parameter_list: // abstract + real 1532 1524 abstract_parameter_declaration 1533 1525 | parameter_declaration … … 1538 1530 ; 1539 1531 1540 / *Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different1541 1542 function prototypes. */ 1543 1544 new_parameter_declaration: / * CFA, new & old style parameter declaration */1532 // Provides optional identifier names (abstract_declarator/variable_declarator), no initialization, different 1533 // semantics for typedef name by using typedef_parameter_redeclarator instead of typedef_redeclarator, and 1534 // function prototypes. 1535 1536 new_parameter_declaration: // CFA, new & old style parameter declaration 1545 1537 parameter_declaration 1546 1538 | new_identifier_parameter_declarator_no_tuple identifier_or_typedef_name assignment_opt 1547 1539 { $$ = $1->addName( $2 ); } 1548 1540 | new_abstract_tuple identifier_or_typedef_name assignment_opt 1549 / * To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). */1541 // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). 1550 1542 { $$ = $1->addName( $2 ); } 1551 1543 | type_qualifier_list new_abstract_tuple identifier_or_typedef_name assignment_opt … … 1554 1546 ; 1555 1547 1556 new_abstract_parameter_declaration: / * CFA, new & old style parameter declaration */1548 new_abstract_parameter_declaration: // CFA, new & old style parameter declaration 1557 1549 abstract_parameter_declaration 1558 1550 | new_identifier_parameter_declarator_no_tuple 1559 1551 | new_abstract_tuple 1560 / * To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). */1552 // To obtain LR(1), these rules must be duplicated here (see new_abstract_declarator). 1561 1553 | type_qualifier_list new_abstract_tuple 1562 1554 { $$ = $2->addQualifiers( $1 ); } … … 1567 1559 declaration_specifier identifier_parameter_declarator assignment_opt 1568 1560 { 1569 typedefTable.addToEnclosingScope( TypedefTable::ID );1561 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1570 1562 $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) ); 1571 1563 } 1572 1564 | declaration_specifier typedef_parameter_redeclarator assignment_opt 1573 1565 { 1574 typedefTable.addToEnclosingScope( TypedefTable::ID );1566 typedefTable.addToEnclosingScope( TypedefTable::ID ); 1575 1567 $$ = $2->addType( $1 )->addInitializer( new InitializerNode($3) ); 1576 1568 } … … 1583 1575 ; 1584 1576 1585 / *ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a1586 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 */1577 // ISO/IEC 9899:1999 Section 6.9.1(6) : "An identifier declared as a typedef name shall not be redeclared as a 1578 // parameter." Because the scope of the K&R-style parameter-list sees the typedef first, the following is 1579 // based only on identifiers. The ANSI-style parameter-list can redefine a typedef name. 1580 1581 identifier_list: // K&R-style parameter list => no types 1590 1582 no_attr_identifier 1591 1583 { $$ = DeclarationNode::newName( $1 ); } … … 1612 1604 ; 1613 1605 1614 type_name_no_function: / * sizeof, alignof, cast (constructor) */1615 new_abstract_declarator_tuple / * CFA */1606 type_name_no_function: // sizeof, alignof, cast (constructor) 1607 new_abstract_declarator_tuple // CFA 1616 1608 | type_specifier 1617 1609 | type_specifier variable_abstract_declarator … … 1619 1611 ; 1620 1612 1621 type_name: / * typeof, assertion */1622 new_abstract_declarator_tuple / * CFA */1623 | new_abstract_function / * CFA */1613 type_name: // typeof, assertion 1614 new_abstract_declarator_tuple // CFA 1615 | new_abstract_function // CFA 1624 1616 | type_specifier 1625 1617 | type_specifier abstract_declarator … … 1645 1637 ; 1646 1638 1647 / *There is an unreconcileable parsing problem between C99 and CFA with respect to designators. The problem1648 1649 1650 int x[10] = { [1] = 3 };1651 1652 1653 1654 1655 supported either due to shift/reduce conflicts */ 1639 // There is an unreconcileable parsing problem between C99 and CFA with respect to designators. The problem 1640 // 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 this 1645 // case, CFA changes the syntax from "=" to ":" as the separator between the designator and initializer. GCC 1646 // does uses ":" for field selection. The optional use of the "=" in GCC, or in this case ":", cannot be 1647 // supported either due to shift/reduce conflicts 1656 1648 1657 1649 designation: 1658 designator_list ':' / * C99, CFA uses ":" instead of "=" */1659 | no_attr_identifier_or_typedef_name ':' / * GCC, field name */1650 designator_list ':' // C99, CFA uses ":" instead of "=" 1651 | no_attr_identifier_or_typedef_name ':' // GCC, field name 1660 1652 { $$ = new VarRefNode( $1 ); } 1661 1653 ; 1662 1654 1663 designator_list: / * C99 */1655 designator_list: // C99 1664 1656 designator 1665 1657 | designator_list designator { $$ = (ExpressionNode *)($1->set_link( $2 )); } … … 1667 1659 1668 1660 designator: 1669 '.' no_attr_identifier_or_typedef_name / * C99, field name */1661 '.' no_attr_identifier_or_typedef_name // C99, field name 1670 1662 { $$ = new VarRefNode( $2 ); } 1671 | '[' push assignment_expression pop ']' / * C99, single array element */1663 | '[' push assignment_expression pop ']' // C99, single array element 1672 1664 /* assignment_expression used instead of constant_expression because of shift/reduce conflicts 1673 1665 with tuple. */ 1674 1666 { $$ = $3; } 1675 | '[' push subrange pop ']' / * CFA, multiple array elements */1667 | '[' push subrange pop ']' // CFA, multiple array elements 1676 1668 { $$ = $3; } 1677 | '[' push constant_expression ELLIPSIS constant_expression pop ']' / * GCC, multiple array elements */1669 | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements 1678 1670 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $3, $5); } 1679 | '.' '[' push field_list pop ']' / * CFA, tuple field selector */1671 | '.' '[' push field_list pop ']' // CFA, tuple field selector 1680 1672 { $$ = $4; } 1681 1673 ; 1682 1674 1683 / *The CFA type system is based on parametric polymorphism, the ability to declare functions with type1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 to declare requirements on type arguments of polymorphic functions. */ 1701 1702 typegen_declaration_specifier: / * CFA */1675 // The CFA type system is based on parametric polymorphism, the ability to declare functions with type 1676 // 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 used 1681 // for object and incomplete types, and "ftype" is used for function types. Type declarations with 1682 // initializers provide definitions of new types. Type declarations with storage class "extern" provide 1683 // opaque types. 1684 // 1685 // Polymorphic functions: A forall clause declares a type parameter. The corresponding argument is inferred at 1686 // 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 more 1689 // types. They serve many of the purposes of abstract classes, and specification hierarchies resemble 1690 // subclass hierarchies. Unlike classes, they can define relationships between types. Assertions declare 1691 // that a type or types provide the operations declared by a specification. Assertions are normally used 1692 // to declare requirements on type arguments of polymorphic functions. 1693 1694 typegen_declaration_specifier: // CFA 1703 1695 typegen_type_specifier 1704 1696 | declaration_qualifier_list typegen_type_specifier 1705 1697 { $$ = $2->addQualifiers( $1 ); } 1706 | typegen_declaration_specifier storage_class / * remaining OBSOLESCENT (see 2) */1698 | typegen_declaration_specifier storage_class // remaining OBSOLESCENT (see 2) 1707 1699 { $$ = $1->addQualifiers( $2 ); } 1708 1700 | typegen_declaration_specifier storage_class type_qualifier_list … … 1710 1702 ; 1711 1703 1712 typegen_type_specifier: / * CFA */1704 typegen_type_specifier: // CFA 1713 1705 TYPEGENname '(' type_name_list ')' 1714 1706 { $$ = DeclarationNode::newFromTypeGen( $1, $3 ); } … … 1719 1711 ; 1720 1712 1721 type_parameter_list: / * CFA */1713 type_parameter_list: // CFA 1722 1714 type_parameter assignment_opt 1723 1715 | type_parameter_list ',' type_parameter assignment_opt … … 1725 1717 ; 1726 1718 1727 type_parameter: / * CFA */1719 type_parameter: // CFA 1728 1720 type_class no_attr_identifier_or_typedef_name 1729 1721 { typedefTable.addToEnclosingScope(*($2), TypedefTable::TD); } … … 1733 1725 ; 1734 1726 1735 type_class: / * CFA */1727 type_class: // CFA 1736 1728 TYPE 1737 1729 { $$ = DeclarationNode::Type; } … … 1742 1734 ; 1743 1735 1744 assertion_list_opt: / * CFA */1745 / * empty */1736 assertion_list_opt: // CFA 1737 // empty 1746 1738 { $$ = 0; } 1747 1739 | assertion_list_opt assertion … … 1749 1741 ; 1750 1742 1751 assertion: / * CFA */1743 assertion: // CFA 1752 1744 '|' no_attr_identifier_or_typedef_name '(' type_name_list ')' 1753 1745 { … … 1761 1753 ; 1762 1754 1763 type_name_list: / * CFA */1755 type_name_list: // CFA 1764 1756 type_name 1765 1757 { $$ = new TypeValueNode( $1 ); } … … 1771 1763 ; 1772 1764 1773 type_declaring_list: / * CFA */1765 type_declaring_list: // CFA 1774 1766 TYPE type_declarator 1775 1767 { $$ = $2; } … … 1780 1772 ; 1781 1773 1782 type_declarator: / * CFA */1774 type_declarator: // CFA 1783 1775 type_declarator_name assertion_list_opt 1784 1776 { $$ = $1->addAssertions( $2 ); } … … 1787 1779 ; 1788 1780 1789 type_declarator_name: / * CFA */1781 type_declarator_name: // CFA 1790 1782 no_attr_identifier_or_typedef_name 1791 1783 { … … 1800 1792 ; 1801 1793 1802 context_specifier: / * CFA */1794 context_specifier: // CFA 1803 1795 CONTEXT no_attr_identifier_or_typedef_name '(' push type_parameter_list pop ')' '{' '}' 1804 1796 { 1805 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );1797 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID ); 1806 1798 $$ = DeclarationNode::newContext( $2, $5, 0 ); 1807 1799 } … … 1814 1806 { 1815 1807 typedefTable.leaveContext(); 1816 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID );1808 typedefTable.addToEnclosingScope(*($2), TypedefTable::ID ); 1817 1809 $$ = DeclarationNode::newContext( $2, $5, $10 ); 1818 1810 } 1819 1811 ; 1820 1812 1821 context_declaration_list: / * CFA */1813 context_declaration_list: // CFA 1822 1814 context_declaration 1823 1815 | context_declaration_list push context_declaration … … 1825 1817 ; 1826 1818 1827 context_declaration: / * CFA */1819 context_declaration: // CFA 1828 1820 new_context_declaring_list pop ';' 1829 1821 | context_declaring_list pop ';' 1830 1822 ; 1831 1823 1832 new_context_declaring_list: / * CFA */1824 new_context_declaring_list: // CFA 1833 1825 new_variable_specifier 1834 1826 { … … 1848 1840 ; 1849 1841 1850 context_declaring_list: / * CFA */1842 context_declaring_list: // CFA 1851 1843 type_specifier declarator 1852 1844 { 1853 typedefTable.addToEnclosingScope2( TypedefTable::ID );1845 typedefTable.addToEnclosingScope2( TypedefTable::ID ); 1854 1846 $$ = $2->addType( $1 ); 1855 1847 } 1856 1848 | context_declaring_list pop ',' push declarator 1857 1849 { 1858 typedefTable.addToEnclosingScope2( TypedefTable::ID );1850 typedefTable.addToEnclosingScope2( TypedefTable::ID ); 1859 1851 $$ = $1->appendList( $1->cloneBaseType( $5 ) ); 1860 1852 } 1861 1853 ; 1862 1854 1863 / ***************************** EXTERNAL DEFINITIONS *****************************/1855 //***************************** EXTERNAL DEFINITIONS ***************************** 1864 1856 1865 1857 translation_unit: 1866 / * empty */ /* empty input file */1867 {} 1858 // empty 1859 {} // empty input file 1868 1860 | external_definition_list 1869 1861 { … … 1880 1872 | external_definition_list push external_definition 1881 1873 { 1882 if ( $1 ) {1883 1884 } else {1885 1886 }1874 if ( $1 ) { 1875 $$ = $1->appendList( $3 ); 1876 } else { 1877 $$ = $3; 1878 } 1887 1879 } 1888 1880 ; 1889 1881 1890 1882 external_definition_list_opt: 1891 /* empty */ 1892 { 1893 $$ = 0; 1894 } 1883 // empty 1884 { $$ = 0; } 1895 1885 | external_definition_list 1896 1886 ; … … 1899 1889 declaration 1900 1890 | function_definition 1901 | asm_statement / * GCC, global assembler statement */1891 | asm_statement // GCC, global assembler statement 1902 1892 {} 1903 1893 | EXTERN STRINGliteral … … 1906 1896 linkage = LinkageSpec::fromString( *$2 ); 1907 1897 } 1908 '{' external_definition_list_opt '}' / * C++-style linkage specifier */1898 '{' external_definition_list_opt '}' // C++-style linkage specifier 1909 1899 { 1910 1900 linkage = linkageStack.top(); … … 1917 1907 1918 1908 function_definition: 1919 new_function_specifier compound_statement / * CFA */1909 new_function_specifier compound_statement // CFA 1920 1910 { 1921 1911 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 1923 1913 $$ = $1->addFunctionBody( $2 ); 1924 1914 } 1925 | declaration_qualifier_list new_function_specifier compound_statement / * CFA */1926 / *declaration_qualifier_list also includes type_qualifier_list, so a semantic check is1927 necessary to preclude them as a type_qualifier cannot appear in this context. */1915 | declaration_qualifier_list new_function_specifier compound_statement // CFA 1916 // declaration_qualifier_list also includes type_qualifier_list, so a semantic check is 1917 // necessary to preclude them as a type_qualifier cannot appear in this context. 1928 1918 { 1929 1919 typedefTable.addToEnclosingScope( TypedefTable::ID ); … … 1939 1929 } 1940 1930 1941 / *These rules are a concession to the "implicit int" type_specifier because there is a1942 1943 1944 1945 declaration must still have a type_specifier. OBSOLESCENT (see 1) */1931 // These rules are a concession to the "implicit int" type_specifier because there is a 1932 // 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 an 1934 // expression (nested functions would preclude this concession). A function prototype 1935 // declaration must still have a type_specifier. OBSOLESCENT (see 1) 1946 1936 | function_declarator compound_statement 1947 1937 { … … 1969 1959 } 1970 1960 1971 / * Old-style K&R function definition, OBSOLESCENT (see 4) */1961 // Old-style K&R function definition, OBSOLESCENT (see 4) 1972 1962 | declaration_specifier old_function_declarator push old_declaration_list_opt compound_statement 1973 1963 { … … 1989 1979 } 1990 1980 1991 / * Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4) */1981 // Old-style K&R function definition with "implicit int" type_specifier, OBSOLESCENT (see 4) 1992 1982 | declaration_qualifier_list old_function_declarator push old_declaration_list_opt compound_statement 1993 1983 { … … 2012 2002 2013 2003 subrange: 2014 constant_expression '~' constant_expression / * CFA, integer subrange */2004 constant_expression '~' constant_expression // CFA, integer subrange 2015 2005 { $$ = new CompositeExprNode(new OperatorNode(OperatorNode::Range), $1, $3); } 2016 2006 ; 2017 2007 2018 asm_name_opt: / * GCC */2019 / * empty */2008 asm_name_opt: // GCC 2009 // empty 2020 2010 | ASM '(' string_literal_list ')' attribute_list_opt 2021 2011 ; 2022 2012 2023 attribute_list_opt: / * GCC */2024 / * empty */2013 attribute_list_opt: // GCC 2014 // empty 2025 2015 | attribute_list 2026 2016 ; 2027 2017 2028 attribute_list: / * GCC */2018 attribute_list: // GCC 2029 2019 attribute 2030 2020 | attribute_list attribute 2031 2021 ; 2032 2022 2033 attribute: / * GCC */2023 attribute: // GCC 2034 2024 ATTRIBUTE '(' '(' attribute_parameter_list ')' ')' 2035 2025 ; 2036 2026 2037 attribute_parameter_list: / * GCC */2027 attribute_parameter_list: // GCC 2038 2028 attrib 2039 2029 | attribute_parameter_list ',' attrib 2040 2030 ; 2041 2031 2042 attrib: / * GCC */2043 / * empty */2032 attrib: // GCC 2033 // empty 2044 2034 | any_word 2045 2035 | any_word '(' comma_expression_opt ')' 2046 2036 ; 2047 2037 2048 any_word: / * GCC */2038 any_word: // GCC 2049 2039 identifier_or_typedef_name {} 2050 2040 | storage_class_name {} … … 2053 2043 ; 2054 2044 2055 / *============================================================================2056 2057 2058 2059 2060 int (*f())[10] { ... };2061 ... (*f())[3] += 1; // definition mimics usage2062 2063 2064 2065 2066 ============================================================================ */ 2067 2068 / *----------------------------------------------------------------------------2069 2070 2071 2072 valid declaration invalid definition2073 ----------------- ------------------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 2080 2081 ---------------------------------------------------------------------------- */ 2082 2083 / *This pattern parses a declaration of a variable that is not redefining a typedef name. The pattern2084 precludes declaring an array of functions versus a pointer to an array of functions. */ 2045 // ============================================================================ 2046 // The following sections are a series of grammar patterns used to parse declarators. Multiple patterns are 2047 // necessary because the type of an identifier in wrapped around the identifier in the same form as its usage 2048 // in an expression, as in: 2049 // 2050 // int (*f())[10] { ... }; 2051 // ... (*f())[3] += 1; // definition mimics usage 2052 // 2053 // Because these patterns are highly recursive, changes at a lower level in the recursion require copying some 2054 // or all of the pattern. Each of these patterns has some subtle variation to ensure correct syntax in a 2055 // particular context. 2056 // ============================================================================ 2057 2058 // ---------------------------------------------------------------------------- 2059 // The set of valid declarators before a compound statement for defining a function is less than the set of 2060 // declarators to define a variable or function prototype, e.g.: 2061 // 2062 // valid declaration invalid definition 2063 // ----------------- ------------------ 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 function 2070 // 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 pattern 2074 // precludes declaring an array of functions versus a pointer to an array of functions. 2085 2075 2086 2076 variable_declarator: … … 2097 2087 $$ = DeclarationNode::newName( $1 ); 2098 2088 } 2099 | '(' paren_identifier ')' / * redundant parenthesis */2089 | '(' paren_identifier ')' // redundant parenthesis 2100 2090 { $$ = $2; } 2101 2091 ; … … 2115 2105 | '(' variable_ptr ')' array_dimension 2116 2106 { $$ = $2->addArray( $4 ); } 2117 | '(' variable_array ')' multi_array_dimension / * redundant parenthesis */2107 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 2118 2108 { $$ = $2->addArray( $4 ); } 2119 | '(' variable_array ')' / * redundant parenthesis */2109 | '(' variable_array ')' // redundant parenthesis 2120 2110 { $$ = $2; } 2121 2111 ; 2122 2112 2123 2113 variable_function: 2124 '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2114 '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2125 2115 { $$ = $2->addParamList( $6 ); } 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 cannot2131 2132 2133 pattern precludes returning arrays and functions versus pointers to arrays and functions. */ 2116 | '(' variable_function ')' // redundant parenthesis 2117 { $$ = $2; } 2118 ; 2119 2120 // This pattern parses a function declarator that is not redefining a typedef name. Because functions cannot 2121 // be nested, there is no context where a function definition can redefine a typedef name. To allow nested 2122 // functions requires further separation of variable and function declarators in typedef_redeclarator. The 2123 // pattern precludes returning arrays and functions versus pointers to arrays and functions. 2134 2124 2135 2125 function_declarator: … … 2140 2130 2141 2131 function_no_ptr: 2142 paren_identifier '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2132 paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2143 2133 { $$ = $1->addParamList( $4 ); } 2144 2134 | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')' 2145 2135 { $$ = $2->addParamList( $6 ); } 2146 | '(' function_no_ptr ')' / * redundant parenthesis */2136 | '(' function_no_ptr ')' // redundant parenthesis 2147 2137 { $$ = $2; } 2148 2138 ; … … 2160 2150 '(' function_ptr ')' array_dimension 2161 2151 { $$ = $2->addArray( $4 ); } 2162 | '(' function_array ')' multi_array_dimension / * redundant parenthesis */2152 | '(' function_array ')' multi_array_dimension // redundant parenthesis 2163 2153 { $$ = $2->addArray( $4 ); } 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 a2169 2170 functions versus pointers to arrays and functions. */ 2154 | '(' function_array ')' // redundant parenthesis 2155 { $$ = $2; } 2156 ; 2157 2158 // This pattern parses an old-style K&R function declarator (OBSOLESCENT, see 4) that is not redefining a 2159 // typedef name (see function_declarator for additional comments). The pattern precludes returning arrays and 2160 // functions versus pointers to arrays and functions. 2171 2161 2172 2162 old_function_declarator: … … 2177 2167 2178 2168 old_function_no_ptr: 2179 paren_identifier '(' identifier_list ')' / * function_declarator handles empty parameter */2169 paren_identifier '(' identifier_list ')' // function_declarator handles empty parameter 2180 2170 { $$ = $1->addIdList( $3 ); } 2181 2171 | '(' old_function_ptr ')' '(' identifier_list ')' 2182 2172 { $$ = $2->addIdList( $5 ); } 2183 | '(' old_function_no_ptr ')' / * redundant parenthesis */2173 | '(' old_function_no_ptr ')' // redundant parenthesis 2184 2174 { $$ = $2; } 2185 2175 ; … … 2197 2187 '(' old_function_ptr ')' array_dimension 2198 2188 { $$ = $2->addArray( $4 ); } 2199 | '(' old_function_array ')' multi_array_dimension / * redundant parenthesis */2189 | '(' old_function_array ')' multi_array_dimension // redundant parenthesis 2200 2190 { $$ = $2->addArray( $4 ); } 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 scope2210 }2211 2212 2213 returning arrays and functions versus pointers to arrays and functions. */ 2191 | '(' old_function_array ')' // redundant parenthesis 2192 { $$ = $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 scope 2200 // } 2201 // 2202 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and 2203 // returning arrays and functions versus pointers to arrays and functions. 2214 2204 2215 2205 typedef_redeclarator: … … 2244 2234 | '(' typedef_ptr ')' array_dimension 2245 2235 { $$ = $2->addArray( $4 ); } 2246 | '(' typedef_array ')' multi_array_dimension / * redundant parenthesis */2236 | '(' typedef_array ')' multi_array_dimension // redundant parenthesis 2247 2237 { $$ = $2->addArray( $4 ); } 2248 | '(' typedef_array ')' / * redundant parenthesis */2238 | '(' typedef_array ')' // redundant parenthesis 2249 2239 { $$ = $2; } 2250 2240 ; 2251 2241 2252 2242 typedef_function: 2253 paren_typedef '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2243 paren_typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2254 2244 { $$ = $1->addParamList( $4 ); } 2255 | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2245 | '(' typedef_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2256 2246 { $$ = $2->addParamList( $6 ); } 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 a2262 2263 2264 and functions versus pointers to arrays and functions. */ 2247 | '(' typedef_function ')' // redundant parenthesis 2248 { $$ = $2; } 2249 ; 2250 2251 // This pattern parses a declaration for a parameter variable or function prototype that is not redefining a 2252 // typedef name and allows the C99 array options, which can only appear in a parameter list. The pattern 2253 // precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 2254 // and functions versus pointers to arrays and functions. 2265 2255 2266 2256 identifier_parameter_declarator: … … 2285 2275 | '(' identifier_parameter_ptr ')' array_dimension 2286 2276 { $$ = $2->addArray( $4 ); } 2287 | '(' identifier_parameter_array ')' multi_array_dimension / * redundant parenthesis */2277 | '(' identifier_parameter_array ')' multi_array_dimension // redundant parenthesis 2288 2278 { $$ = $2->addArray( $4 ); } 2289 | '(' identifier_parameter_array ')' / * redundant parenthesis */2279 | '(' identifier_parameter_array ')' // redundant parenthesis 2290 2280 { $$ = $2; } 2291 2281 ; 2292 2282 2293 2283 identifier_parameter_function: 2294 paren_identifier '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2284 paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2295 2285 { $$ = $1->addParamList( $4 ); } 2296 | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2286 | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2297 2287 { $$ = $2->addParamList( $6 ); } 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 a2303 typedef name,e.g.:2304 2305 typedef int foo;2306 int f( int foo ); // redefine typedef name in new scope2307 2308 and allows the C99 array options, which can only appear in a parameter list. In addition, the pattern 2309 handles thespecial 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 in2312 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 2316 2317 typedef float T;2318 int f( int ( T [5] ) ); // see abstract_parameter_declarator2319 int g( int ( T ( int ) ) ); // see abstract_parameter_declarator2320 int f( int f1( T a[5] ) ); // see identifier_parameter_declarator2321 int g( int g1( T g2( int p ) ) ); // see identifier_parameter_declarator2322 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 returningarrays and2326 functions versus pointers to arrays and functions. */ 2288 | '(' identifier_parameter_function ')' // redundant parenthesis 2289 { $$ = $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 scope 2297 // 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 in 2302 // 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_declarator 2309 // int g( int ( T ( int ) ) ); // see abstract_parameter_declarator 2310 // int f( int f1( T a[5] ) ); // see identifier_parameter_declarator 2311 // int g( int g1( T g2( int p ) ) ); // see identifier_parameter_declarator 2312 // 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 to arrays and 2316 // functions. 2327 2317 2328 2318 typedef_parameter_redeclarator: … … 2358 2348 2359 2349 typedef_parameter_function: 2360 typedef '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2350 typedef '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2361 2351 { $$ = $1->addParamList( $4 ); } 2362 | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2352 | '(' typedef_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2363 2353 { $$ = $2->addParamList( $6 ); } 2364 2354 ; 2365 2355 2366 / * This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no2367 identifier towhich 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. */ 2356 // This pattern parses a declaration of an abstract variable or function prototype, i.e., there is no identifier to 2357 // 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. 2374 2364 2375 2365 abstract_declarator: … … 2396 2386 | '(' abstract_ptr ')' array_dimension 2397 2387 { $$ = $2->addArray( $4 ); } 2398 | '(' abstract_array ')' multi_array_dimension / * redundant parenthesis */2388 | '(' abstract_array ')' multi_array_dimension // redundant parenthesis 2399 2389 { $$ = $2->addArray( $4 ); } 2400 | '(' abstract_array ')' / * redundant parenthesis */2390 | '(' abstract_array ')' // redundant parenthesis 2401 2391 { $$ = $2; } 2402 2392 ; 2403 2393 2404 2394 abstract_function: 2405 '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2395 '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2406 2396 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); } 2407 | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2397 | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2408 2398 { $$ = $2->addParamList( $6 ); } 2409 | '(' abstract_function ')' / * redundant parenthesis */2399 | '(' abstract_function ')' // redundant parenthesis 2410 2400 { $$ = $2; } 2411 2401 ; 2412 2402 2413 2403 array_dimension: 2414 / * Only the first dimension can be empty. */2404 // Only the first dimension can be empty. 2415 2405 '[' push pop ']' 2416 2406 { $$ = DeclarationNode::newArray( 0, 0, false ); } … … 2423 2413 '[' push assignment_expression pop ']' 2424 2414 { $$ = DeclarationNode::newArray( $3, 0, false ); } 2425 | '[' push '*' pop ']' / * C99 */2415 | '[' push '*' pop ']' // C99 2426 2416 { $$ = DeclarationNode::newVarArray( 0 ); } 2427 2417 | multi_array_dimension '[' push assignment_expression pop ']' 2428 2418 { $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); } 2429 | multi_array_dimension '[' push '*' pop ']' / * C99 */2419 | multi_array_dimension '[' push '*' pop ']' // C99 2430 2420 { $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); } 2431 2421 ; 2432 2422 2433 / *This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no2434 2435 2436 int f( int ); // abstract variable parameter; no parameter name specified2437 int f( int (int) ); // abstract function-prototype parameter; no parameter name specified2438 2439 The pattern precludes declaring an array of functions versus a pointer to an array of functions, and 2440 returning arraysand functions versus pointers to arrays and functions. */2423 // This pattern parses a declaration of a parameter abstract variable or function prototype, i.e., there is no 2424 // identifier to which the type applies, e.g.: 2425 // 2426 // int f( int ); // abstract variable parameter; no parameter name specified 2427 // int f( int (int) ); // abstract function-prototype parameter; no parameter name specified 2428 // 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. */ 2441 2431 2442 2432 abstract_parameter_declarator: … … 2463 2453 | '(' abstract_parameter_ptr ')' array_parameter_dimension 2464 2454 { $$ = $2->addArray( $4 ); } 2465 | '(' abstract_parameter_array ')' multi_array_dimension / * redundant parenthesis */2455 | '(' abstract_parameter_array ')' multi_array_dimension // redundant parenthesis 2466 2456 { $$ = $2->addArray( $4 ); } 2467 | '(' abstract_parameter_array ')' / * redundant parenthesis */2457 | '(' abstract_parameter_array ')' // redundant parenthesis 2468 2458 { $$ = $2; } 2469 2459 ; 2470 2460 2471 2461 abstract_parameter_function: 2472 '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2462 '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2473 2463 { $$ = DeclarationNode::newFunction( 0, 0, $3, 0 ); } 2474 | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2464 | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2475 2465 { $$ = $2->addParamList( $6 ); } 2476 | '(' abstract_parameter_function ')' / * redundant parenthesis */2466 | '(' abstract_parameter_function ')' // redundant parenthesis 2477 2467 { $$ = $2; } 2478 2468 ; 2479 2469 2480 2470 array_parameter_dimension: 2481 / * Only the first dimension can be empty or have qualifiers. */2471 // Only the first dimension can be empty or have qualifiers. 2482 2472 array_parameter_1st_dimension 2483 2473 | array_parameter_1st_dimension multi_array_dimension … … 2486 2476 ; 2487 2477 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." */ 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." 2493 2482 2494 2483 array_parameter_1st_dimension: … … 2496 2485 { $$ = DeclarationNode::newArray( 0, 0, false ); } 2497 2486 // multi_array_dimension handles the '[' '*' ']' case 2498 | '[' push type_qualifier_list '*' pop ']' / * remaining C99 */2487 | '[' push type_qualifier_list '*' pop ']' // remaining C99 2499 2488 { $$ = DeclarationNode::newVarArray( $3 ); } 2500 2489 | '[' push type_qualifier_list pop ']' … … 2509 2498 ; 2510 2499 2511 / * This pattern parses a declaration of an abstract variable, i.e., there is no identifier to which the type2512 applies,e.g.:2513 2514 sizeof( int ); // abstract variable; no identifier name specified2515 2516 The pattern precludes declaring an array of functions versus a pointer to an array of functions, and 2517 returning arraysand functions versus pointers to arrays and functions. */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 specified 2504 // 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. */ 2518 2507 2519 2508 variable_abstract_declarator: … … 2540 2529 | '(' variable_abstract_ptr ')' array_dimension 2541 2530 { $$ = $2->addArray( $4 ); } 2542 | '(' variable_abstract_array ')' multi_array_dimension / * redundant parenthesis */2531 | '(' variable_abstract_array ')' multi_array_dimension // redundant parenthesis 2543 2532 { $$ = $2->addArray( $4 ); } 2544 | '(' variable_abstract_array ')' / * redundant parenthesis */2533 | '(' variable_abstract_array ')' // redundant parenthesis 2545 2534 { $$ = $2; } 2546 2535 ; 2547 2536 2548 2537 variable_abstract_function: 2549 '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' / * empty parameter list OBSOLESCENT (see 3) */2538 '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2550 2539 { $$ = $2->addParamList( $6 ); } 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 */ 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 2560 2548 new_identifier_parameter_declarator_no_tuple 2561 2549 | new_abstract_tuple … … 2564 2552 ; 2565 2553 2566 new_identifier_parameter_declarator_no_tuple: / * CFA */2554 new_identifier_parameter_declarator_no_tuple: // CFA 2567 2555 new_identifier_parameter_ptr 2568 2556 | new_identifier_parameter_array 2569 2557 ; 2570 2558 2571 new_identifier_parameter_ptr: / * CFA */2559 new_identifier_parameter_ptr: // CFA 2572 2560 '*' type_specifier 2573 2561 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } … … 2584 2572 ; 2585 2573 2586 new_identifier_parameter_array: / * CFA */2587 / * Only the first dimension can be empty or have qualifiers. Empty dimension must be factored2588 out due toshift/reduce conflict with new-style empty (void) function return type. */2574 new_identifier_parameter_array: // CFA 2575 // Only the first dimension can be empty or have qualifiers. Empty dimension must be factored out due to 2576 // shift/reduce conflict with new-style empty (void) function return type. */ 2589 2577 '[' push pop ']' type_specifier 2590 2578 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } … … 2610 2598 2611 2599 new_array_parameter_1st_dimension: 2612 '[' push type_qualifier_list '*' pop ']' / * remaining C99 */2600 '[' push type_qualifier_list '*' pop ']' // remaining C99 2613 2601 { $$ = DeclarationNode::newVarArray( $3 ); } 2614 2602 | '[' push type_qualifier_list assignment_expression pop ']' 2615 2603 { $$ = DeclarationNode::newArray( $4, $3, false ); } 2616 2604 | '[' push declaration_qualifier_list assignment_expression pop ']' 2617 / * declaration_qualifier_list must be used because of shift/reduce conflict with2618 assignment_expression, so a semantic check is necessary to preclude them as a2619 type_qualifier cannot appear in this context. */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 this 2607 // context. 2620 2608 { $$ = DeclarationNode::newArray( $4, $3, true ); } 2621 2609 | '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']' … … 2623 2611 ; 2624 2612 2625 / * This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is2626 noidentifier to which the type applies, e.g.:2627 2628 [int] f( int ); // abstract variable parameter; no parameter name specified2629 [int] f( [int] (int) ); // abstract function-prototype parameter; no parameter name specified2630 2631 2632 2633 new_abstract_tuple identifier_or_typedef_name2634 '[' new_parameter_list ']' identifier_or_typedef_name '(' new_parameter_type_list_opt ')'2635 2636 2637 2638 [int, int] t;2639 [int, int] f( int );2640 2641 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 */2613 // This pattern parses a new-style declaration of an abstract variable or function prototype, i.e., there is no 2614 // identifier to which the type applies, e.g.: 2615 // 2616 // [int] f( int ); // abstract variable parameter; no parameter name specified 2617 // [int] f( [int] (int) ); // abstract function-prototype parameter; no parameter name specified 2618 // 2619 // These rules need LR(3): 2620 // 2621 // new_abstract_tuple identifier_or_typedef_name 2622 // '[' 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 reduce 2630 // 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: // CFA 2647 2635 new_abstract_tuple 2648 2636 | type_qualifier_list new_abstract_tuple … … 2651 2639 ; 2652 2640 2653 new_abstract_declarator_no_tuple: / * CFA */2641 new_abstract_declarator_no_tuple: // CFA 2654 2642 new_abstract_ptr 2655 2643 | new_abstract_array 2656 2644 ; 2657 2645 2658 new_abstract_ptr: / * CFA */2646 new_abstract_ptr: // CFA 2659 2647 '*' type_specifier 2660 2648 { $$ = $2->addNewPointer( DeclarationNode::newPointer( 0 ) ); } … … 2671 2659 ; 2672 2660 2673 new_abstract_array: / * CFA */2674 / * Only the first dimension can be empty. Empty dimension must be factored out due to2675 shift/reduce conflict with empty (void) function return type. */2661 new_abstract_array: // CFA 2662 // Only the first dimension can be empty. Empty dimension must be factored out due to shift/reduce 2663 // conflict with empty (void) function return type. 2676 2664 '[' push pop ']' type_specifier 2677 2665 { $$ = $5->addNewArray( DeclarationNode::newArray( 0, 0, false ) ); } … … 2688 2676 ; 2689 2677 2690 new_abstract_tuple: / * CFA */2678 new_abstract_tuple: // CFA 2691 2679 '[' push new_abstract_parameter_list pop ']' 2692 2680 { $$ = DeclarationNode::newTuple( $3 ); } 2693 2681 ; 2694 2682 2695 new_abstract_function: / * CFA */2683 new_abstract_function: // CFA 2696 2684 '[' push pop ']' '(' new_parameter_type_list_opt ')' 2697 2685 { $$ = DeclarationNode::newFunction( 0, DeclarationNode::newTuple( 0 ), $6, 0 ); } … … 2702 2690 ; 2703 2691 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 */ 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 2722 2708 | ',' 2723 2709 ; 2724 2710 2725 2711 assignment_opt: 2726 / * empty */2712 // empty 2727 2713 { $$ = 0; } 2728 2714 | '=' assignment_expression … … 2731 2717 2732 2718 %% 2733 / * ----end of grammar----*/2719 // ----end of grammar---- 2734 2720 2735 2721 void yyerror( char *string ) { … … 2743 2729 } 2744 2730 2745 / * Local Variables: */2746 / * fill-column: 110 */2747 / * compile-command: "make install" */2748 / * End: */2731 // Local Variables: // 2732 // fill-column: 110 // 2733 // compile-command: "make install" // 2734 // End: // -
translator/ResolvExpr/CastCost.cc
rd4778a6 rc11e31c 1 /*2 * This file is part of the Cforall project3 *4 * $Id: CastCost.cc,v 1.11 2005/08/29 20:14:15 rcbilson Exp $5 *6 */7 8 1 #include "typeops.h" 9 2 #include "Cost.h" … … 15 8 16 9 namespace ResolvExpr { 10 class CastCost : public ConversionCost { 11 public: 12 CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 13 14 virtual void visit( BasicType *basicType ); 15 virtual void visit( PointerType *pointerType ); 16 }; 17 17 18 class CastCost : public ConversionCost 19 { 20 public: 21 CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 22 23 virtual void visit(BasicType *basicType); 24 virtual void visit(PointerType *pointerType); 25 }; 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 46 } 26 47 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 } 48 CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) 49 : ConversionCost( dest, indexer, env ) { 46 50 } 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 ); 51 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 } // if 62 58 } 63 }64 }65 59 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 } 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 } // if 78 } // if 79 } // if 101 80 } 102 }103 }104 105 81 } // namespace ResolvExpr -
translator/ResolvExpr/PtrsAssignable.cc
rd4778a6 rc11e31c 1 /*2 * This file is part of the Cforall project3 *4 * $Id: PtrsAssignable.cc,v 1.3 2005/08/29 20:14:16 rcbilson Exp $5 *6 */7 8 1 #include "typeops.h" 9 2 #include "SynTree/Type.h" … … 13 6 14 7 namespace ResolvExpr { 8 class PtrsAssignable : public Visitor { 9 public: 10 PtrsAssignable( Type *dest, const TypeEnvironment &env ); 11 12 int get_result() const { return result; } 15 13 16 class PtrsAssignable : public Visitor 17 { 18 public: 19 PtrsAssignable( Type *dest, const TypeEnvironment &env ); 20 21 int get_result() const { return result; } 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 }; 22 30 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); 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 } 45 } 34 46 35 private: 36 Type *dest; 37 int result; 38 const TypeEnvironment &env; 39 }; 47 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) { 48 } 40 49 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 ); 50 void PtrsAssignable::visit(VoidType *voidType) { 51 if ( dynamic_cast< FunctionType* >( dest ) ) { 52 result = 0; 53 } else { 54 result = -1; 55 } 48 56 } 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 }58 57 59 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) 60 : dest( dest ), result( 0 ), env( env ) 61 { 62 } 58 void PtrsAssignable::visit( BasicType *basicType ) { 59 } 63 60 64 void 65 PtrsAssignable::visit(VoidType *voidType) 66 { 67 if( dynamic_cast< FunctionType* >( dest ) ) { 68 result = 0; 69 } else { 70 result = -1; 71 } 72 } 61 void PtrsAssignable::visit( PointerType *pointerType ) { 62 } 73 63 74 void 75 PtrsAssignable::visit(BasicType *basicType) 76 { 77 } 64 void PtrsAssignable::visit( ArrayType *arrayType ) { 65 } 78 66 79 void 80 PtrsAssignable::visit(PointerType *pointerType) 81 { 82 } 67 void PtrsAssignable::visit( FunctionType *functionType ) { 68 result = -1; 69 } 83 70 84 void 85 PtrsAssignable::visit(ArrayType *arrayType) 86 { 87 } 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 } 88 74 89 void 90 PtrsAssignable::visit(FunctionType *functionType) 91 { 92 result = -1; 93 } 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 } 94 78 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 } 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 } 100 86 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 } 87 void PtrsAssignable::visit( ContextInstType *inst ) { 88 // I definitely don't think we should be doing anything here 89 } 106 90 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 } 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 } 116 99 117 void 118 PtrsAssignable::visit(ContextInstType *inst) 119 { 120 // I definitely don't think we should be doing anything here 121 } 122 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 } 133 134 void 135 PtrsAssignable::visit(TupleType *tupleType) 136 { 100 void PtrsAssignable::visit( TupleType *tupleType ) { 137 101 /// // This code doesn't belong here, but it might be useful somewhere else 138 /// if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) {102 /// if ( TupleType *destAsTuple = dynamic_cast< TupleType* >( dest ) ) { 139 103 /// int ret = 0; 140 104 /// std::list< Type* >::const_iterator srcIt = tupleType->get_types().begin(); … … 142 106 /// while( srcIt != tupleType->get_types().end() && destIt != destAsTuple->get_types().end() ) { 143 107 /// int assignResult = ptrsAssignable( *srcIt++, *destIt++ ); 144 /// if ( assignResult == 0 ) {108 /// if ( assignResult == 0 ) { 145 109 /// result = assignResult; 146 110 /// return; … … 151 115 /// } 152 116 /// } 153 /// if ( srcIt == tupleType->get_types().end() && destIt == destAsTuple->get_types().end() ) {117 /// if ( srcIt == tupleType->get_types().end() && destIt == destAsTuple->get_types().end() ) { 154 118 /// result = ret; 155 119 /// } else { … … 157 121 /// } 158 122 /// } 159 } 160 123 } 161 124 } // namespace ResolvExpr -
translator/ResolvExpr/Resolver.cc
rd4778a6 rc11e31c 98 98 return bt->isInteger(); 99 99 } else { 100 return true;100 return false; 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 switchcontrol expression", untyped );123 throw SemanticError( "Too many interpretations for case control expression", untyped ); 124 124 } else { 125 125 newExpr = i->expr->clone(); … … 128 128 } // if 129 129 } // for 130 if ( ! newExpr ) {131 throw SemanticError( " Too many interpretations for switchcontrol expression", untyped );130 if ( ! newExpr ) { 131 throw SemanticError( "No interpretations for case control expression", untyped ); 132 132 } // if 133 133 finishExpr( newExpr, *newEnv ); -
translator/SymTab/Validate.cc
rd4778a6 rc11e31c 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 ), enumDecl->get_name() ) );280 obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) ); 281 281 } // for 282 282 Parent::visit( enumDecl ); -
translator/SynTree/CompoundStmt.cc
rd4778a6 rc11e31c 11 11 #include <functional> 12 12 13 using std::string; 14 using std::endl; 13 15 14 16 CompoundStmt::CompoundStmt( std::list<Label> labels ) … … 31 33 CompoundStmt::print( std::ostream &os, int indent ) 32 34 { 33 printAll( kids, os, indent ); 35 os << "\r" << string(indent, ' ') << "CompoundStmt Statement" << endl ; 36 printAll( kids, os, indent + 4 ); 34 37 } 35 38 -
translator/SynTree/Declaration.h
rd4778a6 rc11e31c 12 12 enum StorageClass { 13 13 NoStorageClass, 14 Extern, 15 Static, 14 16 Auto, 15 Static,16 Extern,17 17 Register, 18 Fortran 18 Inline, 19 Fortran, 19 20 }; 20 21 … … 108 109 CompoundStmt *get_statements() const { return statements; } 109 110 void set_statements( CompoundStmt *newValue ) { statements = newValue; } 110 bool get_isInline() const { return isInline; }111 void set_isInline( bool newValue ) { isInline = newValue; }111 // bool get_isInline() const { return isInline; } 112 // void set_isInline( bool newValue ) { isInline = newValue; } 112 113 std::list< std::string >& get_oldIdents() { return oldIdents; } 113 114 std::list< Declaration* >& get_oldDecls() { return oldDecls; } -
translator/SynTree/FunctionDecl.cc
rd4778a6 rc11e31c 1 /*2 * This file is part of the Cforall project3 *4 * $Id: FunctionDecl.cc,v 1.15 2005/08/29 20:59:25 rcbilson Exp $5 *6 */7 8 1 #include <cassert> 9 2 … … 14 7 15 8 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" ) { 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" ) { 22 13 set_linkage( LinkageSpec::C ); 23 14 } … … 25 16 26 17 FunctionDecl::FunctionDecl( const FunctionDecl &other ) 27 : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), 28 isInline( other.isInline ) 29 { 18 : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), isInline( other.isInline ) { 30 19 } 31 20 32 FunctionDecl::~FunctionDecl() 33 { 21 FunctionDecl::~FunctionDecl() { 34 22 delete type; 35 23 delete statements; 36 24 } 37 25 38 Type* 39 FunctionDecl::get_type() const 40 { 26 Type * FunctionDecl::get_type() const { 41 27 return type; 42 28 } 43 29 44 void 45 FunctionDecl::set_type(Type *t) 46 { 30 void FunctionDecl::set_type( Type *t ) { 47 31 type = dynamic_cast< FunctionType* >( t ); 48 32 assert( type ); 49 33 } 50 34 51 void 52 FunctionDecl::print( std::ostream &os, int indent ) const 53 { 35 void FunctionDecl::print( std::ostream &os, int indent ) const { 54 36 using std::endl; 55 37 using std::string; 56 38 57 if ( get_name() != "" ) {39 if ( get_name() != "" ) { 58 40 os << get_name() << ": a "; 59 41 } 60 if ( get_linkage() != LinkageSpec::Cforall ) {42 if ( get_linkage() != LinkageSpec::Cforall ) { 61 43 os << LinkageSpec::toString( get_linkage() ) << " "; 62 44 } 63 if ( isInline ) {45 if ( isInline ) { 64 46 os << "inline "; 65 47 } 66 if ( get_storageClass() != NoStorageClass ) {48 if ( get_storageClass() != NoStorageClass ) { 67 49 os << storageClassName[ get_storageClass() ] << ' '; 68 50 } 69 if ( get_type() ) {51 if ( get_type() ) { 70 52 get_type()->print( os, indent ); 71 53 } else { 72 54 os << "untyped entity "; 73 55 } 74 if ( !oldIdents.empty() ) {56 if ( ! oldIdents.empty() ) { 75 57 os << string( indent+2, ' ' ) << "with parameter names" << endl; 76 58 for( std::list< std::string >::const_iterator i = oldIdents.begin(); i != oldIdents.end(); ++i ) { … … 78 60 } 79 61 } 80 if ( !oldDecls.empty() ) {62 if ( ! oldDecls.empty() ) { 81 63 os << string( indent+2, ' ' ) << "with parameter declarations" << endl; 82 64 printAll( oldDecls, os, indent+4 ); 83 65 } 84 if ( statements ) {66 if ( statements ) { 85 67 os << string( indent+2, ' ' ) << "with body " << endl; 86 68 statements->print( os, indent+4 ); … … 88 70 } 89 71 90 void 91 FunctionDecl::printShort( std::ostream &os, int indent ) const 92 { 72 void FunctionDecl::printShort( std::ostream &os, int indent ) const { 93 73 using std::endl; 94 74 using std::string; 95 75 96 if ( get_name() != "" ) {76 if ( get_name() != "" ) { 97 77 os << get_name() << ": a "; 98 78 } 99 if ( isInline ) {79 if ( isInline ) { 100 80 os << "inline "; 101 81 } 102 if ( get_storageClass() != NoStorageClass ) {82 if ( get_storageClass() != NoStorageClass ) { 103 83 os << storageClassName[ get_storageClass() ] << ' '; 104 84 } 105 if ( get_type() ) {85 if ( get_type() ) { 106 86 get_type()->print( os, indent ); 107 87 } else { … … 109 89 } 110 90 } 111 -
translator/SynTree/Statement.cc
rd4778a6 rc11e31c 14 14 15 15 16 // *** Statement17 16 Statement::Statement(std::list<Label> _labels): 18 17 labels(_labels) {} … … 22 21 Statement::~Statement() {} 23 22 24 //*** ExprStmt25 23 ExprStmt::ExprStmt( std::list<Label> _labels, Expression *_expr ): 26 24 Statement(_labels), expr(_expr) {} … … 33 31 } 34 32 35 //*** BranchStmt36 33 const char *BranchStmt::brType[] = { "Goto", "Break", "Continue" }; 37 34 … … 57 54 } 58 55 59 //*** ReturnStmt60 56 ReturnStmt::ReturnStmt( std::list<Label> labels, Expression *_expr, bool throwP ) : 61 57 Statement( labels ), expr( _expr ), isThrow( throwP ) {} … … 72 68 73 69 74 // *** IfStmt75 70 IfStmt::IfStmt( std::list<Label> _labels, Expression *_condition, Statement *_thenPart, Statement *_elsePart ): 76 71 Statement(_labels), condition(_condition), thenPart(_thenPart), elsePart(_elsePart) {} … … 91 86 } 92 87 93 // *** SwitchStmt94 88 SwitchStmt::SwitchStmt(std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_branches): 95 89 Statement(_labels), condition(_condition), branches(_branches) … … 116 110 } 117 111 118 // *** CaseStmt119 112 CaseStmt::CaseStmt( std::list<Label> _labels, Expression *_condition, 120 113 std::list<Statement *> &_statements, bool deflt ) … … 147 140 } 148 141 149 //*** ChooseStmt150 142 //ChooseStmt::ChooseStmt( std::list<Label> labels, Expression *condition, Statement *body ) {} 151 143 ChooseStmt::ChooseStmt(std::list<Label> _labels, Expression * _condition, std::list<Statement *> &_branches): … … 172 164 } 173 165 174 //*** FallthruStmt175 166 void FallthruStmt::print(std::ostream &os, int indent) { 176 167 os << "\r" << string(indent, ' ') << "Fall-through statement" << endl; 177 168 } 178 169 179 //*** WhileStmt180 170 WhileStmt::WhileStmt( std::list<Label> labels, Expression *condition_, 181 171 Statement *body_, bool isDoWhile_ ): … … 196 186 } 197 187 198 //*** ForStmt199 188 ForStmt::ForStmt( std::list<Label> labels, Statement *initialization_, 200 189 Expression *condition_, Expression *increment_, Statement *body_ ): … … 233 222 } 234 223 235 //*** TryStmt236 224 TryStmt::TryStmt( std::list<Label> labels, CompoundStmt *tryBlock, std::list<Statement *> &_handlers, FinallyStmt *_finallyBlock ) : 237 225 Statement( labels ), block( tryBlock ), handlers( _handlers ), finallyBlock( _finallyBlock ) … … 266 254 } 267 255 268 //*** CatchStmt269 256 CatchStmt::CatchStmt( std::list<Label> labels, Declaration *_decl, Statement *_body, bool isCatchRest ) : 270 257 Statement( labels ), decl ( _decl ), body( _body ), catchRest ( isCatchRest ) … … 290 277 291 278 292 //*** FinallyStmt293 279 FinallyStmt::FinallyStmt( std::list<Label> labels, CompoundStmt *_block ) : 294 280 Statement( labels ), block( _block ) … … 307 293 } 308 294 309 //*** NullStmt310 295 NullStmt::NullStmt( std::list<Label> labels ) : CompoundStmt( labels ) {} 311 296 NullStmt::NullStmt() : CompoundStmt( std::list<Label>() ) {} -
translator/SynTree/Statement.h
rd4778a6 rc11e31c 1 /*2 * This file is part of the Cforall project3 *4 * $Id: Statement.h,v 1.18 2005/08/29 20:59:26 rcbilson Exp $5 *6 */7 8 1 #ifndef STATEMENT_H 9 2 #define STATEMENT_H -
translator/SynTree/Type.h
rd4778a6 rc11e31c 10 10 public: 11 11 struct Qualifiers { 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) {}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 ) {} 14 14 15 15 Qualifiers &operator+=( const Qualifiers &other ); … … 28 28 bool isLvalue; 29 29 bool isAtomic; 30 bool isAttribute; 30 31 }; 31 32 … … 40 41 bool get_isLvalue() { return tq.isLvalue; } 41 42 bool get_isAtomic() { return tq.isAtomic; } 43 bool get_isAttribute() { return tq.isAttribute; } 42 44 void set_isConst( bool newValue ) { tq.isConst = newValue; } 43 45 void set_iisVolatile( bool newValue ) { tq.isVolatile = newValue; } … … 45 47 void set_isLvalue( bool newValue ) { tq.isLvalue = newValue; } 46 48 void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; } 49 void set_isAttribute( bool newValue ) { tq.isAttribute = newValue; } 47 50 std::list<TypeDecl*>& get_forall() { return forall; } 48 51 -
translator/examples/identity.c
rd4778a6 rc11e31c 9 9 ofstream *sout = ofstream_stdout(); 10 10 char c = 'a'; 11 c = identity( c ); 11 12 sout << c << ' ' << identity( c ) << '\n'; 12 13 int i = 5; 14 i = identity( i ); 13 15 sout << i << ' ' << identity( i ) << '\n'; 14 16 double d = 3.2; 17 d = identity( d ); 15 18 sout << d << ' ' << identity( d ) << '\n'; 16 19 } -
translator/examples/min.c
rd4778a6 rc11e31c 1 1 extern "C" { 2 2 int printf( const char *, ... ); 3 //#include <stdio.h> 3 4 } 4 5 … … 10 11 int main() { 11 12 char c; 12 c = min( 'z', 'a' );13 printf( "minimum %d\n", c );13 // c = min( 'z', 'a' ); 14 // printf( "minimum %d\n", c ); 14 15 int i; 15 16 i = min( 4, 3 ); -
translator/examples/s.c
rd4778a6 rc11e31c 1 int ?!=?( int, int ); 2 int 0; 1 //int ?!=?( int, int ); 3 2 4 void f() 5 { 3 void f() { 4 // int a; 5 // a ? 4 : 5; 6 1 ? 4 : 5; 6 7 0 ? 4 : 5; 7 8 } -
translator/examples/square.c
rd4778a6 rc11e31c 1 // './cfa square.c'2 3 1 extern "C" { 4 2 #include <stdio.h> -
translator/examples/swap.c
rd4778a6 rc11e31c 5 5 forall( type T ) 6 6 void swap( T *left, T *right ) { 7 T temp; 8 temp = *left; 7 T temp = *left; 9 8 *left = *right; 10 9 *right = temp;
Note: See TracChangeset
for help on using the changeset viewer.