home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 20 / AACD20.BIN / AACD / Programming / Jikes / Source / src / body.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-24  |  97.3 KB  |  2,362 lines

  1. // $Id: body.cpp,v 1.34 2001/02/18 23:21:18 mdejong 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://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10.  
  11. #include "platform.h"
  12. #include "semantic.h"
  13. #include "control.h"
  14.  
  15. #ifdef    HAVE_JIKES_NAMESPACE
  16. namespace Jikes {    // Open namespace Jikes block
  17. #endif
  18.  
  19. void Semantic::ProcessBlockStatements(AstBlock *block_body)
  20. {
  21.     //
  22.     // An empty block that is not a switch block can complete normally
  23.     // iff it is reachable. A nonempty block that is not a switch
  24.     // block can complete normally iff the last statement in it can
  25.     // complete normally.
  26.     //
  27.     if (block_body -> NumStatements() == 0)
  28.          block_body -> can_complete_normally = block_body -> is_reachable;
  29.     else
  30.     {
  31.         //
  32.         // The first statement in a nonempty block that is not a
  33.         // switch block is reachable iff the block is reachable.
  34.         // Every other statement S in a nonempty block that is not a
  35.         // switch block is reachable iff the statement preceeding S
  36.         // can complete normally.
  37.         //
  38.         AstStatement *statement = (AstStatement *) block_body -> Statement(0);
  39.         statement -> is_reachable = block_body -> is_reachable;
  40.         AstStatement *first_unreachable_statement = (AstStatement *) (statement -> is_reachable ? NULL : statement);
  41.         ProcessStatement(statement);
  42.         for (int i = 1; i < block_body -> NumStatements(); i++)
  43.         {
  44.             AstStatement *previous_statement = statement;
  45.             statement = (AstStatement *) block_body -> Statement(i);
  46.             statement -> is_reachable = previous_statement -> can_complete_normally;
  47.             if (! statement -> is_reachable && (first_unreachable_statement == NULL))
  48.                 first_unreachable_statement = statement;
  49.  
  50.             ProcessStatement(statement);
  51.         }
  52.  
  53.         if (statement -> can_complete_normally)
  54.             block_body -> can_complete_normally = true;
  55.  
  56.         //
  57.         // If we have one or more unreachable statements that are contained in a
  58.         // reachable block then issue message. (If the enclosing block is not reachable
  59.         // the message will be issued later for the enclosing block.)
  60.         //
  61.         if (first_unreachable_statement && LocalBlockStack().TopBlock() -> is_reachable)
  62.         {
  63.             if (first_unreachable_statement == statement)
  64.             {
  65.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  66.                                statement -> LeftToken(),
  67.                                statement -> RightToken());
  68.             }
  69.             else
  70.             {
  71.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENTS,
  72.                                first_unreachable_statement -> LeftToken(),
  73.                                statement -> RightToken());
  74.             }
  75.         }
  76.  
  77.         //
  78.         // If an enclosed block has a higher max_variable_index than the current block,
  79.         // update max_variable_index in the current_block, accordingly.
  80.         //
  81.         BlockSymbol *block = block_body -> block_symbol;
  82.         if (block -> max_variable_index < LocalBlockStack().TopMaxEnclosedVariableIndex())
  83.             block -> max_variable_index = LocalBlockStack().TopMaxEnclosedVariableIndex();
  84.     }
  85.  
  86.     return;
  87. }
  88.  
  89.  
  90. void Semantic::ProcessBlock(Ast *stmt)
  91. {
  92.     AstBlock *block_body = (AstBlock *) stmt;
  93.  
  94.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  95.  
  96.     //
  97.     // Guess that the number of elements will not exceed the number of statements + 3. The +3 takes into account
  98.     // one label + one ForInit declaration and one extra something else.
  99.     //
  100.     int table_size = block_body -> NumStatements() + 3;
  101.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(table_size);
  102.     //
  103.     // enclosing_block is not present only when we are processing the block of a static initializer
  104.     //
  105.     block -> max_variable_index = (enclosing_block ? enclosing_block -> block_symbol -> max_variable_index : 1);
  106.     LocalSymbolTable().Push(block -> Table());
  107.  
  108.     block_body -> block_symbol = block;
  109.     block_body -> nesting_level = LocalBlockStack().Size();
  110.     LocalBlockStack().Push(block_body);
  111.  
  112.     //
  113.     // Note that in constructing the Ast, the parser encloses each
  114.     // labeled statement in its own block. Therefore the declaration
  115.     // of this label will not conflict with the declaration of another
  116.     // label with the same name declared at the same nesting level.
  117.     //
  118.     // For example, the following sequence of statements is legal:
  119.     //
  120.     //     l: a = b;
  121.     //     l: b = c;
  122.     //
  123.     for (int i = 0; i < block_body -> NumLabels(); i++)
  124.     {
  125.         NameSymbol *name_symbol = lex_stream -> NameSymbol(block_body -> Label(i));
  126.         Symbol *symbol = NULL;
  127.         for (SemanticEnvironment *env = state_stack.Top(); env; env = env -> previous)
  128.         {
  129.             symbol = env -> symbol_table.FindLabelSymbol(name_symbol);
  130.             if (symbol)
  131.                 break;
  132.         }
  133.  
  134.         if (symbol)
  135.         {
  136.             ReportSemError(SemanticError::DUPLICATE_LABEL,
  137.                            block_body -> Label(i),
  138.                            block_body -> Label(i),
  139.                            name_symbol -> Name());
  140.         }
  141.         else
  142.         {
  143.             LabelSymbol *label = LocalSymbolTable().Top() -> InsertLabelSymbol(name_symbol);
  144.             label -> block = block_body;
  145.             label -> nesting_level = block_body -> nesting_level;
  146.         }
  147.     }
  148.  
  149.     ProcessBlockStatements(block_body);
  150.  
  151.     LocalBlockStack().Pop();
  152.     LocalSymbolTable().Pop();
  153.  
  154.     //
  155.     // Update the information for the block that immediately encloses the current block.
  156.     //
  157.     if (enclosing_block)
  158.     {
  159.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  160.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  161.     }
  162.  
  163.     block -> CompressSpace(); // space optimization
  164.  
  165.     return;
  166. }
  167.  
  168.  
  169. void Semantic::ProcessLocalVariableDeclarationStatement(Ast *stmt)
  170. {
  171.     AstLocalVariableDeclarationStatement *local_decl = (AstLocalVariableDeclarationStatement *) stmt;
  172.  
  173.     AstArrayType *array_type = local_decl -> type -> ArrayTypeCast();
  174.     Ast *actual_type = (array_type ? array_type -> type : local_decl -> type);
  175.  
  176.     AccessFlags access_flags = ProcessLocalModifiers(local_decl);
  177.  
  178.     AstPrimitiveType *primitive_type = actual_type -> PrimitiveTypeCast();
  179.     TypeSymbol *field_type = (primitive_type ? field_type = FindPrimitiveType(primitive_type) : MustFindType(actual_type));
  180.  
  181.     for (int i = 0; i < local_decl -> NumVariableDeclarators(); i++)
  182.     {
  183.         AstVariableDeclarator *variable_declarator = local_decl -> VariableDeclarator(i);
  184.         AstVariableDeclaratorId *name = variable_declarator -> variable_declarator_name;
  185.         NameSymbol *name_symbol = lex_stream -> NameSymbol(name -> identifier_token);
  186.  
  187. //
  188. // TODO: Confirm that this new test is indeed the case. In 1.0, only the more restricted test below was necessary.
  189. //
  190. //        if (LocalSymbolTable().FindVariableSymbol(name_symbol))
  191. //        {
  192. //            ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  193. //                           name -> identifier_token,
  194. //                           name -> identifier_token,
  195. //                           name_symbol -> Name());
  196. //        }
  197. //
  198.         SemanticEnvironment *where_found;
  199.         Tuple<VariableSymbol *> variables_found(2);
  200.         SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(), name_symbol, name -> identifier_token);
  201.         VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  202.         if (symbol && symbol -> IsLocal())
  203.         {
  204.             ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  205.                            name -> identifier_token,
  206.                            name -> identifier_token,
  207.                            name_symbol -> Name());
  208.         }
  209.         else
  210.         {
  211.             symbol = LocalSymbolTable().Top() -> InsertVariableSymbol(name_symbol);
  212.             variable_declarator -> symbol = symbol;
  213.  
  214.             int num_dimensions = (array_type ? array_type -> NumBrackets() : 0) + name -> NumBrackets();
  215.             if (num_dimensions == 0)
  216.                  symbol -> SetType(field_type);
  217.             else symbol -> SetType(field_type -> GetArrayType((Semantic *) this, num_dimensions));
  218.             symbol -> SetFlags(access_flags);
  219.             symbol -> SetOwner(ThisMethod());
  220.             symbol -> declarator = variable_declarator;
  221.             BlockSymbol *block = LocalBlockStack().TopBlock() -> block_symbol;
  222.             symbol -> SetLocalVariableIndex(block -> max_variable_index++); // Assigning a local_variable_index to a variable
  223.                                                                             // also marks it complete as a side-effect.
  224.             if (control.IsDoubleWordType(symbol -> Type()))
  225.                 block -> max_variable_index++;
  226.  
  227.             if (variable_declarator -> variable_initializer_opt)
  228.                  ProcessVariableInitializer(variable_declarator);
  229.         }
  230.     }
  231.  
  232.     //
  233.     // A local variable declaration statement can complete normally
  234.     // iff it is reachable.
  235.     //
  236.     local_decl -> can_complete_normally = local_decl -> is_reachable;
  237.  
  238.     return;
  239. }
  240.  
  241.  
  242. void Semantic::ProcessExpressionStatement(Ast *stmt)
  243. {
  244.     AstExpressionStatement *expression_statement = (AstExpressionStatement *) stmt;
  245.  
  246.     ProcessExpression(expression_statement -> expression);
  247.  
  248.     //
  249.     // An expression statement can complete normally iff it is reachable.
  250.     //
  251.     expression_statement -> can_complete_normally = expression_statement -> is_reachable;
  252.  
  253.     return;
  254. }
  255.  
  256.  
  257. void Semantic::ProcessSynchronizedStatement(Ast *stmt)
  258. {
  259.     AstSynchronizedStatement *synchronized_statement = (AstSynchronizedStatement *) stmt;
  260.  
  261.     ProcessExpression(synchronized_statement -> expression);
  262.  
  263.     synchronized_statement -> block -> is_reachable = synchronized_statement -> is_reachable;
  264.  
  265.     if (synchronized_statement -> expression -> Type() -> Primitive())
  266.     {
  267.         ReportSemError(SemanticError::TYPE_NOT_REFERENCE,
  268.                        synchronized_statement -> expression -> LeftToken(),
  269.                        synchronized_statement -> expression -> RightToken(),
  270.                        synchronized_statement -> expression -> Type() -> Name());
  271.     }
  272.  
  273.     AstBlock *enclosing_block = LocalBlockStack().TopBlock(),
  274.              *block_body = synchronized_statement -> block;
  275.  
  276.     //
  277.     // "synchronized" blocks require two more local variable slots for synchronization,
  278.     // plus one extra variable slot if the containing method returns a value, plus an
  279.     // additional slot if the value returned is double or long.
  280.     //
  281.     BlockSymbol *enclosing_block_symbol = enclosing_block -> block_symbol;
  282.     if (enclosing_block_symbol -> try_or_synchronized_variable_index == 0) // first such statement encountered in enclosing block?
  283.     {
  284.         enclosing_block_symbol -> try_or_synchronized_variable_index = enclosing_block_symbol -> max_variable_index;
  285.         enclosing_block_symbol -> max_variable_index += 2;
  286.         if (ThisMethod() -> Type() != control.void_type)
  287.         {
  288.              if (control.IsDoubleWordType(ThisMethod() -> Type()))
  289.                   enclosing_block_symbol -> max_variable_index += 2;
  290.              else enclosing_block_symbol -> max_variable_index += 1;
  291.         }
  292.     }
  293.  
  294.     //
  295.     // Guess that the number of elements will not exceed the number of statements + 3.
  296.     //
  297.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(block_body -> NumStatements() + 3);
  298.     block -> max_variable_index = enclosing_block_symbol -> max_variable_index;
  299.     LocalSymbolTable().Push(block -> Table());
  300.  
  301.     block_body -> block_symbol = block;
  302.     block_body -> nesting_level = LocalBlockStack().Size();
  303.     LocalBlockStack().Push(block_body);
  304.  
  305.     ProcessBlockStatements(block_body);
  306.  
  307.     LocalBlockStack().Pop();
  308.     LocalSymbolTable().Pop();
  309.  
  310.     if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  311.         LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  312.  
  313.     //
  314.     // If the synchronized_statement is enclosed in a loop and it contains a reachable continue statement
  315.     // then it may have already been marked as "can complete normally";
  316.     //
  317.     synchronized_statement -> can_complete_normally = synchronized_statement -> can_complete_normally ||
  318.                                                       synchronized_statement -> block -> can_complete_normally;
  319.  
  320.     block -> CompressSpace(); // space optimization
  321.  
  322.     return;
  323. }
  324.  
  325.  
  326. void Semantic::ProcessIfStatement(Ast *stmt)
  327. {
  328.     AstIfStatement *if_statement = (AstIfStatement *) stmt;
  329.  
  330.     ProcessExpression(if_statement -> expression);
  331.  
  332.     if (if_statement -> expression -> Type() != control.no_type &&
  333.         if_statement -> expression -> Type() != control.boolean_type)
  334.     {
  335.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  336.                        if_statement -> expression -> LeftToken(),
  337.                        if_statement -> expression -> RightToken(),
  338.                        if_statement -> expression -> Type() -> Name());
  339.     }
  340.  
  341.     //
  342.     // Recall that the parser ensures that the statements that appear in an if-statement
  343.     // (both the true and false statement) are enclosed in a block.
  344.     //
  345.     if_statement -> true_statement -> is_reachable = if_statement -> is_reachable;
  346.     ProcessBlock(if_statement -> true_statement);
  347.  
  348.     if (if_statement -> false_statement_opt)
  349.     {
  350.         if_statement -> false_statement_opt -> is_reachable = if_statement -> is_reachable;
  351.         ProcessBlock(if_statement -> false_statement_opt);
  352.  
  353.         //
  354.         // If the if_statement is enclosed in a loop and it contains a reachable continue statement
  355.         // then it may have already been marked as "can complete normally";
  356.         //
  357.         if_statement -> can_complete_normally = if_statement -> can_complete_normally ||
  358.                                                 if_statement -> true_statement -> can_complete_normally ||
  359.                                                 if_statement -> false_statement_opt -> can_complete_normally;
  360.     }
  361.     else if_statement -> can_complete_normally = if_statement -> is_reachable;
  362.  
  363.     return;
  364. }
  365.  
  366.  
  367. void Semantic::ProcessWhileStatement(Ast *stmt)
  368. {
  369.     AstWhileStatement *while_statement = (AstWhileStatement *) stmt;
  370.  
  371.     //
  372.     // Recall that each while statement is enclosed in a unique block by the parser
  373.     //
  374.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  375.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  376.  
  377.     AstStatement *enclosed_statement = while_statement -> statement;
  378.     enclosed_statement -> is_reachable = while_statement -> is_reachable;
  379.  
  380.     ProcessExpression(while_statement -> expression);
  381.     if (while_statement -> expression -> Type() == control.boolean_type)
  382.     {
  383.         if (while_statement -> expression -> IsConstant())
  384.         {
  385.             IntLiteralValue *literal = (IntLiteralValue *) while_statement -> expression -> value;
  386.             if (! literal -> value)
  387.             {
  388.                  if (while_statement -> is_reachable)
  389.                      while_statement -> can_complete_normally = true;
  390.                  enclosed_statement -> is_reachable = false;
  391.             }
  392.         }
  393.         else if (while_statement -> is_reachable)
  394.              while_statement -> can_complete_normally = true;
  395.     }
  396.     else if (while_statement -> expression -> Type() != control.no_type)
  397.     {
  398.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  399.                        while_statement -> expression -> LeftToken(),
  400.                        while_statement -> expression -> RightToken(),
  401.                        while_statement -> expression -> Type() -> Name());
  402.     }
  403.  
  404.     ProcessStatement(enclosed_statement);
  405.  
  406.     if ((! enclosed_statement -> is_reachable) && (while_statement -> is_reachable))
  407.     {
  408.         ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  409.                        enclosed_statement -> LeftToken(),
  410.                        enclosed_statement -> RightToken());
  411.     }
  412.  
  413.     //
  414.     // If the while statement contained a reachable break statement,
  415.     // then the while statement can complete normally. It is marked
  416.     // here only for completeness, as marking the enclosing block is
  417.     // enough to propagate the proper information upward.
  418.     //
  419.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  420.     if (block_body -> can_complete_normally)
  421.         while_statement -> can_complete_normally = true;
  422.  
  423.     BreakableStatementStack().Pop();
  424.     ContinuableStatementStack().Pop();
  425.  
  426.     return;
  427. }
  428.  
  429.  
  430. void Semantic::ProcessForStatement(Ast *stmt)
  431. {
  432.     AstForStatement *for_statement = (AstForStatement *) stmt;
  433.  
  434.     //
  435.     // Note that in constructing the Ast, the parser encloses each
  436.     // for-statement whose for-init-statements starts with a local
  437.     // variable declaration in its own block. Therefore a redeclaration
  438.     // of another local variable with the same name in a different loop
  439.     // at the same nesting level will not cause any conflict.
  440.     //
  441.     // For example, the following sequence of statements is legal:
  442.     //
  443.     //     for (int i = 0; i < 10; i++);
  444.     //     for (int i = 10; i < 20; i++);
  445.     //
  446.     for (int i = 0; i < for_statement -> NumForInitStatements(); i++)
  447.         ProcessStatement(for_statement -> ForInitStatement(i));
  448.  
  449.     //
  450.     // Recall that each for statement is enclosed in a unique block by the parser
  451.     //
  452.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  453.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  454.  
  455.     //
  456.     // Assume that if the for_statement is reachable then its
  457.     // contained statement is also reachable. If it turns out that the
  458.     // condition (end) expression is a constant FALSE expression we will
  459.     // change the assumption...
  460.     //
  461.     AstStatement *enclosed_statement = for_statement -> statement;
  462.     enclosed_statement -> is_reachable = for_statement -> is_reachable;
  463.  
  464.     if (for_statement -> end_expression_opt)
  465.     {
  466.         ProcessExpression(for_statement -> end_expression_opt);
  467.         if (for_statement -> end_expression_opt -> Type() == control.boolean_type)
  468.         {
  469.             if (for_statement -> end_expression_opt -> IsConstant())
  470.             {
  471.                 IntLiteralValue *literal = (IntLiteralValue *) for_statement -> end_expression_opt -> value;
  472.                 if (! literal -> value)
  473.                 {
  474.                      if (for_statement -> is_reachable)
  475.                          for_statement -> can_complete_normally = true;
  476.                      enclosed_statement -> is_reachable = false;
  477.                 }
  478.             }
  479.             else if (for_statement -> is_reachable)
  480.                  for_statement -> can_complete_normally = true;
  481.         }
  482.         else if (for_statement -> end_expression_opt -> Type() != control.no_type)
  483.         {
  484.             ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  485.                            for_statement -> end_expression_opt -> LeftToken(),
  486.                            for_statement -> end_expression_opt -> RightToken(),
  487.                            for_statement -> end_expression_opt -> Type() -> Name());
  488.         }
  489.     }
  490.  
  491.     ProcessStatement(enclosed_statement);
  492.  
  493.     if ((! enclosed_statement -> is_reachable) && (for_statement -> is_reachable))
  494.     {
  495.         ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  496.                        enclosed_statement -> LeftToken(),
  497.                        enclosed_statement -> RightToken());
  498.     }
  499.  
  500.     for (int j = 0; j < for_statement -> NumForUpdateStatements(); j++)
  501.         ProcessExpressionStatement(for_statement -> ForUpdateStatement(j));
  502.  
  503.     //
  504.     // If the for statement contained a reachable break statement,
  505.     // then the for statement can complete normally. It is marked
  506.     // here only for completeness, as marking the enclosing block is
  507.     // enough to propagate the proper information upward.
  508.     //
  509.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  510.     if (block_body -> can_complete_normally)
  511.         for_statement -> can_complete_normally = true;
  512.  
  513.     BreakableStatementStack().Pop();
  514.     ContinuableStatementStack().Pop();
  515.  
  516.     return;
  517. }
  518.  
  519.  
  520. void Semantic::ProcessSwitchStatement(Ast *stmt)
  521. {
  522.     AstSwitchStatement *switch_statement = (AstSwitchStatement *) stmt;
  523.  
  524.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  525.  
  526.     //
  527.     // We estimate a size for the switch symbol table based on the number of lines in it.
  528.     //
  529.     AstBlock *block_body = switch_statement -> switch_block;
  530.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol();
  531.     block -> max_variable_index = enclosing_block -> block_symbol -> max_variable_index;
  532.     LocalSymbolTable().Push(block -> Table());
  533.  
  534.     block_body -> block_symbol = block;
  535.     block_body -> nesting_level = LocalBlockStack().Size();
  536.     LocalBlockStack().Push(block_body);
  537.     BreakableStatementStack().Push(block_body);
  538.  
  539.     ProcessExpression(switch_statement -> expression);
  540.     TypeSymbol *type = switch_statement -> expression -> Type();
  541.  
  542.     if (type != control.int_type  && type != control.short_type &&
  543.         type != control.char_type && type != control.byte_type  && type != control.no_type)
  544.     {
  545.         ReportSemError(SemanticError::TYPE_NOT_VALID_FOR_SWITCH,
  546.                        switch_statement -> expression -> LeftToken(),
  547.                        switch_statement -> expression -> RightToken(),
  548.                        type -> ContainingPackage() -> PackageName(),
  549.                        type -> ExternalName());
  550.     }
  551.  
  552.     switch_statement -> default_case.switch_block_statement = NULL;
  553.  
  554.     //
  555.     // Count the number case labels in this switch statement
  556.     //
  557.     int num_case_labels = 0;
  558.     for (int i = 0; i < block_body -> NumStatements(); i++)
  559.     {
  560.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) block_body -> Statement(i);
  561.         num_case_labels += switch_block_statement -> NumSwitchLabels();
  562.     }
  563.     switch_statement -> AllocateCases(num_case_labels);
  564.  
  565.     //
  566.     // A switch block is reachable iff its switch statement is reachable.
  567.     //
  568.     block_body -> is_reachable = switch_statement -> is_reachable;
  569.     for (int j = 0; j < block_body -> NumStatements(); j++)
  570.     {
  571.         AstSwitchBlockStatement *switch_block_statement = (AstSwitchBlockStatement *) block_body -> Statement(j);
  572.  
  573.         for (int k = 0; k < switch_block_statement -> NumSwitchLabels(); k++)
  574.         {
  575.             AstCaseLabel *case_label = switch_block_statement -> SwitchLabel(k) -> CaseLabelCast();
  576.  
  577.             if (case_label)
  578.             {
  579.                 ProcessExpression(case_label -> expression);
  580.  
  581.                 if (case_label -> expression -> Type() != control.no_type)
  582.                 {
  583.                     if (! case_label -> expression -> IsConstant())
  584.                     {
  585.                         ReportSemError(SemanticError::EXPRESSION_NOT_CONSTANT,
  586.                                        case_label -> expression -> LeftToken(),
  587.                                        case_label -> expression -> RightToken());
  588.                         case_label -> expression -> symbol = control.no_type;
  589.                     }
  590.                     else if (type != control.no_type)
  591.                     {
  592.                         if (CanAssignmentConvert(type, case_label -> expression))
  593.                         {
  594.                             if (case_label -> expression -> Type() != type)
  595.                                 case_label -> expression = ConvertToType(case_label -> expression, type);
  596.  
  597.                             case_label -> map_index = switch_statement -> NumCases();
  598.  
  599.                             CaseElement *case_element = compilation_unit -> ast_pool -> GenCaseElement();
  600.                             switch_statement -> AddCase(case_element);
  601.  
  602.                             case_element -> expression = case_label -> expression;
  603.                             case_element -> switch_block_statement = switch_block_statement;
  604.                             case_element -> index = case_label -> map_index; // use this index to keep sort stable !
  605.                         }
  606.                         else if (case_label -> expression -> Type() == control.int_type &&
  607.                                  ! IsIntValueRepresentableInType(case_label -> expression, type))
  608.                         {
  609.                             IntToWstring value(((IntLiteralValue *) (case_label -> expression -> value)) -> value);
  610.  
  611.                             ReportSemError(SemanticError::VALUE_NOT_REPRESENTABLE_IN_SWITCH_TYPE,
  612.                                            case_label -> expression -> LeftToken(),
  613.                                            case_label -> expression -> RightToken(),
  614.                                            value.String(),
  615.                                            type -> Name());
  616.                         }
  617.                         else
  618.                         {
  619.                             ReportSemError(SemanticError::TYPE_NOT_CONVERTIBLE_TO_SWITCH_TYPE,
  620.                                            case_label -> expression -> LeftToken(),
  621.                                            case_label -> expression -> RightToken(),
  622.                                            case_label -> expression -> Type() -> Name(),
  623.                                            type -> Name());
  624.                         }
  625.                     }
  626.                 }
  627.             }
  628.             else if (switch_statement -> default_case.switch_block_statement == NULL)
  629.                 switch_statement -> default_case.switch_block_statement = switch_block_statement;
  630.             else
  631.             {
  632.                 ReportSemError(SemanticError::MULTIPLE_DEFAULT_LABEL,
  633.                                ((AstDefaultLabel *) switch_block_statement -> SwitchLabel(k)) -> LeftToken(),
  634.                                ((AstDefaultLabel *) switch_block_statement -> SwitchLabel(k)) -> RightToken());
  635.             }
  636.         }
  637.  
  638.         //
  639.         // The parser ensures that a switch block statement always has one statement.
  640.         // When a switch block ends with a sequence of switch labels that are not followed
  641.         // by any executable statements, an artificial "empty" statement is added by the parser.
  642.         //
  643.         assert(switch_block_statement -> NumStatements() > 0);
  644.  
  645.         //
  646.         // A statement in a switch block is reachable iff its
  647.         // switch statement is reachable and at least one of the
  648.         // following is true:
  649.         //
  650.         // . it bears a case or default label
  651.         // . there is a statement preceeding it in the switch block and that
  652.         // preceeding  statement can compile normally.
  653.         //
  654.         AstStatement *statement = (AstStatement *) switch_block_statement -> Statement(0);
  655.         statement -> is_reachable = switch_statement -> is_reachable;
  656.         AstStatement *first_unreachable_statement = (AstStatement *) (statement -> is_reachable ? NULL : statement);
  657.         ProcessStatement(statement);
  658.         for (int j = 1; j < switch_block_statement -> NumStatements(); j++)
  659.         {
  660.             AstStatement *previous_statement = statement;
  661.             statement = (AstStatement *) switch_block_statement -> Statement(j);
  662.             if (switch_statement -> is_reachable)
  663.             {
  664.                 statement -> is_reachable = previous_statement -> can_complete_normally;
  665.                 if ((! statement -> is_reachable) && (first_unreachable_statement == NULL))
  666.                     first_unreachable_statement = statement;
  667.             }
  668.  
  669.             ProcessStatement(statement);
  670.         }
  671.  
  672.         if (first_unreachable_statement)
  673.         {
  674.             if (first_unreachable_statement == statement)
  675.             {
  676.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENT,
  677.                                statement -> LeftToken(),
  678.                                statement -> RightToken());
  679.             }
  680.             else
  681.             {
  682.                 ReportSemError(SemanticError::UNREACHABLE_STATEMENTS,
  683.                                first_unreachable_statement -> LeftToken(),
  684.                                statement -> RightToken());
  685.             }
  686.         }
  687.     }
  688.  
  689.     //
  690.     // A switch statement can complete normally iff at least one of the
  691.     // following is true:
  692.     //
  693.     // . there is a reachable break statement that exits the switch
  694.     //   statement. (See ProcessBreakStatement)
  695.     // . the switch block is empty or contains only switch labels
  696.     //   //
  697.     //   // TODO: This statement seems to be erroneous. The proper statement
  698.     //   //       as implemented here is:
  699.     //   //
  700.     //   //           . the switch block is empty or contains only case labels
  701.     //   //
  702.     // . there is at least one switch label after the last switch block
  703.     //   statement group.
  704.     // . the last statement in the switch block can complete normally
  705.     //
  706.     if (block_body -> can_complete_normally)
  707.         switch_statement -> can_complete_normally = true;
  708.     else if (switch_statement -> default_case.switch_block_statement == NULL)
  709.         switch_statement -> can_complete_normally = true;
  710.     else
  711.     {
  712.         AstSwitchBlockStatement *last_switch_block_statement = (AstSwitchBlockStatement *)
  713.                                                                block_body -> Statement(block_body -> NumStatements() - 1);
  714.  
  715.         assert(last_switch_block_statement -> NumStatements() > 0);
  716.  
  717.         AstStatement *last_statement = (AstStatement *)
  718.                                        last_switch_block_statement -> Statement(last_switch_block_statement -> NumStatements() - 1);
  719.         if (last_statement -> can_complete_normally)
  720.             switch_statement -> can_complete_normally = true;
  721.     }
  722.  
  723.     switch_statement -> SortCases();
  724.     for (int k = 1; k < switch_statement -> NumCases(); k++)
  725.     {
  726.         if (switch_statement -> Case(k) -> Value() == switch_statement -> Case(k - 1) -> Value())
  727.         {
  728.             IntToWstring value(switch_statement -> Case(k) -> Value());
  729.  
  730.             ReportSemError(SemanticError::DUPLICATE_CASE_VALUE,
  731.                            switch_statement -> Case(k) -> expression -> LeftToken(),
  732.                            switch_statement -> Case(k) -> expression -> RightToken(),
  733.                            value.String());
  734.         }
  735.     }
  736.  
  737.     //
  738.     // If an enclosed block has a higher max_variable_index than the current block,
  739.     // update max_variable_index in the current_block, accordingly.
  740.     // Also, update the information for the block that immediately encloses the current block.
  741.     //
  742.     if (block -> max_variable_index < LocalBlockStack().TopMaxEnclosedVariableIndex())
  743.         block -> max_variable_index = LocalBlockStack().TopMaxEnclosedVariableIndex();
  744.  
  745.     BreakableStatementStack().Pop();
  746.     LocalBlockStack().Pop();
  747.     LocalSymbolTable().Pop();
  748.  
  749.     if (enclosing_block)
  750.     {
  751.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  752.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  753.     }
  754.  
  755.     block -> CompressSpace(); // space optimization
  756.  
  757.     return;
  758. }
  759.  
  760.  
  761. void Semantic::ProcessDoStatement(Ast *stmt)
  762. {
  763.     AstDoStatement *do_statement = (AstDoStatement *) stmt;
  764.  
  765.     //
  766.     // Recall that each Do statement is enclosed in a unique block by the parser
  767.     //
  768.     BreakableStatementStack().Push(LocalBlockStack().TopBlock());
  769.     ContinuableStatementStack().Push(LocalBlockStack().TopBlock());
  770.  
  771.     AstStatement *enclosed_statement = do_statement -> statement;
  772.     enclosed_statement -> is_reachable = do_statement -> is_reachable;
  773.  
  774.     ProcessStatement(enclosed_statement);
  775.  
  776.     ProcessExpression(do_statement -> expression);
  777.  
  778.     IntLiteralValue *literal = NULL;
  779.     if (do_statement -> expression -> Type() == control.boolean_type)
  780.     {
  781.         if (do_statement -> expression -> IsConstant())
  782.             literal = (IntLiteralValue *) do_statement -> expression -> value;
  783.     }
  784.     else if (do_statement -> expression -> Type() != control.no_type)
  785.     {
  786.         ReportSemError(SemanticError::TYPE_NOT_BOOLEAN,
  787.                        do_statement -> expression -> LeftToken(),
  788.                        do_statement -> expression -> RightToken(),
  789.                        do_statement -> expression -> Type() -> Name());
  790.     }
  791.  
  792.     //
  793.     // A do statement can complete normally, iff at least one of the following is true:
  794.     //     1. The contained statement can complete normally and the condition expression
  795.     //        is not a constant expression with the value true
  796.     //     2. There is a reachable break statement that exits the do statement
  797.     //        (This condition is true is the block that immediately encloses this do statement
  798.     //         can complete normally. See ProcessBreakStatement)
  799.     //
  800.     AstBlock *block_body = (AstBlock *) BreakableStatementStack().Top();
  801.     do_statement -> can_complete_normally = (enclosed_statement -> can_complete_normally && ((! literal) || literal -> value == 0)) ||
  802.                                             block_body -> can_complete_normally;
  803.  
  804.     BreakableStatementStack().Pop();
  805.     ContinuableStatementStack().Pop();
  806.  
  807.     return;
  808. }
  809.  
  810.  
  811. void Semantic::ProcessBreakStatement(Ast *stmt)
  812. {
  813.     AstBreakStatement *break_statement = (AstBreakStatement *) stmt;
  814.  
  815.     //
  816.     // Recall that it is possible to break out of any labeled statement even if it is not a
  817.     // do, for, while or switch statement.
  818.     //
  819.     if (break_statement -> identifier_token_opt)
  820.     {
  821.         NameSymbol *name_symbol = lex_stream -> NameSymbol(break_statement -> identifier_token_opt);
  822.         LabelSymbol *label_symbol = LocalSymbolTable().FindLabelSymbol(name_symbol);
  823.  
  824.         if (label_symbol)
  825.         {
  826.             break_statement -> nesting_level = label_symbol -> nesting_level;
  827.             AstBlock *block_body = label_symbol -> block;
  828.             //
  829.             // A labeled statement can complete normally if there is a
  830.             // reachable break statement that exits the labeled statement.
  831.             //
  832.             if (block_body && break_statement -> is_reachable)
  833.                 block_body -> can_complete_normally = true;
  834.         }
  835.         else
  836.         {
  837.             AstBlock *block_body = (AstBlock *) LocalBlockStack().TopBlock();
  838.             break_statement -> nesting_level = block_body -> nesting_level;
  839.             ReportSemError(SemanticError::UNDECLARED_LABEL,
  840.                            break_statement -> identifier_token_opt,
  841.                            break_statement -> identifier_token_opt,
  842.                            lex_stream -> NameString(break_statement -> identifier_token_opt));
  843.         }
  844.     }
  845.     else
  846.     {
  847.         AstBlock *block_body = (AstBlock *) (BreakableStatementStack().Size() > 0 ? BreakableStatementStack().Top()
  848.                                                                                   : LocalBlockStack().TopBlock());
  849.         break_statement -> nesting_level = block_body -> nesting_level;
  850.         if (BreakableStatementStack().Size() > 0)
  851.         {
  852.             if (break_statement -> is_reachable)
  853.                 block_body -> can_complete_normally = true;
  854.         }
  855.         else ReportSemError(SemanticError::MISPLACED_BREAK_STATEMENT,
  856.                             break_statement -> LeftToken(),
  857.                             break_statement -> RightToken());
  858.     }
  859.  
  860.     return;
  861. }
  862.  
  863.  
  864. void Semantic::ProcessContinueStatement(Ast *stmt)
  865. {
  866.     AstContinueStatement *continue_statement = (AstContinueStatement *) stmt;
  867.  
  868.     //
  869.     // The loop statement that is to be continued.
  870.     //
  871.     Ast *loop_statement = NULL;
  872.  
  873.     if (ContinuableStatementStack().Size() <= 0)
  874.     {
  875.         ReportSemError(SemanticError::MISPLACED_CONTINUE_STATEMENT,
  876.                        continue_statement -> LeftToken(),
  877.                        continue_statement -> RightToken());
  878.     }
  879.     else if (continue_statement -> identifier_token_opt)
  880.     {
  881.         NameSymbol *name_symbol = lex_stream -> NameSymbol(continue_statement -> identifier_token_opt);
  882.         LabelSymbol *label_symbol = LocalSymbolTable().FindLabelSymbol(name_symbol);
  883.  
  884.         if (label_symbol)
  885.         {
  886.             continue_statement -> nesting_level = label_symbol -> nesting_level;
  887.  
  888.             assert(label_symbol -> block -> NumStatements() > 0);
  889.  
  890.             loop_statement = label_symbol -> block -> Statement(0);
  891.         }
  892.         else
  893.         {
  894.             AstBlock *block_body = (AstBlock *) LocalBlockStack().TopBlock();
  895.             continue_statement -> nesting_level = block_body -> nesting_level;
  896.             ReportSemError(SemanticError::UNDECLARED_LABEL,
  897.                            continue_statement -> identifier_token_opt,
  898.                            continue_statement -> identifier_token_opt,
  899.                            lex_stream -> NameString(continue_statement -> identifier_token_opt));
  900.         }
  901.     }
  902.     else
  903.     {
  904.         AstBlock *block_body = (AstBlock *) ContinuableStatementStack().Top();
  905.         loop_statement = block_body -> Statement(0);
  906.         continue_statement -> nesting_level = block_body -> nesting_level;
  907.     }
  908.  
  909.     //
  910.     // If this is a valid continue statement, it is associated with a loop statement.
  911.     // Since the loop can be continued, its enclosed statement "can complete normally".
  912.     //
  913.     if (loop_statement)
  914.     {
  915.         AstDoStatement *do_statement = loop_statement -> DoStatementCast();
  916.         AstForStatement *for_statement = loop_statement -> ForStatementCast();
  917.         AstWhileStatement *while_statement = loop_statement -> WhileStatementCast();
  918.  
  919.         AstStatement *enclosed_statement = (do_statement ? do_statement -> statement
  920.                                                          : (for_statement ? for_statement -> statement
  921.                                                                           : (while_statement ? while_statement -> statement
  922.                                                                                              : (AstStatement *) NULL)));
  923.         if (enclosed_statement)
  924.             enclosed_statement -> can_complete_normally = true;
  925.         else
  926.         {
  927.             assert(continue_statement -> identifier_token_opt);
  928.  
  929.             ReportSemError(SemanticError::INVALID_CONTINUE_TARGET,
  930.                            continue_statement -> LeftToken(),
  931.                            continue_statement -> RightToken(),
  932.                            lex_stream -> NameString(continue_statement -> identifier_token_opt));
  933.         }
  934.     }
  935.  
  936.     return;
  937. }
  938.  
  939.  
  940. void Semantic::ProcessReturnStatement(Ast *stmt)
  941. {
  942.     AstReturnStatement *return_statement = (AstReturnStatement *) stmt;
  943.  
  944.     MethodSymbol *this_method = ThisMethod();
  945.  
  946.     if (this_method -> name_symbol == control.clinit_name_symbol || this_method -> name_symbol == control.block_init_name_symbol)
  947.     {
  948.         ReportSemError(SemanticError::RETURN_STATEMENT_IN_INITIALIZER,
  949.                        return_statement -> LeftToken(),
  950.                        return_statement -> RightToken());
  951.     }
  952.     else if (return_statement -> expression_opt)
  953.     {
  954.         ProcessExpression(return_statement -> expression_opt);
  955.  
  956.         if (this_method -> Type() == control.void_type)
  957.         {
  958.             ReportSemError(SemanticError::MISPLACED_RETURN_WITH_EXPRESSION,
  959.                            return_statement -> LeftToken(),
  960.                            return_statement -> RightToken());
  961.         }
  962.         else if (return_statement -> expression_opt -> Type() != control.no_type)
  963.         {
  964.             if (this_method -> Type() != return_statement -> expression_opt -> Type())
  965.             {
  966.                 if (CanAssignmentConvert(this_method -> Type(), return_statement -> expression_opt))
  967.                     return_statement -> expression_opt = ConvertToType(return_statement -> expression_opt, this_method -> Type());
  968.                 else
  969.                 {
  970.                     ReportSemError(SemanticError::MISMATCHED_RETURN_AND_METHOD_TYPE,
  971.                                    return_statement -> expression_opt -> LeftToken(),
  972.                                    return_statement -> expression_opt -> RightToken(),
  973.                                    return_statement -> expression_opt -> Type() -> ContainingPackage() -> PackageName(),
  974.                                    return_statement -> expression_opt -> Type() -> ExternalName(),
  975.                                    this_method -> Type() -> ContainingPackage() -> PackageName(),
  976.                                    this_method -> Type() -> ExternalName());
  977.                 }
  978.             }
  979.         }
  980.     }
  981.     else if (this_method -> Type() != control.void_type)
  982.     {
  983.         ReportSemError(SemanticError::MISPLACED_RETURN_WITH_NO_EXPRESSION,
  984.                        return_statement -> LeftToken(),
  985.                        return_statement -> RightToken());
  986.     }
  987.  
  988.     return;
  989. }
  990.  
  991.  
  992. bool Semantic::CatchableException(TypeSymbol *exception)
  993. {
  994.     //
  995.     // An unchecked exception or an error is ok !!
  996.     //
  997.     if (! CheckedException(exception) || exception == control.no_type)
  998.         return true;
  999.  
  1000.     //
  1001.     // Firstly, check the stack of try statements to see if the exception in question is catchable.
  1002.     //
  1003.     for (int i = TryStatementStack().Size() - 1; i >= 0; i--)
  1004.     {
  1005.         AstTryStatement *try_statement = (AstTryStatement *) TryStatementStack()[i];
  1006.  
  1007.         //
  1008.         // If a try statement contains a finally clause that can complete abruptly
  1009.         // then any exception that can reach it is assumed to be catchable.
  1010.         // See Spec 11.3.
  1011.         //
  1012.         if (try_statement -> finally_clause_opt && (! try_statement -> finally_clause_opt -> block -> can_complete_normally))
  1013.             return true;
  1014.  
  1015.         //
  1016.         // Check each catch clause in turn.
  1017.         //
  1018.         for (int k = 0; k < try_statement -> NumCatchClauses(); k++)
  1019.         {
  1020.             AstCatchClause *clause = try_statement -> CatchClause(k);
  1021.             VariableSymbol *symbol = clause -> parameter_symbol;
  1022.             if (CanAssignmentConvertReference(symbol -> Type(), exception))
  1023.                 return true;
  1024.         }
  1025.     }
  1026.  
  1027.     //
  1028.     // If we are processing the initialization expression of a field,
  1029.     // ThisMethod() is not defined.
  1030.     //
  1031.     MethodSymbol *this_method = ThisMethod();
  1032.     if (this_method)
  1033.     {
  1034.         for (int l = this_method -> NumThrows() - 1; l >= 0; l--)
  1035.         {
  1036.             if (CanAssignmentConvertReference(this_method -> Throws(l), exception))
  1037.                 return true;
  1038.         }
  1039.  
  1040.         if (this_method -> NumInitializerConstructors() > 0)
  1041.         {
  1042.             int j;
  1043.             for (j = this_method -> NumInitializerConstructors() - 1; j >= 0; j--)
  1044.             {
  1045.                 MethodSymbol *method = this_method -> InitializerConstructor(j);
  1046.                 int k;
  1047.                 for (k = method -> NumThrows() - 1; k >= 0; k--)
  1048.                 {
  1049.                     if (CanAssignmentConvertReference(method -> Throws(k), exception))
  1050.                         break;
  1051.                 }
  1052.                 if (k < 0) // no hit was found in method.
  1053.                     return false;
  1054.             }
  1055.             if (j < 0) // all the relevant constructors can catch the exception
  1056.                 return true;
  1057.         }
  1058.     }
  1059.  
  1060.     return false;
  1061. }
  1062.  
  1063.  
  1064. void Semantic::ProcessThrowStatement(Ast *stmt)
  1065. {
  1066.     AstThrowStatement *throw_statement = (AstThrowStatement *) stmt;
  1067.  
  1068.     ProcessExpression(throw_statement -> expression);
  1069.     TypeSymbol *type = throw_statement -> expression -> Type();
  1070.  
  1071.     if (type != control.no_type && (! CanAssignmentConvertReference(control.Throwable(), type)))
  1072.     {
  1073.         ReportSemError(SemanticError::EXPRESSION_NOT_THROWABLE,
  1074.                        throw_statement -> LeftToken(),
  1075.                        throw_statement -> RightToken());
  1076.     }
  1077.  
  1078.     SymbolSet *exception_set = TryExceptionTableStack().Top();
  1079.     if (exception_set)
  1080.         exception_set -> AddElement(type);
  1081.  
  1082.     if (! CatchableException(type))
  1083.     {
  1084.         MethodSymbol *this_method = ThisMethod();
  1085.         MethodSymbol *method = (this_method && this_method -> Identity() != control.clinit_name_symbol
  1086.                                             && this_method -> Identity() != control.block_init_name_symbol
  1087.                                                             ? this_method
  1088.                                                             : (MethodSymbol *) NULL);
  1089.  
  1090.         if (TryStatementStack().Size() > 0)
  1091.             ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION_IN_TRY,
  1092.                            throw_statement -> LeftToken(),
  1093.                            throw_statement -> RightToken(),
  1094.                            type -> ContainingPackage() -> PackageName(),
  1095.                            type -> ExternalName(),
  1096.                            (method ? method -> Header() : StringConstant::US_EMPTY));
  1097.         else if (method)
  1098.              ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION_IN_METHOD,
  1099.                             throw_statement -> LeftToken(),
  1100.                             throw_statement -> RightToken(),
  1101.                             type -> ContainingPackage() -> PackageName(),
  1102.                             type -> ExternalName(),
  1103.                             method -> Header());
  1104.         else ReportSemError(SemanticError::BAD_THROWABLE_EXPRESSION,
  1105.                             throw_statement -> LeftToken(),
  1106.                             throw_statement -> RightToken(),
  1107.                             type -> ContainingPackage() -> PackageName(),
  1108.                             type -> ExternalName());
  1109.     }
  1110.  
  1111.     return;
  1112. }
  1113.  
  1114.  
  1115. void Semantic::ProcessTryStatement(Ast *stmt)
  1116. {
  1117.     AstTryStatement *try_statement = (AstTryStatement *) stmt;
  1118.  
  1119.     //
  1120.     // A try_statement containing a finally clause requires some extra local
  1121.     // variables in its immediately enclosing block. If it is enclosed in a method
  1122.     // that returns void then 2 extra elements are needed. If the method
  1123.     // returns a long or a double value, two additional elements are needed.
  1124.     // Otherwise, one additional element is needed.
  1125.     // If this try_statement is the first try_statement with a finally clause
  1126.     // that was encountered in the immediately enclosing block, we allocate
  1127.     // two extra slots for the special local variables.
  1128.     //
  1129.     AstBlock *enclosing_block = LocalBlockStack().TopBlock();
  1130.     if (try_statement -> finally_clause_opt)
  1131.     {
  1132.         BlockSymbol *enclosing_block_symbol = enclosing_block -> block_symbol;
  1133.         if (enclosing_block_symbol -> try_or_synchronized_variable_index == 0) // first such statement encountered in enclosing block?
  1134.         {
  1135.             enclosing_block_symbol -> try_or_synchronized_variable_index = enclosing_block_symbol -> max_variable_index;
  1136.             enclosing_block_symbol -> max_variable_index += 2;
  1137.             if (ThisMethod() -> Type() != control.void_type)
  1138.             {
  1139.                  if (control.IsDoubleWordType(ThisMethod() -> Type()))
  1140.                       enclosing_block_symbol -> max_variable_index += 2;
  1141.                  else enclosing_block_symbol -> max_variable_index += 1;
  1142.             }
  1143.         }
  1144.  
  1145.         //
  1146.         // A finally block is processed in the environment of its immediate enclosing block.
  1147.         // (as opposed to the environment of its associated try block).
  1148.         //
  1149.         // Note that the finally block must be processed prior to the other
  1150.         // blocks in the try statement, because the computation of whether or not
  1151.         // an exception is catchable in a try statement depends on the termination
  1152.         // status of the associated finally block. See CatchableException function.
  1153.         //
  1154.         AstBlock *block_body = try_statement -> finally_clause_opt -> block;
  1155.         block_body -> is_reachable = try_statement -> is_reachable;
  1156.         ProcessBlock(block_body);
  1157.     }
  1158.  
  1159.     //
  1160.     // Note that the catch clauses are processed first - prior to processing
  1161.     // the main block - so that we can have their parameters available when we
  1162.     // are processing the main block, in case that block contains a throw
  1163.     // statement. See ProcessThrowStatement for more information.
  1164.     //
  1165.     // Also, recall that the body of the catch blocks must not be
  1166.     // processed within the environment of the associated try whose
  1167.     // exceptions they are supposed to catch but within the immediate enclosing
  1168.     // block (which may itself be a try block).
  1169.     //
  1170.     for (int i = 0; i < try_statement -> NumCatchClauses(); i++)
  1171.     {
  1172.         AstCatchClause *clause = try_statement -> CatchClause(i);
  1173.         AstFormalParameter *parameter = clause -> formal_parameter;
  1174.  
  1175.         TypeSymbol *parm_type;
  1176.  
  1177.         if (parameter -> type -> PrimitiveTypeCast())
  1178.         {
  1179.             ReportSemError(SemanticError::CATCH_PRIMITIVE_TYPE,
  1180.                            parameter -> LeftToken(),
  1181.                            parameter -> RightToken());
  1182.             parm_type = control.Error();
  1183.         }
  1184.         else if (parameter -> type -> ArrayTypeCast())
  1185.         {
  1186.             ReportSemError(SemanticError::CATCH_ARRAY_TYPE,
  1187.                            parameter -> LeftToken(),
  1188.                            parameter -> RightToken());
  1189.             parm_type = control.Error();
  1190.         }
  1191.         else parm_type = MustFindType(parameter -> type);
  1192.  
  1193.         if (! parm_type -> IsSubclass(control.Throwable()))
  1194.         {
  1195.             ReportSemError(SemanticError::TYPE_NOT_THROWABLE,
  1196.                            parameter -> LeftToken(),
  1197.                            parameter -> RightToken(),
  1198.                            parm_type -> ContainingPackage() -> PackageName(),
  1199.                            parm_type -> ExternalName());
  1200.         }
  1201.  
  1202.         AstVariableDeclaratorId *name = parameter -> formal_declarator -> variable_declarator_name;
  1203.         NameSymbol *name_symbol = lex_stream -> NameSymbol(name -> identifier_token);
  1204.         if (LocalSymbolTable().FindVariableSymbol(name_symbol))
  1205.         {
  1206.             ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  1207.                            name -> identifier_token,
  1208.                            name -> identifier_token,
  1209.                            name_symbol -> Name());
  1210.         }
  1211.  
  1212.         AstBlock *block_body = clause -> block;
  1213.         //
  1214.         // Guess that the number of elements in the table will not exceed the number of statements + the clause parameter.
  1215.         //
  1216.         BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(block_body -> NumStatements() + 1);
  1217.         block -> max_variable_index = enclosing_block -> block_symbol -> max_variable_index;
  1218.         LocalSymbolTable().Push(block -> Table());
  1219.  
  1220.         AccessFlags access_flags = ProcessFormalModifiers(parameter);
  1221.  
  1222.         VariableSymbol *symbol = LocalSymbolTable().Top() -> InsertVariableSymbol(name_symbol);
  1223.         symbol -> SetFlags(access_flags);
  1224.         symbol -> SetType(parm_type);
  1225.         symbol -> SetOwner(ThisMethod());
  1226.         symbol -> SetLocalVariableIndex(block -> max_variable_index++);
  1227.         symbol -> declarator = parameter -> formal_declarator;
  1228.  
  1229.         clause -> parameter_symbol = symbol;
  1230.  
  1231.         //
  1232.         // Note that for the purpose of semantic checking we assume that
  1233.         // the body of the catch block is reachable. Whether or not the catch
  1234.         // statement can be executed at all is checked later.
  1235.         //
  1236.         block_body -> is_reachable = true;
  1237.  
  1238.         block_body -> block_symbol = block;
  1239.         block_body -> nesting_level = LocalBlockStack().Size();
  1240.         LocalBlockStack().Push(block_body);
  1241.  
  1242.         ProcessBlockStatements(block_body);
  1243.  
  1244.         LocalBlockStack().Pop();
  1245.         LocalSymbolTable().Pop();
  1246.  
  1247.         //
  1248.         // Update the information for the block that immediately encloses the current block.
  1249.         //
  1250.         if (LocalBlockStack().TopMaxEnclosedVariableIndex() < block -> max_variable_index)
  1251.             LocalBlockStack().TopMaxEnclosedVariableIndex() = block -> max_variable_index;
  1252.  
  1253.         //
  1254.         // If a catch clause block can complete normally, we assume
  1255.         // that the try statement can complete normally. This may
  1256.         // prove to be false later if we find out that the finally
  1257.         // clause cannot complete normally...
  1258.         //
  1259.         if (block_body -> can_complete_normally)
  1260.             try_statement -> can_complete_normally = true;
  1261.  
  1262.         block -> CompressSpace(); // space optimization
  1263.     }
  1264.  
  1265.     //
  1266.     //
  1267.     //
  1268.     TryStatementStack().Push(try_statement);
  1269.     SymbolSet *exception_set = new SymbolSet;
  1270.     TryExceptionTableStack().Push(exception_set);
  1271.  
  1272.     try_statement -> block -> is_reachable = try_statement -> is_reachable;
  1273.     ProcessBlock(try_statement -> block);
  1274.     if (try_statement -> block -> can_complete_normally)
  1275.         try_statement -> can_complete_normally = true;
  1276.  
  1277.     //
  1278.     // A catch block is reachable iff both of the following are true:
  1279.     //
  1280.     //     . Some expression or throw statement in the try block is reachable
  1281.     //       and can throw an exception that is assignable to the parameter
  1282.     //       of the catch clause C.
  1283.     //
  1284.     //     . There is no earlier catch block A in the try statement such that the
  1285.     //       type of C's parameter is the same as or a subclass of the type of A's
  1286.     //       parameter.
  1287.     //
  1288.     // Note that the use of the word assignable here is slightly misleading.
  1289.     // It does not mean assignable in the strict sense defined in section 5.2.
  1290.     // Using the strict definition of 5.2, the rule can be more accurately 
  1291.     // stated as follows:
  1292.     //
  1293.     //    . Catchable Exception:
  1294.     //      some expression or throw statement in the try block is reachable
  1295.     //      and can throw an exception S that is assignable to the parameter
  1296.     //      with type T (S is a subclass of T) of the catch clause C.
  1297.     //
  1298.     //      In this case, when S is thrown it will definitely be caught by
  1299.     //      clause C.
  1300.     //
  1301.     //    . Convertible Exception:
  1302.     //      the type T of the parameter of the catch clause C is assignable to
  1303.     //      the type S (T is a subclass of S) of an exception that can be thrown by
  1304.     //      some expression or throw statement in the try block that is reachable.
  1305.     //      
  1306.     //      This rule captures the idea that at run time an object declared to
  1307.     //      be of type S can actually be an instance of an object of type T in
  1308.     //      which case it will be caught by clause C.
  1309.     //
  1310.     //
  1311.     Tuple<TypeSymbol *> catchable_exceptions,
  1312.                         convertible_exceptions;
  1313.     for (int l = 0; l < try_statement -> NumCatchClauses(); l++)
  1314.     {
  1315.         AstCatchClause *clause = try_statement -> CatchClause(l);
  1316.         VariableSymbol *symbol = clause -> parameter_symbol;
  1317.         if (CheckedException(symbol -> Type()))
  1318.         {
  1319.             int initial_length = catchable_exceptions.Length() + convertible_exceptions.Length();
  1320.  
  1321.             for (TypeSymbol *exception = (TypeSymbol *) exception_set -> FirstElement();
  1322.                  exception;
  1323.                  exception = (TypeSymbol *) exception_set -> NextElement())
  1324.             {
  1325.                 if (CanAssignmentConvertReference(symbol -> Type(), exception))
  1326.                      catchable_exceptions.Next() = exception;
  1327.                 else if (CanAssignmentConvertReference(exception, symbol -> Type()))
  1328.                      convertible_exceptions.Next() = exception;
  1329.             }
  1330.  
  1331.             //
  1332.             // No clause was found whose parameter can possibly accept this exception.
  1333.             //
  1334.             if ((catchable_exceptions.Length() + convertible_exceptions.Length()) == initial_length)
  1335.             {
  1336.                 if (symbol -> Type() == control.Throwable() || symbol -> Type() == control.Exception())
  1337.                      ReportSemError(SemanticError::UNREACHABLE_DEFAULT_CATCH_CLAUSE,
  1338.                                     clause -> formal_parameter -> LeftToken(),
  1339.                                     clause -> formal_parameter -> RightToken(),
  1340.                                     symbol -> Type() -> ContainingPackage() -> PackageName(),
  1341.                                     symbol -> Type() -> ExternalName());
  1342.                 else ReportSemError(SemanticError::UNREACHABLE_CATCH_CLAUSE,
  1343.                                     clause -> formal_parameter -> LeftToken(),
  1344.                                     clause -> formal_parameter -> RightToken(),
  1345.                                     symbol -> Type() -> ContainingPackage() -> PackageName(),
  1346.                                     symbol -> Type() -> ExternalName());
  1347.             }
  1348.             else
  1349.             {
  1350.                 //
  1351.                 // TODO: I know, I know, this is a sequential search...
  1352.                 //
  1353.                 AstCatchClause *previous_clause;
  1354.                 int k;
  1355.                 for (k = 0; k < l; k++)
  1356.                 {
  1357.                     previous_clause = try_statement -> CatchClause(k);
  1358.                     if (symbol -> Type() -> IsSubclass(previous_clause -> parameter_symbol -> Type()))
  1359.                         break;
  1360.                 }
  1361.  
  1362.                 if (k < l)
  1363.                 {
  1364.                      FileLocation loc(lex_stream, previous_clause -> formal_parameter -> RightToken());
  1365.                      ReportSemError(SemanticError::BLOCKED_CATCH_CLAUSE,
  1366.                                     clause -> formal_parameter -> LeftToken(),
  1367.                                     clause -> formal_parameter -> RightToken(),
  1368.                                     symbol -> Type() -> ContainingPackage() -> PackageName(),
  1369.                                     symbol -> Type() -> ExternalName(),
  1370.                                     loc.location);
  1371.                 }
  1372.                 else clause -> block -> is_reachable = true;
  1373.             }
  1374.         }
  1375.     }
  1376.  
  1377.     TryStatementStack().Pop();
  1378.     TryExceptionTableStack().Pop();
  1379.     if (TryExceptionTableStack().Top())
  1380.     {
  1381.         //
  1382.         // First, remove all the thrown exceptions that are definitely caught by the
  1383.         // enclosing try statement. Then, add the remaining ones to the set that must
  1384.         // be caught by the immediately enclosing try statement.
  1385.         //
  1386.         for (int i = 0; i < catchable_exceptions.Length(); i++)
  1387.             exception_set -> RemoveElement(catchable_exceptions[i]);
  1388.         TryExceptionTableStack().Top() -> Union(*exception_set);
  1389.     }
  1390.     delete exception_set;
  1391.  
  1392.     //
  1393.     // A try statement cannot complete normally if it contains a finally
  1394.     // clause that cannot complete normally.
  1395.     //
  1396.     if (try_statement -> finally_clause_opt && (! try_statement -> finally_clause_opt -> block -> can_complete_normally))
  1397.         try_statement -> can_complete_normally = false;
  1398.  
  1399.     return;
  1400. }
  1401.  
  1402.  
  1403. void Semantic::ProcessEmptyStatement(Ast *stmt)
  1404. {
  1405.     AstEmptyStatement *empty_statement = (AstEmptyStatement *) stmt;
  1406.  
  1407.     //
  1408.     // An empty statement can complete normally iff it is reachable.
  1409.     //
  1410.     empty_statement -> can_complete_normally = empty_statement -> is_reachable;
  1411.  
  1412.     return;
  1413. }
  1414.  
  1415.  
  1416. TypeSymbol *Semantic::GetLocalType(AstClassDeclaration *class_declaration)
  1417. {
  1418.     NameSymbol *name_symbol = lex_stream -> NameSymbol(class_declaration -> identifier_token);
  1419.     TypeSymbol *type = LocalSymbolTable().Top() -> InsertNestedTypeSymbol(name_symbol);
  1420.  
  1421.     TypeSymbol *outermost_type = ThisType() -> outermost_type;
  1422.     if (! outermost_type -> local)
  1423.         outermost_type -> local = new SymbolSet;
  1424.  
  1425.     IntToWstring value(outermost_type -> local -> NameCount(name_symbol) + 1);
  1426.  
  1427.     int length = value.Length() + outermost_type -> NameLength() + 1 + name_symbol -> NameLength() + 1; // +1 for $,... +1 for $
  1428.     wchar_t *external_name = new wchar_t[length + 1]; // +1 for '\0';
  1429.     wcscpy(external_name, outermost_type -> Name());
  1430.     wcscat(external_name, StringConstant::US__DS);
  1431.     wcscat(external_name, value.String());
  1432.     wcscat(external_name, StringConstant::US__DS);
  1433.     wcscat(external_name, name_symbol -> Name());
  1434.  
  1435.     type -> SetACC_PRIVATE();
  1436.     type -> outermost_type = outermost_type;
  1437.     type -> SetExternalIdentity(control.FindOrInsertName(external_name, length));
  1438.     outermost_type -> local -> AddElement(type);
  1439.  
  1440.     delete [] external_name;
  1441.  
  1442.     return type;
  1443. }
  1444.  
  1445.  
  1446. void Semantic::ProcessClassDeclaration(Ast *stmt)
  1447. {
  1448.     AstClassDeclaration *class_declaration = (AstClassDeclaration *) stmt;
  1449.     AstClassBody *class_body = class_declaration -> class_body;
  1450.  
  1451.     class_declaration -> MarkLocal(); // identify class as "statement" and assert that it is "reachable" and "can_complete_normally"
  1452.     CheckNestedTypeDuplication(state_stack.Top(), class_declaration -> identifier_token);
  1453.  
  1454.     TypeSymbol *inner_type = GetLocalType(class_declaration);
  1455.     inner_type -> outermost_type = ThisType() -> outermost_type;
  1456.     inner_type -> supertypes_closure = new SymbolSet;
  1457.     inner_type -> subtypes_closure = new SymbolSet;
  1458.     inner_type -> subtypes = new SymbolSet;
  1459.     inner_type -> semantic_environment = new SemanticEnvironment((Semantic *) this,
  1460.                                                                  inner_type,
  1461.                                                                  state_stack.Top());
  1462.     inner_type -> declaration = class_declaration;
  1463.     inner_type -> file_symbol = source_file_symbol;
  1464.     inner_type -> SetFlags(ProcessLocalClassModifiers(class_declaration));
  1465.     inner_type -> SetOwner(ThisMethod());
  1466.     //
  1467.     // Add 3 extra elements for padding. May need a default constructor and other support elements.
  1468.     //
  1469.     inner_type -> SetSymbolTable(class_body -> NumClassBodyDeclarations() + 3);
  1470.     inner_type -> SetLocation();
  1471.     inner_type -> SetSignature(control);
  1472.  
  1473.     if (StaticRegion())
  1474.          inner_type -> SetACC_STATIC();
  1475.     else inner_type -> InsertThis(0);
  1476.  
  1477.     class_declaration -> semantic_environment = inner_type -> semantic_environment; // save for processing bodies later.
  1478.  
  1479.     CheckClassMembers(inner_type, class_body);
  1480.  
  1481.     ProcessTypeHeaders(class_declaration);
  1482.  
  1483.     ProcessMembers(class_declaration -> semantic_environment, class_body);
  1484.     CompleteSymbolTable(class_declaration -> semantic_environment, class_declaration -> identifier_token, class_body);
  1485.     ProcessExecutableBodies(class_declaration -> semantic_environment, class_body);
  1486.  
  1487.     UpdateLocalConstructors(inner_type);
  1488.  
  1489.     return;
  1490. }
  1491.  
  1492.  
  1493. void Semantic::ProcessThisCall(AstThisCall *this_call)
  1494. {
  1495.     TypeSymbol *this_type = ThisType(),
  1496.                *containing_type = this_type -> ContainingType();
  1497.  
  1498.     ExplicitConstructorInvocation() = this_call; // signal that we are about to process an explicit constructor invocation
  1499.  
  1500.     if (this_call -> base_opt)
  1501.     {
  1502.         ProcessExpression(this_call -> base_opt);
  1503.  
  1504.         TypeSymbol *expr_type = this_call -> base_opt -> Type();
  1505.         if (expr_type != control.no_type)
  1506.         {
  1507.             if (! containing_type)
  1508.             {
  1509.                 ReportSemError(SemanticError::TYPE_NOT_INNER_CLASS,
  1510.                                this_call -> base_opt -> LeftToken(),
  1511.                                this_call -> base_opt -> RightToken(),
  1512.                                this_type -> ContainingPackage() -> PackageName(),
  1513.                                this_type -> ExternalName(),
  1514.                                expr_type -> ContainingPackage() -> PackageName(),
  1515.                                expr_type -> ExternalName());
  1516.                 this_call -> base_opt -> symbol = control.no_type;
  1517.             }
  1518.             //
  1519.             // 1.2 change. In 1.1, we used to allow access to any subclass of type. Now, there must
  1520.             // be a perfect match.
  1521.             //
  1522.             // else if (! expr_type -> IsSubclass(containing_type))
  1523.             //
  1524.             else if (expr_type != containing_type)
  1525.             {
  1526.                 ReportSemError(SemanticError::INVALID_ENCLOSING_INSTANCE,
  1527.                                this_call -> base_opt -> LeftToken(),
  1528.                                this_call -> base_opt -> RightToken(),
  1529.                                this_type -> ContainingPackage() -> PackageName(),
  1530.                                this_type -> ExternalName(),
  1531.                                containing_type -> ContainingPackage() -> PackageName(),
  1532.                                containing_type -> ExternalName(),
  1533.                                expr_type -> ContainingPackage() -> PackageName(),
  1534.                                expr_type -> ExternalName());
  1535.                 this_call -> base_opt -> symbol = control.no_type;
  1536.             }
  1537.         }
  1538.     }
  1539.     else // (! this_call -> base_opt)
  1540.     {
  1541.         if (this_type -> IsInner())
  1542.             this_call -> base_opt = CreateAccessToType(this_call, containing_type);
  1543.     }
  1544.  
  1545.     bool no_bad_argument = true;
  1546.  
  1547.     for (int i = 0; i < this_call -> NumArguments(); i++)
  1548.     {
  1549.         AstExpression *expr = (AstExpression *) this_call -> Argument(i);
  1550.         ProcessExpressionOrStringConstant(expr);
  1551.         no_bad_argument = no_bad_argument && (expr -> Type() != control.no_type);
  1552.     }
  1553.     if (no_bad_argument)
  1554.     {
  1555.         MethodSymbol *constructor = FindConstructor(this_type, this_call, this_call -> this_token, this_call -> RightToken());
  1556.         if (constructor)
  1557.         {
  1558.             this_call -> symbol = constructor;
  1559.  
  1560.             for (int i = 0; i < this_call -> NumArguments(); i++)
  1561.             {
  1562.                 AstExpression *expr = this_call -> Argument(i);
  1563.                 if (expr -> Type() != constructor -> FormalParameter(i) -> Type())
  1564.                     this_call -> Argument(i) = ConvertToType(expr, constructor -> FormalParameter(i) -> Type());
  1565.             }
  1566.  
  1567.             for (int k = constructor -> NumThrows() - 1; k >= 0; k--)
  1568.             {
  1569.                 TypeSymbol *exception = constructor -> Throws(k);
  1570.                 if (! CatchableException(exception))
  1571.                 {
  1572.                     ReportSemError(SemanticError::CONSTRUCTOR_DOES_NOT_THROW_THIS_EXCEPTION,
  1573.                                    this_call -> this_token,
  1574.                                    this_call -> this_token,
  1575.                                    exception -> ContainingPackage() -> PackageName(),
  1576.                                    exception -> ExternalName());
  1577.                 }
  1578.             }
  1579.  
  1580.             if (this_type -> IsLocal()) // a local type may use enclosed local variables?
  1581.                 this_type -> AddLocalConstructorCallEnvironment(GetEnvironment(this_call));
  1582.  
  1583.             //
  1584.             // Note that there is no need to do access-checking as we are allowed,
  1585.             // within the body of a class, to invoke any other constructor or member
  1586.             // (private or otherwise) in that class.
  1587.             //
  1588.         }
  1589.     }
  1590.  
  1591.     ExplicitConstructorInvocation() = NULL; // signal that we are no longer processing an explicit constructor invocation
  1592.  
  1593.     this_call -> can_complete_normally = this_call -> is_reachable;
  1594.  
  1595.     return;
  1596. }
  1597.  
  1598.  
  1599. void Semantic::ProcessSuperCall(AstSuperCall *super_call)
  1600. {
  1601.     TypeSymbol *this_type = ThisType();
  1602.     ExplicitConstructorInvocation() = super_call; // signal that we are about to process an explicit constructor invocation
  1603.  
  1604.     TypeSymbol *super_type = this_type -> super;
  1605.     if (! super_type) // this is only possible if we are compiling an illegal Object.java source file.
  1606.         super_type = control.Object();
  1607.  
  1608.     if (super_call -> base_opt)
  1609.     {
  1610.         ProcessExpression(super_call -> base_opt);
  1611.  
  1612.         TypeSymbol *expr_type = super_call -> base_opt -> Type();
  1613.         if (expr_type != control.no_type)
  1614.         {
  1615.             TypeSymbol *containing_type = super_type -> ContainingType();
  1616.             if (! containing_type)
  1617.             {
  1618.                 ReportSemError(SemanticError::SUPER_TYPE_NOT_INNER_CLASS,
  1619.                                super_call -> base_opt -> LeftToken(),
  1620.                                super_call -> base_opt -> RightToken(),
  1621.                                super_type -> ContainingPackage() -> PackageName(),
  1622.                                super_type -> ExternalName(),
  1623.                                this_type -> ContainingPackage() -> PackageName(),
  1624.                                this_type -> ExternalName(),
  1625.                                expr_type -> ContainingPackage() -> PackageName(),
  1626.                                expr_type -> ExternalName());
  1627.                 super_call -> base_opt -> symbol = control.no_type;
  1628.             }
  1629.             //
  1630.             // 1.2 change. In 1.1, we used to allow access to any subclass of type. Now, there must
  1631.             // be a perfect match.
  1632.             //
  1633.             // else if (! expr_type -> IsSubclass(containing_type))
  1634.             //
  1635.             else if (expr_type != containing_type)
  1636.             {
  1637.                 ReportSemError(SemanticError::INVALID_ENCLOSING_INSTANCE,
  1638.                                super_call -> base_opt -> LeftToken(),
  1639.                                super_call -> base_opt -> RightToken(),
  1640.                                this_type -> ContainingPackage() -> PackageName(),
  1641.                                this_type -> ExternalName(),
  1642.                                containing_type -> ContainingPackage() -> PackageName(),
  1643.                                containing_type -> ExternalName(),
  1644.                                expr_type -> ContainingPackage() -> PackageName(),
  1645.                                expr_type -> ExternalName());
  1646.                 super_call -> base_opt -> symbol = control.no_type;
  1647.             }
  1648.         }
  1649.     }
  1650.     else // (! super_call -> base_opt)
  1651.     {
  1652.         if (super_type && super_type -> IsInner())
  1653.             super_call -> base_opt = CreateAccessToType(super_call, super_type -> ContainingType());
  1654.     }
  1655.  
  1656.     bool no_bad_argument = true;
  1657.     for (int i = 0; i < super_call -> NumArguments(); i++)
  1658.     {
  1659.         AstExpression *expr = (AstExpression *) super_call -> Argument(i);
  1660.         ProcessExpressionOrStringConstant(expr);
  1661.         no_bad_argument = no_bad_argument && (expr -> Type() != control.no_type);
  1662.     }
  1663.  
  1664.     if (this_type == control.Object())
  1665.     {
  1666.         super_call -> symbol = NULL;
  1667.         ReportSemError(SemanticError::MISPLACED_SUPER_EXPRESSION,
  1668.                        super_call -> super_token,
  1669.                        super_call -> super_token);
  1670.     }
  1671.     else if (no_bad_argument)
  1672.     {
  1673.         MethodSymbol *constructor = FindConstructor(super_type, super_call, super_call -> super_token, super_call -> RightToken());
  1674.  
  1675.         if (constructor)
  1676.         {
  1677.             //
  1678.             // No need to do a full access-check. Do the minimal stuff here !
  1679.             //
  1680.             if (constructor -> ACC_PRIVATE())
  1681.             {
  1682.                 if (this_type -> outermost_type == super_type -> outermost_type)
  1683.                 {
  1684.                      if (! constructor -> LocalConstructor())
  1685.                      {
  1686.                          constructor = super_type -> GetReadAccessMethod(constructor);
  1687.  
  1688.                          //
  1689.                          // Add extra argument for read access constructor;
  1690.                          //
  1691.                          super_call -> AddNullArgument();
  1692.                      }
  1693.                 }
  1694.                 else ReportSemError(SemanticError::PRIVATE_CONSTRUCTOR_NOT_ACCESSIBLE,
  1695.                                     super_call -> LeftToken(),
  1696.                                     super_call -> RightToken(),
  1697.                                     constructor -> Header(),
  1698.                                     super_type -> ContainingPackage() -> PackageName(),
  1699.                                     super_type -> ExternalName());
  1700.             }
  1701.             else if (! (constructor -> ACC_PUBLIC() || constructor -> ACC_PROTECTED()))
  1702.             {
  1703.                 if (! (this_type -> outermost_type == super_type -> outermost_type ||
  1704.                        super_type -> ContainingPackage() == this_package))
  1705.                     ReportSemError(SemanticError::DEFAULT_CONSTRUCTOR_NOT_ACCESSIBLE,
  1706.                                    super_call -> super_token,
  1707.                                    super_call -> super_token,
  1708.                                    constructor -> Header(),
  1709.                                    super_type -> ContainingPackage() -> PackageName(),
  1710.                                    super_type -> ExternalName());
  1711.             }
  1712.  
  1713.             super_call -> symbol = constructor;
  1714.  
  1715.             if (super_call -> base_opt &&
  1716.                 (super_call -> base_opt -> Type() != control.no_type) &&
  1717.                 (super_call -> base_opt -> Type() != super_type -> ContainingType()))
  1718.             {
  1719.                 assert(CanMethodInvocationConvert(super_type -> ContainingType(), super_call -> base_opt -> Type()));
  1720.  
  1721.                 super_call -> base_opt = ConvertToType(super_call -> base_opt, super_type -> ContainingType());
  1722.             }
  1723.  
  1724.             for (int i = 0; i < super_call -> NumArguments(); i++)
  1725.             {
  1726.                 AstExpression *expr = super_call -> Argument(i);
  1727.                 TypeSymbol * ctor_param_type;
  1728.                 if (super_call -> NeedsExtraNullArgument()) {
  1729.                     // Synthetic constructor signature includes a synthetic
  1730.                     // class pointer as the first parameter.
  1731.                     ctor_param_type = constructor -> FormalParameter(i + 1) -> Type();
  1732.                 } else {
  1733.                     ctor_param_type = constructor -> FormalParameter(i) -> Type();
  1734.                 }
  1735.                 if (expr -> Type() != ctor_param_type)
  1736.                     super_call -> Argument(i) = ConvertToType(expr, ctor_param_type);
  1737.             }
  1738.  
  1739.             //
  1740.             // Make sure that the throws signature of the constructor is processed.
  1741.             //
  1742.             for (int k = constructor -> NumThrows() - 1; k >= 0; k--)
  1743.             {
  1744.                 TypeSymbol *exception = constructor -> Throws(k);
  1745.                 if (! CatchableException(exception))
  1746.                 {
  1747.                     ReportSemError(SemanticError::CONSTRUCTOR_DOES_NOT_THROW_SUPER_EXCEPTION,
  1748.                                    super_call -> LeftToken(),
  1749.                                    super_call -> RightToken(),
  1750.                                    this_type -> Name(),
  1751.                                    exception -> ContainingPackage() -> PackageName(),
  1752.                                    exception -> ExternalName(),
  1753.                                    constructor -> containing_type -> ContainingPackage() -> PackageName(),
  1754.                                    constructor -> containing_type -> ExternalName());
  1755.                 }
  1756.             }
  1757.  
  1758.             if (super_type -> IsLocal()) // a local type may use enclosed local variables?
  1759.             {
  1760.                 if (super_type -> LocalClassProcessingCompleted())
  1761.                 {
  1762.                     assert(ThisMethod() -> LocalConstructor() && (! ThisMethod() -> IsGeneratedLocalConstructor()));
  1763.  
  1764.                     assert(constructor -> LocalConstructor() && (! constructor -> IsGeneratedLocalConstructor()));
  1765.  
  1766.                     super_call -> symbol = constructor -> LocalConstructor();
  1767.  
  1768.                     //
  1769.                     // Recall that as a side-effect, when a local shadow is created in a type
  1770.                     // an argument that will be used to initialize the local shadow that has
  1771.                     // the same identity must be passed to every constructor in the type. Since
  1772.                     // we are currently processing a constructor, such an argument must be available.
  1773.                     //
  1774.                     BlockSymbol *block_symbol = ThisMethod() -> LocalConstructor() -> block_symbol;
  1775.                     for (int i = (super_type -> ACC_STATIC() ? 0 : 1); i < super_type -> NumConstructorParameters(); i++)
  1776.                     {
  1777.                         VariableSymbol *local = super_type -> ConstructorParameter(i) -> accessed_local,
  1778.                                        *local_shadow = this_type -> FindOrInsertLocalShadow(local);
  1779.  
  1780.                         AstSimpleName *simple_name = compilation_unit -> ast_pool -> GenSimpleName(super_call -> super_token);
  1781.                         simple_name -> symbol = block_symbol -> FindVariableSymbol(local_shadow -> Identity());
  1782.  
  1783.                         assert(simple_name -> symbol);
  1784.  
  1785.                         super_call -> AddLocalArgument(simple_name);
  1786.                     }
  1787.                 }
  1788.                 else // are we currently within the body of the type in question ?
  1789.                 {
  1790.                     super_type -> AddLocalConstructorCallEnvironment(GetEnvironment(super_call));
  1791.                 }
  1792.             }
  1793.         }
  1794.     }
  1795.  
  1796.     ExplicitConstructorInvocation() = NULL; // signal that we are no longer processing an explicit constructor invocation
  1797.  
  1798.     super_call -> can_complete_normally = super_call -> is_reachable;
  1799.  
  1800.     return;
  1801. }
  1802.  
  1803.  
  1804. void Semantic::CheckThrow(AstExpression *throw_expression)
  1805. {
  1806.     TypeSymbol *throw_type = throw_expression -> symbol -> TypeCast();
  1807.  
  1808.     assert(throw_type);
  1809.  
  1810.     if (throw_type -> ACC_INTERFACE())
  1811.     {
  1812.         ReportSemError(SemanticError::NOT_A_CLASS,
  1813.                        throw_expression -> LeftToken(),
  1814.                        throw_expression -> RightToken(),
  1815.                        throw_type -> ContainingPackage() -> PackageName(),
  1816.                        throw_type -> ExternalName());
  1817.     }
  1818.     else if (! throw_type -> IsSubclass(control.Throwable()))
  1819.     {
  1820.         ReportSemError(SemanticError::TYPE_NOT_THROWABLE,
  1821.                        throw_expression -> LeftToken(),
  1822.                        throw_expression -> RightToken(),
  1823.                        throw_type -> ContainingPackage() -> PackageName(),
  1824.                        throw_type -> ExternalName());
  1825.     }
  1826.  
  1827.     return;
  1828. }
  1829.  
  1830.  
  1831. void Semantic::ProcessMethodBody(AstMethodDeclaration *method_declaration)
  1832. {
  1833.     MethodSymbol *this_method = ThisMethod();
  1834.  
  1835.     for (int k = 0; k < method_declaration -> NumThrows(); k++)
  1836.         CheckThrow(method_declaration -> Throw(k));
  1837.  
  1838.  
  1839.     if (! method_declaration -> method_body -> EmptyStatementCast())
  1840.     {
  1841.         //
  1842.         // The block that is the body of a method is reachable
  1843.         //
  1844.         AstBlock *block_body;
  1845.  
  1846.         //
  1847.         // The body of a method must be a regular block. If instead, it
  1848.         // is a constructor block, mark the compilation unit as a bad
  1849.         // compilation so that the parser can properly diagnose this
  1850.         // problem later.
  1851.         //
  1852.         AstConstructorBlock *constructor_block = method_declaration -> method_body -> ConstructorBlockCast();
  1853.         if (constructor_block)
  1854.         {
  1855.             compilation_unit -> kind = Ast::BAD_COMPILATION; // invalidate the compilation unit
  1856.  
  1857.             constructor_block -> is_reachable = true;
  1858.             block_body = constructor_block -> block;
  1859.  
  1860.             //
  1861.             // If the parser recognizes the body of a method as a ConstructorBlock
  1862.             // then it must have an explicit_constructor_invocation.
  1863.             //
  1864.             AstThisCall *this_call = constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast();
  1865.             if (this_call)
  1866.             {
  1867.                 this_call -> is_reachable = true;
  1868.                 //
  1869.                 // Do not process the explicit constructor invocation as this could
  1870.                 // cause problems with assertions (e.g. for inner classes) that will
  1871.                 // turn out not to be true.
  1872.                 //
  1873.                 // ProcessThisCall(this_call);
  1874.                 //
  1875.                 block_body -> is_reachable = this_call -> can_complete_normally;
  1876.             }
  1877.             else
  1878.             {
  1879.                 AstSuperCall *super_call = (AstSuperCall *) constructor_block -> explicit_constructor_invocation_opt;
  1880.                 super_call -> is_reachable = true;
  1881.                 //
  1882.                 // Do not process the explicit constructor invocation as this could
  1883.                 // cause problems with assertions (e.g. for inner classes) that will
  1884.                 // turn out not to be true.
  1885.                 //
  1886.                 // ProcessSuperCall(super_call);
  1887.                 //
  1888.                 block_body -> is_reachable = super_call -> can_complete_normally;
  1889.             }
  1890.         }
  1891.         else
  1892.         {
  1893.             block_body = (AstBlock *) method_declaration -> method_body;
  1894.             block_body -> is_reachable = true;
  1895.         }
  1896.  
  1897.         block_body -> block_symbol = this_method -> block_symbol;
  1898.         block_body -> nesting_level = LocalBlockStack().Size();
  1899.         LocalBlockStack().Push(block_body);
  1900.  
  1901.         ProcessBlockStatements(block_body);
  1902.  
  1903.         LocalBlockStack().Pop();
  1904.  
  1905.         if (block_body -> can_complete_normally)
  1906.         {
  1907.             if (this_method -> Type() == control.void_type)
  1908.             {
  1909.                 AstReturnStatement *return_statement = compilation_unit -> ast_pool -> GenReturnStatement();
  1910.                 return_statement -> return_token = block_body -> right_brace_token;
  1911.                 return_statement -> expression_opt = NULL;
  1912.                 return_statement -> semicolon_token = block_body -> right_brace_token;
  1913.                 return_statement -> is_reachable = true;
  1914.                 block_body -> can_complete_normally = false;
  1915.                 block_body -> AddStatement(return_statement);
  1916.             }
  1917.             else
  1918.             {
  1919.                 ReportSemError(SemanticError::TYPED_METHOD_WITH_NO_RETURN,
  1920.                                method_declaration -> type -> LeftToken(),
  1921.                                method_declaration -> method_declarator -> identifier_token,
  1922.                                this_method -> Header(),
  1923.                                this_method -> Type() -> Name());
  1924.             }
  1925.         }
  1926.  
  1927.         if (this_method -> ACC_ABSTRACT() || this_method -> ACC_NATIVE())
  1928.         {
  1929.             ReportSemError(SemanticError::ABSTRACT_METHOD_WITH_BODY,
  1930.                            method_declaration -> LeftToken(),
  1931.                            method_declaration -> RightToken(),
  1932.                            this_method -> Header());
  1933.         }
  1934.     }
  1935.     else if (! (this_method -> ACC_ABSTRACT() || this_method -> ACC_NATIVE()))
  1936.     {
  1937.         ReportSemError(SemanticError::NON_ABSTRACT_METHOD_WITHOUT_BODY,
  1938.                        method_declaration -> LeftToken(),
  1939.                        method_declaration -> RightToken(),
  1940.                        this_method -> Header());
  1941.     }
  1942.  
  1943.     this_method -> block_symbol -> CompressSpace(); // space optimization
  1944.  
  1945.     return;
  1946. }
  1947.  
  1948.  
  1949. void Semantic::ProcessConstructorBody(AstConstructorDeclaration *constructor_declaration, bool body_reachable)
  1950. {
  1951.     TypeSymbol *this_type = ThisType();
  1952.     MethodSymbol *this_method = ThisMethod();
  1953.  
  1954.     for (int k = 0; k < constructor_declaration -> NumThrows(); k++)
  1955.         CheckThrow(constructor_declaration -> Throw(k));
  1956.  
  1957.     //
  1958.     // The block that is the body of a constructor is reachable
  1959.     //
  1960.     AstConstructorBlock *constructor_block = constructor_declaration -> constructor_body;
  1961.  
  1962.     constructor_block -> is_reachable = true;
  1963.     AstBlock *block_body = constructor_block -> block;
  1964.     AstThisCall *this_call = NULL;
  1965.     AstSuperCall *super_call = NULL;
  1966.     TypeSymbol *super_type = this_type -> super;
  1967.  
  1968.     if (constructor_block -> explicit_constructor_invocation_opt)
  1969.     {
  1970.         this_call = constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast();
  1971.         super_call = constructor_block -> explicit_constructor_invocation_opt -> SuperCallCast();
  1972.     }
  1973.     else if (super_type)
  1974.     {
  1975.         LexStream::TokenIndex loc = block_body -> LeftToken();
  1976.         super_call                            = compilation_unit -> ast_pool -> GenSuperCall();
  1977.         super_call -> base_opt                = NULL;
  1978.         super_call -> dot_token_opt           = loc;
  1979.         super_call -> super_token             = loc;
  1980.         super_call -> left_parenthesis_token  = loc;
  1981.         super_call -> right_parenthesis_token = loc;
  1982.         super_call -> semicolon_token         = loc;
  1983.  
  1984.         constructor_block -> explicit_constructor_invocation_opt = super_call;
  1985.  
  1986.         if (super_type -> IsInner() && (! this_type -> CanAccess(super_type -> ContainingType())))
  1987.         {
  1988.             ReportSemError(SemanticError::ENCLOSING_INSTANCE_NOT_ACCESSIBLE,
  1989.                            constructor_declaration -> constructor_declarator -> LeftToken(),
  1990.                            constructor_declaration -> constructor_declarator -> RightToken(),
  1991.                            super_type -> ContainingType() -> ContainingPackage() -> PackageName(),
  1992.                            super_type -> ContainingType() -> ExternalName());
  1993.         }
  1994.     }
  1995.  
  1996.     //
  1997.     // If the constructor starts with an explicit_constructor_invocation, either
  1998.     // one specified by the user or generated, we process it and set up the proper
  1999.     // local environment, if appropriate...
  2000.     //
  2001.     if (constructor_block -> explicit_constructor_invocation_opt)
  2002.     {
  2003.         //
  2004.         // If we are processing a local constructor, set up the generated environment...
  2005.         //
  2006.         if (this_type -> IsLocal())
  2007.         {
  2008.             LocalSymbolTable().Pop();
  2009.  
  2010.             assert(this_method -> LocalConstructor() && (! this_method -> IsGeneratedLocalConstructor()));
  2011.  
  2012.             LocalSymbolTable().Push(this_method -> LocalConstructor() -> block_symbol -> Table());
  2013.         }
  2014.  
  2015.             if (this_call)
  2016.             {
  2017.                 this_call -> is_reachable = true;
  2018.                 ProcessThisCall(this_call);
  2019.             }
  2020.             else
  2021.             {
  2022.                 assert(super_call);
  2023.  
  2024.                 super_call -> is_reachable = true;
  2025.                 ProcessSuperCall(super_call);
  2026.             }
  2027.  
  2028.         //
  2029.         // If we are processing a local constructor, restore its original environment...
  2030.         //
  2031.         if (this_type -> IsLocal())
  2032.         {
  2033.             LocalSymbolTable().Pop();
  2034.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2035.         }
  2036.     }
  2037.  
  2038.     if (! (body_reachable || (constructor_block -> explicit_constructor_invocation_opt &&
  2039.                               constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast())))
  2040.     {
  2041.         ReportSemError(SemanticError::UNREACHABLE_CONSTRUCTOR_BODY,
  2042.                        constructor_declaration -> LeftToken(),
  2043.                        constructor_declaration -> RightToken());
  2044.     }
  2045.  
  2046.     //
  2047.     // Guess that the number of elements will not exceed the number of statements.
  2048.     //
  2049.     int table_size = block_body -> NumStatements();
  2050.     BlockSymbol *block = LocalSymbolTable().Top() -> InsertBlockSymbol(table_size);
  2051.     block -> max_variable_index = this_method -> block_symbol -> max_variable_index;
  2052.     LocalSymbolTable().Push(block -> Table());
  2053.  
  2054.     block_body -> is_reachable = true;
  2055.     block_body -> block_symbol = block;
  2056.     block_body -> nesting_level = LocalBlockStack().Size();
  2057.     LocalBlockStack().Push(block_body);
  2058.  
  2059.     ProcessBlockStatements(block_body);
  2060.  
  2061.     if (block_body -> can_complete_normally)
  2062.     {
  2063.         AstReturnStatement *return_statement = compilation_unit -> ast_pool -> GenReturnStatement();
  2064.         return_statement -> return_token = block_body -> right_brace_token;
  2065.         return_statement -> expression_opt = NULL;
  2066.         return_statement -> semicolon_token = block_body -> right_brace_token;
  2067.         return_statement -> is_reachable = true;
  2068.         block_body -> can_complete_normally = false;
  2069.         block_body -> AddStatement(return_statement);
  2070.     }
  2071.  
  2072.     constructor_block -> can_complete_normally = block_body -> can_complete_normally;
  2073.  
  2074.     LocalBlockStack().Pop();
  2075.     LocalSymbolTable().Pop();
  2076.  
  2077.     //
  2078.     // Update the local variable info for the main block associated with this constructor.
  2079.     //
  2080.     if (this_method -> block_symbol -> max_variable_index < block -> max_variable_index)
  2081.         this_method -> block_symbol -> max_variable_index = block -> max_variable_index;
  2082.  
  2083.     block -> CompressSpace(); // space optimization
  2084.  
  2085.     return;
  2086. }
  2087.  
  2088.  
  2089. void Semantic::ProcessExecutableBodies(SemanticEnvironment *environment, AstClassBody *class_body)
  2090. {
  2091.     state_stack.Push(environment);
  2092.     TypeSymbol *this_type = ThisType();
  2093.  
  2094.     assert(this_type -> HeaderProcessed());
  2095.     assert(this_type -> ConstructorMembersProcessed());
  2096.     assert(this_type -> MethodMembersProcessed());
  2097.     assert(this_type -> FieldMembersProcessed());
  2098.  
  2099.     ThisVariable() = NULL; // All variable declarations have already been processed
  2100.  
  2101.     //
  2102.     // Compute the set of instance final variables declared by the user in this type
  2103.     // as well as the set of instance final variables that have not yet been initialized.
  2104.     //
  2105.     Tuple<VariableSymbol *> finals(this_type -> NumVariableSymbols()),
  2106.                             unassigned_finals(this_type -> NumVariableSymbols());
  2107.     for (int k = 0; k < this_type -> NumVariableSymbols(); k++)
  2108.     {
  2109.         VariableSymbol *variable_symbol = this_type -> VariableSym(k);
  2110.         if (variable_symbol -> ACC_FINAL() && variable_symbol -> declarator)
  2111.         {
  2112.             finals.Next() = variable_symbol;
  2113.  
  2114.             if (! variable_symbol -> IsDefinitelyAssigned())
  2115.                 unassigned_finals.Next() = variable_symbol;
  2116.         }
  2117.     }
  2118.  
  2119.     AstBlock *last_block_body = (class_body -> NumBlocks() > 0 ? class_body -> Block(class_body -> NumBlocks() - 1)
  2120.                                                                : (AstBlock *) NULL);
  2121.     if (class_body -> NumConstructors() == 0)
  2122.     {
  2123.         //
  2124.         // Issue an error for each unassigned final.
  2125.         //
  2126.         for (int k = 0; k < unassigned_finals.Length(); k++)
  2127.         {
  2128.             ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE,
  2129.                            unassigned_finals[k] -> declarator -> LeftToken(),
  2130.                            unassigned_finals[k] -> declarator -> RightToken());
  2131.         }
  2132.  
  2133.         //
  2134.         // Process the body of the default constructor, if there is one.
  2135.         // (An anonymous class does not yet have a default constructor at this point.)
  2136.         //
  2137.         AstConstructorDeclaration *constructor_decl = class_body -> default_constructor;
  2138.         if (constructor_decl)
  2139.         {
  2140.             ThisMethod() = constructor_decl -> constructor_symbol;
  2141.  
  2142.             LocalSymbolTable().Push(ThisMethod() -> block_symbol -> Table());
  2143.             LocalBlockStack().max_size = 0;
  2144.             ProcessConstructorBody(constructor_decl, ((! last_block_body) || last_block_body -> can_complete_normally));
  2145.             LocalSymbolTable().Pop();
  2146.             ThisMethod() -> max_block_depth = LocalBlockStack().max_size;
  2147.         }
  2148.     }
  2149.     else
  2150.     {
  2151.         for (int i = 0; i < class_body -> NumConstructors(); i++)
  2152.         {
  2153.             AstConstructorDeclaration *constructor_decl = class_body -> Constructor(i);
  2154.  
  2155.             ThisMethod() = constructor_decl -> constructor_symbol;
  2156.             MethodSymbol *this_method = ThisMethod();
  2157.             if (this_method)
  2158.             {
  2159.                 for (int l = 0; l < this_method -> NumFormalParameters(); l++)
  2160.                 {
  2161.                     VariableSymbol *parm = this_method -> FormalParameter(l);
  2162.                     AstVariableDeclaratorId *name = parm -> declarator -> variable_declarator_name;
  2163.  
  2164.                     SemanticEnvironment *where_found;
  2165.                     Tuple<VariableSymbol *> variables_found(2);
  2166.                     SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(),
  2167.                                                    parm -> Identity(),
  2168.                                                    name -> identifier_token);
  2169.                     VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  2170.                     if (symbol && symbol -> IsLocal())
  2171.                     {
  2172.                         ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  2173.                                        name -> identifier_token,
  2174.                                        name -> identifier_token,
  2175.                                        parm -> Name());
  2176.                     }
  2177.                 }
  2178.  
  2179.                 AstConstructorBlock *constructor_block = constructor_decl -> constructor_body;
  2180.                 if (constructor_block -> explicit_constructor_invocation_opt &&
  2181.                     constructor_block -> explicit_constructor_invocation_opt -> ThisCallCast())
  2182.                 {
  2183.                     for (int j = 0; j < unassigned_finals.Length(); j++)
  2184.                         unassigned_finals[j] -> MarkDefinitelyAssigned();
  2185.                 }
  2186.                 else
  2187.                 {
  2188.                     for (int j = 0; j < unassigned_finals.Length(); j++)
  2189.                         unassigned_finals[j] -> MarkNotDefinitelyAssigned();
  2190.                 }
  2191.  
  2192.                 LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2193.                 LocalBlockStack().max_size = 0;
  2194.  
  2195.                 int start_num_errors = NumErrors();
  2196.                 ProcessConstructorBody(constructor_decl, ((! last_block_body) || last_block_body -> can_complete_normally));
  2197.  
  2198.                 LocalSymbolTable().Pop();
  2199.                 this_method -> max_block_depth = LocalBlockStack().max_size;
  2200.  
  2201.                 if (NumErrors() == start_num_errors)
  2202.                     DefiniteConstructorBody(constructor_decl, finals);
  2203.  
  2204.                 for (int k = 0; k < unassigned_finals.Length(); k++)
  2205.                 {
  2206.                     VariableSymbol *variable_symbol = unassigned_finals[k];
  2207.                     if (! variable_symbol -> IsDefinitelyAssigned())
  2208.                     {
  2209.                         ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE_IN_CONSTRUCTOR,
  2210.                                        constructor_decl -> LeftToken(),
  2211.                                        constructor_decl -> RightToken(),
  2212.                                        variable_symbol -> Name());
  2213.                     }
  2214.                 }
  2215.             }
  2216.         }
  2217.  
  2218.         for (int l = 0; l < this_type -> NumPrivateAccessConstructors(); l++)
  2219.         {
  2220.             ThisMethod() = this_type -> PrivateAccessConstructor(l);
  2221.             MethodSymbol *this_method = ThisMethod();
  2222.             AstConstructorDeclaration *constructor_decl = (AstConstructorDeclaration *)
  2223.                                                           this_method -> method_or_constructor_declaration;
  2224.  
  2225.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2226.             LocalBlockStack().max_size = 0;
  2227.             ProcessConstructorBody(constructor_decl, true);
  2228.             LocalSymbolTable().Pop();
  2229.             this_method -> max_block_depth = LocalBlockStack().max_size;
  2230.         }
  2231.  
  2232.         ConstructorCycleChecker cycle_checker(class_body);
  2233.     }
  2234.  
  2235.     for (int j = 0; j < class_body -> NumMethods(); j++)
  2236.     {
  2237.         AstMethodDeclaration *method_decl = class_body -> Method(j);
  2238.  
  2239.         ThisMethod() = method_decl -> method_symbol;
  2240.         MethodSymbol *this_method = ThisMethod();
  2241.         if (this_method)
  2242.         {
  2243.             //
  2244.             // TODO: Confirm that this new test is indeed necessary. In 1.0, a more restricted test was used...
  2245.             //
  2246.             for (int i = 0; i < this_method -> NumFormalParameters(); i++)
  2247.             {
  2248.                 VariableSymbol *parm = this_method -> FormalParameter(i);
  2249.                 AstVariableDeclaratorId *name = parm -> declarator -> variable_declarator_name;
  2250.  
  2251.                 SemanticEnvironment *where_found;
  2252.                 Tuple<VariableSymbol *> variables_found(2);
  2253.                 SearchForVariableInEnvironment(variables_found, where_found, state_stack.Top(),
  2254.                                                parm -> Identity(),
  2255.                                                name -> identifier_token);
  2256.                 VariableSymbol *symbol = (variables_found.Length() > 0 ? variables_found[0] : (VariableSymbol *) NULL);
  2257.                 if (symbol && symbol -> IsLocal())
  2258.                 {
  2259.                     ReportSemError(SemanticError::DUPLICATE_LOCAL_VARIABLE_DECLARATION,
  2260.                                    name -> identifier_token,
  2261.                                    name -> identifier_token,
  2262.                                    parm -> Name());
  2263.                 }
  2264.             }
  2265.  
  2266.             LocalSymbolTable().Push(this_method -> block_symbol -> Table());
  2267.             LocalBlockStack().max_size = 0;
  2268.  
  2269.             int start_num_errors = NumErrors();
  2270.             ProcessMethodBody(method_decl);
  2271.  
  2272.             LocalSymbolTable().Pop();
  2273.             this_method -> max_block_depth = LocalBlockStack().max_size;
  2274.  
  2275.             if (NumErrors() == start_num_errors)
  2276.                 DefiniteMethodBody(method_decl, finals);
  2277.         }
  2278.     }
  2279.  
  2280.     //
  2281.     // Mark all instance variables and constructor parameters final.
  2282.     //
  2283.     for (int i = 0; i <  this_type -> NumConstructorParameters(); i++)
  2284.         this_type -> ConstructorParameter(i) -> SetACC_FINAL();
  2285.  
  2286.     for (int l = 0; l <  this_type -> NumEnclosingInstances(); l++)
  2287.         this_type -> EnclosingInstance(l) -> SetACC_FINAL();
  2288.  
  2289.     //
  2290.     // We are done with all the methods, indicate that there is no method
  2291.     // being currently compiled in this environment.
  2292.     //
  2293.     ThisMethod() = NULL;
  2294.  
  2295.     //
  2296.     // Recursively process all inner types
  2297.     //
  2298.     for (int m = 0; m < class_body -> NumNestedClasses(); m++)
  2299.     {
  2300.         AstClassDeclaration *class_declaration = class_body -> NestedClass(m);
  2301.         if (class_declaration -> semantic_environment)
  2302.             ProcessExecutableBodies(class_declaration -> semantic_environment, class_declaration -> class_body);
  2303.     }
  2304.  
  2305.     for (int n = 0; n < class_body -> NumNestedInterfaces(); n++)
  2306.     {
  2307.         if (class_body -> NestedInterface(n) -> semantic_environment)
  2308.             ProcessExecutableBodies(class_body -> NestedInterface(n));
  2309.     }
  2310.  
  2311.     state_stack.Pop();
  2312.  
  2313.     return;
  2314. }
  2315.  
  2316.  
  2317. void Semantic::ProcessExecutableBodies(AstInterfaceDeclaration *interface_declaration)
  2318. {
  2319.     state_stack.Push(interface_declaration -> semantic_environment);
  2320.     TypeSymbol *this_type = ThisType();
  2321.  
  2322.     assert(this_type -> HeaderProcessed());
  2323.     assert(this_type -> MethodMembersProcessed());
  2324.     assert(this_type -> FieldMembersProcessed());
  2325.  
  2326.     for (int k = 0; k < this_type -> NumVariableSymbols(); k++)
  2327.     {
  2328.         VariableSymbol *variable_symbol = this_type -> VariableSym(k);
  2329.         if (! variable_symbol -> IsDefinitelyAssigned())
  2330.         {
  2331.             ReportSemError(SemanticError::UNINITIALIZED_FINAL_VARIABLE,
  2332.                            variable_symbol -> declarator -> LeftToken(),
  2333.                            variable_symbol -> declarator -> RightToken());
  2334.         }
  2335.     }
  2336.  
  2337.     //
  2338.     // Recursively process all inner types
  2339.     //
  2340.     for (int m = 0; m < interface_declaration -> NumNestedClasses(); m++)
  2341.     {
  2342.         AstClassDeclaration *class_declaration = interface_declaration -> NestedClass(m);
  2343.         if (class_declaration -> semantic_environment)
  2344.             ProcessExecutableBodies(class_declaration -> semantic_environment, class_declaration -> class_body);
  2345.     }
  2346.  
  2347.     for (int n = 0; n < interface_declaration -> NumNestedInterfaces(); n++)
  2348.     {
  2349.         if (interface_declaration -> NestedInterface(n) -> semantic_environment)
  2350.             ProcessExecutableBodies(interface_declaration -> NestedInterface(n));
  2351.     }
  2352.  
  2353.     state_stack.Pop();
  2354.  
  2355.     return;
  2356. }
  2357.  
  2358. #ifdef    HAVE_JIKES_NAMESPACE
  2359. }            // Close namespace Jikes block
  2360. #endif
  2361.  
  2362.