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