Flatten the nested pair of BlockStmt for the body of every proc


The parser creates an empty BlockStmt for the body of a proc when the
proc is constructed.  If the body of the procedure is a block statement
it inserts the new BlockStmt into the existing one which results in
nesting.

A little work demonstrated that the only code that currently relies on
this nesting is insertAutoDestroyCalls() in resolution/callDestructors.cpp.


This patch contains the following


1) Changes to build.cpp to remove the nesting.


   Changes are limited to buildFunctionSymbol() and buildFunctionDecl().
   Most of the changes are for formatting

   a) The formals list for both function spanned two lines with multiple
      params on each line.  Switch to one line per param since they can't
      all fit on one line with a reasonable screen width.

   b) There were a couple of calls where the argument list spread a long-ish
      list of actuals over two lines.  Converted to one line per actual.

   c) Modified the bracing style to match the dominant style for the file.


   The functional change is near the end of buildFunctionDecl.  If the
   BlockStmt for the body is currently empty, then copy the statements
   in the new BlockStmt in to the body.

   It is important to copy the statements from the new BlockStmt to the
   existing BlockStmt, rather than assign the new Stmt to the body, to
   preserve the line number for any error/warning messsages.





2) Two important changes to the logic for inserting autoDestroy calls
   and then some minor tweaks.


   The function to insert autoDestory calls performs a linear walk of
   every block statement and

     A) Collects every variable declaration that needs needs a matching
        auto-destroy

     B) If any statement *contains* code that jumps out of the current
        block (gotos that are generated for return, yield, break, continue),
        insert the required set of auto-destory calls immediately before
        the goto.

     C) Detect the end of the block (fall of the end, a goto, or a return)
        and insert the required auto-destroy immediately before the end


   The changes are

     a) Trivial: In insertAutoDestroyCalls()

        Skip the "GOTO from block" analysis if there aren't any autoDestroy variables

        If we have found the end of the block, remove the call to clear the Vec vars 
        immediately before the break.  vars is about to go out of scope.


     b) Trivial: In stmtDefinesAnAutoDestroyedVariable()

        Add an additional test to avoid collecting variables that have been
        flagged as AUTO_DESTROY but where the variable's type does not have
        a function in the autoDestroyMap.

        This test is copied from the guard code for actually inserting any
        autoDestroy calls.  This will reduce the number of elements in
        vars[] for some blocks and may reduce the analysis time.


     c) Important: In gotoExitsBlock()

        This is part of the logic for (B). Consider a function of the form

        proc test() {
          var myVar : MyClass;


          if (****)
             return;

          .....
        }

        where myVar should be autoDestroyed at the end of the block.  The
        current code inserts an auto-destroy immediately before the 
        explicit return statement because (i) an earlier pass had inserted
        the return label in the outermost block stmt (ii) the test for (B)
        saw a goto from the "user's top-level" Block to the enclosing
        block.

        The synthesized label and the return are now in the same block and
        hence break the "leaving the block" test.

        Added an explicit check for a goto with tag GOTO_RETURN to handle this.
        This has the small benefit of short-circuiting the nesting analysis for
        this case.

        I believe RETURN is the only kind of GOTO that requires this change but
        one or two others (YIELD?) may benefit.


     d) Important: In stmtMustExitBlock()

        There are several tests to determine if we've found the point at
        which we are committed to leaving a block; this becomes the
        anchor-point for inserting the auto-destroy calls.

        Extend this list of checks to take note of a label that immediately
        preceeds a GOTO rather than just a GOTO.  This is the matching case
        for handling a return correctly.  Without this change the auto destroy
        calls would be inserted between the label and the actual goto but the
        returns would jump to the label.

     e) Trivial:    In stmtMustExitBlock()

        Refactored a couple of the tests with trivial "helper" functions to
        help the code to flow a little better.





Compiled:   clang STD,   gcc STD/LLVM

Tested:     paratest
            paratest with memleaks

Reviewed:   Tom

       
  



git-svn-id: http://svn.code.sf.net/p/chapel/code/trunk@23859 3a8e244f-b0f2-452b-bcba-4c88e055c3ca