1 /*----------------------------------------------------------------------- 2 3 SDCC.y - parser definition file for sdcc : 4 Written By : Sandeep Dutta . sandeep.dutta@usa.net (1997) 5 6 This program is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by the 8 Free Software Foundation; either version 2, or (at your option) any 9 later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 20 In other words, you are welcome to use, share and improve this program. 21 You are forbidden to forbid anyone else to use, share and improve 22 what you give them. Help stamp out software-hoarding! 23 -------------------------------------------------------------------------*/ 24 %{ 25 #include <stdio.h> 26 #include <stdarg.h> 27 #include <string.h> 28 #include "SDCCglobl.h" 29 #include "SDCCsymt.h" 30 #include "SDCChasht.h" 31 #include "SDCCval.h" 32 #include "SDCCmem.h" 33 #include "SDCCast.h" 34 #include "port.h" 35 #include "newalloc.h" 36 #include "SDCCerr.h" 37 #include "SDCCutil.h" 38 #include "SDCCbtree.h" 39 #include "SDCCopt.h" 40 41 extern int yyerror (char *); 42 extern FILE *yyin; 43 long NestLevel = 0; /* current NestLevel */ 44 int stackPtr = 1; /* stack pointer */ 45 int xstackPtr = 0; /* xstack pointer */ 46 int reentrant = 0; 47 int blockNo = 0; /* sequential block number */ 48 int currBlockno=0; 49 int inCriticalFunction = 0; 50 int inCriticalBlock = 0; 51 int seqPointNo= 1; /* sequence point number */ 52 int ignoreTypedefType=0; 53 extern int yylex(); 54 int yyparse(void); 55 extern int noLineno; 56 char lbuff[1024]; /* local buffer */ 57 char function_name[256] = {0}; 58 59 /* break & continue stacks */ 60 STACK_DCL(continueStack ,symbol *,MAX_NEST_LEVEL) 61 STACK_DCL(breakStack ,symbol *,MAX_NEST_LEVEL) 62 STACK_DCL(forStack ,symbol *,MAX_NEST_LEVEL) 63 STACK_DCL(swStk ,ast *,MAX_NEST_LEVEL) 64 STACK_DCL(blockNum,int,MAX_NEST_LEVEL*3) 65 66 value *cenum = NULL; /* current enumeration type chain*/ 67 bool uselessDecl = TRUE; 68 69 #define YYDEBUG 1 70 71 %} 72 %expect 11 73 74 %union { 75 symbol *sym; /* symbol table pointer */ 76 structdef *sdef; /* structure definition */ 77 char yychar[SDCC_NAME_MAX+1]; 78 sym_link *lnk; /* declarator or specifier */ 79 int yyint; /* integer value returned */ 80 value *val; /* for integer constant */ 81 initList *ilist; /* initial list */ 82 designation*dsgn; /* designator */ 83 const char *yystr; /* pointer to dynamicaly allocated string */ 84 ast *asts; /* expression tree */ 85 } 86 87 %token <yychar> IDENTIFIER TYPE_NAME ADDRSPACE_NAME 88 %token <val> CONSTANT 89 %token SIZEOF ALIGNOF TYPEOF OFFSETOF 90 %token PTR_OP INC_OP DEC_OP LEFT_OP RIGHT_OP LE_OP GE_OP EQ_OP NE_OP 91 %token AND_OP OR_OP 92 %token ATTRIBCOLON 93 %token <yyint> MUL_ASSIGN DIV_ASSIGN MOD_ASSIGN ADD_ASSIGN 94 %token <yyint> SUB_ASSIGN LEFT_ASSIGN RIGHT_ASSIGN AND_ASSIGN 95 %token <yyint> XOR_ASSIGN OR_ASSIGN 96 %token TYPEDEF EXTERN STATIC AUTO REGISTER CODE EEPROM INTERRUPT SFR SFR16 SFR32 ADDRESSMOD STATIC_ASSERT 97 %token AT SBIT REENTRANT USING XDATA DATA IDATA PDATA VAR_ARGS CRITICAL 98 %token NONBANKED BANKED SHADOWREGS SD_WPARAM 99 %token SD_BOOL SD_CHAR SD_SHORT SD_INT SD_LONG SIGNED UNSIGNED SD_FLOAT DOUBLE FIXED16X16 SD_CONST VOLATILE SD_VOID BIT 100 %token STRUCT UNION ENUM RANGE SD_FAR 101 %token CASE DEFAULT IF ELSE SWITCH WHILE DO FOR GOTO CONTINUE BREAK RETURN 102 %token NAKED JAVANATIVE OVERLAY TRAP 103 %token <yystr> STRING_LITERAL INLINEASM 104 %token IFX ADDRESS_OF GET_VALUE_AT_ADDRESS SET_VALUE_AT_ADDRESS SPIL UNSPIL GETHBIT GETABIT GETBYTE GETWORD 105 %token BITWISEAND UNARYMINUS IPUSH IPOP PCALL ENDFUNCTION JUMPTABLE 106 %token RRC RLC 107 %token CAST CALL PARAM NULLOP BLOCK LABEL RECEIVE SEND ARRAYINIT 108 %token DUMMY_READ_VOLATILE ENDCRITICAL SWAP INLINE NORETURN RESTRICT SMALLC PRESERVES_REGS Z88DK_FASTCALL Z88DK_CALLEE ALIGNAS Z88DK_SHORTCALL Z88DK_PARAMS_OFFSET 109 %token GENERIC GENERIC_ASSOC_LIST GENERIC_ASSOCIATION 110 %token ASM 111 112 %type <yyint> Interrupt_storage 113 %type <sym> identifier declarator declarator2 direct_declarator array_declarator enumerator_list enumerator 114 %type <sym> member_declarator function_declarator 115 %type <sym> member_declarator_list member_declaration member_declaration_list 116 %type <sym> declaration init_declarator_list init_declarator 117 %type <sym> declaration_list identifier_list 118 %type <sym> declaration_after_statement 119 %type <sym> declarator2_function_attributes while do for critical 120 %type <sym> addressmod 121 %type <lnk> pointer type_specifier_list type_specifier_list_ type_specifier type_qualifier_list type_qualifier type_name 122 %type <lnk> storage_class_specifier struct_or_union_specifier function_specifier alignment_specifier 123 %type <lnk> declaration_specifiers declaration_specifiers_ sfr_reg_bit sfr_attributes 124 %type <lnk> function_attribute function_attributes enum_specifier 125 %type <lnk> abstract_declarator direct_abstract_declarator array_abstract_declarator function_abstract_declarator 126 %type <lnk> unqualified_pointer 127 %type <val> parameter_type_list parameter_list parameter_declaration opt_assign_expr 128 %type <sdef> stag opt_stag 129 %type <asts> primary_expr 130 %type <asts> postfix_expr unary_expr offsetof_member_designator cast_expr multiplicative_expr 131 %type <asts> additive_expr shift_expr relational_expr equality_expr 132 %type <asts> and_expr exclusive_or_expr inclusive_or_expr logical_or_expr 133 %type <asts> logical_and_expr conditional_expr assignment_expr constant_expr 134 %type <asts> expr argument_expr_list function_definition expr_opt 135 %type <asts> statement_list statement labeled_statement compound_statement 136 %type <asts> expression_statement selection_statement iteration_statement 137 %type <asts> jump_statement function_body else_statement string_literal_val 138 %type <asts> critical_statement asm_statement label 139 %type <asts> generic_selection generic_assoc_list generic_association 140 %type <asts> implicit_block statements_and_implicit block_item_list 141 %type <dsgn> designator designator_list designation designation_opt 142 %type <ilist> initializer initializer_list 143 %type <yyint> unary_operator assignment_operator struct_or_union 144 %type <yystr> asm_string_literal 145 146 %start file 147 148 %% 149 150 /* C2X A.2.1 Expressions */ 151 152 primary_expr 153 : identifier { $$ = newAst_VALUE (symbolVal ($1)); } 154 | CONSTANT { $$ = newAst_VALUE ($1); } 155 | string_literal_val 156 | '(' expr ')' { $$ = $2; } 157 | generic_selection 158 ; 159 160 generic_selection 161 : GENERIC '(' assignment_expr ',' generic_assoc_list ')' { $$ = newNode (GENERIC, $3, $5); } 162 ; 163 164 generic_assoc_list 165 : generic_association { $$ = newNode (GENERIC_ASSOC_LIST, NULL, $1); } 166 | generic_assoc_list ',' generic_association { $$ = newNode (GENERIC_ASSOC_LIST, $1, $3); } 167 ; 168 169 generic_association 170 : type_name ':' assignment_expr { $$ = newNode (GENERIC_ASSOCIATION, newAst_LINK($1), $3); } 171 | DEFAULT ':' assignment_expr { $$ = newNode (GENERIC_ASSOCIATION,NULL,$3); } 172 ; 173 174 postfix_expr 175 : primary_expr 176 | postfix_expr '[' expr ']' { $$ = newNode ('[', $1, $3); } 177 | postfix_expr '(' ')' { $$ = newNode (CALL,$1,NULL); 178 $$->left->funcName = 1;} 179 | postfix_expr '(' argument_expr_list ')' 180 { 181 $$ = newNode (CALL,$1,$3); $$->left->funcName = 1; 182 } 183 | postfix_expr '.' { ignoreTypedefType = 1; } identifier 184 { 185 ignoreTypedefType = 0; 186 $4 = newSymbol($4->name,NestLevel); 187 $4->implicit = 1; 188 $$ = newNode(PTR_OP,newNode('&',$1,NULL),newAst_VALUE(symbolVal($4))); 189 } 190 | postfix_expr PTR_OP { ignoreTypedefType = 1; } identifier 191 { 192 ignoreTypedefType = 0; 193 $4 = newSymbol($4->name,NestLevel); 194 $4->implicit = 1; 195 $$ = newNode(PTR_OP,$1,newAst_VALUE(symbolVal($4))); 196 } 197 | postfix_expr INC_OP 198 { $$ = newNode(INC_OP,$1,NULL);} 199 | postfix_expr DEC_OP 200 { $$ = newNode(DEC_OP,$1,NULL); } 201 | '(' type_name ')' '{' initializer_list '}' 202 { 203 /* if (!options.std_c99) */ 204 werror(E_COMPOUND_LITERALS_C99); 205 206 /* TODO: implement compound literals (C99) */ 207 } 208 | '(' type_name ')' '{' initializer_list ',' '}' 209 { 210 /* if (!options.std_c99) */ 211 werror(E_COMPOUND_LITERALS_C99); 212 213 /* TODO: implement compound literals (C99) */ 214 } 215 ; 216 217 argument_expr_list 218 : assignment_expr 219 | assignment_expr ',' argument_expr_list { $$ = newNode(PARAM,$1,$3); } 220 ; 221 222 unary_expr 223 : postfix_expr 224 | INC_OP unary_expr { $$ = newNode (INC_OP, NULL, $2); } 225 | DEC_OP unary_expr { $$ = newNode (DEC_OP, NULL, $2); } 226 | unary_operator cast_expr 227 { 228 if ($1 == '&' && IS_AST_OP ($2) && $2->opval.op == '*' && $2->right == NULL) 229 $$ = $2->left; 230 else if ($1 == '*' && IS_AST_OP ($2) && $2->opval.op == '&' && $2->right == NULL) 231 $$ = $2->left; 232 else 233 $$ = newNode ($1, $2, NULL); 234 } 235 | SIZEOF unary_expr { $$ = newNode (SIZEOF, NULL, $2); } 236 | SIZEOF '(' type_name ')' { $$ = newAst_VALUE (sizeofOp ($3)); } 237 | ALIGNOF '(' type_name ')'{ $$ = newAst_VALUE (alignofOp ($3)); } 238 | TYPEOF unary_expr { $$ = newNode (TYPEOF, NULL, $2); } 239 | OFFSETOF '(' type_name ',' offsetof_member_designator ')' { $$ = offsetofOp($3, $5); } 240 ; 241 242 unary_operator 243 : '&' { $$ = '&';} 244 | '*' { $$ = '*';} 245 | '+' { $$ = '+';} 246 | '-' { $$ = '-';} 247 | '~' { $$ = '~';} 248 | '!' { $$ = '!';} 249 ; 250 251 cast_expr 252 : unary_expr 253 | '(' type_name ')' cast_expr { $$ = newNode(CAST,newAst_LINK($2),$4); } 254 ; 255 256 multiplicative_expr 257 : cast_expr 258 | multiplicative_expr '*' cast_expr { $$ = newNode('*',$1,$3);} 259 | multiplicative_expr '/' cast_expr { $$ = newNode('/',$1,$3);} 260 | multiplicative_expr '%' cast_expr { $$ = newNode('%',$1,$3);} 261 ; 262 263 additive_expr 264 : multiplicative_expr 265 | additive_expr '+' multiplicative_expr { $$=newNode('+',$1,$3);} 266 | additive_expr '-' multiplicative_expr { $$=newNode('-',$1,$3);} 267 ; 268 269 shift_expr 270 : additive_expr 271 | shift_expr LEFT_OP additive_expr { $$ = newNode(LEFT_OP,$1,$3); } 272 | shift_expr RIGHT_OP additive_expr { $$ = newNode(RIGHT_OP,$1,$3); } 273 ; 274 275 relational_expr 276 : shift_expr 277 | relational_expr '<' shift_expr { $$ = newNode('<', $1,$3);} 278 | relational_expr '>' shift_expr { $$ = newNode('>', $1,$3);} 279 | relational_expr LE_OP shift_expr { $$ = newNode(LE_OP,$1,$3);} 280 | relational_expr GE_OP shift_expr { $$ = newNode(GE_OP,$1,$3);} 281 ; 282 283 equality_expr 284 : relational_expr 285 | equality_expr EQ_OP relational_expr { $$ = newNode(EQ_OP,$1,$3);} 286 | equality_expr NE_OP relational_expr { $$ = newNode(NE_OP,$1,$3);} 287 ; 288 289 and_expr 290 : equality_expr 291 | and_expr '&' equality_expr { $$ = newNode('&',$1,$3);} 292 ; 293 294 exclusive_or_expr 295 : and_expr 296 | exclusive_or_expr '^' and_expr { $$ = newNode('^',$1,$3);} 297 ; 298 299 inclusive_or_expr 300 : exclusive_or_expr 301 | inclusive_or_expr '|' exclusive_or_expr { $$ = newNode('|',$1,$3);} 302 ; 303 304 logical_and_expr 305 : inclusive_or_expr 306 | logical_and_expr AND_OP { seqPointNo++;} inclusive_or_expr 307 { $$ = newNode(AND_OP,$1,$4);} 308 ; 309 310 logical_or_expr 311 : logical_and_expr 312 | logical_or_expr OR_OP { seqPointNo++;} logical_and_expr 313 { $$ = newNode(OR_OP,$1,$4); } 314 ; 315 316 conditional_expr 317 : logical_or_expr 318 | logical_or_expr '?' { seqPointNo++;} expr ':' conditional_expr 319 { 320 $$ = newNode(':',$4,$6); 321 $$ = newNode('?',$1,$$); 322 } 323 ; 324 325 assignment_expr 326 : conditional_expr 327 | cast_expr assignment_operator assignment_expr 328 { 329 330 switch ($2) { 331 case '=': 332 $$ = newNode($2,$1,$3); 333 break; 334 case MUL_ASSIGN: 335 $$ = createRMW($1, '*', $3); 336 break; 337 case DIV_ASSIGN: 338 $$ = createRMW($1, '/', $3); 339 break; 340 case MOD_ASSIGN: 341 $$ = createRMW($1, '%', $3); 342 break; 343 case ADD_ASSIGN: 344 $$ = createRMW($1, '+', $3); 345 break; 346 case SUB_ASSIGN: 347 $$ = createRMW($1, '-', $3); 348 break; 349 case LEFT_ASSIGN: 350 $$ = createRMW($1, LEFT_OP, $3); 351 break; 352 case RIGHT_ASSIGN: 353 $$ = createRMW($1, RIGHT_OP, $3); 354 break; 355 case AND_ASSIGN: 356 $$ = createRMW($1, '&', $3); 357 break; 358 case XOR_ASSIGN: 359 $$ = createRMW($1, '^', $3); 360 break; 361 case OR_ASSIGN: 362 $$ = createRMW($1, '|', $3); 363 break; 364 default : 365 $$ = NULL; 366 } 367 368 } 369 ; 370 371 assignment_operator 372 : '=' { $$ = '=';} 373 | MUL_ASSIGN 374 | DIV_ASSIGN 375 | MOD_ASSIGN 376 | ADD_ASSIGN 377 | SUB_ASSIGN 378 | LEFT_ASSIGN 379 | RIGHT_ASSIGN 380 | AND_ASSIGN 381 | XOR_ASSIGN 382 | OR_ASSIGN 383 ; 384 385 expr 386 : assignment_expr 387 | expr ',' { seqPointNo++;} assignment_expr { $$ = newNode(',',$1,$4);} 388 ; 389 390 expr_opt 391 : { $$ = NULL; seqPointNo++; } 392 | expr { $$ = $1; seqPointNo++; } 393 ; 394 395 constant_expr 396 : conditional_expr 397 ; 398 399 /* C2X A.2.2 Declarations */ 400 401 declaration 402 : declaration_specifiers ';' 403 { 404 /* Special case: if incomplete struct/union declared without name, */ 405 /* make sure an incomplete type for it exists in the current scope */ 406 if (IS_STRUCT($1)) 407 { 408 structdef *sdef = SPEC_STRUCT($1); 409 structdef *osdef; 410 osdef = findSymWithBlock (StructTab, sdef->tagsym, currBlockno, NestLevel); 411 if (osdef && osdef->block != currBlockno) 412 { 413 sdef = newStruct(osdef->tagsym->name); 414 sdef->level = NestLevel; 415 sdef->block = currBlockno; 416 sdef->tagsym = newSymbol (osdef->tagsym->name, NestLevel); 417 addSym (StructTab, sdef, sdef->tag, sdef->level, currBlockno, 0); 418 uselessDecl = FALSE; 419 } 420 } 421 if (uselessDecl) 422 werror(W_USELESS_DECL); 423 uselessDecl = TRUE; 424 $$ = NULL; 425 } 426 | declaration_specifiers init_declarator_list ';' 427 { 428 /* add the specifier list to the id */ 429 symbol *sym , *sym1; 430 431 for (sym1 = sym = reverseSyms($2);sym != NULL;sym = sym->next) { 432 sym_link *lnk = copyLinkChain($1); 433 sym_link *l0 = NULL, *l1 = NULL, *l2 = NULL; 434 /* check illegal declaration */ 435 for (l0 = sym->type; l0 != NULL; l0 = l0->next) 436 if (IS_PTR (l0)) 437 break; 438 /* check if creating intances of structs with flexible arrays */ 439 for (l1 = lnk; l1 != NULL; l1 = l1->next) 440 if (IS_STRUCT (l1) && SPEC_STRUCT (l1)->b_flexArrayMember) 441 break; 442 if (!options.std_c99 && l0 == NULL && l1 != NULL && SPEC_EXTR($1) != 1) 443 werror (W_FLEXARRAY_INSTRUCT, sym->name); 444 /* check if creating intances of function type */ 445 for (l1 = lnk; l1 != NULL; l1 = l1->next) 446 if (IS_FUNC (l1)) 447 break; 448 for (l2 = lnk; l2 != NULL; l2 = l2->next) 449 if (IS_PTR (l2)) 450 break; 451 if (l0 == NULL && l2 == NULL && l1 != NULL) 452 werrorfl(sym->fileDef, sym->lineDef, E_TYPE_IS_FUNCTION, sym->name); 453 /* do the pointer stuff */ 454 pointerTypes(sym->type,lnk); 455 addDecl (sym,0,lnk); 456 } 457 458 uselessDecl = TRUE; 459 $$ = sym1; 460 } 461 | static_assert_declaration 462 { 463 $$ = NULL; 464 } 465 | attribute_declaration 466 { 467 $$ = NULL; 468 } 469 ; 470 471 declaration_specifiers : declaration_specifiers_ { $$ = finalizeSpec($1); }; 472 473 declaration_specifiers_ 474 : storage_class_specifier { $$ = $1; } 475 | storage_class_specifier declaration_specifiers_ { 476 /* if the decl $2 is not a specifier */ 477 /* find the spec and replace it */ 478 $$ = mergeDeclSpec($1, $2, "storage_class_specifier declaration_specifiers - skipped"); 479 } 480 | type_specifier { $$ = $1; } 481 | type_specifier declaration_specifiers_ { 482 /* if the decl $2 is not a specifier */ 483 /* find the spec and replace it */ 484 $$ = mergeDeclSpec($1, $2, "type_specifier declaration_specifiers - skipped"); 485 } 486 | function_specifier { $$ = $1; } 487 | function_specifier declaration_specifiers_ { 488 /* if the decl $2 is not a specifier */ 489 /* find the spec and replace it */ 490 $$ = mergeDeclSpec($1, $2, "function_specifier declaration_specifiers - skipped"); 491 } 492 | alignment_specifier { $$ = $1; } 493 | alignment_specifier declaration_specifiers_ { 494 /* if the decl $2 is not a specifier */ 495 /* find the spec and replace it */ 496 $$ = mergeDeclSpec($1, $2, "alignment_specifier declaration_specifiers - skipped"); 497 } 498 ; 499 500 init_declarator_list 501 : init_declarator 502 | init_declarator_list ',' init_declarator { $3->next = $1; $$ = $3;} 503 ; 504 505 init_declarator 506 : declarator { $1->ival = NULL; } 507 | declarator '=' initializer { $1->ival = $3; seqPointNo++; } 508 ; 509 510 attribute_declaration 511 : attribute_specifier_sequence ';' 512 ; 513 514 storage_class_specifier 515 : TYPEDEF { 516 $$ = newLink (SPECIFIER); 517 SPEC_TYPEDEF($$) = 1; 518 } 519 | EXTERN { 520 $$ = newLink(SPECIFIER); 521 SPEC_EXTR($$) = 1; 522 } 523 | STATIC { 524 $$ = newLink (SPECIFIER); 525 SPEC_STAT($$) = 1; 526 } 527 | AUTO { 528 $$ = newLink (SPECIFIER); 529 SPEC_SCLS($$) = S_AUTO; 530 } 531 | REGISTER { 532 $$ = newLink (SPECIFIER); 533 SPEC_SCLS($$) = S_REGISTER; 534 } 535 ; 536 537 type_specifier 538 : type_qualifier { $$ = $1; } 539 | SD_BOOL { 540 $$=newLink(SPECIFIER); 541 SPEC_NOUN($$) = V_BOOL; 542 ignoreTypedefType = 1; 543 } 544 | SD_CHAR { 545 $$=newLink(SPECIFIER); 546 SPEC_NOUN($$) = V_CHAR; 547 ignoreTypedefType = 1; 548 } 549 | SD_SHORT { 550 $$=newLink(SPECIFIER); 551 SPEC_SHORT($$) = 1; 552 ignoreTypedefType = 1; 553 } 554 | SD_INT { 555 $$=newLink(SPECIFIER); 556 SPEC_NOUN($$) = V_INT; 557 ignoreTypedefType = 1; 558 } 559 | SD_LONG { 560 $$=newLink(SPECIFIER); 561 SPEC_LONG($$) = 1; 562 ignoreTypedefType = 1; 563 } 564 | SIGNED { 565 $$=newLink(SPECIFIER); 566 $$->select.s.b_signed = 1; 567 ignoreTypedefType = 1; 568 } 569 | UNSIGNED { 570 $$=newLink(SPECIFIER); 571 SPEC_USIGN($$) = 1; 572 ignoreTypedefType = 1; 573 } 574 | SD_VOID { 575 $$=newLink(SPECIFIER); 576 SPEC_NOUN($$) = V_VOID; 577 ignoreTypedefType = 1; 578 } 579 | SD_FLOAT { 580 $$=newLink(SPECIFIER); 581 SPEC_NOUN($$) = V_FLOAT; 582 ignoreTypedefType = 1; 583 } 584 | FIXED16X16 { 585 $$=newLink(SPECIFIER); 586 SPEC_NOUN($$) = V_FIXED16X16; 587 ignoreTypedefType = 1; 588 } 589 | BIT { 590 $$=newLink(SPECIFIER); 591 SPEC_NOUN($$) = V_BIT; 592 SPEC_SCLS($$) = S_BIT; 593 SPEC_BLEN($$) = 1; 594 SPEC_BSTR($$) = 0; 595 ignoreTypedefType = 1; 596 } 597 | AT constant_expr { 598 $$=newLink(SPECIFIER); 599 /* add this to the storage class specifier */ 600 SPEC_ABSA($$) = 1; /* set the absolute addr flag */ 601 /* now get the abs addr from value */ 602 SPEC_ADDR($$) = (unsigned int) ulFromVal(constExprValue($2,TRUE)); 603 } 604 | struct_or_union_specifier { 605 uselessDecl = FALSE; 606 $$ = $1; 607 ignoreTypedefType = 1; 608 } 609 | enum_specifier { 610 cenum = NULL; 611 uselessDecl = FALSE; 612 ignoreTypedefType = 1; 613 $$ = $1; 614 } 615 | TYPE_NAME 616 { 617 symbol *sym; 618 sym_link *p; 619 sym = findSym(TypedefTab,NULL,$1); 620 $$ = p = copyLinkChain(sym ? sym->type : NULL); 621 SPEC_TYPEDEF(getSpec(p)) = 0; 622 ignoreTypedefType = 1; 623 } 624 | sfr_reg_bit 625 ; 626 627 struct_or_union_specifier 628 : struct_or_union opt_stag 629 { 630 structdef *sdef; 631 632 if (! $2->tagsym) 633 { 634 /* no tag given, so new struct def for current scope */ 635 addSym (StructTab, $2, $2->tag, $2->level, currBlockno, 0); 636 } 637 else 638 { 639 sdef = findSymWithBlock (StructTab, $2->tagsym, currBlockno, NestLevel); 640 if (sdef) 641 { 642 /* Error if a complete type already defined in this scope */ 643 if (sdef->block == currBlockno) 644 { 645 if (sdef->fields) 646 { 647 werror(E_STRUCT_REDEF, $2->tag); 648 werrorfl(sdef->tagsym->fileDef, sdef->tagsym->lineDef, E_PREVIOUS_DEF); 649 } 650 else 651 { 652 $2 = sdef; /* We are completing an incomplete type */ 653 } 654 } 655 else 656 { 657 /* There is an existing struct def in an outer scope. */ 658 /* Create new struct def for current scope */ 659 addSym (StructTab, $2, $2->tag, $2->level, currBlockno, 0); 660 } 661 } 662 else 663 { 664 /* There is no existing struct def at all. */ 665 /* Create new struct def for current scope */ 666 addSym (StructTab, $2, $2->tag, $2->level, currBlockno, 0); 667 } 668 } 669 670 if (!$2->type) 671 { 672 $2->type = $1; 673 } 674 else 675 { 676 if ($2->type != $1) 677 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union"); 678 } 679 } 680 '{' member_declaration_list '}' 681 { 682 structdef *sdef; 683 symbol *sym, *dsym; 684 685 // check for errors in structure members 686 for (sym=$5; sym; sym=sym->next) 687 { 688 if (IS_ABSOLUTE(sym->etype)) 689 { 690 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "'at'"); 691 SPEC_ABSA(sym->etype) = 0; 692 } 693 if (IS_SPEC(sym->etype) && SPEC_SCLS(sym->etype)) 694 { 695 werrorfl(sym->fileDef, sym->lineDef, E_NOT_ALLOWED, "storage class"); 696 printTypeChainRaw (sym->type, NULL); 697 SPEC_SCLS(sym->etype) = 0; 698 } 699 for (dsym=sym->next; dsym; dsym=dsym->next) 700 { 701 if (*dsym->name && strcmp(sym->name, dsym->name)==0) 702 { 703 werrorfl(sym->fileDef, sym->lineDef, E_DUPLICATE_MEMBER, 704 $1==STRUCT ? "struct" : "union", sym->name); 705 werrorfl(dsym->fileDef, dsym->lineDef, E_PREVIOUS_DEF); 706 } 707 } 708 } 709 710 /* Create a structdef */ 711 sdef = $2; 712 sdef->fields = reverseSyms($5); /* link the fields */ 713 sdef->size = compStructSize($1, sdef); /* update size of */ 714 promoteAnonStructs ($1, sdef); 715 716 /* Create the specifier */ 717 $$ = newLink (SPECIFIER); 718 SPEC_NOUN($$) = V_STRUCT; 719 SPEC_STRUCT($$)= sdef; 720 } 721 | struct_or_union stag 722 { 723 structdef *sdef; 724 725 sdef = findSymWithBlock (StructTab, $2->tagsym, currBlockno, NestLevel); 726 727 if (sdef) 728 $2 = sdef; 729 else 730 { 731 /* new struct def for current scope */ 732 addSym (StructTab, $2, $2->tag, $2->level, currBlockno, 0); 733 } 734 $$ = newLink(SPECIFIER); 735 SPEC_NOUN($$) = V_STRUCT; 736 SPEC_STRUCT($$) = $2; 737 738 if (!$2->type) 739 { 740 $2->type = $1; 741 } 742 else 743 { 744 if ($2->type != $1) 745 werror(E_BAD_TAG, $2->tag, $1==STRUCT ? "struct" : "union"); 746 } 747 } 748 ; 749 750 struct_or_union 751 : STRUCT { $$ = STRUCT; ignoreTypedefType = 1; } 752 | UNION { $$ = UNION; ignoreTypedefType = 1; } 753 ; 754 755 member_declaration_list 756 : member_declaration 757 | member_declaration_list member_declaration 758 { 759 symbol *sym = $2; 760 761 /* go to the end of the chain */ 762 while (sym->next) sym = sym->next; 763 sym->next = $1; 764 765 $$ = $2; 766 } 767 ; 768 769 member_declaration 770 : type_specifier_list member_declarator_list ';' 771 { 772 /* add this type to all the symbols */ 773 symbol *sym; 774 for ( sym = $2; sym != NULL; sym = sym->next ) 775 { 776 sym_link *btype = copyLinkChain($1); 777 778 pointerTypes(sym->type, btype); 779 if (!sym->type) 780 { 781 sym->type = btype; 782 sym->etype = getSpec(sym->type); 783 } 784 else 785 addDecl (sym, 0, btype); 786 /* make sure the type is complete and sane */ 787 checkTypeSanity(sym->etype, sym->name); 788 } 789 ignoreTypedefType = 0; 790 $$ = $2; 791 } 792 ; 793 794 member_declarator_list 795 : member_declarator 796 | member_declarator_list ',' member_declarator 797 { 798 $3->next = $1; 799 $$ = $3; 800 } 801 ; 802 803 member_declarator 804 : declarator 805 | ':' constant_expr 806 { 807 unsigned int bitsize; 808 $$ = newSymbol (genSymName(NestLevel), NestLevel); 809 bitsize = (unsigned int) ulFromVal(constExprValue($2, TRUE)); 810 if (!bitsize) 811 bitsize = BITVAR_PAD; 812 $$->bitVar = bitsize; 813 $$->bitUnnamed = 1; 814 } 815 | declarator ':' constant_expr 816 { 817 unsigned int bitsize; 818 bitsize = (unsigned int) ulFromVal(constExprValue($3, TRUE)); 819 820 if (!bitsize) 821 { 822 $$ = newSymbol (genSymName(NestLevel), NestLevel); 823 $$->bitVar = BITVAR_PAD; 824 werror(W_BITFLD_NAMED); 825 } 826 else 827 $1->bitVar = bitsize; 828 } 829 | { $$ = newSymbol ("", NestLevel); } 830 ; 831 832 enum_specifier 833 : ENUM '{' enumerator_list '}' 834 { 835 $$ = newEnumType ($3); 836 SPEC_SCLS(getSpec($$)) = 0; 837 } 838 | ENUM identifier '{' enumerator_list '}' 839 { 840 symbol *csym; 841 sym_link *enumtype; 842 843 csym = findSymWithLevel(enumTab, $2); 844 if ((csym && csym->level == $2->level)) 845 { 846 werrorfl($2->fileDef, $2->lineDef, E_DUPLICATE_TYPEDEF, csym->name); 847 werrorfl(csym->fileDef, csym->lineDef, E_PREVIOUS_DEF); 848 } 849 850 enumtype = newEnumType ($4); 851 SPEC_SCLS(getSpec(enumtype)) = 0; 852 $2->type = enumtype; 853 854 /* add this to the enumerator table */ 855 if (!csym) 856 addSym (enumTab, $2, $2->name, $2->level, $2->block, 0); 857 $$ = copyLinkChain(enumtype); 858 } 859 | ENUM identifier 860 { 861 symbol *csym; 862 863 /* check the enumerator table */ 864 if ((csym = findSymWithLevel(enumTab, $2))) 865 $$ = copyLinkChain(csym->type); 866 else 867 { 868 $$ = newLink(SPECIFIER); 869 SPEC_NOUN($$) = V_INT; 870 } 871 } 872 ; 873 874 enumerator_list 875 : enumerator 876 | enumerator_list ',' 877 | enumerator_list ',' enumerator 878 { 879 $3->next = $1; 880 $$ = $3; 881 } 882 ; 883 884 enumerator 885 : identifier opt_assign_expr 886 { 887 symbol *sym; 888 889 // check if the symbol at the same level already exists 890 if ((sym = findSymWithLevel (SymbolTab, $1)) && sym->level == $1->level) 891 { 892 werrorfl ($1->fileDef, $1->lineDef, E_DUPLICATE_MEMBER, "enum", $1->name); 893 werrorfl (sym->fileDef, sym->lineDef, E_PREVIOUS_DEF); 894 } 895 $1->type = copyLinkChain ($2->type); 896 $1->etype = getSpec ($1->type); 897 SPEC_ENUM ($1->etype) = 1; 898 $$ = $1; 899 // do this now, so we can use it for the next enums in the list 900 addSymChain (&$1); 901 } 902 ; 903 904 type_qualifier 905 : SD_CONST { 906 $$=newLink(SPECIFIER); 907 SPEC_CONST($$) = 1; 908 } 909 | RESTRICT { 910 $$=newLink(SPECIFIER); 911 SPEC_RESTRICT($$) = 1; 912 } 913 | VOLATILE { 914 $$=newLink(SPECIFIER); 915 SPEC_VOLATILE($$) = 1; 916 } 917 | ADDRSPACE_NAME { 918 $$=newLink(SPECIFIER); 919 SPEC_ADDRSPACE($$) = findSym (AddrspaceTab, 0, $1); 920 } 921 | XDATA { 922 $$ = newLink (SPECIFIER); 923 SPEC_SCLS($$) = S_XDATA; 924 } 925 | CODE { 926 $$ = newLink (SPECIFIER); 927 SPEC_SCLS($$) = S_CODE; 928 } 929 | EEPROM { 930 $$ = newLink (SPECIFIER); 931 SPEC_SCLS($$) = S_EEPROM; 932 } 933 | DATA { 934 $$ = newLink (SPECIFIER); 935 SPEC_SCLS($$) = S_DATA; 936 } 937 | IDATA { 938 $$ = newLink (SPECIFIER); 939 SPEC_SCLS($$) = S_IDATA; 940 } 941 | PDATA { 942 $$ = newLink (SPECIFIER); 943 SPEC_SCLS($$) = S_PDATA; 944 } 945 ; 946 947 function_specifier 948 : INLINE { 949 $$ = newLink (SPECIFIER); 950 SPEC_INLINE($$) = 1; 951 } 952 | NORETURN { 953 $$ = newLink (SPECIFIER); 954 SPEC_NORETURN($$) = 1; 955 } 956 ; 957 958 alignment_specifier 959 : ALIGNAS '(' type_name ')' 960 { 961 checkTypeSanity ($3, "(_Alignas)"); 962 $$ = newLink (SPECIFIER); 963 SPEC_ALIGNAS($$) = 1; 964 } 965 | ALIGNAS '(' constant_expr ')' 966 { 967 value *val = constExprValue ($3, TRUE); 968 $$ = newLink (SPECIFIER); 969 SPEC_ALIGNAS($$) = 0; 970 if (!val) 971 werror (E_CONST_EXPECTED); 972 else if (ulFromVal (val) == 0 || isPowerOf2 (ulFromVal (val)) && ulFromVal (val) <= port->mem.maxextalign) 973 SPEC_ALIGNAS($$) = ulFromVal(val); 974 else 975 werror (E_ALIGNAS, ulFromVal(val)); 976 } 977 ; 978 979 declarator 980 : direct_declarator { $$ = $1; } 981 | pointer direct_declarator 982 { 983 addDecl ($2,0,reverseLink($1)); 984 $$ = $2; 985 } 986 ; 987 988 direct_declarator 989 : identifier 990 | '(' declarator ')' { $$ = $2; } 991 | array_declarator 992 | declarator2_function_attributes 993 ; 994 995 declarator2 996 : identifier 997 | '(' declarator ')' { $$ = $2; } 998 | array_declarator 999 ; 1000 1001 array_declarator: 1002 direct_declarator '[' ']' 1003 { 1004 sym_link *p; 1005 1006 p = newLink (DECLARATOR); 1007 DCL_TYPE(p) = ARRAY; 1008 DCL_ELEM(p) = 0; 1009 addDecl($1,0,p); 1010 } 1011 | direct_declarator '[' type_qualifier_list ']' 1012 { 1013 sym_link *p, *n; 1014 1015 if (!options.std_c99) 1016 werror (E_QUALIFIED_ARRAY_PARAM_C99); 1017 1018 p = newLink (DECLARATOR); 1019 DCL_TYPE(p) = ARRAY; 1020 DCL_ELEM(p) = 0; 1021 DCL_PTR_CONST(p) = SPEC_CONST ($3); 1022 DCL_PTR_RESTRICT(p) = SPEC_RESTRICT ($3); 1023 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE ($3); 1024 DCL_PTR_ADDRSPACE(p) = SPEC_ADDRSPACE ($3); 1025 addDecl($1,0,p); 1026 n = newLink (SPECIFIER); 1027 SPEC_NEEDSPAR(n) = 1; 1028 addDecl($1,0,n); 1029 } 1030 | direct_declarator '[' constant_expr ']' 1031 { 1032 sym_link *p; 1033 value *tval; 1034 int size; 1035 1036 tval = constExprValue($3, TRUE); 1037 /* if it is not a constant then Error */ 1038 p = newLink (DECLARATOR); 1039 DCL_TYPE(p) = ARRAY; 1040 1041 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) 1042 { 1043 werror(E_CONST_EXPECTED); 1044 /* Assume a single item array to limit the cascade */ 1045 /* of additional errors. */ 1046 size = 1; 1047 } 1048 else 1049 { 1050 if ((size = (int) ulFromVal(tval)) < 0) 1051 { 1052 werror(E_NEGATIVE_ARRAY_SIZE, $1->name); 1053 size = 1; 1054 } 1055 } 1056 DCL_ELEM(p) = size; 1057 addDecl($1, 0, p); 1058 } 1059 | direct_declarator '[' STATIC constant_expr ']' 1060 { 1061 sym_link *p, *n; 1062 value *tval; 1063 int size; 1064 1065 if (!options.std_c99) 1066 werror (E_STATIC_ARRAY_PARAM_C99); 1067 1068 tval = constExprValue($4, TRUE); 1069 /* if it is not a constant then Error */ 1070 p = newLink (DECLARATOR); 1071 DCL_TYPE(p) = ARRAY; 1072 1073 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) 1074 { 1075 werror(E_CONST_EXPECTED); 1076 /* Assume a single item array to limit the cascade */ 1077 /* of additional errors. */ 1078 size = 1; 1079 } 1080 else 1081 { 1082 if ((size = (int) ulFromVal(tval)) < 0) 1083 { 1084 werror(E_NEGATIVE_ARRAY_SIZE, $1->name); 1085 size = 1; 1086 } 1087 } 1088 DCL_ELEM(p) = size; 1089 addDecl($1, 0, p); 1090 n = newLink (SPECIFIER); 1091 SPEC_NEEDSPAR(n) = 1; 1092 addDecl($1,0,n); 1093 } 1094 | direct_declarator '[' type_qualifier_list constant_expr ']' 1095 { 1096 sym_link *p, *n; 1097 value *tval; 1098 int size; 1099 1100 if (!options.std_c99) 1101 werror (E_QUALIFIED_ARRAY_PARAM_C99); 1102 1103 tval = constExprValue($4, TRUE); 1104 /* if it is not a constant then Error */ 1105 p = newLink (DECLARATOR); 1106 DCL_TYPE(p) = ARRAY; 1107 1108 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) 1109 { 1110 werror(E_CONST_EXPECTED); 1111 /* Assume a single item array to limit the cascade */ 1112 /* of additional errors. */ 1113 size = 1; 1114 } 1115 else 1116 { 1117 if ((size = (int) ulFromVal(tval)) < 0) 1118 { 1119 werror(E_NEGATIVE_ARRAY_SIZE, $1->name); 1120 size = 1; 1121 } 1122 } 1123 DCL_ELEM(p) = size; 1124 DCL_PTR_CONST(p) = SPEC_CONST ($3); 1125 DCL_PTR_RESTRICT(p) = SPEC_RESTRICT ($3); 1126 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE ($3); 1127 DCL_PTR_ADDRSPACE(p) = SPEC_ADDRSPACE ($3); 1128 addDecl($1, 0, p); 1129 n = newLink (SPECIFIER); 1130 SPEC_NEEDSPAR(n) = 1; 1131 addDecl($1,0,n); 1132 } 1133 | direct_declarator '[' STATIC type_qualifier_list constant_expr ']' 1134 { 1135 sym_link *p, *n; 1136 value *tval; 1137 int size; 1138 1139 if (!options.std_c99) 1140 { 1141 werror (E_STATIC_ARRAY_PARAM_C99); 1142 werror (E_QUALIFIED_ARRAY_PARAM_C99); 1143 } 1144 1145 tval = constExprValue($5, TRUE); 1146 /* if it is not a constant then Error */ 1147 p = newLink (DECLARATOR); 1148 DCL_TYPE(p) = ARRAY; 1149 1150 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) 1151 { 1152 werror(E_CONST_EXPECTED); 1153 /* Assume a single item array to limit the cascade */ 1154 /* of additional errors. */ 1155 size = 1; 1156 } 1157 else 1158 { 1159 if ((size = (int) ulFromVal(tval)) < 0) 1160 { 1161 werror(E_NEGATIVE_ARRAY_SIZE, $1->name); 1162 size = 1; 1163 } 1164 } 1165 DCL_ELEM(p) = size; 1166 DCL_PTR_CONST(p) = SPEC_CONST ($4); 1167 DCL_PTR_RESTRICT(p) = SPEC_RESTRICT ($4); 1168 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE ($4); 1169 DCL_PTR_ADDRSPACE(p) = SPEC_ADDRSPACE ($4); 1170 addDecl($1, 0, p); 1171 n = newLink (SPECIFIER); 1172 SPEC_NEEDSPAR(n) = 1; 1173 addDecl($1,0,n); 1174 } 1175 | direct_declarator '[' type_qualifier_list STATIC constant_expr ']' 1176 { 1177 sym_link *p, *n; 1178 value *tval; 1179 int size; 1180 1181 if (!options.std_c99) 1182 { 1183 werror (E_QUALIFIED_ARRAY_PARAM_C99); 1184 werror (E_STATIC_ARRAY_PARAM_C99); 1185 } 1186 1187 tval = constExprValue($5, TRUE); 1188 /* if it is not a constant then Error */ 1189 p = newLink (DECLARATOR); 1190 DCL_TYPE(p) = ARRAY; 1191 1192 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) 1193 { 1194 werror(E_CONST_EXPECTED); 1195 /* Assume a single item array to limit the cascade */ 1196 /* of additional errors. */ 1197 size = 1; 1198 } 1199 else 1200 { 1201 if ((size = (int) ulFromVal(tval)) < 0) 1202 { 1203 werror(E_NEGATIVE_ARRAY_SIZE, $1->name); 1204 size = 1; 1205 } 1206 } 1207 DCL_ELEM(p) = size; 1208 DCL_PTR_CONST(p) = SPEC_CONST ($3); 1209 DCL_PTR_RESTRICT(p) = SPEC_RESTRICT ($3); 1210 DCL_PTR_VOLATILE(p) = SPEC_VOLATILE ($3); 1211 DCL_PTR_ADDRSPACE(p) = SPEC_ADDRSPACE ($3); 1212 addDecl($1, 0, p); 1213 n = newLink (SPECIFIER); 1214 SPEC_NEEDSPAR(n) = 1; 1215 addDecl($1,0,n); 1216 } 1217 ; 1218 1219 declarator2_function_attributes 1220 : function_declarator { $$ = $1; } 1221 | function_declarator function_attribute { 1222 // copy the functionAttributes (not the args and hasVargs !!) 1223 struct value *args; 1224 unsigned hasVargs; 1225 sym_link *funcType=$1->type; 1226 1227 while (funcType && !IS_FUNC(funcType)) 1228 funcType = funcType->next; 1229 1230 if (!funcType) 1231 werror (E_FUNC_ATTR); 1232 else 1233 { 1234 args=FUNC_ARGS(funcType); 1235 hasVargs=FUNC_HASVARARGS(funcType); 1236 1237 memcpy (&funcType->funcAttrs, &$2->funcAttrs, 1238 sizeof($2->funcAttrs)); 1239 1240 FUNC_ARGS(funcType)=args; 1241 FUNC_HASVARARGS(funcType)=hasVargs; 1242 1243 // just to be sure 1244 memset (&$2->funcAttrs, 0, 1245 sizeof($2->funcAttrs)); 1246 1247 addDecl ($1,0,$2); 1248 } 1249 } 1250 ; 1251 1252 function_declarator 1253 : declarator2 '(' ')' 1254 { 1255 addDecl ($1, FUNCTION, NULL); 1256 } 1257 | declarator2 '(' 1258 { 1259 NestLevel += LEVEL_UNIT; 1260 STACK_PUSH(blockNum, currBlockno); 1261 btree_add_child(currBlockno, ++blockNo); 1262 currBlockno = blockNo; 1263 seqPointNo++; /* not a true sequence point, but helps resolve scope */ 1264 } 1265 parameter_type_list ')' 1266 { 1267 sym_link *funcType; 1268 1269 addDecl ($1, FUNCTION, NULL); 1270 1271 funcType = $1->type; 1272 while (funcType && !IS_FUNC(funcType)) 1273 funcType = funcType->next; 1274 1275 assert (funcType); 1276 1277 FUNC_HASVARARGS(funcType) = IS_VARG($4); 1278 FUNC_ARGS(funcType) = reverseVal($4); 1279 1280 /* nest level was incremented to take care of the parms */ 1281 NestLevel -= LEVEL_UNIT; 1282 currBlockno = STACK_POP(blockNum); 1283 seqPointNo++; /* not a true sequence point, but helps resolve scope */ 1284 1285 // if this was a pointer (to a function) 1286 if (!IS_FUNC($1->type)) 1287 cleanUpLevel(SymbolTab, NestLevel + LEVEL_UNIT); 1288 1289 $$ = $1; 1290 } 1291 | declarator2 '(' identifier_list ')' 1292 { 1293 werror(E_OLD_STYLE,$1->name); 1294 /* assume it returns an int */ 1295 $1->type = $1->etype = newIntLink(); 1296 $$ = $1; 1297 } 1298 ; 1299 1300 pointer 1301 : unqualified_pointer { $$ = $1;} 1302 | unqualified_pointer AT constant_expr /* Special case to allow __at at the end */ 1303 { 1304 sym_link *n = newLink(SPECIFIER); 1305 /* add this to the storage class specifier */ 1306 SPEC_ABSA(n) = 1; /* set the absolute addr flag */ 1307 /* now get the abs addr from value */ 1308 SPEC_ADDR(n) = (unsigned int) ulFromVal(constExprValue($3,TRUE)); 1309 n->next = $1; 1310 $$ = n; 1311 } 1312 | unqualified_pointer type_qualifier_list 1313 { 1314 $$ = $1; 1315 if (IS_SPEC($2)) { 1316 DCL_TSPEC($1) = $2; 1317 DCL_PTR_CONST($1) = SPEC_CONST($2); 1318 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2); 1319 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2); 1320 DCL_PTR_ADDRSPACE($1) = SPEC_ADDRSPACE($2); 1321 } 1322 else 1323 werror (W_PTR_TYPE_INVALID); 1324 } 1325 | unqualified_pointer type_qualifier_list AT constant_expr /* Special case to allow __at at the end */ 1326 { 1327 if (IS_SPEC($2)) { 1328 DCL_TSPEC($1) = $2; 1329 DCL_PTR_CONST($1) = SPEC_CONST($2); 1330 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2); 1331 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2); 1332 DCL_PTR_ADDRSPACE($1) = SPEC_ADDRSPACE($2); 1333 } 1334 else 1335 werror (W_PTR_TYPE_INVALID); 1336 1337 sym_link *n = newLink(SPECIFIER); 1338 /* add this to the storage class specifier */ 1339 SPEC_ABSA(n) = 1; /* set the absolute addr flag */ 1340 /* now get the abs addr from value */ 1341 SPEC_ADDR(n) = (unsigned int) ulFromVal(constExprValue($4,TRUE)); 1342 n->next = $1; 1343 $$ = n; 1344 } 1345 | unqualified_pointer pointer 1346 { 1347 $$ = $1; 1348 $$->next = $2; 1349 DCL_TYPE($2)=port->unqualified_pointer; 1350 } 1351 | unqualified_pointer type_qualifier_list pointer 1352 { 1353 $$ = $1; 1354 if (IS_SPEC($2) && DCL_TYPE($3) == UPOINTER) { 1355 DCL_PTR_CONST($1) = SPEC_CONST($2); 1356 DCL_PTR_VOLATILE($1) = SPEC_VOLATILE($2); 1357 DCL_PTR_RESTRICT($1) = SPEC_RESTRICT($2); 1358 DCL_PTR_ADDRSPACE($1) = SPEC_ADDRSPACE($2); 1359 switch (SPEC_SCLS($2)) { 1360 case S_XDATA: 1361 DCL_TYPE($3) = FPOINTER; 1362 break; 1363 case S_IDATA: 1364 DCL_TYPE($3) = IPOINTER; 1365 break; 1366 case S_PDATA: 1367 DCL_TYPE($3) = PPOINTER; 1368 break; 1369 case S_DATA: 1370 DCL_TYPE($3) = POINTER; 1371 break; 1372 case S_CODE: 1373 DCL_TYPE($3) = CPOINTER; 1374 break; 1375 case S_EEPROM: 1376 DCL_TYPE($3) = EEPPOINTER; 1377 break; 1378 default: 1379 // this could be just "constant" 1380 // werror(W_PTR_TYPE_INVALID); 1381 ; 1382 } 1383 } 1384 else 1385 werror (W_PTR_TYPE_INVALID); 1386 $$->next = $3; 1387 } 1388 ; 1389 1390 unqualified_pointer 1391 : '*' 1392 { 1393 $$ = newLink(DECLARATOR); 1394 DCL_TYPE($$)=UPOINTER; 1395 } 1396 ; 1397 1398 type_qualifier_list 1399 : type_qualifier 1400 | type_qualifier_list type_qualifier 1401 { 1402 $$ = mergeDeclSpec($1, $2, "type_qualifier_list type_qualifier skipped"); 1403 } 1404 ; 1405 1406 parameter_type_list 1407 : parameter_list 1408 | parameter_list ',' VAR_ARGS { $1->vArgs = 1;} 1409 ; 1410 1411 parameter_list 1412 : parameter_declaration 1413 | parameter_list ',' parameter_declaration 1414 { 1415 $3->next = $1; 1416 $$ = $3; 1417 } 1418 ; 1419 1420 parameter_declaration 1421 : declaration_specifiers declarator 1422 { 1423 symbol *loop; 1424 1425 if (IS_SPEC ($1) && !IS_VALID_PARAMETER_STORAGE_CLASS_SPEC ($1)) 1426 { 1427 werror (E_STORAGE_CLASS_FOR_PARAMETER, $2->name); 1428 } 1429 pointerTypes ($2->type, $1); 1430 if (IS_SPEC ($2->etype)) 1431 SPEC_NEEDSPAR($2->etype) = 0; 1432 addDecl ($2, 0, $1); 1433 for (loop = $2; loop; loop->_isparm = 1, loop = loop->next) 1434 ; 1435 $$ = symbolVal ($2); 1436 ignoreTypedefType = 0; 1437 } 1438 | type_name 1439 { 1440 $$ = newValue (); 1441 $$->type = $1; 1442 $$->etype = getSpec ($$->type); 1443 ignoreTypedefType = 0; 1444 } 1445 ; 1446 1447 abstract_declarator 1448 : pointer { $$ = reverseLink($1); } 1449 | direct_abstract_declarator 1450 | pointer direct_abstract_declarator { $1 = reverseLink($1); $2->next = $1; $$ = $2; 1451 if (IS_PTR($1) && IS_FUNC($2)) 1452 DCL_TYPE($1) = CPOINTER; 1453 } 1454 ; 1455 1456 direct_abstract_declarator 1457 : '(' abstract_declarator ')' { $$ = $2; } 1458 | array_abstract_declarator 1459 | function_abstract_declarator 1460 ; 1461 1462 array_abstract_declarator 1463 : '[' ']' { 1464 $$ = newLink (DECLARATOR); 1465 DCL_TYPE($$) = ARRAY; 1466 DCL_ELEM($$) = 0; 1467 } 1468 | '[' constant_expr ']' { 1469 value *val; 1470 $$ = newLink (DECLARATOR); 1471 DCL_TYPE($$) = ARRAY; 1472 DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($2,TRUE)); 1473 } 1474 | direct_abstract_declarator '[' ']' { 1475 $$ = newLink (DECLARATOR); 1476 DCL_TYPE($$) = ARRAY; 1477 DCL_ELEM($$) = 0; 1478 $$->next = $1; 1479 } 1480 | direct_abstract_declarator '[' constant_expr ']' 1481 { 1482 value *val; 1483 $$ = newLink (DECLARATOR); 1484 DCL_TYPE($$) = ARRAY; 1485 DCL_ELEM($$) = (int) ulFromVal(val = constExprValue($3,TRUE)); 1486 $$->next = $1; 1487 } 1488 ; 1489 1490 function_abstract_declarator 1491 : '(' ')' { $$ = NULL;} 1492 | '(' parameter_type_list ')' { $$ = NULL;} 1493 | direct_abstract_declarator '(' ')' { 1494 // $1 must be a pointer to a function 1495 sym_link *p=newLink(DECLARATOR); 1496 DCL_TYPE(p) = FUNCTION; 1497 if (!$1) { 1498 // ((void (code *) ()) 0) () 1499 $1=newLink(DECLARATOR); 1500 DCL_TYPE($1)=CPOINTER; 1501 $$ = $1; 1502 } 1503 $1->next=p; 1504 } 1505 | direct_abstract_declarator '(' 1506 { 1507 NestLevel += LEVEL_UNIT; 1508 STACK_PUSH(blockNum, currBlockno); 1509 btree_add_child(currBlockno, ++blockNo); 1510 currBlockno = blockNo; 1511 } 1512 parameter_type_list ')' 1513 { 1514 sym_link *p = newLink(DECLARATOR), *q; 1515 DCL_TYPE(p) = FUNCTION; 1516 1517 FUNC_HASVARARGS(p) = IS_VARG($4); 1518 FUNC_ARGS(p) = reverseVal($4); 1519 1520 /* nest level was incremented to take care of the parms */ 1521 NestLevel -= LEVEL_UNIT; 1522 currBlockno = STACK_POP(blockNum); 1523 if (!$1) 1524 { 1525 /* ((void (code *) (void)) 0) () */ 1526 $1 = newLink(DECLARATOR); 1527 DCL_TYPE($1) = CPOINTER; 1528 $$ = $1; 1529 } 1530 for (q = $1; q && q->next; q = q->next); 1531 q->next = p; 1532 } 1533 ; 1534 1535 initializer 1536 : assignment_expr { $$ = newiList(INIT_NODE,$1); } 1537 | '{' initializer_list '}' { $$ = newiList(INIT_DEEP,revinit($2)); } 1538 | '{' initializer_list ',' '}' { $$ = newiList(INIT_DEEP,revinit($2)); } 1539 ; 1540 1541 initializer_list 1542 : designation_opt initializer { $2->designation = $1; $$ = $2; } 1543 | initializer_list ',' designation_opt initializer 1544 { 1545 $4->designation = $3; 1546 $4->next = $1; 1547 $$ = $4; 1548 } 1549 ; 1550 1551 designation_opt 1552 : { $$ = NULL; } 1553 | designation 1554 ; 1555 1556 designation 1557 : designator_list '=' { $$ = revDesignation($1); } 1558 ; 1559 1560 designator_list 1561 : designator 1562 | designator_list designator { $2->next = $1; $$ = $2; } 1563 ; 1564 1565 designator 1566 : '[' constant_expr ']' 1567 { 1568 value *tval; 1569 int elemno; 1570 1571 tval = constExprValue($2, TRUE); 1572 /* if it is not a constant then Error */ 1573 if (!tval || (SPEC_SCLS(tval->etype) != S_LITERAL)) 1574 { 1575 werror (E_CONST_EXPECTED); 1576 elemno = 0; /* arbitrary fixup */ 1577 } 1578 else 1579 { 1580 if ((elemno = (int) ulFromVal(tval)) < 0) 1581 { 1582 werror (E_BAD_DESIGNATOR); 1583 elemno = 0; /* arbitrary fixup */ 1584 } 1585 } 1586 $$ = newDesignation(DESIGNATOR_ARRAY, &elemno); 1587 } 1588 | '.' identifier { $$ = newDesignation(DESIGNATOR_STRUCT,$2); } 1589 ; 1590 1591 static_assert_declaration 1592 : STATIC_ASSERT '(' constant_expr ',' STRING_LITERAL ')' ';' 1593 { 1594 value *val = constExprValue ($3, TRUE); 1595 if (!val) 1596 werror (E_CONST_EXPECTED); 1597 else if (!ulFromVal(val)) 1598 werror (W_STATIC_ASSERTION, $5); 1599 } 1600 | STATIC_ASSERT '(' constant_expr ')' ';' 1601 { 1602 value *val = constExprValue ($3, TRUE); 1603 if (!options.std_c2x) 1604 werror (E_STATIC_ASSERTION_C2X); 1605 if (!val) 1606 werror (E_CONST_EXPECTED); 1607 else if (!ulFromVal(val)) 1608 werror (W_STATIC_ASSERTION_2); 1609 } 1610 ; 1611 1612 attribute_specifier_sequence 1613 : attribute_specifier_sequence attribute_specifier 1614 | attribute_specifier 1615 ; 1616 1617 attribute_specifier_sequence_opt 1618 : /* empty */ 1619 | attribute_specifier_sequence 1620 ; 1621 1622 attribute_specifier 1623 : '[' '[' attribute_list ']' ']' 1624 { 1625 if (!options.std_c2x) 1626 werror(E_ATTRIBUTE_C2X); 1627 } 1628 ; 1629 1630 attribute_list 1631 : /* empty */ 1632 | attribute 1633 | attribute_list ',' 1634 | attribute_list ',' attribute 1635 ; 1636 1637 attribute 1638 : attribute_token 1639 | attribute_token attribute_argument_clause 1640 ; 1641 1642 attribute_token 1643 : identifier 1644 | identifier ATTRIBCOLON identifier 1645 ; 1646 1647 attribute_argument_clause 1648 : '(' ')' 1649 | '(' balanced_token_sequence ')' 1650 ; 1651 1652 balanced_token_sequence 1653 : balanced_token 1654 | balanced_token_sequence balanced_token 1655 ; 1656 1657 balanced_token 1658 : identifier 1659 | STRING_LITERAL 1660 ; 1661 1662 /* C2X A.2.3 Statements */ 1663 1664 statement 1665 : labeled_statement 1666 | expression_statement 1667 | attribute_specifier_sequence_opt compound_statement 1668 { 1669 $$ = $2; 1670 } 1671 | attribute_specifier_sequence_opt selection_statement 1672 { 1673 $$ = $2; 1674 } 1675 | attribute_specifier_sequence_opt iteration_statement 1676 { 1677 $$ = $2; 1678 } 1679 | attribute_specifier_sequence_opt jump_statement 1680 { 1681 $$ = $2; 1682 } 1683 | critical_statement 1684 | asm_statement 1685 ; 1686 1687 labeled_statement 1688 : label statement { if ($1) {$$ = $1; $1->right = $2;} else $$ = newNode (BLOCK, NULL, NULL); } 1689 | attribute_specifier_sequence label statement { if ($2) {$$ = $2; $2->right = $3;} else $$ = newNode (BLOCK, NULL, NULL); } 1690 | label '}' 1691 { /* Support a label without a statement at the end of a */ 1692 /* compound statement as a SDCC extension. Include the */ 1693 /* closing brace as part of the rule to avoid an */ 1694 /* unacceptably large number of shift/reduce conflicts */ 1695 /* and then reinsert it to be parsed a second time. */ 1696 werror(W_LABEL_WITHOUT_STATEMENT); 1697 $$ = $1; 1698 yychar = '}'; 1699 } 1700 ; 1701 1702 label 1703 : identifier ':' { $$ = createLabel($1,NULL); 1704 $1->isitmp = 0; } 1705 | CASE constant_expr ':' 1706 { 1707 if (STACK_EMPTY(swStk)) 1708 $$ = createCase(NULL,$2,NULL); 1709 else 1710 $$ = createCase(STACK_PEEK(swStk),$2,NULL); 1711 } 1712 | DEFAULT { $<asts>$ = newNode(DEFAULT,NULL,NULL); } ':' 1713 { 1714 if (STACK_EMPTY(swStk)) 1715 $$ = createDefault(NULL,$<asts>2,NULL); 1716 else 1717 $$ = createDefault(STACK_PEEK(swStk),$<asts>2,NULL); 1718 } 1719 ; 1720 1721 start_block 1722 : '{' 1723 { 1724 NestLevel += LEVEL_UNIT; 1725 STACK_PUSH(blockNum, currBlockno); 1726 btree_add_child(currBlockno, ++blockNo); 1727 currBlockno = blockNo; 1728 ignoreTypedefType = 0; 1729 } 1730 ; 1731 1732 end_block 1733 : '}' 1734 { 1735 NestLevel -= LEVEL_UNIT; 1736 currBlockno = STACK_POP(blockNum); 1737 } 1738 ; 1739 1740 compound_statement 1741 : start_block end_block { $$ = createBlock(NULL, NULL); } 1742 | start_block block_item_list end_block 1743 { 1744 $$ = $2; 1745 cleanUpLevel(StructTab, NestLevel + LEVEL_UNIT); 1746 } 1747 | error ';' { $$ = NULL; } 1748 ; 1749 1750 block_item_list 1751 : statements_and_implicit { $$ = createBlock(NULL, $1); } 1752 | declaration_list { $$ = createBlock($1, NULL); } 1753 | declaration_list statements_and_implicit { $$ = createBlock($1, $2); } 1754 ; 1755 1756 expression_statement 1757 : expr_opt ';' 1758 | attribute_specifier_sequence expr ';' { $$ = $2; seqPointNo++;} 1759 ; 1760 1761 selection_statement 1762 : IF '(' expr ')' { seqPointNo++;} statement else_statement 1763 { 1764 noLineno++; 1765 $$ = createIf ($3, $6, $7 ); 1766 $$->lineno = $3->lineno; 1767 $$->filename = $3->filename; 1768 noLineno--; 1769 } 1770 | SWITCH '(' expr ')' { 1771 ast *ex; 1772 static int swLabel = 0; 1773 1774 seqPointNo++; 1775 /* create a node for expression */ 1776 ex = newNode(SWITCH,$3,NULL); 1777 STACK_PUSH(swStk,ex); /* save it in the stack */ 1778 ex->values.switchVals.swNum = swLabel; 1779 1780 /* now create the label */ 1781 SNPRINTF(lbuff, sizeof(lbuff), 1782 "_swBrk_%d",swLabel++); 1783 $<sym>$ = newSymbol(lbuff,NestLevel); 1784 /* put label in the break stack */ 1785 STACK_PUSH(breakStack,$<sym>$); 1786 } 1787 statement { 1788 /* get back the switch form the stack */ 1789 $$ = STACK_POP(swStk); 1790 $$->right = newNode (NULLOP,$6,createLabel($<sym>5,NULL)); 1791 STACK_POP(breakStack); 1792 } 1793 ; 1794 1795 iteration_statement 1796 : while '(' expr ')' { seqPointNo++;} statement 1797 { 1798 noLineno++; 1799 $$ = createWhile ( $1, STACK_POP(continueStack), 1800 STACK_POP(breakStack), $3, $6 ); 1801 $$->lineno = $1->lineDef; 1802 $$->filename = $1->fileDef; 1803 noLineno--; 1804 } 1805 | do statement WHILE '(' expr ')' ';' 1806 { 1807 seqPointNo++; 1808 noLineno++; 1809 $$ = createDo ( $1 , STACK_POP(continueStack), 1810 STACK_POP(breakStack), $5, $2); 1811 $$->lineno = $1->lineDef; 1812 $$->filename = $1->fileDef; 1813 noLineno--; 1814 } 1815 | for '(' expr_opt ';' expr_opt ';' expr_opt ')' statement 1816 { 1817 noLineno++; 1818 1819 $$ = newNode(FOR,$9,NULL); 1820 AST_FOR($$,trueLabel) = $1; 1821 AST_FOR($$,continueLabel) = STACK_POP(continueStack); 1822 AST_FOR($$,falseLabel) = STACK_POP(breakStack); 1823 AST_FOR($$,condLabel) = STACK_POP(forStack); 1824 AST_FOR($$,initExpr) = $3; 1825 AST_FOR($$,condExpr) = $5; 1826 AST_FOR($$,loopExpr) = $7; 1827 1828 /* This continue label is not at the correct location, */ 1829 /* but we need to create it now for proper binding. The */ 1830 /* code that handles the FOR node will move it to the */ 1831 /* proper location inside the for loop. */ 1832 if (AST_FOR($$,continueLabel)->isref) 1833 $$->right = createLabel(AST_FOR($$,continueLabel),NULL); 1834 $$ = newNode(NULLOP,$$,createLabel(AST_FOR($$,falseLabel),NULL)); 1835 noLineno--; 1836 1837 NestLevel -= LEVEL_UNIT; 1838 currBlockno = STACK_POP(blockNum); 1839 } 1840 | for '(' declaration expr_opt ';' expr_opt ')' 1841 { 1842 if (!options.std_c99) 1843 werror (E_FOR_INITAL_DECLARATION_C99); 1844 1845 if ( $3 && IS_TYPEDEF($3->etype)) 1846 allocVariables ($3); 1847 ignoreTypedefType = 0; 1848 addSymChain(&$3); 1849 } 1850 statement 1851 { 1852 1853 noLineno++; 1854 1855 $$ = newNode(FOR,$9,NULL); 1856 AST_FOR($$,trueLabel) = $1; 1857 AST_FOR($$,continueLabel) = STACK_POP(continueStack); 1858 AST_FOR($$,falseLabel) = STACK_POP(breakStack); 1859 AST_FOR($$,condLabel) = STACK_POP(forStack); 1860 AST_FOR($$,initExpr) = 0; 1861 AST_FOR($$,condExpr) = $4; 1862 AST_FOR($$,loopExpr) = $6; 1863 1864 /* This continue label is not at the correct location, */ 1865 /* but we need to create it now for proper binding. The */ 1866 /* code that handles the FOR node will move it to the */ 1867 /* proper location inside the for loop. */ 1868 if (AST_FOR($$,continueLabel)->isref) 1869 $$->right = createLabel(AST_FOR($$,continueLabel),NULL); 1870 $$ = createBlock($3, newNode(NULLOP,$$,createLabel(AST_FOR($$,falseLabel),NULL))); 1871 cleanUpLevel(StructTab, NestLevel + LEVEL_UNIT); 1872 noLineno--; 1873 1874 NestLevel -= LEVEL_UNIT; 1875 currBlockno = STACK_POP(blockNum); 1876 } 1877 ; 1878 1879 jump_statement 1880 : GOTO identifier ';' { 1881 if (inCriticalBlock) { 1882 werror(E_INVALID_CRITICAL); 1883 $$ = NULL; 1884 } else { 1885 $2->islbl = 1; 1886 $$ = newAst_VALUE(symbolVal($2)); 1887 $$ = newNode(GOTO,$$,NULL); 1888 } 1889 } 1890 | CONTINUE ';' { 1891 /* make sure continue is in context */ 1892 if (STACK_EMPTY(continueStack) || STACK_PEEK(continueStack) == NULL) { 1893 werror(E_BREAK_CONTEXT); 1894 $$ = NULL; 1895 } 1896 else { 1897 $$ = newAst_VALUE(symbolVal(STACK_PEEK(continueStack))); 1898 $$ = newNode(GOTO,$$,NULL); 1899 /* mark the continue label as referenced */ 1900 STACK_PEEK(continueStack)->isref = 1; 1901 } 1902 } 1903 | BREAK ';' { 1904 if (STACK_EMPTY(breakStack) || STACK_PEEK(breakStack) == NULL) { 1905 werror(E_BREAK_CONTEXT); 1906 $$ = NULL; 1907 } else { 1908 $$ = newAst_VALUE(symbolVal(STACK_PEEK(breakStack))); 1909 $$ = newNode(GOTO,$$,NULL); 1910 STACK_PEEK(breakStack)->isref = 1; 1911 } 1912 } 1913 | RETURN ';' { 1914 seqPointNo++; 1915 if (inCriticalBlock) { 1916 werror(E_INVALID_CRITICAL); 1917 $$ = NULL; 1918 } else { 1919 $$ = newNode(RETURN,NULL,NULL); 1920 } 1921 } 1922 | RETURN expr ';' { 1923 seqPointNo++; 1924 if (inCriticalBlock) { 1925 werror(E_INVALID_CRITICAL); 1926 $$ = NULL; 1927 } else { 1928 $$ = newNode(RETURN,NULL,$2); 1929 } 1930 } 1931 ; 1932 1933 /* C2X A.2.4 External definitions */ 1934 1935 translation_unit 1936 : external_declaration 1937 | translation_unit external_declaration 1938 ; 1939 1940 external_declaration 1941 : function_definition 1942 { 1943 // blockNo = 0; 1944 } 1945 | declaration 1946 { 1947 ignoreTypedefType = 0; 1948 if ($1 && $1->type && IS_FUNC($1->type)) 1949 { 1950 /* The only legal storage classes for 1951 * a function prototype (declaration) 1952 * are extern and static. extern is the 1953 * default. Thus, if this function isn't 1954 * explicitly marked static, mark it 1955 * extern. 1956 */ 1957 if ($1->etype && IS_SPEC($1->etype) && !SPEC_STAT($1->etype)) 1958 { 1959 SPEC_EXTR($1->etype) = 1; 1960 } 1961 } 1962 addSymChain (&$1); 1963 allocVariables ($1); 1964 cleanUpLevel (SymbolTab, 1); 1965 } 1966 | addressmod 1967 { 1968 /* These empty braces here are apparently required by some version of GNU bison on MS Windows. See bug #2858. */ 1969 } 1970 ; 1971 1972 function_definition 1973 : declarator 1974 { /* function type not specified */ 1975 /* assume it to be 'int' */ 1976 addDecl($1,0,newIntLink()); 1977 $1 = createFunctionDecl($1); 1978 if ($1) 1979 { 1980 if (FUNC_ISCRITICAL ($1->type)) 1981 inCriticalFunction = 1; 1982 strncpy (function_name, $1->name, sizeof (function_name) - 4); 1983 memset (function_name + sizeof (function_name) - 4, 0x00, 4); 1984 } 1985 } 1986 function_body 1987 { 1988 $$ = createFunction($1,$3); 1989 if ($1 && FUNC_ISCRITICAL ($1->type)) 1990 inCriticalFunction = 0; 1991 } 1992 | declaration_specifiers declarator 1993 { 1994 sym_link *p = copyLinkChain($1); 1995 pointerTypes($2->type,p); 1996 addDecl($2,0,p); 1997 $2 = createFunctionDecl($2); 1998 if ($2) 1999 { 2000 if (FUNC_ISCRITICAL ($2->type)) 2001 inCriticalFunction = 1; 2002 // warn for loss of calling convention for inlined functions. 2003 if (FUNC_ISINLINE ($2->type) && 2004 ( FUNC_ISZ88DK_CALLEE ($2->type) || FUNC_ISZ88DK_FASTCALL ($2->type) || 2005 FUNC_BANKED ($2->type) || FUNC_REGBANK ($2->type) || 2006 FUNC_ISOVERLAY ($2->type) || FUNC_ISISR ($2->type) )) 2007 werror (W_INLINE_FUNCATTR, $2->name); 2008 strncpy (function_name, $2->name, sizeof (function_name) - 4); 2009 memset (function_name + sizeof (function_name) - 4, 0x00, 4); 2010 } 2011 } 2012 function_body 2013 { 2014 $$ = createFunction($2,$4); 2015 if ($2 && FUNC_ISCRITICAL ($2->type)) 2016 inCriticalFunction = 0; 2017 } 2018 ; 2019 2020 function_body 2021 : compound_statement 2022 | declaration_list compound_statement 2023 { 2024 werror (E_OLD_STYLE, ($1 ? $1->name: "")); 2025 exit (1); 2026 } 2027 ; 2028 2029 /* SDCC-specific stuff */ 2030 2031 file 2032 : /* empty */ 2033 { 2034 werror(W_EMPTY_SOURCE_FILE); 2035 } 2036 | translation_unit 2037 ; 2038 2039 2040 2041 2042 function_attribute 2043 : function_attributes 2044 | function_attributes function_attribute { $$ = mergeSpec($1,$2,"function_attribute"); } 2045 ; 2046 2047 function_attributes 2048 : USING constant_expr { 2049 $$ = newLink(SPECIFIER); 2050 FUNC_REGBANK($$) = (int) ulFromVal(constExprValue($2,TRUE)); 2051 } 2052 | REENTRANT { $$ = newLink (SPECIFIER); 2053 FUNC_ISREENT($$)=1; 2054 } 2055 | CRITICAL { $$ = newLink (SPECIFIER); 2056 FUNC_ISCRITICAL($$) = 1; 2057 } 2058 | NAKED { $$ = newLink (SPECIFIER); 2059 FUNC_ISNAKED($$)=1; 2060 } 2061 | JAVANATIVE { $$ = newLink (SPECIFIER); 2062 FUNC_ISJAVANATIVE($$)=1; 2063 } 2064 | OVERLAY { $$ = newLink (SPECIFIER); 2065 FUNC_ISOVERLAY($$)=1; 2066 } 2067 | NONBANKED {$$ = newLink (SPECIFIER); 2068 FUNC_NONBANKED($$) = 1; 2069 if (FUNC_BANKED($$)) { 2070 werror(W_BANKED_WITH_NONBANKED); 2071 } 2072 } 2073 | SHADOWREGS {$$ = newLink (SPECIFIER); 2074 FUNC_ISSHADOWREGS($$) = 1; 2075 } 2076 | SD_WPARAM {$$ = newLink (SPECIFIER); 2077 FUNC_ISWPARAM($$) = 1; 2078 } 2079 | BANKED {$$ = newLink (SPECIFIER); 2080 FUNC_BANKED($$) = 1; 2081 if (FUNC_NONBANKED($$)) { 2082 werror(W_BANKED_WITH_NONBANKED); 2083 } 2084 } 2085 | Interrupt_storage 2086 { 2087 $$ = newLink (SPECIFIER); 2088 FUNC_INTNO($$) = $1; 2089 FUNC_ISISR($$) = 1; 2090 } 2091 | TRAP 2092 { 2093 $$ = newLink (SPECIFIER); 2094 FUNC_INTNO($$) = INTNO_TRAP; 2095 FUNC_ISISR($$) = 1; 2096 } 2097 | SMALLC { $$ = newLink (SPECIFIER); 2098 FUNC_ISSMALLC($$) = 1; 2099 } 2100 | Z88DK_FASTCALL { $$ = newLink (SPECIFIER); 2101 FUNC_ISZ88DK_FASTCALL($$) = 1; 2102 } 2103 | Z88DK_CALLEE { $$ = newLink (SPECIFIER); 2104 FUNC_ISZ88DK_CALLEE($$) = 1; 2105 } 2106 | Z88DK_PARAMS_OFFSET '(' constant_expr ')' 2107 { 2108 value *offset_v = constExprValue ($3, TRUE); 2109 int offset = 0; 2110 $$ = newLink(SPECIFIER); 2111 if ( offset_v ) 2112 offset = ulFromVal(offset_v); 2113 $$->funcAttrs.z88dk_params_offset = offset; 2114 } 2115 | Z88DK_SHORTCALL '(' constant_expr ',' constant_expr ')' 2116 { 2117 value *rst_v = constExprValue ($3, TRUE); 2118 value *value_v = constExprValue ($5, TRUE); 2119 int rst = -1, value = -1; 2120 $$ = newLink(SPECIFIER); 2121 2122 if ( rst_v ) 2123 rst = ulFromVal(rst_v); 2124 if ( value_v ) 2125 value = ulFromVal(value_v); 2126 2127 if ( rst < 0 || rst > 56 || ( rst % 8 ) ) 2128 { 2129 werror(E_SHORTCALL_INVALID_VALUE, "rst", rst); 2130 } 2131 if ( value < 0 || value > 0xfff ) 2132 { 2133 werror(E_SHORTCALL_INVALID_VALUE, "value", value); 2134 } 2135 $$->funcAttrs.z88dk_shortcall_rst = rst; 2136 $$->funcAttrs.z88dk_shortcall_val = value; 2137 FUNC_ISZ88DK_SHORTCALL($$) = 1; 2138 } 2139 | PRESERVES_REGS '(' identifier_list ')' 2140 { 2141 const struct symbol *regsym; 2142 $$ = newLink (SPECIFIER); 2143 2144 for(regsym = $3; regsym; regsym = regsym->next) 2145 { 2146 int regnum; 2147 2148 if (!port->getRegByName || ((regnum = port->getRegByName(regsym->name)) < 0)) 2149 werror (W_UNKNOWN_REG, regsym->name); 2150 else 2151 $$->funcAttrs.preserved_regs[regnum] = TRUE; 2152 } 2153 } 2154 ; 2155 2156 offsetof_member_designator 2157 : identifier { $$ = newAst_VALUE (symbolVal ($1)); } 2158 | offsetof_member_designator '.' { ignoreTypedefType = 1; } identifier 2159 { 2160 ignoreTypedefType = 0; 2161 $4 = newSymbol ($4->name, NestLevel); 2162 $4->implicit = 1; 2163 $$ = newNode ('.', $1, newAst_VALUE (symbolVal ($4))); 2164 } 2165 | offsetof_member_designator '[' expr ']' 2166 { 2167 $$ = newNode ('[', $1, $3); 2168 } 2169 ; 2170 2171 string_literal_val 2172 : STRING_LITERAL { 2173 int cnt = 1; 2174 int max = 253, min = 1; 2175 char fb[256]; 2176 /* refer to support/cpp/libcpp/macro.c for details */ 2177 while ((((int) ($1[cnt] & 0xff)) & 0xff) == 0xff) 2178 cnt++; 2179 2180 if (cnt <= max) 2181 { 2182 $$ = newAst_VALUE (strVal ($1)); 2183 } 2184 else 2185 { 2186 memset (fb, 0x00, sizeof (fb)); 2187 fb[0] = '"'; 2188 strncpy (fb + 1, function_name, max - min + 1); 2189 fb[max + 1] = '"'; 2190 fb[max + 2] = 0; 2191 fb[strlen (fb)] = '"'; 2192 fb[strlen (fb) + 1] = 0; 2193 $$ = newAst_VALUE (strVal (fb)); 2194 } 2195 } 2196 ; 2197 2198 Interrupt_storage 2199 : INTERRUPT { $$ = INTNO_UNSPEC; } 2200 | INTERRUPT constant_expr 2201 { 2202 value *val = constExprValue($2,TRUE); 2203 int intno = (int) ulFromVal(val); 2204 if (val && (intno >= 0) && (intno <= INTNO_MAX)) 2205 $$ = intno; 2206 else 2207 { 2208 werror(E_INT_BAD_INTNO, intno); 2209 $$ = INTNO_UNSPEC; 2210 } 2211 } 2212 ; 2213 2214 sfr_reg_bit 2215 : SBIT { 2216 $$ = newLink(SPECIFIER); 2217 SPEC_NOUN($$) = V_SBIT; 2218 SPEC_SCLS($$) = S_SBIT; 2219 SPEC_BLEN($$) = 1; 2220 SPEC_BSTR($$) = 0; 2221 ignoreTypedefType = 1; 2222 } 2223 | sfr_attributes 2224 ; 2225 2226 sfr_attributes 2227 : SFR { 2228 $$ = newLink(SPECIFIER); 2229 FUNC_REGBANK($$) = 0; 2230 SPEC_NOUN($$) = V_CHAR; 2231 SPEC_SCLS($$) = S_SFR; 2232 SPEC_USIGN($$) = 1; 2233 ignoreTypedefType = 1; 2234 } 2235 | SFR BANKED { 2236 $$ = newLink(SPECIFIER); 2237 FUNC_REGBANK($$) = 1; 2238 SPEC_NOUN($$) = V_CHAR; 2239 SPEC_SCLS($$) = S_SFR; 2240 SPEC_USIGN($$) = 1; 2241 ignoreTypedefType = 1; 2242 } 2243 ; 2244 2245 sfr_attributes 2246 : SFR16 { 2247 $$ = newLink(SPECIFIER); 2248 FUNC_REGBANK($$) = 0; 2249 SPEC_NOUN($$) = V_INT; 2250 SPEC_SCLS($$) = S_SFR; 2251 SPEC_USIGN($$) = 1; 2252 ignoreTypedefType = 1; 2253 } 2254 ; 2255 2256 sfr_attributes 2257 : SFR32 { 2258 $$ = newLink(SPECIFIER); 2259 FUNC_REGBANK($$) = 0; 2260 SPEC_NOUN($$) = V_INT; 2261 SPEC_SCLS($$) = S_SFR; 2262 SPEC_LONG($$) = 1; 2263 SPEC_USIGN($$) = 1; 2264 ignoreTypedefType = 1; 2265 } 2266 ; 2267 2268 opt_stag 2269 : stag 2270 | { /* synthesize a name add to structtable */ 2271 ignoreTypedefType = 0; 2272 $$ = newStruct(genSymName(NestLevel)); 2273 $$->level = NestLevel; 2274 $$->block = currBlockno; 2275 $$->tagsym = NULL; 2276 //addSym (StructTab, $$, $$->tag, $$->level, currBlockno, 0); 2277 } 2278 ; 2279 2280 stag 2281 : identifier 2282 { /* add name to structure table */ 2283 ignoreTypedefType = 0; 2284 $$ = newStruct($1->name); 2285 $$->level = NestLevel; 2286 $$->block = currBlockno; 2287 $$->tagsym = $1; 2288 //$$ = findSymWithBlock (StructTab, $1, currBlockno); 2289 //if (! $$ ) 2290 // { 2291 // $$ = newStruct($1->name); 2292 // $$->level = NestLevel; 2293 // $$->tagsym = $1; 2294 // //addSym (StructTab, $$, $$->tag, $$->level, currBlockno, 0); 2295 // } 2296 } 2297 ; 2298 2299 opt_assign_expr 2300 : '=' constant_expr 2301 { 2302 value *val; 2303 2304 val = constExprValue($2, TRUE); 2305 if (!IS_INT(val->type) && !IS_CHAR(val->type) && !IS_BOOL(val->type)) 2306 { 2307 werror(E_ENUM_NON_INTEGER); 2308 SNPRINTF(lbuff, sizeof(lbuff), "%d", (int) ulFromVal(val)); 2309 val = constVal(lbuff); 2310 } 2311 $$ = cenum = val; 2312 } 2313 | { 2314 if (cenum) 2315 { 2316 SNPRINTF(lbuff, sizeof(lbuff), "%d", (int) ulFromVal(cenum)+1); 2317 $$ = cenum = constVal(lbuff); 2318 } 2319 else 2320 { 2321 $$ = cenum = constCharVal(0); 2322 } 2323 } 2324 ; 2325 2326 type_specifier_list : type_specifier_list_ { $$ = finalizeSpec($1); }; 2327 2328 type_specifier_list_ 2329 : type_specifier 2330 //| type_specifier_list_ type_specifier { $$ = mergeSpec ($1,$2, "type_specifier_list"); } 2331 | type_specifier_list_ type_specifier { 2332 /* if the decl $2 is not a specifier */ 2333 /* find the spec and replace it */ 2334 $$ = mergeDeclSpec($1, $2, "type_specifier_list type_specifier skipped"); 2335 } 2336 ; 2337 2338 identifier_list 2339 : identifier 2340 | identifier_list ',' identifier 2341 { 2342 $3->next = $1; 2343 $$ = $3; 2344 } 2345 ; 2346 2347 type_name 2348 : declaration_specifiers 2349 { 2350 if (IS_SPEC ($1) && !IS_VALID_PARAMETER_STORAGE_CLASS_SPEC ($1)) 2351 { 2352 werror (E_STORAGE_CLASS_FOR_PARAMETER, "type name"); 2353 } 2354 $$ = $1; ignoreTypedefType = 0; 2355 } 2356 | declaration_specifiers abstract_declarator 2357 { 2358 /* go to the end of the list */ 2359 sym_link *p; 2360 2361 if (IS_SPEC ($1) && !IS_VALID_PARAMETER_STORAGE_CLASS_SPEC ($1)) 2362 { 2363 werror (E_STORAGE_CLASS_FOR_PARAMETER, "type name"); 2364 } 2365 pointerTypes ($2,$1); 2366 for (p = $2; p && p->next; p = p->next) 2367 ; 2368 if (!p) 2369 { 2370 werror(E_SYNTAX_ERROR, yytext); 2371 } 2372 else 2373 { 2374 p->next = $1; 2375 } 2376 $$ = $2; 2377 ignoreTypedefType = 0; 2378 } 2379 ; 2380 2381 critical 2382 : CRITICAL { 2383 if (inCriticalFunction || inCriticalBlock) 2384 werror(E_INVALID_CRITICAL); 2385 inCriticalBlock = 1; 2386 STACK_PUSH(continueStack,NULL); 2387 STACK_PUSH(breakStack,NULL); 2388 $$ = NULL; 2389 } 2390 ; 2391 2392 critical_statement 2393 : critical statement { 2394 STACK_POP(breakStack); 2395 STACK_POP(continueStack); 2396 $$ = newNode(CRITICAL,$2,NULL); 2397 inCriticalBlock = 0; 2398 } 2399 ; 2400 2401 statements_and_implicit 2402 : statement_list 2403 | statement_list implicit_block 2404 { 2405 $$ = newNode(NULLOP, $1, $2); 2406 if (!options.std_c99) 2407 werror(E_DECL_AFTER_STATEMENT_C99); 2408 } 2409 ; 2410 2411 declaration_after_statement 2412 : { 2413 NestLevel += SUBLEVEL_UNIT; 2414 STACK_PUSH(blockNum, currBlockno); 2415 btree_add_child(currBlockno, ++blockNo); 2416 currBlockno = blockNo; 2417 ignoreTypedefType = 0; 2418 } 2419 declaration_list { $$ = $2; } 2420 ; 2421 2422 implicit_block 2423 : declaration_after_statement statements_and_implicit 2424 { 2425 NestLevel -= SUBLEVEL_UNIT; 2426 currBlockno = STACK_POP(blockNum); 2427 $$ = createBlock($1, $2); 2428 cleanUpLevel(StructTab, NestLevel + SUBLEVEL_UNIT); 2429 } 2430 | declaration_after_statement 2431 { 2432 NestLevel -= SUBLEVEL_UNIT; 2433 currBlockno = STACK_POP(blockNum); 2434 $$ = createBlock($1, NULL); 2435 cleanUpLevel(StructTab, NestLevel + SUBLEVEL_UNIT); 2436 } 2437 ; 2438 2439 declaration_list 2440 : declaration 2441 { 2442 /* if this is typedef declare it immediately */ 2443 if ( $1 && IS_TYPEDEF($1->etype)) { 2444 allocVariables ($1); 2445 $$ = NULL; 2446 } 2447 else 2448 $$ = $1; 2449 ignoreTypedefType = 0; 2450 addSymChain(&$1); 2451 } 2452 2453 | declaration_list declaration 2454 { 2455 symbol *sym; 2456 2457 /* if this is a typedef */ 2458 if ($2 && IS_TYPEDEF($2->etype)) { 2459 allocVariables ($2); 2460 $$ = $1; 2461 } 2462 else { 2463 /* get to the end of the previous decl */ 2464 if ( $1 ) { 2465 $$ = sym = $1; 2466 while (sym->next) 2467 sym = sym->next; 2468 sym->next = $2; 2469 } 2470 else 2471 $$ = $2; 2472 } 2473 ignoreTypedefType = 0; 2474 addSymChain(&$2); 2475 } 2476 ; 2477 2478 statement_list 2479 : statement 2480 | statement_list statement { $$ = newNode(NULLOP,$1,$2);} 2481 ; 2482 2483 else_statement 2484 : ELSE statement { $$ = $2; } 2485 | { $$ = NULL; } 2486 ; 2487 2488 2489 2490 while : WHILE { /* create and push the continue , break & body labels */ 2491 static int Lblnum = 0; 2492 /* continue */ 2493 SNPRINTF (lbuff, sizeof(lbuff), "_whilecontinue_%d",Lblnum); 2494 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel)); 2495 /* break */ 2496 SNPRINTF (lbuff, sizeof(lbuff), "_whilebreak_%d",Lblnum); 2497 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel)); 2498 /* body */ 2499 SNPRINTF (lbuff, sizeof(lbuff), "_whilebody_%d",Lblnum++); 2500 $$ = newSymbol(lbuff,NestLevel); 2501 } 2502 ; 2503 2504 do : DO { /* create and push the continue , break & body Labels */ 2505 static int Lblnum = 0; 2506 2507 /* continue */ 2508 SNPRINTF(lbuff, sizeof(lbuff), "_docontinue_%d",Lblnum); 2509 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel)); 2510 /* break */ 2511 SNPRINTF(lbuff, sizeof(lbuff), "_dobreak_%d",Lblnum); 2512 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel)); 2513 /* do body */ 2514 SNPRINTF(lbuff, sizeof(lbuff), "_dobody_%d",Lblnum++); 2515 $$ = newSymbol (lbuff,NestLevel); 2516 } 2517 ; 2518 2519 for : FOR { /* create & push continue, break & body labels */ 2520 static int Lblnum = 0; 2521 2522 NestLevel += LEVEL_UNIT; 2523 STACK_PUSH(blockNum, currBlockno); 2524 btree_add_child(currBlockno, ++blockNo); 2525 currBlockno = blockNo; 2526 ignoreTypedefType = 0; 2527 2528 /* continue */ 2529 SNPRINTF(lbuff, sizeof(lbuff), "_forcontinue_%d",Lblnum); 2530 STACK_PUSH(continueStack,newSymbol(lbuff,NestLevel)); 2531 /* break */ 2532 SNPRINTF(lbuff, sizeof(lbuff), "_forbreak_%d",Lblnum); 2533 STACK_PUSH(breakStack,newSymbol(lbuff,NestLevel)); 2534 /* body */ 2535 SNPRINTF(lbuff, sizeof(lbuff), "_forbody_%d",Lblnum); 2536 $$ = newSymbol(lbuff,NestLevel); 2537 /* condition */ 2538 SNPRINTF(lbuff, sizeof(lbuff), "_forcond_%d",Lblnum++); 2539 STACK_PUSH(forStack,newSymbol(lbuff,NestLevel)); 2540 } 2541 ; 2542 2543 asm_string_literal 2544 : STRING_LITERAL 2545 ; 2546 2547 asm_statement 2548 : ASM '(' asm_string_literal ')' ';' 2549 { 2550 ast *ex; 2551 2552 seqPointNo++; 2553 ex = newNode(INLINEASM, NULL, NULL); 2554 ex->values.inlineasm = strdup(copyStr ($3, NULL)); 2555 seqPointNo++; 2556 $$ = ex; 2557 } 2558 | INLINEASM ';' 2559 { 2560 ast *ex; 2561 2562 seqPointNo++; 2563 ex = newNode(INLINEASM, NULL, NULL); 2564 ex->values.inlineasm = strdup($1); 2565 seqPointNo++; 2566 $$ = ex; 2567 } 2568 ; 2569 2570 addressmod 2571 : ADDRESSMOD identifier identifier ';' { 2572 symbol *sym; 2573 if ((sym = findSymWithLevel (AddrspaceTab, $3)) && sym->level == $3->level) 2574 werrorfl (sym->fileDef, sym->lineDef, E_PREVIOUS_DEF); 2575 if (!findSymWithLevel (SymbolTab, $2)) 2576 werror (E_ID_UNDEF, $2->name); 2577 addSym (AddrspaceTab, $3, $3->name, $3->level, $3->block, 0); 2578 sym = findSymWithLevel (AddrspaceTab, $3); 2579 sym->addressmod[0] = findSymWithLevel (SymbolTab, $2); 2580 sym->addressmod[1] = 0; 2581 } 2582 | ADDRESSMOD identifier SD_CONST identifier ';' { 2583 symbol *sym; 2584 sym_link *type; 2585 if ((sym = findSymWithLevel (AddrspaceTab, $4)) && sym->level == $4->level) 2586 werrorfl (sym->fileDef, sym->lineDef, E_PREVIOUS_DEF); 2587 if (!findSymWithLevel (SymbolTab, $2)) 2588 werror (E_ID_UNDEF, $2->name); 2589 addSym (AddrspaceTab, $4, $4->name, $4->level, $4->block, 0); 2590 sym = findSymWithLevel (AddrspaceTab, $4); 2591 sym->addressmod[0] = findSymWithLevel (SymbolTab, $2); 2592 sym->addressmod[1] = 0; 2593 type = newLink (SPECIFIER); 2594 SPEC_CONST(type) = 1; 2595 sym->type = sym->etype = type; 2596 } 2597 ; 2598 2599 identifier 2600 : IDENTIFIER { $$ = newSymbol ($1, NestLevel); } 2601 ; 2602 %% 2603