1 // $Id: body.cpp,v 1.103 2004/08/18 08:49:15 elliott-oss Exp $
2 //
3 // This software is subject to the terms of the IBM Jikes Compiler
4 // License Agreement available at the following URL:
5 // http://ibm.com/developerworks/opensource/jikes.
6 // Copyright (C) 1996, 2004 IBM Corporation and others. All Rights Reserved.
7 // You must accept the terms of that agreement to use this software.
8 //
9
10 #include "platform.h"
11 #include "semantic.h"
12 #include "control.h"
13 #include "option.h"
14 #include "stream.h"
15
16 #ifdef HAVE_JIKES_NAMESPACE
17 namespace Jikes { // Open namespace Jikes block
18 #endif
19
ProcessBlockStatements(AstBlock * block_body)20 void Semantic::ProcessBlockStatements(AstBlock* block_body)
21 {
22 //
23 // An empty block that is not a switch block can complete normally
24 // iff it is reachable. A nonempty block that is not a switch
25 // block can complete normally iff the last statement in it can
26 // complete normally.
27 //
28 if (block_body -> NumStatements() == 0)
29 block_body -> can_complete_normally = block_body -> is_reachable;
30 else
31 {
32 //
33 // The first statement in a nonempty block that is not a
34 // switch block is reachable iff the block is reachable.
35 // Every other statement S in a nonempty block that is not a
36 // switch block is reachable iff the statement preceeding S
37 // can complete normally.
38 //
39 AstStatement* statement = block_body -> Statement(0);
40 statement -> is_reachable = block_body -> is_reachable;
41 AstStatement* first_unreachable_statement =
42 (AstStatement*) (statement -> is_reachable ? NULL : statement);
43 ProcessStatement(statement);
44 for (unsigned i = 1; i < block_body -> NumStatements(); i++)
45 {
46 AstStatement* previous_statement = statement;
47 statement = block_body -> Statement(i);
48 statement -> is_reachable =
49 previous_statement -> can_complete_normally;
50 if (! statement -> is_reachable &&
51 first_unreachable_statement == NULL)
52 {
53 first_unreachable_statement = statement;
54 }
55 ProcessStatement(statement);
56 }
57
58 if (statement -> can_complete_normally)
59 block_body -> can_complete_normally = true;
60
61 //
62 // If we have one or more unreachable statements that are contained in
63 // a reachable block then issue message. (If the enclosing block is
64 // not reachable the message will be issued later for the enclosing
65 // block.)
66 //
67 if (first_unreachable_statement &&
68 LocalBlockStack().TopBlock() -> is_reachable)
69 {
70 if (first_unreachable_statement == statement)
71 {
72 ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
73 statement);
74 }
75 else
76 {
77 ReportSemError(SemanticError::UNREACHABLE_STATEMENTS,
78 first_unreachable_statement -> LeftToken(),
79 statement -> RightToken());
80 }
81 }
82
83 //
84 // If an enclosed block has a higher max_variable_index than the
85 // current block, update max_variable_index in the current_block,
86 // accordingly.
87 //
88 BlockSymbol* block = block_body -> block_symbol;
89 if (block -> max_variable_index <
90 LocalBlockStack().TopMaxEnclosedVariableIndex())
91 {
92 block -> max_variable_index =
93 LocalBlockStack().TopMaxEnclosedVariableIndex();
94 }
95 }
96 }
97
98
ProcessBlock(Ast * stmt)99 void Semantic::ProcessBlock(Ast* stmt)
100 {
101 AstBlock* block_body = (AstBlock*) stmt;
102
103 AstBlock* enclosing_block = LocalBlockStack().TopBlock();
104
105 //
106 // Guess that the number of elements will not exceed the number of
107 // statements + 3. The +3 takes into account one label + one ForInit
108 // declaration and one extra something else.
109 //
110 int table_size = block_body -> NumStatements() + 3;
111 BlockSymbol* block =
112 LocalSymbolTable().Top() -> InsertBlockSymbol(table_size);
113 //
114 // enclosing_block is not present only when we are processing the block
115 // of a static initializer
116 //
117 block -> max_variable_index =
118 enclosing_block
119 ? enclosing_block -> block_symbol -> max_variable_index : 1;
120 LocalSymbolTable().Push(block -> Table());
121
122 block_body -> block_symbol = block;
123 block_body -> nesting_level = LocalBlockStack().Size();
124 LocalBlockStack().Push(block_body);
125
126 //
127 // Note that in constructing the Ast, the parser encloses each
128 // labeled statement in its own block. Therefore the declaration
129 // of this label will not conflict with the declaration of another
130 // label with the same name declared at the same nesting level.
131 //
132 // For example, the following sequence of statements is legal:
133 //
134 // l: a = b;
135 // l: b = c;
136 //
137 if (block_body -> label_opt != BAD_TOKEN)
138 {
139 NameSymbol* name_symbol =
140 lex_stream -> NameSymbol(block_body -> label_opt);
141 if (LocalSymbolTable().FindLabelSymbol(name_symbol))
142 {
143 ReportSemError(SemanticError::DUPLICATE_LABEL,
144 block_body -> label_opt,
145 name_symbol -> Name());
146 }
147 else
148 {
149 LabelSymbol* label =
150 LocalSymbolTable().Top() -> InsertLabelSymbol(name_symbol);
151 label -> block = block_body;
152 label -> nesting_level = block_body -> nesting_level;
153 }
154 }
155
156 ProcessBlockStatements(block_body);
157
158 LocalBlockStack().Pop();
159 LocalSymbolTable().Pop();
160
161 //
162 // Update the information for the block that immediately encloses the
163 // current block.
164 //
165 if (enclosing_block && (LocalBlockStack().TopMaxEnclosedVariableIndex() <
166 block -> max_variable_index))
167 {
168 LocalBlockStack().TopMaxEnclosedVariableIndex() =
169 block -> max_variable_index;
170 }
171
172 block -> CompressSpace(); // space optimization
173 }
174
175
WarnOfAccessibleFieldWithName(SemanticError::SemanticErrorKind problem,AstVariableDeclaratorId * name,NameSymbol * name_symbol,bool is_static)176 void Semantic::WarnOfAccessibleFieldWithName(SemanticError::SemanticErrorKind problem,
177 AstVariableDeclaratorId* name,
178 NameSymbol* name_symbol,
179 bool is_static)
180 {
181 TypeSymbol* this_type = ThisType();
182 for (TypeSymbol* type = this_type; type != 0; type = type -> super)
183 {
184 //
185 // Try to find a variable with the same name_symbol, first in the
186 // type itself, then in any of its implemented interfaces.
187 //
188 VariableSymbol* variable = type -> FindVariableSymbol(name_symbol);
189 for (unsigned i = 0; variable == 0 && i < type -> NumInterfaces(); ++i)
190 {
191 variable = type -> Interface(i) -> FindVariableSymbol(name_symbol);
192 }
193
194 //
195 // Warn if we found an accessible field with the same name_symbol.
196 //
197 if (variable && MemberAccessCheck(this_type, variable, 0))
198 {
199 // Ignore static variables if we're looking for non-static,
200 // and non-static if we're looking for static.
201 if (variable -> ACC_STATIC() != is_static)
202 {
203 continue;
204 }
205
206 TypeSymbol* containing_type = variable -> ContainingType();
207 ReportSemError(problem,
208 name -> identifier_token,
209 name_symbol -> Name(),
210 containing_type -> ContainingPackageName(),
211 containing_type -> ExternalName());
212 return;
213 }
214 }
215 }
216
217
ProcessLocalVariableStatement(Ast * stmt)218 void Semantic::ProcessLocalVariableStatement(Ast* stmt)
219 {
220 AstLocalVariableStatement* local_decl = (AstLocalVariableStatement*) stmt;
221 ProcessType(local_decl -> type);
222 TypeSymbol* field_type = local_decl -> type -> symbol;
223 AccessFlags access_flags = ProcessLocalModifiers(local_decl);
224
225 for (unsigned i = 0; i < local_decl -> NumVariableDeclarators(); i++)
226 {
227 AstVariableDeclarator* variable_declarator =
228 local_decl -> VariableDeclarator(i);
229 AstVariableDeclaratorId* name =
230 variable_declarator -> variable_declarator_name;
231 NameSymbol* name_symbol =
232 lex_stream -> NameSymbol(name -> identifier_token);
233
234 //
235 // According to JLS2 14.4.2, only check for a duplicate in
236 // the local class scope; don't worry about enclosing classes
237 //
238 VariableSymbol* duplicate =
239 LocalSymbolTable().FindVariableSymbol(name_symbol);
240 if (duplicate)
241 {
242 ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
243 name -> identifier_token, name_symbol -> Name(),
244 duplicate -> FileLoc());
245 }
246 else
247 {
248 WarnOfAccessibleFieldWithName(SemanticError::LOCAL_SHADOWS_FIELD,
249 name, name_symbol, ThisMethod() -> ACC_STATIC());
250 AstBlock* block = LocalBlockStack().TopBlock();
251 SymbolTable* table;
252 if (block -> Tag() == AstBlock::SWITCH)
253 {
254 //
255 // Local variables declared in a switch statement are in scope
256 // for the entire switch, rather than the nearest label (unlike
257 // local classes). Hence, we have to check if the top block is
258 // a switch statement, and use the next level up if so.
259 //
260 block = LocalBlockStack()[LocalBlockStack().Size() - 2];
261 table = LocalSymbolTable()[LocalSymbolTable().Size() - 2];
262 }
263 else table = LocalSymbolTable().Top();
264 VariableSymbol* symbol =
265 table -> InsertVariableSymbol(name_symbol);
266 variable_declarator -> symbol = symbol;
267
268 unsigned dims =
269 field_type -> num_dimensions + name -> NumBrackets();
270 symbol -> SetType(field_type -> GetArrayType(this, dims));
271 symbol -> SetFlags(access_flags);
272 symbol -> SetOwner(ThisMethod());
273 symbol -> declarator = variable_declarator;
274 symbol -> SetLocation();
275 symbol -> SetLocalVariableIndex(block -> block_symbol ->
276 max_variable_index++);
277 if (control.IsDoubleWordType(symbol -> Type()))
278 block -> block_symbol -> max_variable_index++;
279
280 //
281 // Warn against unconventional names. Note that there's no
282 // strong convention for final local variables, so we allow
283 // both the usual style for local variables and the usual
284 // style for constant fields. We recommend the local variable
285 // style, somewhat arbitrarily.
286 //
287 if (! symbol -> ACC_FINAL() &&
288 name_symbol -> IsBadStyleForVariable())
289 {
290 ReportSemError(SemanticError::UNCONVENTIONAL_VARIABLE_NAME,
291 name -> identifier_token, name_symbol -> Name());
292 }
293 else if (symbol -> ACC_FINAL() &&
294 name_symbol -> IsBadStyleForVariable() &&
295 name_symbol -> IsBadStyleForConstantField())
296 {
297 ReportSemError(SemanticError::UNCONVENTIONAL_VARIABLE_NAME,
298 name -> identifier_token, name_symbol -> Name());
299 }
300
301 ProcessVariableInitializer(variable_declarator);
302 }
303 }
304
305 //
306 // A local variable declaration statement can complete normally
307 // iff it is reachable.
308 //
309 local_decl -> can_complete_normally = local_decl -> is_reachable;
310 }
311
312
ProcessExpressionStatement(Ast * stmt)313 void Semantic::ProcessExpressionStatement(Ast* stmt)
314 {
315 AstExpressionStatement* expression_statement =
316 (AstExpressionStatement*) stmt;
317
318 ProcessExpression(expression_statement -> expression);
319
320 //
321 // An expression statement can complete normally iff it is reachable.
322 //
323 expression_statement -> can_complete_normally =
324 expression_statement -> is_reachable;
325 }
326
327
ProcessSynchronizedStatement(Ast * stmt)328 void Semantic::ProcessSynchronizedStatement(Ast* stmt)
329 {
330 AstSynchronizedStatement* synchronized_statement =
331 (AstSynchronizedStatement*) stmt;
332
333 //
334 // Notice that in the case of a complex string constant, it is
335 // vital to inline correctly; otherwise, we would not be using
336 // the correct object as the monitor.
337 //
338 ProcessExpressionOrStringConstant(synchronized_statement -> expression);
339
340 synchronized_statement -> block -> is_reachable =
341 synchronized_statement -> is_reachable;
342
343 if (synchronized_statement -> expression -> Type() -> Primitive() ||
344 synchronized_statement -> expression -> symbol == control.null_type)
345 {
346 ReportSemError(SemanticError::TYPE_NOT_REFERENCE,
347 synchronized_statement -> expression,
348 synchronized_statement -> expression -> Type() -> Name());
349 }
350
351 AstBlock* enclosing_block = LocalBlockStack().TopBlock();
352 AstBlock* block_body = synchronized_statement -> block;
353
354 //
355 // Synchronized blocks require one special local variable slot for the
356 // monitor. However, since a try-finally may require up to four slots, we
357 // reserve them all at this time. Otherwise, the sequence {synchronized;
358 // variable declaration; try-finally} within the same enclosing block will
359 // cause a VerifyError. The VM should not care if some of these special
360 // slots are unused.
361 //
362 // TODO: Is it worth optimizing this and try-finally to avoid wasting
363 // variable slots?
364 //
365 BlockSymbol* enclosing_block_symbol = enclosing_block -> block_symbol;
366 // first such statement encountered in enclosing block?
367 if (enclosing_block_symbol -> helper_variable_index < 0)
368 {
369 enclosing_block_symbol -> helper_variable_index =
370 enclosing_block_symbol -> max_variable_index;
371 enclosing_block_symbol -> max_variable_index += 2;
372 if (ThisMethod() -> Type() != control.void_type)
373 {
374 if (control.IsDoubleWordType(ThisMethod() -> Type()))
375 enclosing_block_symbol -> max_variable_index += 2;
376 else enclosing_block_symbol -> max_variable_index += 1;
377 }
378 }
379
380 //
381 // Guess that the number of elements will not exceed the number of
382 // statements + 3.
383 //
384 BlockSymbol* block = LocalSymbolTable().Top() ->
385 InsertBlockSymbol(block_body -> NumStatements() + 3);
386 block -> max_variable_index = enclosing_block_symbol -> max_variable_index;
387 LocalSymbolTable().Push(block -> Table());
388
389 block_body -> block_symbol = block;
390 block_body -> nesting_level = LocalBlockStack().Size();
391 LocalBlockStack().Push(block_body);
392
393 ProcessBlockStatements(block_body);
394
395 LocalBlockStack().Pop();
396 LocalSymbolTable().Pop();
397
398 if (LocalBlockStack().TopMaxEnclosedVariableIndex() <
399 block -> max_variable_index)
400 {
401 LocalBlockStack().TopMaxEnclosedVariableIndex() =
402 block -> max_variable_index;
403 }
404
405 synchronized_statement -> can_complete_normally =
406 synchronized_statement -> block -> can_complete_normally;
407
408 block -> CompressSpace(); // space optimization
409 }
410
411
CheckForAssignmentUsedAsTruthValue(Ast * expression)412 void Semantic::CheckForAssignmentUsedAsTruthValue(Ast* expression)
413 {
414 //
415 // Warn about boolean assignments within if/while guards, i.e.
416 // code such as "if (booleanLocal = booleanMethod())"
417 // instead of "if (booleanLocal == booleanMethod())".
418 //
419 // We deliberately don't do anything like StripNops because
420 // we want to allow the same compiler-quitening fix as gcc:
421 // "if ((booleanLocal = booleanMethod()))".
422 //
423 AstAssignmentExpression* assignment_expression =
424 expression -> AssignmentExpressionCast();
425 if (assignment_expression &&
426 assignment_expression -> SimpleAssignment() &&
427 assignment_expression -> Type() == control.boolean_type)
428 {
429 ReportSemError(SemanticError::ASSIGNMENT_USED_AS_TRUTH_VALUE,
430 expression);
431 }
432 }
433
434
ProcessIfStatement(Ast * stmt)435 void Semantic::ProcessIfStatement(Ast* stmt)
436 {
437 AstIfStatement* if_statement = (AstIfStatement*) stmt;
438
439 ProcessExpression(if_statement -> expression);
440
441 TypeSymbol* cond_type = if_statement -> expression -> Type();
442 if (cond_type != control.boolean_type && cond_type != control.no_type)
443 {
444 ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
445 if_statement -> expression,
446 cond_type -> ContainingPackageName(),
447 cond_type -> ExternalName());
448 }
449 CheckForAssignmentUsedAsTruthValue(if_statement -> expression);
450
451 //
452 // Recall that the parser enclosed both true and false statements in
453 // blocks, if necessary.
454 //
455 if_statement -> true_statement -> is_reachable =
456 if_statement -> is_reachable;
457 ProcessBlock(if_statement -> true_statement);
458
459 if (if_statement -> false_statement_opt)
460 {
461 if_statement -> false_statement_opt -> is_reachable =
462 if_statement -> is_reachable;
463 ProcessBlock(if_statement -> false_statement_opt);
464
465 if_statement -> can_complete_normally =
466 if_statement -> true_statement -> can_complete_normally ||
467 if_statement -> false_statement_opt -> can_complete_normally;
468 }
469 else if_statement -> can_complete_normally = if_statement -> is_reachable;
470 }
471
472
ProcessWhileStatement(Ast * stmt)473 void Semantic::ProcessWhileStatement(Ast* stmt)
474 {
475 AstWhileStatement* while_statement = (AstWhileStatement*) stmt;
476
477 //
478 // Recall that each while statement is enclosed in a unique block by the
479 // parser, as is the loop body.
480 //
481 BreakableStatementStack().Push(LocalBlockStack().TopBlock());
482 ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
483
484 AstBlock* enclosed_statement = while_statement -> statement;
485 enclosed_statement -> is_reachable = while_statement -> is_reachable;
486
487 ProcessExpression(while_statement -> expression);
488 TypeSymbol* cond_type = while_statement -> expression -> Type();
489 if (cond_type == control.boolean_type)
490 {
491 if (IsConstantFalse(while_statement -> expression))
492 {
493 if (while_statement -> is_reachable)
494 while_statement -> can_complete_normally = true;
495 enclosed_statement -> is_reachable = false;
496 }
497 else if (! IsConstantTrue(while_statement -> expression) &&
498 while_statement -> is_reachable)
499 {
500 while_statement -> can_complete_normally = true;
501 }
502 }
503 else if (cond_type != control.no_type)
504 {
505 ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
506 while_statement -> expression,
507 cond_type -> ContainingPackageName(),
508 cond_type -> ExternalName());
509 }
510 CheckForAssignmentUsedAsTruthValue(while_statement -> expression);
511
512 ProcessBlock(enclosed_statement);
513
514 if (! enclosed_statement -> is_reachable &&
515 while_statement -> is_reachable)
516 {
517 ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
518 enclosed_statement);
519 }
520
521 //
522 // If the while statement contained a reachable break statement,
523 // then the while statement can complete normally. It is marked
524 // here only for completeness, as marking the enclosing block is
525 // enough to propagate the proper information upward.
526 //
527 AstBlock* block_body = BreakableStatementStack().Top();
528 if (block_body -> can_complete_normally)
529 while_statement -> can_complete_normally = true;
530
531 BreakableStatementStack().Pop();
532 ContinuableStatementStack().Pop();
533 }
534
535
ProcessForStatement(Ast * stmt)536 void Semantic::ProcessForStatement(Ast* stmt)
537 {
538 AstForStatement* for_statement = (AstForStatement*) stmt;
539
540 //
541 // Note that in constructing the Ast, the parser encloses each
542 // for-statement whose for-init-statements starts with a local
543 // variable declaration in its own block. Therefore a redeclaration
544 // of another local variable with the same name in a different loop
545 // at the same nesting level will not cause any conflict.
546 //
547 // For example, the following sequence of statements is legal:
548 //
549 // for (int i = 0; i < 10; i++);
550 // for (int i = 10; i < 20; i++);
551 //
552 for (unsigned i = 0; i < for_statement -> NumForInitStatements(); i++)
553 ProcessStatement(for_statement -> ForInitStatement(i));
554
555 //
556 // Recall that each for statement is enclosed in a unique block by the
557 // parser, as is the loop body.
558 //
559 BreakableStatementStack().Push(LocalBlockStack().TopBlock());
560 ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
561
562 //
563 // Assume that if the for_statement is reachable then its
564 // contained statement is also reachable. If it turns out that the
565 // condition (end) expression is a constant FALSE expression we will
566 // change the assumption...
567 //
568 AstBlock* enclosed_statement = for_statement -> statement;
569 enclosed_statement -> is_reachable = for_statement -> is_reachable;
570
571 if (for_statement -> end_expression_opt)
572 {
573 ProcessExpression(for_statement -> end_expression_opt);
574 TypeSymbol* cond_type = for_statement -> end_expression_opt -> Type();
575 if (cond_type == control.boolean_type)
576 {
577 if (IsConstantFalse(for_statement -> end_expression_opt))
578 {
579 if (for_statement -> is_reachable)
580 for_statement -> can_complete_normally = true;
581 enclosed_statement -> is_reachable = false;
582 }
583 else if (! IsConstantTrue(for_statement -> end_expression_opt) &&
584 for_statement -> is_reachable)
585 {
586 for_statement -> can_complete_normally = true;
587 }
588 }
589 else if (cond_type != control.no_type)
590 {
591 ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
592 for_statement -> end_expression_opt,
593 cond_type -> ContainingPackageName(),
594 cond_type -> ExternalName());
595 }
596 }
597
598 ProcessBlock(enclosed_statement);
599
600 if (! enclosed_statement -> is_reachable &&
601 for_statement -> is_reachable)
602 {
603 ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
604 enclosed_statement);
605 }
606
607 for (unsigned j = 0; j < for_statement -> NumForUpdateStatements(); j++)
608 ProcessExpressionStatement(for_statement -> ForUpdateStatement(j));
609
610 //
611 // If the for statement contained a reachable break statement,
612 // then the for statement can complete normally. It is marked
613 // here only for completeness, as marking the enclosing block is
614 // enough to propagate the proper information upward.
615 //
616 AstBlock* block_body = BreakableStatementStack().Top();
617 if (block_body -> can_complete_normally)
618 for_statement -> can_complete_normally = true;
619
620 BreakableStatementStack().Pop();
621 ContinuableStatementStack().Pop();
622 }
623
624
625 //
626 // Enhanced for loops (or foreach loops) were added in JDK 1.5, by JSR 201.
627 //
ProcessForeachStatement(Ast * stmt)628 void Semantic::ProcessForeachStatement(Ast* stmt)
629 {
630 AstForeachStatement* foreach = (AstForeachStatement*) stmt;
631
632 //
633 // Note that in constructing the Ast, the parser encloses each
634 // for-statement whose for-init-statements starts with a local
635 // variable declaration in its own block. Therefore a redeclaration
636 // of another local variable with the same name in a different loop
637 // at the same nesting level will not cause any conflict.
638 //
639 // For example, the following sequence of statements is legal:
640 //
641 // for (int i : new int[0]);
642 // for (int i : new int[0]);
643 //
644 // Recall that each for statement is enclosed in a unique block by the
645 // parser, as is the loop body.
646 //
647 AstBlock* enclosing_block = LocalBlockStack().TopBlock();
648 BlockSymbol* enclosing_block_symbol = enclosing_block -> block_symbol;
649 assert(enclosing_block_symbol -> helper_variable_index < 0);
650 BreakableStatementStack().Push(enclosing_block);
651 ContinuableStatementStack().Push(enclosing_block);
652
653 //
654 // The contained statement of a foreach is reachable iff the foreach is
655 // reachable.
656 //
657 AstBlock* enclosed_statement = foreach -> statement;
658 enclosed_statement -> is_reachable = foreach -> is_reachable;
659
660 ProcessType(foreach -> formal_parameter -> type);
661 assert(! foreach -> formal_parameter -> ellipsis_token_opt);
662 TypeSymbol* index_type = foreach -> formal_parameter -> type -> symbol;
663 AccessFlags access_flags =
664 ProcessFormalModifiers(foreach -> formal_parameter);
665 AstVariableDeclarator* variable_declarator =
666 foreach -> formal_parameter -> formal_declarator;
667 AstVariableDeclaratorId* name =
668 variable_declarator -> variable_declarator_name;
669 NameSymbol* name_symbol =
670 lex_stream -> NameSymbol(name -> identifier_token);
671 VariableSymbol* duplicate =
672 LocalSymbolTable().FindVariableSymbol(name_symbol);
673 if (duplicate)
674 {
675 ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
676 name -> identifier_token, name_symbol -> Name(),
677 duplicate -> FileLoc());
678 }
679 else
680 {
681 WarnOfAccessibleFieldWithName(SemanticError::LOCAL_SHADOWS_FIELD,
682 name, name_symbol, false);
683 SymbolTable* table = LocalSymbolTable().Top();
684 VariableSymbol* symbol = table -> InsertVariableSymbol(name_symbol);
685 variable_declarator -> symbol = symbol;
686 unsigned dims = index_type -> num_dimensions + name -> NumBrackets();
687 symbol -> SetType(index_type -> GetArrayType(this, dims));
688 symbol -> SetFlags(access_flags);
689 symbol -> SetOwner(ThisMethod());
690 symbol -> declarator = variable_declarator;
691 symbol -> SetLocation();
692 symbol -> SetLocalVariableIndex(enclosing_block_symbol ->
693 max_variable_index++);
694 if (control.IsDoubleWordType(symbol -> Type()))
695 enclosing_block_symbol -> max_variable_index++;
696
697 //
698 // Warn against unconventional names. Note that there's no
699 // strong convention for final local variables, so we allow
700 // both the usual style for local variables and the usual
701 // style for constant fields. We recommend the local variable
702 // style, somewhat arbitrarily.
703 //
704 if (! symbol -> ACC_FINAL() && name_symbol -> IsBadStyleForVariable())
705 {
706 ReportSemError(SemanticError::UNCONVENTIONAL_VARIABLE_NAME,
707 name -> identifier_token, name_symbol -> Name());
708 }
709 else if (symbol -> ACC_FINAL() &&
710 name_symbol -> IsBadStyleForVariable() &&
711 name_symbol -> IsBadStyleForConstantField())
712 {
713 ReportSemError(SemanticError::UNCONVENTIONAL_VARIABLE_NAME,
714 name -> identifier_token, name_symbol -> Name());
715 }
716 }
717
718 ProcessExpression(foreach -> expression);
719 TypeSymbol* cond_type = foreach -> expression -> Type();
720 TypeSymbol* component_type;
721 if (control.option.source < JikesOption::SDK1_5)
722 {
723 ReportSemError(SemanticError::FOREACH_UNSUPPORTED,
724 stmt -> RightToken(),
725 foreach -> statement -> LeftToken() - 1);
726 }
727 else if (cond_type -> IsArray())
728 {
729 component_type = cond_type -> ArraySubtype();
730 if (! CanAssignmentConvertReference(index_type, component_type))
731 {
732 ReportSemError(SemanticError::INCOMPATIBLE_TYPE_FOR_FOREACH,
733 foreach -> expression,
734 component_type -> ContainingPackageName(),
735 component_type -> ExternalName(),
736 index_type -> ContainingPackageName(),
737 index_type -> ExternalName());
738 }
739 // Need local variabls to stash array, array.length, and counter.
740 enclosing_block_symbol -> helper_variable_index =
741 enclosing_block_symbol -> max_variable_index;
742 enclosing_block_symbol -> max_variable_index += 3;
743 }
744 else if (cond_type -> IsSubtype(control.Iterable()))
745 {
746 // FIXME: Support generics. Until then, we blindly accept all types,
747 // and cause a ClassCastException if the user was wrong (this is not
748 // semantically correct, but it allows testing).
749 component_type = control.Object();
750 if (! CanAssignmentConvertReference(index_type, component_type))
751 {
752 // HACK. Only complain about primitives, until generics are
753 // fully supported and we can see if cond_type is parameterized,
754 // and until autounboxing is implemented.
755 if (index_type -> Primitive())
756 ReportSemError(SemanticError::INCOMPATIBLE_TYPE_FOR_FOREACH,
757 foreach -> expression,
758 component_type -> ContainingPackageName(),
759 component_type -> ExternalName(),
760 index_type -> ContainingPackageName(),
761 index_type -> ExternalName());
762
763 }
764 // Need synthetic local variable to stash iterator.
765 enclosing_block_symbol -> helper_variable_index =
766 enclosing_block_symbol -> max_variable_index;
767 enclosing_block_symbol -> max_variable_index++;
768 }
769 else if (cond_type != control.no_type)
770 {
771 ReportSemError(SemanticError::TYPE_NOT_ITERABLE, foreach -> expression,
772 cond_type -> ContainingPackageName(),
773 cond_type -> ExternalName());
774 }
775 ProcessBlock(enclosed_statement);
776
777 //
778 // Foreach statements can always complete normally, if reachable, because
779 // the array/iterator length could be 0.
780 //
781 foreach -> can_complete_normally = foreach -> is_reachable;
782 BreakableStatementStack().Pop();
783 ContinuableStatementStack().Pop();
784 }
785
786
ProcessSwitchStatement(Ast * stmt)787 void Semantic::ProcessSwitchStatement(Ast* stmt)
788 {
789 AstSwitchStatement* switch_statement = (AstSwitchStatement*) stmt;
790
791 AstBlock* enclosing_block = LocalBlockStack().TopBlock();
792
793 //
794 // We estimate a size for the switch symbol table based on the number of
795 // lines in it. In a switch statement, local variable declarations have
796 // scope over the entire main_block, but local classes only have scope in
797 // the current switch block statement.
798 //
799 AstBlock* block_body = switch_statement -> switch_block;
800 BlockSymbol* main_block = LocalSymbolTable().Top() -> InsertBlockSymbol();
801 main_block -> max_variable_index =
802 enclosing_block -> block_symbol -> max_variable_index;
803 LocalSymbolTable().Push(main_block -> Table());
804
805 block_body -> block_symbol = main_block;
806 block_body -> nesting_level = LocalBlockStack().Size();
807 LocalBlockStack().Push(block_body);
808 BreakableStatementStack().Push(block_body);
809
810 ProcessExpression(switch_statement -> expression);
811 TypeSymbol* type = switch_statement -> expression -> Type();
812
813 if (! control.IsSimpleIntegerValueType(type) && type != control.no_type)
814 {
815 ReportSemError(SemanticError::TYPE_NOT_INTEGER,
816 switch_statement -> expression,
817 type -> ContainingPackageName(),
818 type -> ExternalName());
819 type = control.no_type;
820 }
821
822 //
823 // Count the number of case labels in this switch statement.
824 //
825 unsigned num_case_labels = 0;
826 for (unsigned i = 0; i < block_body -> NumStatements(); i++)
827 num_case_labels += switch_statement -> Block(i) -> NumSwitchLabels();
828 switch_statement -> AllocateCases(num_case_labels);
829
830 //
831 // A switch block is reachable iff its switch statement is reachable.
832 //
833 block_body -> is_reachable = switch_statement -> is_reachable;
834 for (unsigned j = 0; j < block_body -> NumStatements(); j++)
835 {
836 AstSwitchBlockStatement* switch_block_statement =
837 switch_statement -> Block(j);
838 for (unsigned k = 0;
839 k < switch_block_statement -> NumSwitchLabels(); k++)
840 {
841 AstSwitchLabel* switch_label =
842 switch_block_statement -> SwitchLabel(k);
843 if (switch_label -> expression_opt)
844 {
845 ProcessExpression(switch_label -> expression_opt);
846 TypeSymbol* case_type =
847 switch_label -> expression_opt -> Type();
848 if (case_type == control.no_type)
849 continue;
850 if (! control.IsSimpleIntegerValueType(case_type))
851 {
852 ReportSemError(SemanticError::TYPE_NOT_INTEGER,
853 switch_label -> expression_opt,
854 case_type -> ContainingPackageName(),
855 case_type -> ExternalName());
856 switch_label -> expression_opt -> symbol = control.no_type;
857 }
858 else if (! switch_label -> expression_opt -> IsConstant())
859 {
860 ReportSemError(SemanticError::EXPRESSION_NOT_CONSTANT,
861 switch_label -> expression_opt);
862 switch_label -> expression_opt -> symbol = control.no_type;
863 }
864 else if (CanAssignmentConvert(type,
865 switch_label -> expression_opt))
866 {
867 switch_label -> expression_opt =
868 ConvertToType(switch_label -> expression_opt, type);
869 CaseElement* case_element =
870 compilation_unit -> ast_pool -> GenCaseElement(j, k);
871 switch_statement -> AddCase(case_element);
872 case_element -> value = DYNAMIC_CAST<IntLiteralValue*>
873 (switch_label -> expression_opt -> value) -> value;
874 }
875 else
876 {
877 IntToWstring value(DYNAMIC_CAST<IntLiteralValue*>
878 (switch_label -> expression_opt ->
879 value) -> value);
880 ReportSemError(SemanticError::VALUE_NOT_REPRESENTABLE_IN_SWITCH_TYPE,
881 switch_label -> expression_opt,
882 value.String(),
883 type -> Name());
884 }
885 }
886 else if (! switch_statement -> DefaultCase())
887 {
888 switch_statement -> DefaultCase() =
889 compilation_unit -> ast_pool -> GenCaseElement(j, k);
890 switch_label -> map_index = num_case_labels - 1;
891 }
892 else
893 {
894 ReportSemError(SemanticError::MULTIPLE_DEFAULT_LABEL,
895 switch_block_statement -> SwitchLabel(k));
896 }
897 }
898
899 //
900 // The parser ensures that a switch block statement always has one
901 // statement. When a switch block ends with a sequence of switch
902 // labels that are not followed by any executable statements, an
903 // artificial "empty" statement is added by the parser. Another
904 // BlockSymbol level is used here for the scope of local classes,
905 // but we share the BlockStack level to make break work correctly.
906 //
907 assert(switch_block_statement -> NumStatements() > 0);
908 BlockSymbol* statement_block =
909 LocalSymbolTable().Top() -> InsertBlockSymbol();
910 statement_block -> max_variable_index =
911 main_block -> max_variable_index;
912 LocalSymbolTable().Push(statement_block -> Table());
913
914 switch_block_statement -> block_symbol = statement_block;
915 switch_block_statement -> nesting_level = LocalBlockStack().Size();
916 LocalBlockStack().Push(block_body);
917 switch_block_statement -> is_reachable =
918 switch_statement -> is_reachable;
919 ProcessBlockStatements(switch_block_statement);
920 if (switch_block_statement -> can_complete_normally &&
921 j != block_body -> NumStatements() - 1)
922 {
923 //
924 // TODO: Improve the parser to allow this warning to be locally
925 // disabled by adding a comment similar to "// fallthrough".
926 //
927 ReportSemError(SemanticError::SWITCH_FALLTHROUGH,
928 switch_block_statement);
929 }
930
931 if (statement_block -> max_variable_index <
932 LocalBlockStack().TopMaxEnclosedVariableIndex())
933 {
934 statement_block -> max_variable_index =
935 LocalBlockStack().TopMaxEnclosedVariableIndex();
936 }
937 LocalBlockStack().Pop();
938 LocalSymbolTable().Pop();
939 if (LocalBlockStack().TopMaxEnclosedVariableIndex() <
940 statement_block -> max_variable_index)
941 {
942 LocalBlockStack().TopMaxEnclosedVariableIndex() =
943 statement_block -> max_variable_index;
944 }
945 statement_block -> CompressSpace();
946 }
947
948 //
949 // A switch statement can complete normally iff at least one of the
950 // following is true:
951 //
952 // . The last statement in the switch block can complete normally.
953 // . The switch block is empty or contains only switch labels.
954 // . There is at least one switch label after the last switch block
955 // statement group.
956 // . The switch block does not contain a default label.
957 // . There is a reachable break statement that exits the switch
958 // statement. (See ProcessBreakStatement)
959 //
960 if (block_body -> can_complete_normally ||
961 ! switch_statement -> DefaultCase())
962 {
963 switch_statement -> can_complete_normally = true;
964 }
965 else
966 {
967 AstSwitchBlockStatement* last_switch_block_statement =
968 switch_statement -> Block(block_body -> NumStatements() - 1);
969
970 assert(last_switch_block_statement -> NumStatements() > 0);
971
972 AstStatement* last_statement = last_switch_block_statement ->
973 Statement(last_switch_block_statement -> NumStatements() - 1);
974 if (last_statement -> can_complete_normally)
975 switch_statement -> can_complete_normally = true;
976 }
977
978 //
979 // Iterate over the sorted cases, checking for duplicates, and setting
980 // the map_index field of each AstCaseLabel (1-based, in order to leave
981 // room for the default label).
982 //
983 if (switch_statement -> NumCases())
984 {
985 switch_statement -> SortCases();
986 CaseElement* first_case = switch_statement -> Case(0);
987 switch_statement -> Block(first_case -> block_index) ->
988 SwitchLabel(first_case -> case_index) -> map_index = 0;
989 }
990 for (unsigned k = 1; k < switch_statement -> NumCases(); k++)
991 {
992 CaseElement* case_elt = switch_statement -> Case(k);
993 switch_statement -> Block(case_elt -> block_index) ->
994 SwitchLabel(case_elt -> case_index) -> map_index = k;
995 if (case_elt -> value == switch_statement -> Case(k - 1) -> value)
996 {
997 IntToWstring value(case_elt -> value);
998 ReportSemError(SemanticError::DUPLICATE_CASE_VALUE,
999 (switch_statement ->
1000 Block(case_elt -> block_index) ->
1001 SwitchLabel(case_elt -> case_index) ->
1002 expression_opt),
1003 value.String());
1004 }
1005 }
1006
1007 //
1008 // If an enclosed block has a higher max_variable_index than the current
1009 // block, update max_variable_index in the current_block, accordingly.
1010 // Also, update the information for the block that immediately encloses
1011 // the current block.
1012 //
1013 if (main_block -> max_variable_index <
1014 LocalBlockStack().TopMaxEnclosedVariableIndex())
1015 {
1016 main_block -> max_variable_index =
1017 LocalBlockStack().TopMaxEnclosedVariableIndex();
1018 }
1019
1020 BreakableStatementStack().Pop();
1021 LocalBlockStack().Pop();
1022 LocalSymbolTable().Pop();
1023
1024 if (enclosing_block && (LocalBlockStack().TopMaxEnclosedVariableIndex() <
1025 main_block -> max_variable_index))
1026 {
1027 LocalBlockStack().TopMaxEnclosedVariableIndex() =
1028 main_block -> max_variable_index;
1029 }
1030
1031 main_block -> CompressSpace(); // space optimization
1032 }
1033
1034
ProcessDoStatement(Ast * stmt)1035 void Semantic::ProcessDoStatement(Ast* stmt)
1036 {
1037 AstDoStatement* do_statement = (AstDoStatement*) stmt;
1038
1039 //
1040 // Recall that each Do statement is enclosed in a unique block by the
1041 // parser, as is the loop body.
1042 //
1043 BreakableStatementStack().Push(LocalBlockStack().TopBlock());
1044 ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
1045
1046 AstBlock* enclosed_statement = do_statement -> statement;
1047 enclosed_statement -> is_reachable = do_statement -> is_reachable;
1048
1049 ProcessBlock(enclosed_statement);
1050
1051 ProcessExpression(do_statement -> expression);
1052
1053 TypeSymbol* type = do_statement -> expression -> Type();
1054 if (type != control.boolean_type && type != control.no_type)
1055 {
1056 ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
1057 do_statement -> expression,
1058 type -> ContainingPackageName(),
1059 type -> ExternalName());
1060 }
1061 CheckForAssignmentUsedAsTruthValue(do_statement -> expression);
1062
1063 //
1064 // A do statement can complete normally, iff at least one of the following
1065 // is true:
1066 // 1. The contained statement can complete normally and the condition
1067 // expression is not a constant expression with the value true
1068 // 2. There is a reachable break statement that exits the do statement
1069 // (This condition is true if the block that immediately encloses
1070 // this do statement can complete normally. See
1071 // ProcessBreakStatement)
1072 //
1073 AstBlock* block_body = (AstBlock*) BreakableStatementStack().Top();
1074 do_statement -> can_complete_normally =
1075 ((enclosed_statement -> can_complete_normally &&
1076 ! IsConstantTrue(do_statement -> expression)) ||
1077 block_body -> can_complete_normally);
1078
1079 BreakableStatementStack().Pop();
1080 ContinuableStatementStack().Pop();
1081 }
1082
1083
ProcessBreakStatement(Ast * stmt)1084 void Semantic::ProcessBreakStatement(Ast* stmt)
1085 {
1086 AstBreakStatement* break_statement = (AstBreakStatement*) stmt;
1087
1088 //
1089 // Recall that it is possible to break out of any labeled statement even
1090 // if it is not a do, for, while or switch statement.
1091 //
1092 if (break_statement -> identifier_token_opt)
1093 {
1094 NameSymbol* name_symbol =
1095 lex_stream -> NameSymbol(break_statement -> identifier_token_opt);
1096 LabelSymbol* label_symbol =
1097 LocalSymbolTable().FindLabelSymbol(name_symbol);
1098
1099 if (label_symbol)
1100 {
1101 break_statement -> nesting_level = label_symbol -> nesting_level;
1102 AstBlock* block_body = label_symbol -> block;
1103 //
1104 // A labeled statement can complete normally if there is a
1105 // reachable break statement that exits the labeled statement.
1106 // If the break occurs in a try or catch block with a finally
1107 // block that completes abruptly, the break is discarded.
1108 //
1109 if (block_body && break_statement -> is_reachable &&
1110 AbruptFinallyStack().Top() < block_body -> nesting_level)
1111 {
1112 block_body -> can_complete_normally = true;
1113 }
1114 }
1115 else
1116 {
1117 AstBlock* block_body = (AstBlock*) LocalBlockStack().TopBlock();
1118 break_statement -> nesting_level = block_body -> nesting_level;
1119 ReportSemError(SemanticError::UNDECLARED_LABEL,
1120 break_statement -> identifier_token_opt,
1121 lex_stream -> NameString(break_statement ->
1122 identifier_token_opt));
1123 }
1124 }
1125 else
1126 {
1127 AstBlock* block_body =
1128 (AstBlock*) (BreakableStatementStack().Size() > 0
1129 ? BreakableStatementStack().Top()
1130 : LocalBlockStack().TopBlock());
1131 break_statement -> nesting_level = block_body -> nesting_level;
1132 if (BreakableStatementStack().Size() > 0)
1133 {
1134 if (break_statement -> is_reachable &&
1135 AbruptFinallyStack().Top() < block_body -> nesting_level)
1136 {
1137 block_body -> can_complete_normally = true;
1138 }
1139 }
1140 else ReportSemError(SemanticError::MISPLACED_BREAK_STATEMENT,
1141 break_statement);
1142 }
1143 }
1144
1145
ProcessContinueStatement(Ast * stmt)1146 void Semantic::ProcessContinueStatement(Ast* stmt)
1147 {
1148 AstContinueStatement* continue_statement = (AstContinueStatement*) stmt;
1149
1150 //
1151 // The loop statement that is to be continued.
1152 //
1153 Ast* loop_statement = NULL;
1154
1155 if (ContinuableStatementStack().Size() <= 0)
1156 {
1157 ReportSemError(SemanticError::MISPLACED_CONTINUE_STATEMENT,
1158 continue_statement);
1159 }
1160 else if (continue_statement -> identifier_token_opt)
1161 {
1162 NameSymbol* name_symbol = lex_stream ->
1163 NameSymbol(continue_statement -> identifier_token_opt);
1164 LabelSymbol* label_symbol =
1165 LocalSymbolTable().FindLabelSymbol(name_symbol);
1166
1167 if (label_symbol)
1168 {
1169 continue_statement -> nesting_level =
1170 label_symbol -> nesting_level;
1171
1172 assert(label_symbol -> block -> NumStatements() > 0);
1173
1174 loop_statement = label_symbol -> block -> Statement(0);
1175 }
1176 else
1177 {
1178 AstBlock* block_body = (AstBlock*) LocalBlockStack().TopBlock();
1179 continue_statement -> nesting_level = block_body -> nesting_level;
1180 ReportSemError(SemanticError::UNDECLARED_LABEL,
1181 continue_statement -> identifier_token_opt,
1182 lex_stream -> NameString(continue_statement ->
1183 identifier_token_opt));
1184 }
1185 }
1186 else
1187 {
1188 AstBlock* block_body = (AstBlock*) ContinuableStatementStack().Top();
1189 loop_statement = block_body -> Statement(0);
1190 continue_statement -> nesting_level = block_body -> nesting_level;
1191 }
1192
1193 //
1194 // If this is a valid continue statement, it is associated with a loop
1195 // statement. The parser created a block, if necessary, so that the loop
1196 // body is always a block, and we mark it as "can complete normally".
1197 // However, if the continue occurs in a try or catch block with a
1198 // corresponding abrupt finally clause, the continue is discarded.
1199 //
1200 if (loop_statement)
1201 {
1202 AstDoStatement* do_statement = loop_statement -> DoStatementCast();
1203 AstForStatement* for_statement = loop_statement -> ForStatementCast();
1204 AstWhileStatement* while_statement =
1205 loop_statement -> WhileStatementCast();
1206 AstForeachStatement* foreach_statement =
1207 loop_statement -> ForeachStatementCast();
1208
1209 AstBlock* enclosed_statement = (do_statement
1210 ? do_statement -> statement
1211 : for_statement
1212 ? for_statement -> statement
1213 : while_statement
1214 ? while_statement -> statement
1215 : foreach_statement
1216 ? foreach_statement -> statement
1217 : (AstBlock*) NULL);
1218 if (enclosed_statement)
1219 {
1220 if (AbruptFinallyStack().Top() <
1221 continue_statement -> nesting_level)
1222 {
1223 enclosed_statement -> can_complete_normally = true;
1224 }
1225 }
1226 else
1227 {
1228 assert(continue_statement -> identifier_token_opt);
1229
1230 ReportSemError(SemanticError::INVALID_CONTINUE_TARGET,
1231 continue_statement,
1232 lex_stream -> NameString(continue_statement ->
1233 identifier_token_opt));
1234 }
1235 }
1236 }
1237
1238
ProcessReturnStatement(Ast * stmt)1239 void Semantic::ProcessReturnStatement(Ast* stmt)
1240 {
1241 AstReturnStatement* return_statement = (AstReturnStatement*) stmt;
1242 MethodSymbol* this_method = ThisMethod();
1243
1244 if (this_method -> name_symbol == control.clinit_name_symbol ||
1245 this_method -> name_symbol == control.block_init_name_symbol)
1246 {
1247 ReportSemError(SemanticError::RETURN_STATEMENT_IN_INITIALIZER,
1248 return_statement);
1249 }
1250 else if (return_statement -> expression_opt)
1251 {
1252 AstExpression* expression = return_statement -> expression_opt;
1253 ProcessExpressionOrStringConstant(expression);
1254 TypeSymbol* method_type = this_method -> Type();
1255 TypeSymbol* expression_type = expression -> Type();
1256
1257 if (method_type == control.void_type ||
1258 this_method -> name_symbol == control.init_name_symbol)
1259 {
1260 ReportSemError(SemanticError::MISPLACED_RETURN_WITH_EXPRESSION,
1261 return_statement);
1262 }
1263 else if (expression_type == control.null_type &&
1264 method_type -> IsArray())
1265 {
1266 ReportSemError(SemanticError::EJ_RETURN_OF_NULL_ARRAY,
1267 return_statement);
1268 }
1269 else if (expression_type != control.no_type)
1270 {
1271 if (method_type != expression_type)
1272 {
1273 if (CanAssignmentConvert(method_type, expression))
1274 return_statement -> expression_opt =
1275 ConvertToType(expression, method_type);
1276 else
1277 {
1278 ReportSemError(SemanticError::MISMATCHED_RETURN_AND_METHOD_TYPE,
1279 expression,
1280 expression_type -> ContainingPackageName(),
1281 expression_type -> ExternalName(),
1282 method_type -> ContainingPackageName(),
1283 method_type -> ExternalName());
1284 }
1285 }
1286 }
1287 }
1288 else if (this_method -> Type() != control.void_type &&
1289 this_method -> name_symbol != control.init_name_symbol)
1290 {
1291 ReportSemError(SemanticError::MISPLACED_RETURN_WITH_NO_EXPRESSION,
1292 return_statement);
1293 }
1294 }
1295
1296
1297 //
1298 // Any exception that is neither RuntimeException or one of its subclasses
1299 // nor Error or one of its subclasses is a checked exception. This also
1300 // ignores invalid types. Additionally, 'throw null' results in a
1301 // NullPointerException, so it is unchecked.
1302 //
CheckedException(TypeSymbol * exception)1303 bool Semantic::CheckedException(TypeSymbol* exception)
1304 {
1305 return (exception != control.null_type &&
1306 exception != control.no_type &&
1307 ! exception -> IsSubclass(control.RuntimeException()) &&
1308 ! exception -> IsSubclass(control.Error()));
1309 }
1310
1311
UncaughtException(TypeSymbol * exception)1312 bool Semantic::UncaughtException(TypeSymbol* exception)
1313 {
1314 //
1315 // An unchecked exception or a bad type is ok !!
1316 //
1317 if (! CheckedException(exception))
1318 return false;
1319
1320 //
1321 // Firstly, check the stack of try statements to see if the exception in
1322 // question is catchable.
1323 //
1324 for (int i = TryStatementStack().Size() - 1; i >= 0; i--)
1325 {
1326 AstTryStatement* try_statement = TryStatementStack()[i];
1327
1328 //
1329 // If a try statement contains a finally clause that can't complete
1330 // normally then the exception is discarded, hence it is considered
1331 // catchable. See Spec 11.3.
1332 //
1333 if (try_statement -> finally_clause_opt &&
1334 (! try_statement -> finally_clause_opt -> block ->
1335 can_complete_normally))
1336 {
1337 return false;
1338 }
1339
1340 //
1341 // Check each catch clause in turn if we are in the try block.
1342 //
1343 if (try_statement -> processing_try_block)
1344 for (unsigned k = 0; k < try_statement -> NumCatchClauses(); k++)
1345 {
1346 AstCatchClause* clause = try_statement -> CatchClause(k);
1347 VariableSymbol* symbol = clause -> parameter_symbol;
1348 if (CanAssignmentConvertReference(symbol -> Type(), exception))
1349 return false;
1350 }
1351 }
1352
1353 //
1354 // Check if the current method declares this in the throws clause (note
1355 // that field initializers are not in a current method).
1356 //
1357 MethodSymbol* this_method = ThisMethod();
1358 if (this_method)
1359 {
1360 for (int l = this_method -> NumThrows() - 1; l >= 0; l--)
1361 {
1362 if (CanAssignmentConvertReference(this_method -> Throws(l),
1363 exception))
1364 return false;
1365 }
1366 }
1367
1368 //
1369 // In the special case of instance field initializers, and instance
1370 // initializer blocks, check if all constructors declare the exception
1371 // in the throws clause.
1372 //
1373 if ((this_method &&
1374 this_method -> Identity() == control.block_init_name_symbol) ||
1375 (ThisVariable() && ! ThisVariable() -> ACC_STATIC()))
1376 {
1377 TypeSymbol* this_type = ThisType();
1378 MethodSymbol* ctor =
1379 this_type -> FindMethodSymbol(control.init_name_symbol);
1380 if (! this_type -> Anonymous())
1381 {
1382 for ( ; ctor; ctor = ctor -> next_method)
1383 {
1384 int k;
1385 for (k = ctor -> NumThrows() - 1; k >= 0; k--)
1386 {
1387 if (CanAssignmentConvertReference(ctor -> Throws(k),
1388 exception))
1389 break;
1390 }
1391 if (k < 0) // No hit was found in constructor.
1392 break;
1393 }
1394 return ctor != NULL; // Did all constructors catch exception?
1395 }
1396 else
1397 {
1398 assert(ctor);
1399 int k = 0;
1400 for (k = ctor -> NumThrows() - 1; k >= 0; k--)
1401 {
1402 if (CanAssignmentConvertReference(ctor -> Throws(k),
1403 exception))
1404 break;
1405 }
1406 //
1407 // Anonymous classes must generate the constructor to handle all
1408 // possible initialization exceptions; this is possible because
1409 // a class instance can only be created at one point, so the
1410 // exception can be caught in the enclosing class. If we don't
1411 // find the exception, we must add it.
1412 //
1413 if (k < 0)
1414 ctor -> AddThrows(exception);
1415 return false;
1416 }
1417 }
1418
1419 return true; // Nothing can catch the exception.
1420 }
1421
1422
UncaughtExceptionContext()1423 const wchar_t* Semantic::UncaughtExceptionContext()
1424 {
1425 ErrorString s;
1426 MethodSymbol* this_method = ThisMethod();
1427 if (this_method)
1428 {
1429 s << " must be enclosed in a try statement that catches the "
1430 << "exception, ";
1431 if (this_method -> Identity() == control.clinit_name_symbol)
1432 {
1433 s << "since static initializers cannot throw checked exceptions.";
1434 }
1435 else
1436 {
1437 if (this_method -> Identity() == control.block_init_name_symbol)
1438 {
1439 assert(! ThisType() -> Anonymous());
1440 s << "or else every constructor in this class";
1441 }
1442 else if (this_method -> Identity() == control.init_name_symbol)
1443 s << "or else this constructor";
1444 else s << "or else this method";
1445 s << " must be declared to throw the exception.";
1446 }
1447 }
1448 else if (ThisType() -> ACC_INTERFACE())
1449 {
1450 s << " must be wrapped in a helper class method which catches the "
1451 << "exception, since interface field initializers cannot throw "
1452 << "checked exceptions.";
1453 }
1454 else
1455 {
1456 VariableSymbol* this_variable = ThisVariable();
1457 assert(this_variable);
1458 if (this_variable -> ACC_STATIC())
1459 s << " must be moved to a static initializer and enclosed in a "
1460 << "try statement which catches the exception, since static "
1461 << "initializers cannot throw checked exceptions.";
1462 else
1463 {
1464 assert(! ThisType() -> Anonymous());
1465 s << " must be moved to an instance initializer or constructor "
1466 << "and enclosed in a try statement which catches the "
1467 << "exception, or else every constructor in this class must be "
1468 << "declared to throw the exception.";
1469 }
1470 }
1471 return s.Array();
1472 }
1473
1474
ProcessThrowStatement(Ast * stmt)1475 void Semantic::ProcessThrowStatement(Ast* stmt)
1476 {
1477 AstThrowStatement* throw_statement = (AstThrowStatement*) stmt;
1478
1479 ProcessExpression(throw_statement -> expression);
1480 TypeSymbol* type = throw_statement -> expression -> Type();
1481
1482 if (type != control.no_type &&
1483 ! CanAssignmentConvertReference(control.Throwable(), type))
1484 {
1485 ReportSemError(SemanticError::EXPRESSION_NOT_THROWABLE,
1486 throw_statement);
1487 }
1488
1489 //
1490 // Since 'throw null' always generates NullPointerException, we do not
1491 // add it to the exception set; otherwise checked exception catch blocks
1492 // would be reachable because null is assignable to them.
1493 //
1494 SymbolSet* exception_set = TryExceptionTableStack().Top();
1495 if (exception_set && type != control.null_type)
1496 exception_set -> AddElement(type);
1497
1498 if (UncaughtException(type))
1499 ReportSemError(SemanticError::UNCAUGHT_THROWN_EXCEPTION,
1500 throw_statement, type -> ContainingPackageName(),
1501 type -> ExternalName(), UncaughtExceptionContext());
1502 }
1503
1504
ProcessTryStatement(Ast * stmt)1505 void Semantic::ProcessTryStatement(Ast* stmt)
1506 {
1507 AstTryStatement* try_statement = (AstTryStatement*) stmt;
1508
1509 //
1510 // A try_statement containing a finally clause requires some extra local
1511 // variables in its immediately enclosing block. The first holds an
1512 // uncaught exception from the try or catch block. The second holds the
1513 // return address of the jsr. And if the method has a return type, 1-2
1514 // more slots are needed to hold the return value in the case of an
1515 // abrupt exit from a try or catch block.
1516 //
1517 // Meanwhile, statements within try or catch blocks cannot share local
1518 // variables with the finally block, because of a potential VerifyError if
1519 // the finally overwrites a register holding a monitor of an enclosed
1520 // synchronized statement during an abrupt exit.
1521 //
1522 AstBlock* enclosing_block = LocalBlockStack().TopBlock();
1523 int max_variable_index =
1524 enclosing_block -> block_symbol -> max_variable_index;
1525
1526 if (try_statement -> finally_clause_opt)
1527 {
1528 BlockSymbol* enclosing_block_symbol = enclosing_block -> block_symbol;
1529 if (enclosing_block_symbol -> helper_variable_index < 0)
1530 {
1531 // first such statement encountered in enclosing block?
1532 enclosing_block_symbol -> helper_variable_index =
1533 enclosing_block_symbol -> max_variable_index;
1534 enclosing_block_symbol -> max_variable_index += 2;
1535 if (ThisMethod() -> Type() != control.void_type)
1536 {
1537 if (control.IsDoubleWordType(ThisMethod() -> Type()))
1538 enclosing_block_symbol -> max_variable_index += 2;
1539 else enclosing_block_symbol -> max_variable_index++;
1540 }
1541 }
1542
1543 //
1544 // A finally block is processed in the environment of its immediate
1545 // enclosing block (as opposed to the environment of its associated
1546 // try block).
1547 //
1548 // Note that the finally block must be processed prior to the other
1549 // blocks in the try statement, because the computation of whether or
1550 // not an exception is catchable in a try statement depends on the
1551 // termination status of the associated finally block. See the
1552 // UncaughtException function. In addition, any variables used in
1553 // the finally block cannot be safely used in the other blocks.
1554 //
1555 AstBlock* block_body = try_statement -> finally_clause_opt -> block;
1556 block_body -> is_reachable = try_statement -> is_reachable;
1557 assert(! try_statement -> can_complete_normally);
1558 ProcessBlock(block_body);
1559 max_variable_index = block_body -> block_symbol -> max_variable_index;
1560
1561 //
1562 // Warn about empty finally blocks.
1563 //
1564 if (block_body -> NumStatements() == 0)
1565 {
1566 ReportSemError(SemanticError::EJ_EMPTY_FINALLY_BLOCK, block_body);
1567 }
1568
1569 //
1570 // If the finally ends abruptly, then it discards any throw generated
1571 // by the try or catch blocks.
1572 //
1573 if (! block_body -> can_complete_normally)
1574 {
1575 TryExceptionTableStack().Push(new SymbolSet());
1576 AbruptFinallyStack().Push(block_body -> nesting_level);
1577 }
1578 }
1579
1580 //
1581 // Note that the catch clauses are processed first - prior to processing
1582 // the main block - so that we can have their parameters available when we
1583 // are processing the main block, in case that block contains a throw
1584 // statement. See ProcessThrowStatement for more information. But since
1585 // a catch clause may be interrupted by an abrupt finally clause, we go
1586 // ahead and push the try block on the stack now, then use the field
1587 // processing_try_block later to mark the difference.
1588 //
1589 // Also, recall that the body of the catch blocks must not be
1590 // processed within the environment of the associated try whose
1591 // exceptions they are supposed to catch but within the immediate enclosing
1592 // block (which may itself be a try block).
1593 //
1594 TryStatementStack().Push(try_statement);
1595 for (unsigned i = 0; i < try_statement -> NumCatchClauses(); i++)
1596 {
1597 AstCatchClause* clause = try_statement -> CatchClause(i);
1598 AstFormalParameter* parameter = clause -> formal_parameter;
1599 assert(! parameter -> ellipsis_token_opt);
1600 AstVariableDeclaratorId* name =
1601 parameter -> formal_declarator -> variable_declarator_name;
1602
1603 ProcessType(parameter -> type);
1604 TypeSymbol* parm_type = parameter -> type -> symbol;
1605 if (name -> NumBrackets())
1606 {
1607 parm_type = parm_type ->
1608 GetArrayType(this, (parm_type -> num_dimensions +
1609 name -> NumBrackets()));
1610 }
1611 if (! parm_type -> IsSubclass(control.Throwable()) &&
1612 parm_type != control.no_type)
1613 {
1614 ReportSemError(SemanticError::TYPE_NOT_THROWABLE, parameter,
1615 parm_type -> ContainingPackageName(),
1616 parm_type -> ExternalName());
1617 parm_type = control.no_type;
1618 }
1619
1620 NameSymbol* name_symbol =
1621 lex_stream -> NameSymbol(name -> identifier_token);
1622 VariableSymbol* duplicate =
1623 LocalSymbolTable().FindVariableSymbol(name_symbol);
1624 if (duplicate)
1625 {
1626 ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
1627 name -> identifier_token, name_symbol -> Name(),
1628 duplicate -> FileLoc());
1629 }
1630 WarnOfAccessibleFieldWithName(SemanticError::LOCAL_SHADOWS_FIELD,
1631 name, name_symbol, false);
1632
1633 AstBlock* block_body = clause -> block;
1634
1635 //
1636 // Warn about empty catch blocks.
1637 //
1638 if (control.option.pedantic && block_body -> NumStatements() == 0)
1639 ReportSemError(SemanticError::EJ_EMPTY_CATCH_BLOCK, block_body);
1640
1641 //
1642 // Guess that the number of elements in the table will not exceed the
1643 // number of statements + the clause parameter.
1644 //
1645 BlockSymbol* block = LocalSymbolTable().Top() ->
1646 InsertBlockSymbol(block_body -> NumStatements() + 1);
1647 block -> max_variable_index = max_variable_index;
1648 LocalSymbolTable().Push(block -> Table());
1649
1650 AccessFlags access_flags = ProcessFormalModifiers(parameter);
1651
1652 VariableSymbol* symbol =
1653 LocalSymbolTable().Top() -> InsertVariableSymbol(name_symbol);
1654 symbol -> SetFlags(access_flags);
1655 symbol -> SetType(parm_type);
1656 symbol -> SetOwner(ThisMethod());
1657 symbol -> SetLocalVariableIndex(block -> max_variable_index++);
1658 symbol -> MarkComplete();
1659 symbol -> declarator = parameter -> formal_declarator;
1660 symbol -> SetLocation();
1661 parameter -> formal_declarator -> symbol = symbol;
1662 clause -> parameter_symbol = symbol;
1663
1664 //
1665 // Note that for the purpose of semantic checking we assume that
1666 // the body of the catch block is reachable. Whether or not the catch
1667 // statement can be executed at all is checked later.
1668 //
1669 block_body -> is_reachable = true;
1670
1671 block_body -> block_symbol = block;
1672 block_body -> nesting_level = LocalBlockStack().Size();
1673 LocalBlockStack().Push(block_body);
1674
1675 ProcessBlockStatements(block_body);
1676
1677 LocalBlockStack().Pop();
1678 LocalSymbolTable().Pop();
1679
1680 //
1681 // Update the information for the block that immediately encloses
1682 // the current block.
1683 //
1684 if (LocalBlockStack().TopMaxEnclosedVariableIndex() <
1685 block -> max_variable_index)
1686 {
1687 LocalBlockStack().TopMaxEnclosedVariableIndex() =
1688 block -> max_variable_index;
1689 }
1690
1691 //
1692 // If a catch clause block can complete normally, we assume
1693 // that the try statement can complete normally. This may
1694 // prove to be false later if we find out that the finally
1695 // clause cannot complete normally...
1696 //
1697 if (block_body -> can_complete_normally)
1698 try_statement -> can_complete_normally = true;
1699
1700 block -> CompressSpace(); // space optimization
1701 }
1702
1703 //
1704 // Finally, process the main try block.
1705 //
1706 try_statement -> processing_try_block = true;
1707 SymbolSet* exception_set = new SymbolSet;
1708 TryExceptionTableStack().Push(exception_set);
1709
1710 try_statement -> block -> is_reachable = try_statement -> is_reachable;
1711 AstBlock* block_body = try_statement -> block;
1712 //
1713 // Guess that the number of elements in the table will not exceed the
1714 // number of statements + 3. This padding allows extra variable
1715 // declarations in things like for-init, without expensive reallocation.
1716 //
1717 BlockSymbol* block = LocalSymbolTable().Top() ->
1718 InsertBlockSymbol(block_body -> NumStatements() + 3);
1719 block -> max_variable_index = max_variable_index;
1720 LocalSymbolTable().Push(block -> Table());
1721
1722 block_body -> block_symbol = block;
1723 block_body -> nesting_level = LocalBlockStack().Size();
1724 LocalBlockStack().Push(block_body);
1725
1726 ProcessBlockStatements(block_body);
1727
1728 LocalBlockStack().Pop();
1729 LocalSymbolTable().Pop();
1730
1731 //
1732 // Update the information for the block that immediately encloses the
1733 // current block.
1734 //
1735 if (LocalBlockStack().TopMaxEnclosedVariableIndex() <
1736 block -> max_variable_index)
1737 {
1738 LocalBlockStack().TopMaxEnclosedVariableIndex() =
1739 block -> max_variable_index;
1740 }
1741
1742 block -> CompressSpace(); // space optimization
1743
1744 if (try_statement -> block -> can_complete_normally)
1745 try_statement -> can_complete_normally = true;
1746
1747 //
1748 // A catch block is reachable iff both of the following are true:
1749 // . Some expression or throw statement in the try block is reachable
1750 // and can throw an exception that is assignable to the parameter
1751 // of the catch clause C. Note that every try block, including an
1752 // empty one, is considered to throw unchecked exceptions.
1753 // . There is no earlier catch block A in the try statement such that
1754 // the type of C's parameter is the same as or a subclass of the
1755 // type of A's parameter.
1756 //
1757 // Note that the use of the word assignable here is slightly misleading.
1758 // It does not mean assignable in the strict sense defined in section 5.2.
1759 // Using the strict definition of 5.2, the rule can be more accurately
1760 // stated as follows:
1761 //
1762 // . Catchable Exception:
1763 // Some expression or throw statement in the try block is reachable
1764 // and can throw an exception S that is assignable to the parameter
1765 // with type T (S is a subclass of T) of the catch clause C.
1766 // In this case, when S is thrown it will definitely be caught by
1767 // clause C.
1768 //
1769 // . Convertible Exception:
1770 // The type T of the parameter of the catch clause C is assignable to
1771 // the type S (T is a subclass of S) of an exception that can be
1772 // thrown by some expression or throw statement in the try block that
1773 // is reachable. This rule captures the idea that at run time an
1774 // object declared to be of type S can actually be an instance of an
1775 // object of type T in which case it will be caught by clause C.
1776 //
1777 Tuple<TypeSymbol*> catchable_exceptions;
1778 Tuple<TypeSymbol*> convertible_exceptions;
1779 exception_set -> AddElement(control.Error());
1780 exception_set -> AddElement(control.RuntimeException());
1781 for (unsigned l = 0; l < try_statement -> NumCatchClauses(); l++)
1782 {
1783 AstCatchClause* clause = try_statement -> CatchClause(l);
1784 TypeSymbol* type = clause -> parameter_symbol -> Type();
1785 if (type == control.no_type)
1786 continue;
1787 unsigned initial_length = catchable_exceptions.Length() +
1788 convertible_exceptions.Length();
1789
1790 for (TypeSymbol* exception =
1791 (TypeSymbol*) exception_set -> FirstElement();
1792 exception;
1793 exception = (TypeSymbol*) exception_set -> NextElement())
1794 {
1795 assert(exception != control.null_type);
1796 if (CanAssignmentConvertReference(type, exception))
1797 catchable_exceptions.Next() = exception;
1798 else if (CanAssignmentConvertReference(exception, type))
1799 convertible_exceptions.Next() = exception;
1800 }
1801
1802 //
1803 // No exception was found which can be caught by this clause.
1804 //
1805 if (catchable_exceptions.Length() + convertible_exceptions.Length() ==
1806 initial_length)
1807 {
1808 ReportSemError(SemanticError::UNREACHABLE_CATCH_CLAUSE,
1809 clause -> formal_parameter,
1810 type -> ContainingPackageName(),
1811 type -> ExternalName());
1812 }
1813 else
1814 {
1815 //
1816 // Search to see if this clause duplicates a prior one.
1817 //
1818 AstCatchClause* previous_clause;
1819 unsigned k;
1820 for (k = 0; k < l; k++)
1821 {
1822 previous_clause = try_statement -> CatchClause(k);
1823 if (type -> IsSubclass(previous_clause -> parameter_symbol ->
1824 Type()))
1825 break;
1826 }
1827
1828 if (k < l)
1829 {
1830 FileLocation loc(lex_stream,
1831 (previous_clause -> formal_parameter ->
1832 RightToken()));
1833 TypeSymbol* prev_type =
1834 previous_clause -> parameter_symbol -> Type();
1835 ReportSemError(SemanticError::BLOCKED_CATCH_CLAUSE,
1836 clause -> formal_parameter,
1837 type -> ContainingPackageName(),
1838 type -> ExternalName(),
1839 prev_type -> ContainingPackageName(),
1840 prev_type -> ExternalName(),
1841 loc.location);
1842 }
1843 else clause -> block -> is_reachable = true;
1844 }
1845 }
1846
1847 try_statement -> processing_try_block = false;
1848 TryStatementStack().Pop();
1849 TryExceptionTableStack().Pop();
1850 if (TryExceptionTableStack().Top())
1851 {
1852 //
1853 // First, remove all the thrown exceptions that are definitely caught
1854 // by the enclosing try statement. Then, add the remaining ones to the
1855 // set that must be caught by the immediately enclosing try statement.
1856 //
1857 for (unsigned i = 0; i < catchable_exceptions.Length(); i++)
1858 exception_set -> RemoveElement(catchable_exceptions[i]);
1859 TryExceptionTableStack().Top() -> Union(*exception_set);
1860 }
1861 delete exception_set;
1862
1863 //
1864 // A try statement cannot complete normally if it contains a finally
1865 // clause that cannot complete normally. But remember that a continue
1866 // statement may have already marked the try statement as completing
1867 // normally. Clean up from above.
1868 //
1869 if (try_statement -> finally_clause_opt &&
1870 ! try_statement -> finally_clause_opt -> block -> can_complete_normally)
1871 {
1872 try_statement -> can_complete_normally = false;
1873 delete TryExceptionTableStack().Top();
1874 TryExceptionTableStack().Pop();
1875 AbruptFinallyStack().Pop();
1876 }
1877 }
1878
1879
ProcessAssertStatement(Ast * stmt)1880 void Semantic::ProcessAssertStatement(Ast* stmt)
1881 {
1882 AstAssertStatement* assert_statement = (AstAssertStatement*) stmt;
1883
1884 ProcessExpression(assert_statement -> condition);
1885
1886 TypeSymbol* type = assert_statement -> condition -> Type();
1887 if (type != control.no_type && type != control.boolean_type)
1888 {
1889 ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
1890 assert_statement -> condition,
1891 type -> ContainingPackageName(),
1892 type -> ExternalName());
1893 }
1894 //
1895 // If the condition is not constant true, store a reference to this class's
1896 // assert variable (creating it if necessary as a side-effect). However,
1897 // if we are not emitting asserts, we can skip this.
1898 //
1899 else if (! IsConstantTrue(assert_statement -> condition) &&
1900 ! control.option.noassert)
1901 {
1902 assert_statement -> assert_variable =
1903 ThisType() -> FindOrInsertAssertVariable();
1904 }
1905
1906 if (assert_statement -> message_opt)
1907 {
1908 ProcessExpressionOrStringConstant(assert_statement -> message_opt);
1909 if (assert_statement -> message_opt -> Type() == control.void_type)
1910 ReportSemError(SemanticError::TYPE_IS_VOID,
1911 assert_statement -> message_opt,
1912 assert_statement -> message_opt -> Type() -> Name());
1913 }
1914
1915 //
1916 // Asserts can complete normally iff reachable.
1917 //
1918 assert_statement -> can_complete_normally =
1919 assert_statement -> is_reachable;
1920 }
1921
1922
ProcessEmptyStatement(Ast * stmt)1923 void Semantic::ProcessEmptyStatement(Ast* stmt)
1924 {
1925 AstEmptyStatement* empty_statement = (AstEmptyStatement*) stmt;
1926
1927 //
1928 // An empty statement can complete normally iff it is reachable.
1929 //
1930 empty_statement -> can_complete_normally = empty_statement -> is_reachable;
1931 }
1932
1933
GetLocalType(AstDeclaredType * class_declaration)1934 TypeSymbol* Semantic::GetLocalType(AstDeclaredType* class_declaration)
1935 {
1936 NameSymbol* name_symbol = lex_stream ->
1937 NameSymbol(class_declaration -> class_body -> identifier_token);
1938 TypeSymbol* type =
1939 LocalSymbolTable().Top() -> InsertTypeSymbol(name_symbol);
1940
1941 TypeSymbol* this_type = ThisType();
1942 TypeSymbol* outermost_type = this_type -> outermost_type;
1943 if (! this_type -> local)
1944 this_type -> local = new SymbolSet;
1945
1946 //
1947 // Anonymous and local classes can clash if we don't use both when
1948 // determining the id number of this class.
1949 //
1950 IntToWstring value(this_type -> NumLocalTypes() +
1951 this_type -> NumAnonymousTypes() + 1);
1952 int length = this_type -> ExternalNameLength() + 1 + value.Length() +
1953 name_symbol -> NameLength(); // +1 for $
1954 wchar_t* external_name = new wchar_t[length + 1]; // +1 for '\0';
1955 wcscpy(external_name, this_type -> ExternalName());
1956 wcscat(external_name, (control.option.target < JikesOption::SDK1_5
1957 ? StringConstant::US_DS : StringConstant::US_MI));
1958 wcscat(external_name, value.String());
1959 wcscat(external_name, name_symbol -> Name());
1960
1961 type -> outermost_type = outermost_type;
1962 type -> SetExternalIdentity(control.FindOrInsertName(external_name,
1963 length));
1964 this_type -> local -> AddElement(type);
1965
1966 delete [] external_name;
1967
1968 return type;
1969 }
1970
1971
ProcessClassDeclaration(Ast * stmt)1972 void Semantic::ProcessClassDeclaration(Ast* stmt)
1973 {
1974 AstLocalClassStatement* class_statement = (AstLocalClassStatement*) stmt;
1975 AstDeclaredType* class_declaration = class_statement -> declaration;
1976 AstClassBody* class_body = class_declaration -> class_body;
1977
1978 CheckNestedTypeDuplication(state_stack.Top(),
1979 class_body -> identifier_token);
1980
1981 TypeSymbol* inner_type = GetLocalType(class_declaration);
1982 inner_type -> outermost_type = ThisType() -> outermost_type;
1983 inner_type -> supertypes_closure = new SymbolSet;
1984 inner_type -> subtypes_closure = new SymbolSet;
1985 inner_type -> subtypes = new SymbolSet;
1986 inner_type -> semantic_environment =
1987 new SemanticEnvironment(this, inner_type, state_stack.Top());
1988 inner_type -> declaration = class_body;
1989 inner_type -> file_symbol = source_file_symbol;
1990 inner_type -> SetFlags(ProcessLocalClassModifiers(class_declaration));
1991 inner_type -> SetOwner(ThisMethod());
1992 //
1993 // Add 3 extra elements for padding. May need a default constructor and
1994 // other support elements.
1995 //
1996 inner_type -> SetSymbolTable(class_body -> NumClassBodyDeclarations() + 3);
1997 inner_type -> SetLocation();
1998 inner_type -> SetSignature(control);
1999
2000 //
2001 // If a local class is not in a static region, it needs a place to store
2002 // the enclosing instance.
2003 //
2004 if (! StaticRegion())
2005 inner_type -> InsertThis0();
2006
2007 // Save environment for processing bodies later.
2008 class_body -> semantic_environment = inner_type -> semantic_environment;
2009 CheckNestedMembers(inner_type, class_body);
2010 ProcessTypeHeaders(class_body);
2011
2012 ProcessMembers(class_body);
2013 CompleteSymbolTable(class_body);
2014 ProcessExecutableBodies(class_body);
2015 UpdateLocalConstructors(inner_type);
2016 }
2017
2018
ProcessThisCall(AstThisCall * this_call)2019 void Semantic::ProcessThisCall(AstThisCall* this_call)
2020 {
2021 TypeSymbol* this_type = ThisType();
2022
2023 // Signal that we are about to process an explicit constructor invocation.
2024 ExplicitConstructorInvocation() = this_call;
2025
2026 if (this_call -> type_arguments_opt)
2027 {
2028 ReportSemError(SemanticError::EXPLICIT_TYPE_ARGUMENTS_UNSUPPORTED,
2029 this_call -> type_arguments_opt);
2030 }
2031 bool bad_argument = ProcessArguments(this_call -> arguments);
2032 if (! bad_argument)
2033 {
2034 MethodSymbol* constructor = FindConstructor(this_type, this_call,
2035 this_call -> this_token,
2036 this_call -> RightToken());
2037 if (constructor)
2038 {
2039 this_call -> symbol = constructor;
2040 MethodInvocationConversion(this_call -> arguments, constructor);
2041 for (unsigned i = 0; i < constructor -> NumThrows(); i++)
2042 {
2043 TypeSymbol* exception = constructor -> Throws(i);
2044 if (UncaughtException(exception))
2045 ReportSemError(SemanticError::UNCAUGHT_EXPLICIT_THIS_EXCEPTION,
2046 this_call -> this_token,
2047 exception -> ContainingPackageName(),
2048 exception -> ExternalName());
2049 }
2050
2051 //
2052 // Not all shadowed variables are known yet, but there is no
2053 // need to save context, since all shadow variables required by
2054 // the target constructor can just be passed along.
2055 //
2056 }
2057 }
2058
2059 //
2060 // Signal that we are no longer processing an explicit constructor
2061 // invocation.
2062 //
2063 ExplicitConstructorInvocation() = NULL;
2064 }
2065
2066
ProcessSuperCall(AstSuperCall * super_call)2067 void Semantic::ProcessSuperCall(AstSuperCall* super_call)
2068 {
2069 TypeSymbol* this_type = ThisType();
2070 if (super_call -> symbol)
2071 {
2072 assert(this_type -> Anonymous());
2073 return;
2074 }
2075
2076 // Signal that we are about to process an explicit constructor invocation.
2077 ExplicitConstructorInvocation() = super_call;
2078
2079 TypeSymbol* super_type = this_type -> super;
2080 if (! super_type)
2081 {
2082 assert(this_type == control.Object());
2083 ReportSemError(SemanticError::OBJECT_HAS_NO_SUPER_TYPE,
2084 super_call -> super_token);
2085 return;
2086 }
2087
2088 if (super_call -> base_opt)
2089 {
2090 ProcessExpression(super_call -> base_opt);
2091
2092 TypeSymbol* expr_type = super_call -> base_opt -> Type();
2093 if (expr_type != control.no_type)
2094 {
2095 TypeSymbol* containing_type = super_type -> EnclosingType();
2096 if (expr_type -> Primitive() || expr_type == control.null_type)
2097 {
2098 ReportSemError(SemanticError::TYPE_NOT_REFERENCE,
2099 super_call -> base_opt,
2100 expr_type -> ExternalName());
2101 super_call -> base_opt -> symbol = control.no_type;
2102 }
2103 else if (! containing_type)
2104 {
2105 if (! super_type -> Bad())
2106 ReportSemError(SemanticError::SUPER_TYPE_NOT_INNER_CLASS,
2107 super_call -> base_opt,
2108 super_type -> ContainingPackageName(),
2109 super_type -> ExternalName(),
2110 this_type -> ContainingPackageName(),
2111 this_type -> ExternalName(),
2112 expr_type -> ContainingPackageName(),
2113 expr_type -> ExternalName());
2114 super_call -> base_opt -> symbol = control.no_type;
2115 }
2116 //
2117 // JLS2 8.8.5.1: For an enclosing class O of the superclass,
2118 // the qualifying primary must be of type O or a subclass.
2119 //
2120 else if (! expr_type -> IsSubclass(containing_type))
2121 {
2122 ReportSemError(SemanticError::INVALID_ENCLOSING_INSTANCE,
2123 super_call -> base_opt,
2124 this_type -> ContainingPackageName(),
2125 this_type -> ExternalName(),
2126 containing_type -> ContainingPackageName(),
2127 containing_type -> ExternalName(),
2128 expr_type -> ContainingPackageName(),
2129 expr_type -> ExternalName());
2130 super_call -> base_opt -> symbol = control.no_type;
2131 }
2132 }
2133 }
2134 else // (! super_call -> base_opt)
2135 {
2136 if (super_type && super_type -> EnclosingType())
2137 super_call -> base_opt =
2138 CreateAccessToType(super_call, super_type -> EnclosingType());
2139 }
2140
2141 if (super_call -> type_arguments_opt)
2142 {
2143 ReportSemError(SemanticError::EXPLICIT_TYPE_ARGUMENTS_UNSUPPORTED,
2144 super_call -> type_arguments_opt);
2145 }
2146 MethodSymbol* constructor = NULL;
2147 bool bad_argument = ProcessArguments(super_call -> arguments);
2148 if (! bad_argument)
2149 {
2150 constructor = FindConstructor(super_type, super_call,
2151 super_call -> super_token,
2152 super_call -> RightToken());
2153 }
2154
2155 if (constructor)
2156 {
2157 if (constructor -> ACC_PRIVATE())
2158 {
2159 //
2160 // Create accessor constructor, and add extra null
2161 // to the constructor invocation.
2162 //
2163 constructor = super_type -> GetReadAccessConstructor(constructor);
2164 super_call -> arguments -> AddNullArgument();
2165 }
2166
2167 super_call -> symbol = constructor;
2168 if (super_call -> base_opt)
2169 {
2170 assert(CanAssignmentConvertReference(super_type -> EnclosingType(),
2171 super_call -> base_opt -> Type()));
2172
2173 super_call -> base_opt =
2174 ConvertToType(super_call -> base_opt,
2175 super_type -> EnclosingType());
2176 }
2177 MethodInvocationConversion(super_call -> arguments, constructor);
2178
2179 //
2180 // Make sure that the throws signature of the constructor is
2181 // processed.
2182 //
2183 unsigned i;
2184 for (i = 0; i < constructor -> NumThrows(); i++)
2185 {
2186 TypeSymbol* exception = constructor -> Throws(i);
2187 if (UncaughtException(exception))
2188 ReportSemError(SemanticError::UNCAUGHT_EXPLICIT_SUPER_EXCEPTION,
2189 super_call,
2190 exception -> ContainingPackageName(),
2191 exception -> ExternalName(),
2192 constructor -> containing_type -> ContainingPackageName(),
2193 constructor -> containing_type -> ExternalName());
2194 }
2195
2196 //
2197 // A local super type may use enclosed local variables. If so, we
2198 // must add the parameters which allow the local type to
2199 // initialize its shadows.
2200 //
2201 if (super_type -> IsLocal())
2202 {
2203 unsigned param_count = super_type -> NumConstructorParameters();
2204 if (super_type -> LocalClassProcessingCompleted() && param_count)
2205 {
2206 super_call -> arguments -> AllocateLocalArguments(param_count);
2207 for (i = 0; i < param_count; i++)
2208 {
2209 //
2210 // We may need to create a shadow in the outermost
2211 // local class enclosing the variable.
2212 //
2213 AstName* simple_name = compilation_unit ->
2214 ast_pool -> GenName(super_call -> super_token);
2215 VariableSymbol* accessor =
2216 FindLocalVariable(super_type -> ConstructorParameter(i),
2217 this_type);
2218 simple_name -> symbol = accessor;
2219 TypeSymbol* owner = accessor -> ContainingType();
2220 if (owner != this_type)
2221 CreateAccessToScopedVariable(simple_name, owner);
2222 super_call -> arguments -> AddLocalArgument(simple_name);
2223 }
2224 }
2225 else
2226 {
2227 //
2228 // We are within body of super_type; save processing for
2229 // later, since not all shadows may be known yet. See
2230 // ProcessClassDeclaration.
2231 //
2232 super_type -> AddLocalConstructorCallEnvironment
2233 (GetEnvironment(super_call -> arguments));
2234 }
2235 }
2236 }
2237
2238 //
2239 // Signal that we are no longer processing an explicit constructor
2240 // invocation.
2241 //
2242 ExplicitConstructorInvocation() = NULL;
2243 }
2244
2245
2246 //
2247 // Checks that types in a throws clause extend Throwable. throws_list is NULL
2248 // except in pedantic mode, where it is used to detect duplicates.
2249 //
CheckThrow(AstTypeName * throw_expression,Tuple<AstTypeName * > * throws_list)2250 void Semantic::CheckThrow(AstTypeName* throw_expression,
2251 Tuple<AstTypeName*>* throws_list)
2252 {
2253 TypeSymbol* throw_type = throw_expression -> symbol;
2254 if (throw_type -> Bad())
2255 return;
2256
2257 if (throw_type -> ACC_INTERFACE())
2258 {
2259 ReportSemError(SemanticError::NOT_A_CLASS, throw_expression,
2260 throw_type -> ContainingPackageName(),
2261 throw_type -> ExternalName());
2262 }
2263 else if (! throw_type -> IsSubclass(control.Throwable()))
2264 {
2265 ReportSemError(SemanticError::TYPE_NOT_THROWABLE, throw_expression,
2266 throw_type -> ContainingPackageName(),
2267 throw_type -> ExternalName());
2268 }
2269 else if (throw_type == control.Exception() ||
2270 throw_type == control.Throwable())
2271 {
2272 ReportSemError(SemanticError::EJ_OVERLY_GENERAL_THROWS_CLAUSE,
2273 throw_expression);
2274 }
2275 else if (control.option.pedantic)
2276 {
2277 assert(throws_list);
2278 if (! CheckedException(throw_type))
2279 ReportSemError(SemanticError::UNCHECKED_THROWS_CLAUSE_CLASS,
2280 throw_expression,
2281 throw_type -> ContainingPackageName(),
2282 throw_type -> ExternalName());
2283 else
2284 {
2285 bool add = true;
2286 for (unsigned i = 0; i < throws_list -> Length(); i++)
2287 {
2288 AstTypeName* other_expr = (*throws_list)[i];
2289 TypeSymbol* other_type = other_expr -> symbol;
2290 if (other_type == throw_type)
2291 {
2292 ReportSemError(SemanticError::DUPLICATE_THROWS_CLAUSE_CLASS,
2293 throw_expression,
2294 throw_type -> ContainingPackageName(),
2295 throw_type -> ExternalName());
2296 add = false;
2297 }
2298 else if (throw_type -> IsSubclass(other_type))
2299 {
2300 ReportSemError(SemanticError::REDUNDANT_THROWS_CLAUSE_CLASS,
2301 throw_expression,
2302 throw_type -> ContainingPackageName(),
2303 throw_type -> ExternalName(),
2304 other_type -> ContainingPackageName(),
2305 other_type -> ExternalName());
2306 add = false;
2307 }
2308 else if (other_type -> IsSubclass(throw_type))
2309 {
2310 ReportSemError(SemanticError::REDUNDANT_THROWS_CLAUSE_CLASS,
2311 other_expr,
2312 other_type -> ContainingPackageName(),
2313 other_type -> ExternalName(),
2314 throw_type -> ContainingPackageName(),
2315 throw_type -> ExternalName());
2316 //
2317 // Remove other type from the list, to reduce extra errors.
2318 //
2319 int last_index = throws_list -> Length() - 1;
2320 (*throws_list)[i] = (*throws_list)[last_index];
2321 throws_list -> Reset(last_index);
2322 i--;
2323 }
2324 }
2325 if (add)
2326 throws_list -> Next() = throw_expression;
2327 }
2328 }
2329 }
2330
2331
ProcessMethodBody(AstMethodDeclaration * method_declaration)2332 void Semantic::ProcessMethodBody(AstMethodDeclaration* method_declaration)
2333 {
2334 MethodSymbol* this_method = ThisMethod();
2335
2336 if (method_declaration -> NumThrows())
2337 {
2338 Tuple<AstTypeName*>* throws_list = NULL;
2339 if (control.option.pedantic)
2340 throws_list = new Tuple<AstTypeName*>
2341 (method_declaration -> NumThrows());
2342 for (unsigned k = 0; k < method_declaration -> NumThrows(); k++)
2343 CheckThrow(method_declaration -> Throw(k), throws_list);
2344 delete throws_list;
2345 }
2346
2347 if (method_declaration -> method_body_opt)
2348 {
2349 AstMethodBody* method_body = method_declaration -> method_body_opt;
2350 if (method_body -> explicit_constructor_opt)
2351 ReportSemError(SemanticError::MISPLACED_EXPLICIT_CONSTRUCTOR,
2352 method_body -> explicit_constructor_opt);
2353 method_body -> block_symbol = this_method -> block_symbol;
2354 method_body -> nesting_level = LocalBlockStack().Size();
2355 LocalBlockStack().Push(method_body);
2356
2357 ProcessBlockStatements(method_body);
2358
2359 LocalBlockStack().Pop();
2360
2361 if (method_body -> can_complete_normally)
2362 {
2363 if (this_method -> Type() == control.void_type)
2364 {
2365 AstReturnStatement* return_statement =
2366 compilation_unit -> ast_pool -> GenReturnStatement();
2367 return_statement -> return_token =
2368 method_body -> right_brace_token;
2369 return_statement -> semicolon_token =
2370 method_body -> right_brace_token;
2371 return_statement -> is_reachable = true;
2372 method_body -> can_complete_normally = false;
2373 method_body -> AddStatement(return_statement);
2374 }
2375 else
2376 {
2377 ReportSemError(SemanticError::TYPED_METHOD_WITH_NO_RETURN,
2378 method_declaration -> type -> LeftToken(),
2379 method_declaration -> method_declarator -> identifier_token,
2380 this_method -> Header(),
2381 this_method -> Type() -> Name());
2382 }
2383 }
2384
2385 if (this_method -> ACC_ABSTRACT() || this_method -> ACC_NATIVE())
2386 {
2387 ReportSemError(SemanticError::ABSTRACT_METHOD_WITH_BODY,
2388 method_declaration, this_method -> Header());
2389 }
2390 }
2391 else if (! (this_method -> ACC_ABSTRACT() || this_method -> ACC_NATIVE()))
2392 {
2393 ReportSemError(SemanticError::NON_ABSTRACT_METHOD_WITHOUT_BODY,
2394 method_declaration, this_method -> Header());
2395 }
2396
2397 this_method -> block_symbol -> CompressSpace(); // space optimization
2398 }
2399
2400
ProcessConstructorBody(AstConstructorDeclaration * constructor_declaration)2401 void Semantic::ProcessConstructorBody(AstConstructorDeclaration* constructor_declaration)
2402 {
2403 TypeSymbol* this_type = ThisType();
2404 MethodSymbol* this_method = ThisMethod();
2405
2406 if (constructor_declaration -> NumThrows())
2407 {
2408 Tuple<AstTypeName*>* throws_list = NULL;
2409 if (control.option.pedantic)
2410 throws_list = new Tuple<AstTypeName*>
2411 (constructor_declaration -> NumThrows());
2412 for (unsigned k = 0; k < constructor_declaration -> NumThrows(); k++)
2413 CheckThrow(constructor_declaration -> Throw(k), throws_list);
2414 delete throws_list;
2415 }
2416
2417 AstMethodBody* constructor_block =
2418 constructor_declaration -> constructor_body;
2419
2420 AstSuperCall* super_call = NULL;
2421 TypeSymbol* super_type = this_type -> super;
2422
2423 if (constructor_block -> explicit_constructor_opt)
2424 {
2425 super_call =
2426 constructor_block -> explicit_constructor_opt -> SuperCallCast();
2427 if (super_call)
2428 ProcessSuperCall(super_call);
2429 else
2430 {
2431 AstThisCall* this_call = constructor_block ->
2432 explicit_constructor_opt -> ThisCallCast();
2433 assert(this_call);
2434 ProcessThisCall(this_call);
2435 }
2436 }
2437 else if (super_type)
2438 {
2439 TokenIndex loc = constructor_block -> LeftToken();
2440 super_call = compilation_unit -> ast_pool -> GenSuperCall();
2441 super_call -> super_token = loc;
2442 super_call -> arguments =
2443 compilation_unit -> ast_pool -> GenArguments(loc, loc);
2444 super_call -> semicolon_token = loc;
2445
2446 constructor_block -> explicit_constructor_opt = super_call;
2447
2448 ProcessSuperCall(super_call);
2449 }
2450
2451 //
2452 // Guess that the number of elements will not exceed the number of
2453 // statements.
2454 //
2455 int table_size = constructor_block -> NumStatements();
2456 BlockSymbol* block = LocalSymbolTable().Top() ->
2457 InsertBlockSymbol(table_size);
2458 block -> max_variable_index =
2459 this_method -> block_symbol -> max_variable_index;
2460 LocalSymbolTable().Push(block -> Table());
2461
2462 constructor_block -> block_symbol = block;
2463 constructor_block -> nesting_level = LocalBlockStack().Size();
2464 LocalBlockStack().Push(constructor_block);
2465
2466 ProcessBlockStatements(constructor_block);
2467
2468 if (constructor_block -> can_complete_normally)
2469 {
2470 AstReturnStatement* return_statement =
2471 compilation_unit -> ast_pool -> GenReturnStatement();
2472 return_statement -> return_token =
2473 constructor_block -> right_brace_token;
2474 return_statement -> semicolon_token =
2475 constructor_block -> right_brace_token;
2476 return_statement -> is_reachable = true;
2477 constructor_block -> can_complete_normally = false;
2478 constructor_block -> AddStatement(return_statement);
2479 }
2480
2481 LocalBlockStack().Pop();
2482 LocalSymbolTable().Pop();
2483
2484 //
2485 // Update the local variable info for the main block associated with this
2486 // constructor.
2487 //
2488 if (this_method -> block_symbol -> max_variable_index <
2489 block -> max_variable_index)
2490 {
2491 this_method -> block_symbol -> max_variable_index =
2492 block -> max_variable_index;
2493 }
2494
2495 block -> CompressSpace(); // space optimization
2496 }
2497
2498
ProcessExecutableBodies(AstClassBody * class_body)2499 void Semantic::ProcessExecutableBodies(AstClassBody* class_body)
2500 {
2501 if (compilation_unit -> BadCompilationUnitCast())
2502 return; // errors were detected, exit now
2503
2504 state_stack.Push(class_body -> semantic_environment);
2505 TypeSymbol* this_type = ThisType();
2506 unsigned i;
2507
2508 assert(this_type -> HeaderProcessed());
2509 assert(this_type -> ConstructorMembersProcessed());
2510 assert(this_type -> MethodMembersProcessed());
2511 assert(this_type -> FieldMembersProcessed());
2512
2513 // All variable declarations have already been processed.
2514 if (! this_type -> ACC_INTERFACE())
2515 {
2516 //
2517 // Compute the set of instance final variables which must be assigned
2518 // in every constructor.
2519 //
2520 Tuple<VariableSymbol*> unassigned(FinalFields() -> Length());
2521 for (i = 0; i < FinalFields() -> Length(); i++)
2522 {
2523 VariableSymbol* variable_symbol = (*FinalFields())[i];
2524 if (! DefinitelyAssignedVariables() -> da_set[i])
2525 {
2526 assert(! variable_symbol -> ACC_STATIC());
2527 unassigned.Next() = variable_symbol;
2528 }
2529 }
2530 if (class_body -> NumConstructors() == 0)
2531 {
2532 //
2533 // Issue an error for each unassigned final.
2534 //
2535 for (i = 0; i < unassigned.Length(); i++)
2536 {
2537 ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE,
2538 unassigned[i] -> declarator,
2539 unassigned[i] -> Name());
2540 }
2541 //
2542 // Process the body of the default constructor, if there is one (if
2543 // the class is invalid, one might not exist).
2544 //
2545 if (class_body -> default_constructor)
2546 {
2547 ThisMethod() =
2548 class_body -> default_constructor -> constructor_symbol;
2549 LocalSymbolTable().Push(ThisMethod() -> block_symbol ->
2550 Table());
2551 ProcessConstructorBody(class_body -> default_constructor);
2552 LocalSymbolTable().Pop();
2553 ThisMethod() -> max_block_depth = 1;
2554 }
2555 }
2556 else
2557 {
2558 DefinitePair initial_state(*DefinitelyAssignedVariables());
2559 for (i = 0; i < class_body -> NumConstructors(); i++)
2560 {
2561 AstConstructorDeclaration* constructor_decl =
2562 class_body -> Constructor(i);
2563 MethodSymbol* this_method =
2564 constructor_decl -> constructor_symbol;
2565 if (! this_method)
2566 continue;
2567 ThisMethod() = this_method;
2568 AstMethodBody* constructor_block =
2569 constructor_decl -> constructor_body;
2570
2571 LocalSymbolTable().Push(this_method -> block_symbol ->
2572 Table());
2573 LocalBlockStack().max_size = 0;
2574 ProcessConstructorBody(constructor_decl);
2575 LocalSymbolTable().Pop();
2576 this_method -> max_block_depth = LocalBlockStack().max_size;
2577 //
2578 // Each constructor starts from the same initial definite
2579 // assignment status, except those which call this() start with
2580 // all fields definitely assigned.
2581 //
2582 if (constructor_block -> explicit_constructor_opt &&
2583 (constructor_block -> explicit_constructor_opt ->
2584 ThisCallCast()))
2585 {
2586 DefinitelyAssignedVariables() -> AssignAll();
2587 DefiniteConstructorBody(constructor_decl);
2588 }
2589 else
2590 {
2591 *DefinitelyAssignedVariables() = initial_state;
2592 DefiniteConstructorBody(constructor_decl);
2593 for (unsigned k = 0; k < unassigned.Length(); k++)
2594 {
2595 VariableSymbol* variable_symbol = unassigned[k];
2596 if (! DefinitelyAssignedVariables() ->
2597 da_set[variable_symbol -> LocalVariableIndex()])
2598 {
2599 ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE_IN_CONSTRUCTOR,
2600 constructor_decl,
2601 variable_symbol -> Name());
2602 }
2603 }
2604 }
2605 }
2606 ConstructorCycleChecker cycle_checker(class_body);
2607 }
2608 }
2609
2610 //
2611 // No need to worry about private access constructors, as we have already
2612 // done all necessary processing when creating them. Following all
2613 // constructors, all fields are definitely assigned, and are no longer
2614 // treated as blank finals.
2615 //
2616 DefinitelyAssignedVariables() -> AssignAll();
2617 BlankFinals() -> SetEmpty();
2618
2619 for (i = 0; i < class_body -> NumMethods(); i++)
2620 {
2621 AstMethodDeclaration* method_decl = class_body -> Method(i);
2622 ThisMethod() = method_decl -> method_symbol;
2623 MethodSymbol* this_method = ThisMethod();
2624 if (this_method)
2625 {
2626 LocalSymbolTable().Push(this_method -> block_symbol -> Table());
2627 LocalBlockStack().max_size = 0;
2628 unsigned start_num_errors = NumErrors();
2629 ProcessMethodBody(method_decl);
2630 LocalSymbolTable().Pop();
2631 this_method -> max_block_depth = LocalBlockStack().max_size;
2632 if (NumErrors() == start_num_errors)
2633 DefiniteMethodBody(method_decl);
2634 }
2635 }
2636 ThisMethod() = NULL;
2637
2638 //
2639 // Recursively process all inner types.
2640 //
2641 for (i = 0; i < class_body -> NumNestedClasses(); i++)
2642 {
2643 AstClassDeclaration* declaration = class_body -> NestedClass(i);
2644 if (declaration -> class_body -> semantic_environment)
2645 ProcessExecutableBodies(declaration -> class_body);
2646 }
2647 for (i = 0; i < class_body -> NumNestedInterfaces(); i++)
2648 {
2649 AstInterfaceDeclaration* declaration =
2650 class_body -> NestedInterface(i);
2651 if (declaration -> class_body -> semantic_environment)
2652 ProcessExecutableBodies(declaration -> class_body);
2653 }
2654
2655 DefiniteCleanUp();
2656 state_stack.Pop();
2657 }
2658
2659
2660 #ifdef HAVE_JIKES_NAMESPACE
2661 } // Close namespace Jikes block
2662 #endif
2663
2664