"James K. Lowden" <jklow...@schemamania.org> writes:

> From 5d53920602e234e4d99ae2d502e662ee3699978e 4 Oct 2024 12:01:22 -0400
> From: "James K. Lowden" <jklow...@symas.com>
> Date: Sat 15 Feb 2025 12:50:53 PM EST
> Subject: [PATCH] 3 new 'cobol' FE files
>
> gcc/cobol/ChangeLog
>       * gengen.cc: New file.
>       * genmath.cc: New file.
>       * genutil.cc: New file.
>
> ---
> gcc/cobol/gengen.cc | 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ++
>  
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ++
>  
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ++
>  
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> gcc/cobol/genmath.cc | 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ++
>  
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> gcc/cobol/genutil.cc | 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ++
>  
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 ++
>  
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 7857 insertions(+), 3 deletions(-)
> diff --git a/gcc/cobol/gengen.cc b/gcc/cobol/gengen.cc
> new file mode 100644
> index 00000000000..b84c3fa0fc9
> --- /dev/null
> +++ b/gcc/cobol/gengen.cc
> @@ -0,0 +1,3477 @@
> +/*
> + * Copyright (c) 2021-2025 Symas Corporation
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions are
> + * met:
> + *
> + * * Redistributions of source code must retain the above copyright
> + *   notice, this list of conditions and the following disclaimer.
> + * * Redistributions in binary form must reproduce the above
> + *   copyright notice, this list of conditions and the following disclaimer
> + *   in the documentation and/or other materials provided with the
> + *   distribution.
> + * * Neither the name of the Symas Corporation nor the names of its
> + *   contributors may be used to endorse or promote products derived from
> + *   this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +/*  The compilation process consists of
> +
> +    1) lexing
> +    2) parsing
> +    3) generation of the GENERIC abstract syntax tree
> +    4) reduction
> +    5) generation of machine code
> +
> +    For your sins, you have wandered into the code that accepts information 
> from
> +    the parser about what the COBOL source code wants done.
> +
> +    Specifically, the routines in this module, which run at compile time, 
> generate
> +    the GENERIC tags that describe the equivalent of the COBOL.  They are 
> rathernnn
> +    low level routines, ultimately used for pretty much everything.  
> Specifically,
> +    they run at compile-time, and they generate the GENERIC tags that 
> control what
> +    ultimately happens at run-time.
> +
> +    It *is* confusing.
> +
> +    I'll try to collect things in a logical way, and name them in a logical 
> way,
> +    and I'll try to comment them well enough so that you have some hope of
> +    understanding what the heck is going on.
> +
> +    There is some information in the GCC internals document, but it was 
> written by
> +    people who live and breathe this stuff, and they don't remember what it 
> was like
> +    to know nothing.
> +
> +    I suspect that those who have tried and failed to create GCC front ends 
> have foundered because
> +    they just couldn't figure out what it was they needed to do.  I 
> certainly floundered
> +    for several days before I hit on the means to figure it out.  I created 
> the
> +    rjd_print_tree() routine, which spits out a text listing of all the nodes
> +    connected to the specified starting node.  (Keep in mind that the 
> GENERIC graph
> +    is cyclic, and consequently there is no real ordering, except that the 
> starting
> +    node you specify is NodeNumber0.  rjd_print_tree follows all links, but 
> it prints
> +    out each unique node exactly once.)
> +
> +    I then built into GCC a call to rjd_print_tree right at the point where 
> the GENERIC tree
> +    is complete and about to be reduced.
> +
> +    And that gave me the ability to create simple C programs and see the 
> resulting GENERIC
> +    tree.  It took a while to sort out what I was seeing, but ultimately 
> things started
> +    to make sense.  The inherent difficulty may start to become clear when 
> you realize that
> +    the program
> +
> +        void foo()
> +            {
> +            }
> +
> +    is implemented by a GENERIC tree with fifty-six nodes.
> +
> +    I can't try to write a whole manual here.  But hopefully there will be 
> enough examples
> +    throughout the code for you to learn how to do things on a highish 
> level, and you can
> +    look at the low -level routines to see how it is accomplished.
> +
> +    That said, I will try to comment things well enough to be meaningful at 
> least to me
> +    when I run across them at some time in the future.  Because I fear that 
> whatever
> +    I do here, the world will little note, and *I* will not long remember, 
> what it was!
> +    */
> +
> +#include "cobol-system.h"
> +#include "coretypes.h"
> +#include "tree.h"
> +#include "tree-iterator.h"
> +#include "stringpool.h"
> +#include "cgraph.h"
> +#include "toplev.h"
> +#include "function.h"
> +#include "fold-const.h"
> +#define HOWEVER_GCC_DEFINES_TREE 1
> +#include "ec.h"
> +#include "common-defs.h"
> +#include "util.h"
> +#include "cbldiag.h"
> +#include "symbols.h"
> +#include "gengen.h"
> +
> +// We are limiting the programmer to functions with 512 or fewer arguments.
> +// Don't like it?  Cry me a river.
> +static const int ARG_LIMIT = 512;
> +
> +static int sv_current_line_number;
> +
> +// These are globally useful constants
> +tree char_nodes[256];
> +
> +tree pvoid_type_node;
> +tree integer_minusone_node;
> +tree integer_two_node;
> +tree integer_eight_node;
> +tree size_t_zero_node;
> +tree int128_zero_node;
> +tree int128_five_node;
> +tree int128_ten_node;
> +tree char_ptr_type_node;
> +tree uchar_ptr_type_node;
> +tree wchar_ptr_type_node;
> +tree long_double_ten_node;
> +tree sizeof_size_t;
> +tree sizeof_pointer;
> +
> +tree bool_true_node;
> +tree bool_false_node;
> +
> +// This is the global translation unit structure; it contains everything 
> needed
> +// to compile one file that you might otherwise be tempted to instantiate as
> +// global variables:
> +
> +struct cbl_translation_unit_t gg_trans_unit;
> +
> +void
> +gg_build_translation_unit(const char *filename)
> +  {
> +  // The translation_unit_decl gets declared once for each processing source
> +  // input file.  It serves as an anchor for each function.  And the
> +  // block referred to by its "initial" member is the anchor for any
> +  // variables whose scope is file.
> +
> +  gg_trans_unit.trans_unit_decl
> +    = build_translation_unit_decl(get_identifier(filename));
> +
> +  gg_trans_unit.filename = filename;
> +
> +  tree tree_block = make_node(BLOCK);
> +  BLOCK_SUPERCONTEXT(tree_block)
> +    = gg_trans_unit.trans_unit_decl;
> +  TREE_USED(tree_block) = 1;
> +  DECL_INITIAL(gg_trans_unit.trans_unit_decl) = tree_block;
> +  }
> +
> +// Explanation of context.  There is a plate of spaghetti that represents
> +// a chain of contexts.
> +
> +// The deconstructed dinner:  The function_decl "initial" points to a block
> +// The block points to the first of a chained set of var_decl, one for each
> +// variable in the block.  The function "saved_tree" entry points to a
> +// bind_expr.  The bind_expr vars member points to the same chain of 
> var_decl.
> +// The bind_expr block member points to the block.  And the bind_expr body
> +// member points to the statement_list for the context.
> +
> +// Those four tags constitute the context.  To push the context, a new block
> +// is chained to the first blocks SUBCHAIN member.  A new bind_expr is 
> created
> +// and put on the statement_list of the enclosing block.  And a new list of
> +// var_decls is set up for the new block and the new bind_expr.
> +
> +// And that's how subcontexts are made.
> +
> +static void
> +gg_chain_onto_block_vars(tree block, tree var)
> +  {
> +  // In order to use a variable in a context, the var_decl has to go
> +  // onto the chain that starts with the "vars" entry of a block
> +
> +  // Upon discovering that chainon has O(N-squared) complexity because it 
> walks
> +  // the entire chain looking for the final member, Dubner put in this map.
> +  static std::unordered_map<tree, tree>blocks;
> +  if( !BLOCK_VARS(block) )
> +    {
> +    // This is the first variable:
> +    BLOCK_VARS(block) = var;
> +    blocks[block] = var;
> +    }
> +  else
> +    {
> +    //chainon(BLOCK_VARS(block), var);
> +    // What follows is the quicker equivalent of calling chainon()
> +    TREE_CHAIN(blocks[block]) = var;
> +    blocks[block] = var;
> +    }
> +  }
> +
> +void
> +gg_append_var_decl(tree var_decl)
> +  {
> +  // The var_decl has to be chained onto the appropriate block.
> +
> +  if( SCOPE_FILE_SCOPE_P(DECL_CONTEXT(var_decl)) )
> +    {
> +    tree context = gg_trans_unit.trans_unit_decl;
> +    tree block = DECL_INITIAL(context);
> +
> +    gg_chain_onto_block_vars(block, var_decl);
> +
> +    rest_of_decl_compilation (var_decl, true, false);
> +
> +    // With global variables, it is probably necessary to do something with
> +    // wrapup_global_declarations.  At this writing, I have not yet
> +    // investigated that.  The advice from g...@gcc.gnu.org came from
> +    // David Malcolm:
> +    /*
> +    You might find libgccjit's gcc/jit/jit-playback.cc helpful for this, as
> +    it tends to contain minimal code to build trees (generally
> +    simplified/reverse-engineered from the C frontend).
> +
> +    playback::context::global_new_decl makes the VAR_DECL node, and such
> +    trees are added to the jit playback::context's m_globals.
> +    In playback::context::replay, we have:
> +
> +      / * Finalize globals. See how FORTRAN 95 does it in gfc_be_parse_file()
> +         for a simple reference. * /
> +      FOR_EACH_VEC_ELT (m_globals, i, global)
> +        rest_of_decl_compilation (global, true, true);
> +
> +      wrapup_global_declarations (m_globals.address(), m_globals.length());
> +    */
> +
> +    // Stash this var_decl in a map so it can be found elsewhere:
> +    //fprintf(stderr, "Stashing %s\n", 
> IDENTIFIER_POINTER(DECL_NAME(var_decl)));
> +    gg_trans_unit.trans_unit_var_decls
> +    [IDENTIFIER_POINTER(DECL_NAME(var_decl))] = var_decl;
> +    }
> +  else
> +    {
> +    // For function-level variables, we use a stack of blocks to keep track
> +    // of which block is active for the current context:
> +
> +    // fprintf(stderr, "%s():  %30s Function Scope\n", __func__, id_name);
> +    tree bind_expr = current_function->bind_expr_stack.back();
> +    tree block = BIND_EXPR_BLOCK(bind_expr);
> +
> +    gg_chain_onto_block_vars(block, var_decl);
> +
> +    // If saved_tree.bind_expr.vars is null, then var_decl is the very
> +    // first variable in the block, and it must be set in bind_expr as well
> +    if( !BIND_EXPR_VARS(bind_expr)  )
> +      {
> +      BIND_EXPR_VARS(bind_expr) = var_decl;
> +      }
> +    }
> +  }
> +
> +location_t
> +location_from_lineno()
> +  {
> +  location_t loc;
> +  loc = linemap_line_start(line_table, sv_current_line_number, 0);
> +  return loc;
> +  }
> +
> +void
> +gg_append_statement(tree stmt)
> +  {
> +  // Likewise, we have a stack of statement_lists, with the current one
> +  // at the back.  (The statement_list stack can get deeper than the block
> +  // stack, because you can create a separate statement list for the insides
> +  // of, say, a WHILE statement without creating a whole context for it)
> +
> +  // This statement list thing looks innocent enough, but it is the general
> +  // way of actually having a GENERIC tree generate executing code.  What 
> goes
> +  // onto a statement list is an expression.  A = B is implemented with a
> +  // modify_expr
> +
> +  // Actually instantiating a variable requires a var_expr
> +
> +  // A subroutine call is effected by putting a call_expr onto the statement
> +  // list.
> +
> +  // It's not the only way; you can have a modify_expr that takes a var_decl
> +  // as a destination, and uses a call_expr as a source.  This requires that
> +  // the type of the var_decl be the same as the type of the function being
> +  // called.
> +
> +  // And so on.  Just keep in mind that you have types, and declarations, and
> +  // expressions, among other things.
> +
> +  // When trying to figure out location_t, take a look at
> +  // ./libcpp/include/line-map.h
> +  // ./libcpp/location-example.txt
> +
> +  gcc_assert(  gg_trans_unit.function_stack.size() );
> +
> +  TREE_SIDE_EFFECTS(stmt) = 1;    // If an expression has no side effects,
> +  //                              // it won't generate code.
> +  TREE_SIDE_EFFECTS(current_function->statement_list_stack.back()) = 1;
> +  append_to_statement_list( stmt, 
> &(current_function->statement_list_stack.back()) );
> +  }
> +
> +tree
> +gg_float(tree floating_type, tree integer_var)
> +  {
> +  // I don't know why, but this fails if 'var' is an INT128
> +  return build1(FLOAT_EXPR, floating_type, integer_var);
> +  }
> +
> +tree
> +gg_trunc(tree integer_type, tree floating_var)
> +  {
> +  /* Conversion of real to fixed point by truncation.  */
> +  return build1(FIX_TRUNC_EXPR, integer_type, floating_var);
> +  }
> +
> +tree
> +gg_cast(tree type, tree var)
> +  {
> +  return fold_convert(type, var);
> +  }
> +
> +static bool saw_pointer;
> +
> +static
> +tree
> +adjust_for_type(tree type)
> +  {
> +  tree retval;
> +
> +  switch( TREE_CODE(type) )
> +    {
> +    case POINTER_TYPE:
> +      saw_pointer = true;
> +      retval = adjust_for_type(TREE_TYPE(type));
> +      break;
> +
> +    case COMPONENT_REF:
> +    case ADDR_EXPR:
> +    case ARRAY_TYPE:
> +    case VAR_DECL:
> +    case FUNCTION_TYPE:
> +      retval = adjust_for_type(TREE_TYPE(type));
> +      break;
> +    case RECORD_TYPE:
> +    default:
> +      retval = type;
> +      break;
> +    }
> +
> +  return retval;
> +  }
> +
> +static
> +char *
> +show_type(tree type)
> +  {
> +  if( !type )
> +    {
> +    cbl_internal_error("The given type is not NULL, and that's just not 
> fair");
> +    }
> +
> +  if( DECL_P(type) )
> +    {
> +    type = TREE_TYPE(type);
> +    }
> +  if( !TYPE_P(type) )
> +    {
> +    cbl_internal_error("The given type is not a DECL or a TYPE");
> +    }
> +
> +  static char ach[1024];
> +  switch( TREE_CODE(type) )
> +    {
> +    case VOID_TYPE:
> +      sprintf(ach, "VOID");
> +      break;
> +
> +    case BOOLEAN_TYPE:
> +      sprintf(ach, "BOOL");
> +      break;
> +
> +    case RECORD_TYPE:
> +      sprintf(ach, "RECORD");
> +      break;
> +
> +    case REAL_TYPE:
> +      sprintf(ach,
> +              "%3ld-bit REAL",
> +              TREE_INT_CST_LOW(TYPE_SIZE(type)));
> +      break;
> +
> +    case INTEGER_TYPE:
> +      sprintf(ach,
> +              "%3ld-bit %s INT",
> +              TREE_INT_CST_LOW(TYPE_SIZE(type)),
> +              (TYPE_UNSIGNED(type) ? "unsigned" : "  signed"));
> +      break;
> +
> +    case FUNCTION_TYPE:
> +      sprintf(ach, "FUNCTION");
> +//      sprintf(ach,
> +//              "%3ld-bit %s INT",
> +//              TREE_INT_CST_LOW(TYPE_SIZE(type)),
> +//              (TYPE_UNSIGNED(type) ? "unsigned" : "  signed"));
> +      break;
> +
> +    default:
> +      cbl_internal_error("Unknown type %d", TREE_CODE(type));
> +    }
> +
> +  return ach;
> +  }
> +
> +void
> +gg_assign(tree dest, const tree source)
> +  {
> +  // This does the equivalent of a C/C++ "dest = source".  When X1 is set, it
> +  // does some checking for conditions that can result in inefficient code, 
> so
> +  // that is useful during development when even an astute programmer might
> +  // need an assist with keeping variable types straight.
> +
> +  // This routine also provides for the possibility that the assignment is
> +  // for a source that is a function invocation, as in
> +  //    "dest = function_call()"
> +
> +  saw_pointer = false;
> +  tree dest_type = adjust_for_type(TREE_TYPE(dest));
> +  bool p1 = saw_pointer;
> +  saw_pointer = false;
> +  tree source_type = adjust_for_type(TREE_TYPE(source));
> +  bool p2 = saw_pointer;
> +
> +  if( getenv("X2") )
> +    {

Leftover debugging code.

> +    fprintf(stderr, "dest is %s%s;",     show_type(dest_type), p1 ? "_P" : 
> "");
> +    fprintf(stderr, " source is %s%s\n", show_type(source_type), p2 ? "_P" : 
> "");
> +    }
> +
> +  bool okay = dest_type == source_type;
> +
> +  if( !okay )
> +    {
> +    if(    TREE_CODE(dest_type)   == INTEGER_TYPE
> +           && TREE_CODE(source_type) == INTEGER_TYPE
> +           && TREE_INT_CST_LOW(TYPE_SIZE(dest_type)) == 
> TREE_INT_CST_LOW(TYPE_SIZE(source_type))
> +           && TYPE_UNSIGNED(dest_type) == TYPE_UNSIGNED(source_type) )
> +      {
> +      okay = true;
> +      }
> +    }
> +
> +  if( okay )
> +    {
> +    tree stmt = build2_loc( location_from_lineno(),
> +                            MODIFY_EXPR,
> +                            TREE_TYPE(dest),
> +                            dest,
> +                            source);
> +    gg_append_statement(stmt);
> +    }
> +  else
> +    {
> +    if( true || getenv("X1") )

Debugging code.

Reply via email to