/* Output Dwarf2 format symbol table information from GCC.
   Copyright (C) 1992-2021 Free Software Foundation, Inc.
   Contributed by Gary Funck (gary@intrepid.com).
   Derived from DWARF 1 implementation of Ron Guilmette (rfg@monkeys.com).
   Extensively modified by Jason Merrill (jason@cygnus.com).

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

/* TODO: Emit .debug_line header even when there are no functions, since
	   the file numbers are used by .debug_info.  Alternately, leave
	   out locations for types and decls.
	 Avoid talking about ctors and op= for PODs.
	 Factor out common prologue sequences into multiple CIEs.  */

/* The first part of this file deals with the DWARF 2 frame unwind
   information, which is also used by the GCC efficient exception handling
   mechanism.  The second part, controlled only by an #ifdef
   DWARF2_DEBUGGING_INFO, deals with the other DWARF 2 debugging
   information.  */

/* DWARF2 Abbreviation Glossary:

   CFA = Canonical Frame Address
	   a fixed address on the stack which identifies a call frame.
	   We define it to be the value of SP just before the call insn.
	   The CFA register and offset, which may change during the course
	   of the function, are used to calculate its value at runtime.

   CFI = Call Frame Instruction
	   an instruction for the DWARF2 abstract machine

   CIE = Common Information Entry
	   information describing information common to one or more FDEs

   DIE = Debugging Information Entry

   FDE = Frame Description Entry
	   information describing the stack call frame, in particular,
	   how to restore registers

   DW_CFA_... = DWARF2 CFA call frame instruction
   DW_TAG_... = DWARF2 DIE tag */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "function.h"
#include "rtl.h"
#include "tree.h"
#include "memmodel.h"
#include "tm_p.h"
#include "stringpool.h"
#include "insn-config.h"
#include "ira.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "varasm.h"
#include "version.h"
#include "flags.h"
#include "rtlhash.h"
#include "reload.h"
#include "output.h"
#include "expr.h"
#include "dwarf2out.h"
#include "dwarf2ctf.h"
#include "dwarf2asm.h"
#include "toplev.h"
#include "md5.h"
#include "tree-pretty-print.h"
#include "print-rtl.h"
#include "debug.h"
#include "common/common-target.h"
#include "langhooks.h"
#include "lra.h"
#include "dumpfile.h"
#include "opts.h"
#include "tree-dfa.h"
#include "gdb/gdb-index.h"
#include "rtl-iter.h"
#include "stringpool.h"
#include "attribs.h"
#include "file-prefix-map.h" /* remap_debug_filename()  */

static void dwarf2out_source_line (unsigned int, unsigned int, const char *,
				   int, bool);
static rtx_insn *last_var_location_insn;
static rtx_insn *cached_next_real_insn;
static void dwarf2out_decl (tree);
static bool is_redundant_typedef (const_tree);

#ifndef XCOFF_DEBUGGING_INFO
#define XCOFF_DEBUGGING_INFO 0
#endif

#ifndef HAVE_XCOFF_DWARF_EXTRAS
#define HAVE_XCOFF_DWARF_EXTRAS 0
#endif

#ifdef VMS_DEBUGGING_INFO
int vms_file_stats_name (const char *, long long *, long *, char *, int *);

/* Define this macro to be a nonzero value if the directory specifications
    which are output in the debug info should end with a separator.  */
#define DWARF2_DIR_SHOULD_END_WITH_SEPARATOR 1
/* Define this macro to evaluate to a nonzero value if GCC should refrain
   from generating indirect strings in DWARF2 debug information, for instance
   if your target is stuck with an old version of GDB that is unable to
   process them properly or uses VMS Debug.  */
#define DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET 1
#else
#define DWARF2_DIR_SHOULD_END_WITH_SEPARATOR 0
#define DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET 0
#endif

/* ??? Poison these here until it can be done generically.  They've been
   totally replaced in this file; make sure it stays that way.  */
#undef DWARF2_UNWIND_INFO
#undef DWARF2_FRAME_INFO
#if (GCC_VERSION >= 3000)
 #pragma GCC poison DWARF2_UNWIND_INFO DWARF2_FRAME_INFO
#endif

/* The size of the target's pointer type.  */
#ifndef PTR_SIZE
#define PTR_SIZE (POINTER_SIZE / BITS_PER_UNIT)
#endif

/* Array of RTXes referenced by the debugging information, which therefore
   must be kept around forever.  */
static GTY(()) vec<rtx, va_gc> *used_rtx_array;

/* A pointer to the base of a list of incomplete types which might be
   completed at some later time.  incomplete_types_list needs to be a
   vec<tree, va_gc> *because we want to tell the garbage collector about
   it.  */
static GTY(()) vec<tree, va_gc> *incomplete_types;

/* Pointers to various DWARF2 sections.  */
static GTY(()) section *debug_info_section;
static GTY(()) section *debug_skeleton_info_section;
static GTY(()) section *debug_abbrev_section;
static GTY(()) section *debug_skeleton_abbrev_section;
static GTY(()) section *debug_aranges_section;
static GTY(()) section *debug_addr_section;
static GTY(()) section *debug_macinfo_section;
static const char *debug_macinfo_section_name;
static unsigned macinfo_label_base = 1;
static GTY(()) section *debug_line_section;
static GTY(()) section *debug_skeleton_line_section;
static GTY(()) section *debug_loc_section;
static GTY(()) section *debug_pubnames_section;
static GTY(()) section *debug_pubtypes_section;
static GTY(()) section *debug_str_section;
static GTY(()) section *debug_line_str_section;
static GTY(()) section *debug_str_dwo_section;
static GTY(()) section *debug_str_offsets_section;
static GTY(()) section *debug_ranges_section;
static GTY(()) section *debug_ranges_dwo_section;
static GTY(()) section *debug_frame_section;

/* Maximum size (in bytes) of an artificially generated label.  */
#define MAX_ARTIFICIAL_LABEL_BYTES	40

/* According to the (draft) DWARF 3 specification, the initial length
   should either be 4 or 12 bytes.  When it's 12 bytes, the first 4
   bytes are 0xffffffff, followed by the length stored in the next 8
   bytes.

   However, the SGI/MIPS ABI uses an initial length which is equal to
   dwarf_offset_size.  It is defined (elsewhere) accordingly.  */

#ifndef DWARF_INITIAL_LENGTH_SIZE
#define DWARF_INITIAL_LENGTH_SIZE (dwarf_offset_size == 4 ? 4 : 12)
#endif

#ifndef DWARF_INITIAL_LENGTH_SIZE_STR
#define DWARF_INITIAL_LENGTH_SIZE_STR (dwarf_offset_size == 4 ? "-4" : "-12")
#endif

/* Round SIZE up to the nearest BOUNDARY.  */
#define DWARF_ROUND(SIZE,BOUNDARY) \
  ((((SIZE) + (BOUNDARY) - 1) / (BOUNDARY)) * (BOUNDARY))

/* CIE identifier.  */
#if HOST_BITS_PER_WIDE_INT >= 64
#define DWARF_CIE_ID \
  (unsigned HOST_WIDE_INT) (dwarf_offset_size == 4 ? DW_CIE_ID : DW64_CIE_ID)
#else
#define DWARF_CIE_ID DW_CIE_ID
#endif


/* A vector for a table that contains frame description
   information for each routine.  */
#define NOT_INDEXED (-1U)
#define NO_INDEX_ASSIGNED (-2U)

static GTY(()) vec<dw_fde_ref, va_gc> *fde_vec;

struct GTY((for_user)) indirect_string_node {
  const char *str;
  unsigned int refcount;
  enum dwarf_form form;
  char *label;
  unsigned int index;
};

struct indirect_string_hasher : ggc_ptr_hash<indirect_string_node>
{
  typedef const char *compare_type;

  static hashval_t hash (indirect_string_node *);
  static bool equal (indirect_string_node *, const char *);
};

static GTY (()) hash_table<indirect_string_hasher> *debug_str_hash;

static GTY (()) hash_table<indirect_string_hasher> *debug_line_str_hash;

/* With split_debug_info, both the comp_dir and dwo_name go in the
   main object file, rather than the dwo, similar to the force_direct
   parameter elsewhere but with additional complications:

   1) The string is needed in both the main object file and the dwo.
   That is, the comp_dir and dwo_name will appear in both places.

   2) Strings can use four forms: DW_FORM_string, DW_FORM_strp,
   DW_FORM_line_strp or DW_FORM_strx/GNU_str_index.

   3) GCC chooses the form to use late, depending on the size and
   reference count.

   Rather than forcing the all debug string handling functions and
   callers to deal with these complications, simply use a separate,
   special-cased string table for any attribute that should go in the
   main object file.  This limits the complexity to just the places
   that need it.  */

static GTY (()) hash_table<indirect_string_hasher> *skeleton_debug_str_hash;

static GTY(()) int dw2_string_counter;

/* True if the compilation unit places functions in more than one section.  */
static GTY(()) bool have_multiple_function_sections = false;

/* The default cold text section.  */
static GTY(()) section *cold_text_section;

/* True if currently in text section.  */
static GTY(()) bool in_text_section_p = false;

/* Last debug-on location in corresponding section.  */
static GTY(()) const char *last_text_label;
static GTY(()) const char *last_cold_label;

/* Mark debug-on/off locations per section.
   NULL means the section is not used at all.  */
static GTY(()) vec<const char *, va_gc> *switch_text_ranges;
static GTY(()) vec<const char *, va_gc> *switch_cold_ranges;

/* The DIE for C++14 'auto' in a function return type.  */
static GTY(()) dw_die_ref auto_die;

/* The DIE for C++14 'decltype(auto)' in a function return type.  */
static GTY(()) dw_die_ref decltype_auto_die;

/* Forward declarations for functions defined in this file.  */

static void output_call_frame_info (int);

/* Personality decl of current unit.  Used only when assembler does not support
   personality CFI.  */
static GTY(()) rtx current_unit_personality;

/* Whether an eh_frame section is required.  */
static GTY(()) bool do_eh_frame = false;

/* .debug_rnglists next index.  */
static unsigned int rnglist_idx;

/* Data and reference forms for relocatable data.  */
#define DW_FORM_data (dwarf_offset_size == 8 ? DW_FORM_data8 : DW_FORM_data4)
#define DW_FORM_ref (dwarf_offset_size == 8 ? DW_FORM_ref8 : DW_FORM_ref4)

#ifndef DEBUG_FRAME_SECTION
#define DEBUG_FRAME_SECTION	".debug_frame"
#endif

#ifndef FUNC_BEGIN_LABEL
#define FUNC_BEGIN_LABEL	"LFB"
#endif

#ifndef FUNC_SECOND_SECT_LABEL
#define FUNC_SECOND_SECT_LABEL	"LFSB"
#endif

#ifndef FUNC_END_LABEL
#define FUNC_END_LABEL		"LFE"
#endif

#ifndef PROLOGUE_END_LABEL
#define PROLOGUE_END_LABEL	"LPE"
#endif

#ifndef EPILOGUE_BEGIN_LABEL
#define EPILOGUE_BEGIN_LABEL	"LEB"
#endif

#ifndef FRAME_BEGIN_LABEL
#define FRAME_BEGIN_LABEL	"Lframe"
#endif
#define CIE_AFTER_SIZE_LABEL	"LSCIE"
#define CIE_END_LABEL		"LECIE"
#define FDE_LABEL		"LSFDE"
#define FDE_AFTER_SIZE_LABEL	"LASFDE"
#define FDE_END_LABEL		"LEFDE"
#define LINE_NUMBER_BEGIN_LABEL	"LSLT"
#define LINE_NUMBER_END_LABEL	"LELT"
#define LN_PROLOG_AS_LABEL	"LASLTP"
#define LN_PROLOG_END_LABEL	"LELTP"
#define DIE_LABEL_PREFIX	"DW"

/* Match the base name of a file to the base name of a compilation unit. */

static int
matches_main_base (const char *path)
{
  /* Cache the last query. */
  static const char *last_path = NULL;
  static int last_match = 0;
  if (path != last_path)
    {
      const char *base;
      int length = base_of_path (path, &base);
      last_path = path;
      last_match = (length == main_input_baselength
                    && memcmp (base, main_input_basename, length) == 0);
    }
  return last_match;
}

#ifdef DEBUG_DEBUG_STRUCT

static int
dump_struct_debug (tree type, enum debug_info_usage usage,
		   enum debug_struct_file criterion, int generic,
		   int matches, int result)
{
  /* Find the type name. */
  tree type_decl = TYPE_STUB_DECL (type);
  tree t = type_decl;
  const char *name = 0;
  if (TREE_CODE (t) == TYPE_DECL)
    t = DECL_NAME (t);
  if (t)
    name = IDENTIFIER_POINTER (t);

  fprintf (stderr, "	struct %d %s %s %s %s %d %p %s\n",
	   criterion,
           DECL_IN_SYSTEM_HEADER (type_decl) ? "sys" : "usr",
           matches ? "bas" : "hdr",
           generic ? "gen" : "ord",
           usage == DINFO_USAGE_DFN ? ";" :
             usage == DINFO_USAGE_DIR_USE ? "." : "*",
           result,
           (void*) type_decl, name);
  return result;
}
#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
  dump_struct_debug (type, usage, criterion, generic, matches, result)

#else

#define DUMP_GSTRUCT(type, usage, criterion, generic, matches, result) \
  (result)

#endif

/* Get the number of HOST_WIDE_INTs needed to represent the precision
   of the number.  */

static unsigned int
get_full_len (const wide_int &op)
{
  int prec = wi::get_precision (op);
  return ((prec + HOST_BITS_PER_WIDE_INT - 1)
	  / HOST_BITS_PER_WIDE_INT);
}

static bool
should_emit_struct_debug (tree type, enum debug_info_usage usage)
{
  if (debug_info_level <= DINFO_LEVEL_TERSE)
    return false;

  enum debug_struct_file criterion;
  tree type_decl;
  bool generic = lang_hooks.types.generic_p (type);

  if (generic)
    criterion = debug_struct_generic[usage];
  else
    criterion = debug_struct_ordinary[usage];

  if (criterion == DINFO_STRUCT_FILE_NONE)
    return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
  if (criterion == DINFO_STRUCT_FILE_ANY)
    return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);

  type_decl = TYPE_STUB_DECL (TYPE_MAIN_VARIANT (type));

  if (type_decl != NULL)
    {
     if (criterion == DINFO_STRUCT_FILE_SYS && DECL_IN_SYSTEM_HEADER (type_decl))
        return DUMP_GSTRUCT (type, usage, criterion, generic, false, true);

      if (matches_main_base (DECL_SOURCE_FILE (type_decl)))
        return DUMP_GSTRUCT (type, usage, criterion, generic, true, true);
    }

  return DUMP_GSTRUCT (type, usage, criterion, generic, false, false);
}

/* Switch [BACK] to eh_frame_section.  If we don't have an eh_frame_section,
   switch to the data section instead, and write out a synthetic start label
   for collect2 the first time around.  */

static void
switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
{
  if (eh_frame_section == 0)
    {
      int flags;

      if (EH_TABLES_CAN_BE_READ_ONLY)
	{
	  int fde_encoding;
	  int per_encoding;
	  int lsda_encoding;

	  fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1,
						       /*global=*/0);
	  per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2,
						       /*global=*/1);
	  lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0,
							/*global=*/0);
	  flags = ((! flag_pic
		    || ((fde_encoding & 0x70) != DW_EH_PE_absptr
			&& (fde_encoding & 0x70) != DW_EH_PE_aligned
			&& (per_encoding & 0x70) != DW_EH_PE_absptr
			&& (per_encoding & 0x70) != DW_EH_PE_aligned
			&& (lsda_encoding & 0x70) != DW_EH_PE_absptr
			&& (lsda_encoding & 0x70) != DW_EH_PE_aligned))
		   ? 0 : SECTION_WRITE);
	}
      else
	flags = SECTION_WRITE;

#ifdef EH_FRAME_SECTION_NAME
      eh_frame_section = get_section (EH_FRAME_SECTION_NAME, flags, NULL);
#else
      eh_frame_section = ((flags == SECTION_WRITE)
			  ? data_section : readonly_data_section);
#endif /* EH_FRAME_SECTION_NAME */
    }

  switch_to_section (eh_frame_section);

#ifdef EH_FRAME_THROUGH_COLLECT2
  /* We have no special eh_frame section.  Emit special labels to guide
     collect2.  */
  if (!back)
    {
      tree label = get_file_function_name ("F");
      ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
      targetm.asm_out.globalize_label (asm_out_file,
					IDENTIFIER_POINTER (label));
      ASM_OUTPUT_LABEL (asm_out_file, IDENTIFIER_POINTER (label));
    }
#endif
}

/* Switch [BACK] to the eh or debug frame table section, depending on
   FOR_EH.  */

static void
switch_to_frame_table_section (int for_eh, bool back)
{
  if (for_eh)
    switch_to_eh_frame_section (back);
  else
    {
      if (!debug_frame_section)
	debug_frame_section = get_section (DEBUG_FRAME_SECTION,
					   SECTION_DEBUG, NULL);
      switch_to_section (debug_frame_section);
    }
}

/* Describe for the GTY machinery what parts of dw_cfi_oprnd1 are used.  */

enum dw_cfi_oprnd_type
dw_cfi_oprnd1_desc (enum dwarf_call_frame_info cfi)
{
  switch (cfi)
    {
    case DW_CFA_nop:
    case DW_CFA_GNU_window_save:
    case DW_CFA_remember_state:
    case DW_CFA_restore_state:
      return dw_cfi_oprnd_unused;

    case DW_CFA_set_loc:
    case DW_CFA_advance_loc1:
    case DW_CFA_advance_loc2:
    case DW_CFA_advance_loc4:
    case DW_CFA_MIPS_advance_loc8:
      return dw_cfi_oprnd_addr;

    case DW_CFA_offset:
    case DW_CFA_offset_extended:
    case DW_CFA_def_cfa:
    case DW_CFA_offset_extended_sf:
    case DW_CFA_def_cfa_sf:
    case DW_CFA_restore:
    case DW_CFA_restore_extended:
    case DW_CFA_undefined:
    case DW_CFA_same_value:
    case DW_CFA_def_cfa_register:
    case DW_CFA_register:
    case DW_CFA_expression:
    case DW_CFA_val_expression:
      return dw_cfi_oprnd_reg_num;

    case DW_CFA_def_cfa_offset:
    case DW_CFA_GNU_args_size:
    case DW_CFA_def_cfa_offset_sf:
      return dw_cfi_oprnd_offset;

    case DW_CFA_def_cfa_expression:
      return dw_cfi_oprnd_loc;

    default:
      gcc_unreachable ();
    }
}

/* Describe for the GTY machinery what parts of dw_cfi_oprnd2 are used.  */

enum dw_cfi_oprnd_type
dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi)
{
  switch (cfi)
    {
    case DW_CFA_def_cfa:
    case DW_CFA_def_cfa_sf:
    case DW_CFA_offset:
    case DW_CFA_offset_extended_sf:
    case DW_CFA_offset_extended:
      return dw_cfi_oprnd_offset;

    case DW_CFA_register:
      return dw_cfi_oprnd_reg_num;

    case DW_CFA_expression:
    case DW_CFA_val_expression:
      return dw_cfi_oprnd_loc;

    case DW_CFA_def_cfa_expression:
      return dw_cfi_oprnd_cfa_loc;

    default:
      return dw_cfi_oprnd_unused;
    }
}

/* Output one FDE.  */

static void
output_fde (dw_fde_ref fde, bool for_eh, bool second,
	    char *section_start_label, int fde_encoding, char *augmentation,
	    bool any_lsda_needed, int lsda_encoding)
{
  const char *begin, *end;
  static unsigned int j;
  char l1[MAX_ARTIFICIAL_LABEL_BYTES], l2[MAX_ARTIFICIAL_LABEL_BYTES];

  targetm.asm_out.emit_unwind_label (asm_out_file, fde->decl, for_eh,
				     /* empty */ 0);
  targetm.asm_out.internal_label (asm_out_file, FDE_LABEL,
				  for_eh + j);
  ASM_GENERATE_INTERNAL_LABEL (l1, FDE_AFTER_SIZE_LABEL, for_eh + j);
  ASM_GENERATE_INTERNAL_LABEL (l2, FDE_END_LABEL, for_eh + j);
  if (!XCOFF_DEBUGGING_INFO || for_eh)
    {
      if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4 && !for_eh)
	dw2_asm_output_data (4, 0xffffffff, "Initial length escape value"
			     " indicating 64-bit DWARF extension");
      dw2_asm_output_delta (for_eh ? 4 : dwarf_offset_size, l2, l1,
			    "FDE Length");
    }
  ASM_OUTPUT_LABEL (asm_out_file, l1);

  if (for_eh)
    dw2_asm_output_delta (4, l1, section_start_label, "FDE CIE offset");
  else
    dw2_asm_output_offset (dwarf_offset_size, section_start_label,
			   debug_frame_section, "FDE CIE offset");

  begin = second ? fde->dw_fde_second_begin : fde->dw_fde_begin;
  end = second ? fde->dw_fde_second_end : fde->dw_fde_end;

  if (for_eh)
    {
      rtx sym_ref = gen_rtx_SYMBOL_REF (Pmode, begin);
      SYMBOL_REF_FLAGS (sym_ref) |= SYMBOL_FLAG_LOCAL;
      dw2_asm_output_encoded_addr_rtx (fde_encoding, sym_ref, false,
				       "FDE initial location");
      dw2_asm_output_delta (size_of_encoded_value (fde_encoding),
			    end, begin, "FDE address range");
    }
  else
    {
      dw2_asm_output_addr (DWARF2_ADDR_SIZE, begin, "FDE initial location");
      dw2_asm_output_delta (DWARF2_ADDR_SIZE, end, begin, "FDE address range");
    }

  if (augmentation[0])
    {
      if (any_lsda_needed)
	{
	  int size = size_of_encoded_value (lsda_encoding);

	  if (lsda_encoding == DW_EH_PE_aligned)
	    {
	      int offset = (  4		/* Length */
			    + 4		/* CIE offset */
			    + 2 * size_of_encoded_value (fde_encoding)
			    + 1		/* Augmentation size */ );
	      int pad = -offset & (PTR_SIZE - 1);

	      size += pad;
	      gcc_assert (size_of_uleb128 (size) == 1);
	    }

	  dw2_asm_output_data_uleb128 (size, "Augmentation size");

	  if (fde->uses_eh_lsda)
	    {
	      ASM_GENERATE_INTERNAL_LABEL (l1, second ? "LLSDAC" : "LLSDA",
					   fde->funcdef_number);
	      dw2_asm_output_encoded_addr_rtx (lsda_encoding,
					       gen_rtx_SYMBOL_REF (Pmode, l1),
					       false,
					       "Language Specific Data Area");
	    }
	  else
	    {
	      if (lsda_encoding == DW_EH_PE_aligned)
		ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (PTR_SIZE));
	      dw2_asm_output_data (size_of_encoded_value (lsda_encoding), 0,
				   "Language Specific Data Area (none)");
	    }
	}
      else
	dw2_asm_output_data_uleb128 (0, "Augmentation size");
    }

  /* Loop through the Call Frame Instructions associated with this FDE.  */
  fde->dw_fde_current_label = begin;
  {
    size_t from, until, i;

    from = 0;
    until = vec_safe_length (fde->dw_fde_cfi);

    if (fde->dw_fde_second_begin == NULL)
      ;
    else if (!second)
      until = fde->dw_fde_switch_cfi_index;
    else
      from = fde->dw_fde_switch_cfi_index;

    for (i = from; i < until; i++)
      output_cfi ((*fde->dw_fde_cfi)[i], fde, for_eh);
  }

  /* If we are to emit a ref/link from function bodies to their frame tables,
     do it now.  This is typically performed to make sure that tables
     associated with functions are dragged with them and not discarded in
     garbage collecting links. We need to do this on a per function basis to
     cope with -ffunction-sections.  */

#ifdef ASM_OUTPUT_DWARF_TABLE_REF
  /* Switch to the function section, emit the ref to the tables, and
     switch *back* into the table section.  */
  switch_to_section (function_section (fde->decl));
  ASM_OUTPUT_DWARF_TABLE_REF (section_start_label);
  switch_to_frame_table_section (for_eh, true);
#endif

  /* Pad the FDE out to an address sized boundary.  */
  ASM_OUTPUT_ALIGN (asm_out_file,
		    floor_log2 ((for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE)));
  ASM_OUTPUT_LABEL (asm_out_file, l2);

  j += 2;
}

/* Return true if frame description entry FDE is needed for EH.  */

static bool
fde_needed_for_eh_p (dw_fde_ref fde)
{
  if (flag_asynchronous_unwind_tables)
    return true;

  if (TARGET_USES_WEAK_UNWIND_INFO && DECL_WEAK (fde->decl))
    return true;

  if (fde->uses_eh_lsda)
    return true;

  /* If exceptions are enabled, we have collected nothrow info.  */
  if (flag_exceptions && (fde->all_throwers_are_sibcalls || fde->nothrow))
    return false;

  return true;
}

/* Output the call frame information used to record information
   that relates to calculating the frame pointer, and records the
   location of saved registers.  */

static void
output_call_frame_info (int for_eh)
{
  unsigned int i;
  dw_fde_ref fde;
  dw_cfi_ref cfi;
  char l1[MAX_ARTIFICIAL_LABEL_BYTES], l2[MAX_ARTIFICIAL_LABEL_BYTES];
  char section_start_label[MAX_ARTIFICIAL_LABEL_BYTES];
  bool any_lsda_needed = false;
  char augmentation[6];
  int augmentation_size;
  int fde_encoding = DW_EH_PE_absptr;
  int per_encoding = DW_EH_PE_absptr;
  int lsda_encoding = DW_EH_PE_absptr;
  int return_reg;
  rtx personality = NULL;
  int dw_cie_version;

  /* Don't emit a CIE if there won't be any FDEs.  */
  if (!fde_vec)
    return;

  /* Nothing to do if the assembler's doing it all.  */
  if (dwarf2out_do_cfi_asm ())
    return;

  /* If we don't have any functions we'll want to unwind out of, don't emit
     any EH unwind information.  If we make FDEs linkonce, we may have to
     emit an empty label for an FDE that wouldn't otherwise be emitted.  We
     want to avoid having an FDE kept around when the function it refers to
     is discarded.  Example where this matters: a primary function template
     in C++ requires EH information, an explicit specialization doesn't.  */
  if (for_eh)
    {
      bool any_eh_needed = false;

      FOR_EACH_VEC_ELT (*fde_vec, i, fde)
	{
	  if (fde->uses_eh_lsda)
	    any_eh_needed = any_lsda_needed = true;
	  else if (fde_needed_for_eh_p (fde))
	    any_eh_needed = true;
	  else if (TARGET_USES_WEAK_UNWIND_INFO)
	    targetm.asm_out.emit_unwind_label (asm_out_file, fde->decl, 1, 1);
	}

      if (!any_eh_needed)
	return;
    }

  /* We're going to be generating comments, so turn on app.  */
  if (flag_debug_asm)
    app_enable ();

  /* Switch to the proper frame section, first time.  */
  switch_to_frame_table_section (for_eh, false);

  ASM_GENERATE_INTERNAL_LABEL (section_start_label, FRAME_BEGIN_LABEL, for_eh);
  ASM_OUTPUT_LABEL (asm_out_file, section_start_label);

  /* Output the CIE.  */
  ASM_GENERATE_INTERNAL_LABEL (l1, CIE_AFTER_SIZE_LABEL, for_eh);
  ASM_GENERATE_INTERNAL_LABEL (l2, CIE_END_LABEL, for_eh);
  if (!XCOFF_DEBUGGING_INFO || for_eh)
    {
      if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4 && !for_eh)
	dw2_asm_output_data (4, 0xffffffff,
	  "Initial length escape value indicating 64-bit DWARF extension");
      dw2_asm_output_delta (for_eh ? 4 : dwarf_offset_size, l2, l1,
			    "Length of Common Information Entry");
    }
  ASM_OUTPUT_LABEL (asm_out_file, l1);

  /* Now that the CIE pointer is PC-relative for EH,
     use 0 to identify the CIE.  */
  dw2_asm_output_data ((for_eh ? 4 : dwarf_offset_size),
		       (for_eh ? 0 : DWARF_CIE_ID),
		       "CIE Identifier Tag");

  /* Use the CIE version 3 for DWARF3; allow DWARF2 to continue to
     use CIE version 1, unless that would produce incorrect results
     due to overflowing the return register column.  */
  return_reg = DWARF2_FRAME_REG_OUT (DWARF_FRAME_RETURN_COLUMN, for_eh);
  dw_cie_version = 1;
  if (return_reg >= 256 || dwarf_version > 2)
    dw_cie_version = 3;
  dw2_asm_output_data (1, dw_cie_version, "CIE Version");

  augmentation[0] = 0;
  augmentation_size = 0;

  personality = current_unit_personality;
  if (for_eh)
    {
      char *p;

      /* Augmentation:
	 z	Indicates that a uleb128 is present to size the
		augmentation section.
	 L	Indicates the encoding (and thus presence) of
		an LSDA pointer in the FDE augmentation.
	 R	Indicates a non-default pointer encoding for
		FDE code pointers.
	 P	Indicates the presence of an encoding + language
		personality routine in the CIE augmentation.  */

      fde_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0);
      per_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
      lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);

      p = augmentation + 1;
      if (personality)
	{
	  *p++ = 'P';
	  augmentation_size += 1 + size_of_encoded_value (per_encoding);
	  assemble_external_libcall (personality);
	}
      if (any_lsda_needed)
	{
	  *p++ = 'L';
	  augmentation_size += 1;
	}
      if (fde_encoding != DW_EH_PE_absptr)
	{
	  *p++ = 'R';
	  augmentation_size += 1;
	}
      if (p > augmentation + 1)
	{
	  augmentation[0] = 'z';
	  *p = '\0';
	}

      /* Ug.  Some platforms can't do unaligned dynamic relocations at all.  */
      if (personality && per_encoding == DW_EH_PE_aligned)
	{
	  int offset = (  4		/* Length */
			+ 4		/* CIE Id */
			+ 1		/* CIE version */
			+ strlen (augmentation) + 1	/* Augmentation */
			+ size_of_uleb128 (1)		/* Code alignment */
			+ size_of_sleb128 (DWARF_CIE_DATA_ALIGNMENT)
			+ 1		/* RA column */
			+ 1		/* Augmentation size */
			+ 1		/* Personality encoding */ );
	  int pad = -offset & (PTR_SIZE - 1);

	  augmentation_size += pad;

	  /* Augmentations should be small, so there's scarce need to
	     iterate for a solution.  Die if we exceed one uleb128 byte.  */
	  gcc_assert (size_of_uleb128 (augmentation_size) == 1);
	}
    }

  dw2_asm_output_nstring (augmentation, -1, "CIE Augmentation");
  if (dw_cie_version >= 4)
    {
      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "CIE Address Size");
      dw2_asm_output_data (1, 0, "CIE Segment Size");
    }
  dw2_asm_output_data_uleb128 (1, "CIE Code Alignment Factor");
  dw2_asm_output_data_sleb128 (DWARF_CIE_DATA_ALIGNMENT,
			       "CIE Data Alignment Factor");

  if (dw_cie_version == 1)
    dw2_asm_output_data (1, return_reg, "CIE RA Column");
  else
    dw2_asm_output_data_uleb128 (return_reg, "CIE RA Column");

  if (augmentation[0])
    {
      dw2_asm_output_data_uleb128 (augmentation_size, "Augmentation size");
      if (personality)
	{
	  dw2_asm_output_data (1, per_encoding, "Personality (%s)",
			       eh_data_format_name (per_encoding));
	  dw2_asm_output_encoded_addr_rtx (per_encoding,
					   personality,
					   true, NULL);
	}

      if (any_lsda_needed)
	dw2_asm_output_data (1, lsda_encoding, "LSDA Encoding (%s)",
			     eh_data_format_name (lsda_encoding));

      if (fde_encoding != DW_EH_PE_absptr)
	dw2_asm_output_data (1, fde_encoding, "FDE Encoding (%s)",
			     eh_data_format_name (fde_encoding));
    }

  FOR_EACH_VEC_ELT (*cie_cfi_vec, i, cfi)
    output_cfi (cfi, NULL, for_eh);

  /* Pad the CIE out to an address sized boundary.  */
  ASM_OUTPUT_ALIGN (asm_out_file,
		    floor_log2 (for_eh ? PTR_SIZE : DWARF2_ADDR_SIZE));
  ASM_OUTPUT_LABEL (asm_out_file, l2);

  /* Loop through all of the FDE's.  */
  FOR_EACH_VEC_ELT (*fde_vec, i, fde)
    {
      unsigned int k;

      /* Don't emit EH unwind info for leaf functions that don't need it.  */
      if (for_eh && !fde_needed_for_eh_p (fde))
	continue;

      for (k = 0; k < (fde->dw_fde_second_begin ? 2 : 1); k++)
	output_fde (fde, for_eh, k, section_start_label, fde_encoding,
		    augmentation, any_lsda_needed, lsda_encoding);
    }

  if (for_eh && targetm.terminate_dw2_eh_frame_info)
    dw2_asm_output_data (4, 0, "End of Table");

  /* Turn off app to make assembly quicker.  */
  if (flag_debug_asm)
    app_disable ();
}

/* Emit .cfi_startproc and .cfi_personality/.cfi_lsda if needed.  */

static void
dwarf2out_do_cfi_startproc (bool second)
{
  int enc;
  rtx ref;

  fprintf (asm_out_file, "\t.cfi_startproc\n");

  targetm.asm_out.post_cfi_startproc (asm_out_file, current_function_decl);

  /* .cfi_personality and .cfi_lsda are only relevant to DWARF2
     eh unwinders.  */
  if (targetm_common.except_unwind_info (&global_options) != UI_DWARF2)
    return;

  rtx personality = get_personality_function (current_function_decl);

  if (personality)
    {
      enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2, /*global=*/1);
      ref = personality;

      /* ??? The GAS support isn't entirely consistent.  We have to
	 handle indirect support ourselves, but PC-relative is done
	 in the assembler.  Further, the assembler can't handle any
	 of the weirder relocation types.  */
      if (enc & DW_EH_PE_indirect)
	{
	  if (targetm.asm_out.make_eh_symbol_indirect != NULL)
	    ref = targetm.asm_out.make_eh_symbol_indirect (ref, true);
	  else
	    ref = dw2_force_const_mem (ref, true);
	}

      fprintf (asm_out_file, "\t.cfi_personality %#x,", enc);
      output_addr_const (asm_out_file, ref);
      fputc ('\n', asm_out_file);
    }

  if (crtl->uses_eh_lsda)
    {
      char lab[MAX_ARTIFICIAL_LABEL_BYTES];

      enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0, /*global=*/0);
      ASM_GENERATE_INTERNAL_LABEL (lab, second ? "LLSDAC" : "LLSDA",
				   current_function_funcdef_no);
      ref = gen_rtx_SYMBOL_REF (Pmode, lab);
      SYMBOL_REF_FLAGS (ref) = SYMBOL_FLAG_LOCAL;

      if (enc & DW_EH_PE_indirect)
	{
	  if (targetm.asm_out.make_eh_symbol_indirect != NULL)
	    ref = targetm.asm_out.make_eh_symbol_indirect (ref, true);
	  else
	    ref = dw2_force_const_mem (ref, true);
	}

      fprintf (asm_out_file, "\t.cfi_lsda %#x,", enc);
      output_addr_const (asm_out_file, ref);
      fputc ('\n', asm_out_file);
    }
}

/* Allocate CURRENT_FDE.  Immediately initialize all we can, noting that
   this allocation may be done before pass_final.  */

dw_fde_ref
dwarf2out_alloc_current_fde (void)
{
  dw_fde_ref fde;

  fde = ggc_cleared_alloc<dw_fde_node> ();
  fde->decl = current_function_decl;
  fde->funcdef_number = current_function_funcdef_no;
  fde->fde_index = vec_safe_length (fde_vec);
  fde->all_throwers_are_sibcalls = crtl->all_throwers_are_sibcalls;
  fde->uses_eh_lsda = crtl->uses_eh_lsda;
  fde->nothrow = crtl->nothrow;
  fde->drap_reg = INVALID_REGNUM;
  fde->vdrap_reg = INVALID_REGNUM;

  /* Record the FDE associated with this function.  */
  cfun->fde = fde;
  vec_safe_push (fde_vec, fde);

  return fde;
}

/* Output a marker (i.e. a label) for the beginning of a function, before
   the prologue.  */

void
dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED,
			  unsigned int column ATTRIBUTE_UNUSED,
			  const char *file ATTRIBUTE_UNUSED)
{
  char label[MAX_ARTIFICIAL_LABEL_BYTES];
  char * dup_label;
  dw_fde_ref fde;
  section *fnsec;
  bool do_frame;

  current_function_func_begin_label = NULL;

  do_frame = dwarf2out_do_frame ();

  /* ??? current_function_func_begin_label is also used by except.c for
     call-site information.  We must emit this label if it might be used.  */
  if (!do_frame
      && (!flag_exceptions
	  || targetm_common.except_unwind_info (&global_options) == UI_SJLJ))
    return;

  fnsec = function_section (current_function_decl);
  switch_to_section (fnsec);
  ASM_GENERATE_INTERNAL_LABEL (label, FUNC_BEGIN_LABEL,
			       current_function_funcdef_no);
  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, FUNC_BEGIN_LABEL,
			  current_function_funcdef_no);
  dup_label = xstrdup (label);
  current_function_func_begin_label = dup_label;

  /* We can elide FDE allocation if we're not emitting frame unwind info.  */
  if (!do_frame)
    return;

  /* Unlike the debug version, the EH version of frame unwind info is a per-
     function setting so we need to record whether we need it for the unit.  */
  do_eh_frame |= dwarf2out_do_eh_frame ();

  /* Cater to the various TARGET_ASM_OUTPUT_MI_THUNK implementations that
     emit insns as rtx but bypass the bulk of rest_of_compilation, which
     would include pass_dwarf2_frame.  If we've not created the FDE yet,
     do so now.  */
  fde = cfun->fde;
  if (fde == NULL)
    fde = dwarf2out_alloc_current_fde ();

  /* Initialize the bits of CURRENT_FDE that were not available earlier.  */
  fde->dw_fde_begin = dup_label;
  fde->dw_fde_current_label = dup_label;
  fde->in_std_section = (fnsec == text_section
			 || (cold_text_section && fnsec == cold_text_section));
  fde->ignored_debug = DECL_IGNORED_P (current_function_decl);
  in_text_section_p = fnsec == text_section;

  /* We only want to output line number information for the genuine dwarf2
     prologue case, not the eh frame case.  */
#ifdef DWARF2_DEBUGGING_INFO
  if (file)
    dwarf2out_source_line (line, column, file, 0, true);
#endif

  if (dwarf2out_do_cfi_asm ())
    dwarf2out_do_cfi_startproc (false);
  else
    {
      rtx personality = get_personality_function (current_function_decl);
      if (!current_unit_personality)
        current_unit_personality = personality;

      /* We cannot keep a current personality per function as without CFI
	 asm, at the point where we emit the CFI data, there is no current
	 function anymore.  */
      if (personality && current_unit_personality != personality)
	sorry ("multiple EH personalities are supported only with assemblers "
	       "supporting %<.cfi_personality%> directive");
    }
}

/* Output a marker (i.e. a label) for the end of the generated code
   for a function prologue.  This gets called *after* the prologue code has
   been generated.  */

void
dwarf2out_vms_end_prologue (unsigned int line ATTRIBUTE_UNUSED,
			    const char *file ATTRIBUTE_UNUSED)
{
  char label[MAX_ARTIFICIAL_LABEL_BYTES];

  /* Output a label to mark the endpoint of the code generated for this
     function.  */
  ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL,
			       current_function_funcdef_no);
  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, PROLOGUE_END_LABEL,
			  current_function_funcdef_no);
  cfun->fde->dw_fde_vms_end_prologue = xstrdup (label);
}

/* Output a marker (i.e. a label) for the beginning of the generated code
   for a function epilogue.  This gets called *before* the prologue code has
   been generated.  */

void
dwarf2out_vms_begin_epilogue (unsigned int line ATTRIBUTE_UNUSED,
			  const char *file ATTRIBUTE_UNUSED)
{
  dw_fde_ref fde = cfun->fde;
  char label[MAX_ARTIFICIAL_LABEL_BYTES];

  if (fde->dw_fde_vms_begin_epilogue)
    return;

  /* Output a label to mark the endpoint of the code generated for this
     function.  */
  ASM_GENERATE_INTERNAL_LABEL (label, EPILOGUE_BEGIN_LABEL,
			       current_function_funcdef_no);
  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, EPILOGUE_BEGIN_LABEL,
			  current_function_funcdef_no);
  fde->dw_fde_vms_begin_epilogue = xstrdup (label);
}

/* Mark the ranges of non-debug subsections in the std text sections.  */

static void
mark_ignored_debug_section (dw_fde_ref fde, bool second)
{
  bool std_section;
  const char *begin_label, *end_label;
  const char **last_end_label;
  vec<const char *, va_gc> **switch_ranges;

  if (second)
    {
      std_section = fde->second_in_std_section;
      begin_label = fde->dw_fde_second_begin;
      end_label   = fde->dw_fde_second_end;
    }
  else
    {
      std_section = fde->in_std_section;
      begin_label = fde->dw_fde_begin;
      end_label   = fde->dw_fde_end;
    }

  if (!std_section)
    return;

  if (in_text_section_p)
    {
      last_end_label = &last_text_label;
      switch_ranges  = &switch_text_ranges;
    }
  else
    {
      last_end_label = &last_cold_label;
      switch_ranges  = &switch_cold_ranges;
    }

  if (fde->ignored_debug)
    {
      if (*switch_ranges && !(vec_safe_length (*switch_ranges) & 1))
	vec_safe_push (*switch_ranges, *last_end_label);
    }
  else
    {
      *last_end_label = end_label;

      if (!*switch_ranges)
	vec_alloc (*switch_ranges, 16);
      else if (vec_safe_length (*switch_ranges) & 1)
	vec_safe_push (*switch_ranges, begin_label);
    }
}

/* Output a marker (i.e. a label) for the absolute end of the generated code
   for a function definition.  This gets called *after* the epilogue code has
   been generated.  */

void
dwarf2out_end_epilogue (unsigned int line ATTRIBUTE_UNUSED,
			const char *file ATTRIBUTE_UNUSED)
{
  dw_fde_ref fde;
  char label[MAX_ARTIFICIAL_LABEL_BYTES];

  last_var_location_insn = NULL;
  cached_next_real_insn = NULL;

  if (dwarf2out_do_cfi_asm ())
    fprintf (asm_out_file, "\t.cfi_endproc\n");

  /* Output a label to mark the endpoint of the code generated for this
     function.  */
  ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
			       current_function_funcdef_no);
  ASM_OUTPUT_LABEL (asm_out_file, label);
  fde = cfun->fde;
  gcc_assert (fde != NULL);
  if (fde->dw_fde_second_begin == NULL)
    fde->dw_fde_end = xstrdup (label);

  mark_ignored_debug_section (fde, fde->dw_fde_second_begin != NULL);
}

void
dwarf2out_frame_finish (void)
{
  /* Output call frame information.  */
  if (targetm.debug_unwind_info () == UI_DWARF2)
    output_call_frame_info (0);

  /* Output another copy for the unwinder.  */
  if (do_eh_frame)
    output_call_frame_info (1);
}

static void var_location_switch_text_section (void);
static void set_cur_line_info_table (section *);

void
dwarf2out_switch_text_section (void)
{
  char label[MAX_ARTIFICIAL_LABEL_BYTES];
  section *sect;
  dw_fde_ref fde = cfun->fde;

  gcc_assert (cfun && fde && fde->dw_fde_second_begin == NULL);

  ASM_GENERATE_INTERNAL_LABEL (label, FUNC_SECOND_SECT_LABEL,
			       current_function_funcdef_no);

  fde->dw_fde_second_begin = ggc_strdup (label);
  if (!in_cold_section_p)
    {
      fde->dw_fde_end = crtl->subsections.cold_section_end_label;
      fde->dw_fde_second_end = crtl->subsections.hot_section_end_label;
    }
  else
    {
      fde->dw_fde_end = crtl->subsections.hot_section_end_label;
      fde->dw_fde_second_end = crtl->subsections.cold_section_end_label;
    }
  have_multiple_function_sections = true;

  if (dwarf2out_do_cfi_asm ())
    fprintf (asm_out_file, "\t.cfi_endproc\n");

  mark_ignored_debug_section (fde, false);

  /* Now do the real section switch.  */
  sect = current_function_section ();
  switch_to_section (sect);

  fde->second_in_std_section
    = (sect == text_section
       || (cold_text_section && sect == cold_text_section));
  in_text_section_p = sect == text_section;

  if (dwarf2out_do_cfi_asm ())
    dwarf2out_do_cfi_startproc (true);

  var_location_switch_text_section ();

  if (cold_text_section != NULL)
    set_cur_line_info_table (sect);
}

/* And now, the subset of the debugging information support code necessary
   for emitting location expressions.  */

/* Describe an entry into the .debug_addr section.  */

enum ate_kind {
  ate_kind_rtx,
  ate_kind_rtx_dtprel,
  ate_kind_label
};

struct GTY((for_user)) addr_table_entry {
  enum ate_kind kind;
  unsigned int refcount;
  unsigned int index;
  union addr_table_entry_struct_union
    {
      rtx GTY ((tag ("0"))) rtl;
      char * GTY ((tag ("1"))) label;
    }
  GTY ((desc ("%1.kind"))) addr;
};

typedef unsigned int var_loc_view;

/* Location lists are ranges + location descriptions for that range,
   so you can track variables that are in different places over
   their entire life.  */
typedef struct GTY(()) dw_loc_list_struct {
  dw_loc_list_ref dw_loc_next;
  const char *begin; /* Label and addr_entry for start of range */
  addr_table_entry *begin_entry;
  const char *end;  /* Label for end of range */
  addr_table_entry *end_entry;
  char *ll_symbol; /* Label for beginning of location list.
		      Only on head of list.  */
  char *vl_symbol; /* Label for beginning of view list.  Ditto.  */
  const char *section; /* Section this loclist is relative to */
  dw_loc_descr_ref expr;
  var_loc_view vbegin, vend;
  hashval_t hash;
  /* True if all addresses in this and subsequent lists are known to be
     resolved.  */
  bool resolved_addr;
  /* True if this list has been replaced by dw_loc_next.  */
  bool replaced;
  /* True if it has been emitted into .debug_loc* / .debug_loclists*
     section.  */
  unsigned char emitted : 1;
  /* True if hash field is index rather than hash value.  */
  unsigned char num_assigned : 1;
  /* True if .debug_loclists.dwo offset has been emitted for it already.  */
  unsigned char offset_emitted : 1;
  /* True if note_variable_value_in_expr has been called on it.  */
  unsigned char noted_variable_value : 1;
  /* True if the range should be emitted even if begin and end
     are the same.  */
  bool force;
} dw_loc_list_node;

static dw_loc_descr_ref int_loc_descriptor (poly_int64);
static dw_loc_descr_ref uint_loc_descriptor (unsigned HOST_WIDE_INT);

/* Convert a DWARF stack opcode into its string name.  */

static const char *
dwarf_stack_op_name (unsigned int op)
{
  const char *name = get_DW_OP_name (op);

  if (name != NULL)
    return name;

  return "OP_<unknown>";
}

/* Return TRUE iff we're to output location view lists as a separate
   attribute next to the location lists, as an extension compatible
   with DWARF 2 and above.  */

static inline bool
dwarf2out_locviews_in_attribute ()
{
  return debug_variable_location_views == 1;
}

/* Return TRUE iff we're to output location view lists as part of the
   location lists, as proposed for standardization after DWARF 5.  */

static inline bool
dwarf2out_locviews_in_loclist ()
{
#ifndef DW_LLE_view_pair
  return false;
#else
  return debug_variable_location_views == -1;
#endif
}

/* Return a pointer to a newly allocated location description.  Location
   descriptions are simple expression terms that can be strung
   together to form more complicated location (address) descriptions.  */

static inline dw_loc_descr_ref
new_loc_descr (enum dwarf_location_atom op, unsigned HOST_WIDE_INT oprnd1,
	       unsigned HOST_WIDE_INT oprnd2)
{
  dw_loc_descr_ref descr = ggc_cleared_alloc<dw_loc_descr_node> ();

  descr->dw_loc_opc = op;
  descr->dw_loc_oprnd1.val_class = dw_val_class_unsigned_const;
  descr->dw_loc_oprnd1.val_entry = NULL;
  descr->dw_loc_oprnd1.v.val_unsigned = oprnd1;
  descr->dw_loc_oprnd2.val_class = dw_val_class_unsigned_const;
  descr->dw_loc_oprnd2.val_entry = NULL;
  descr->dw_loc_oprnd2.v.val_unsigned = oprnd2;

  return descr;
}

/* Add a location description term to a location description expression.  */

static inline void
add_loc_descr (dw_loc_descr_ref *list_head, dw_loc_descr_ref descr)
{
  dw_loc_descr_ref *d;

  /* Find the end of the chain.  */
  for (d = list_head; (*d) != NULL; d = &(*d)->dw_loc_next)
    ;

  *d = descr;
}

/* Compare two location operands for exact equality.  */

static bool
dw_val_equal_p (dw_val_node *a, dw_val_node *b)
{
  if (a->val_class != b->val_class)
    return false;
  switch (a->val_class)
    {
    case dw_val_class_none:
      return true;
    case dw_val_class_addr:
      return rtx_equal_p (a->v.val_addr, b->v.val_addr);

    case dw_val_class_offset:
    case dw_val_class_unsigned_const:
    case dw_val_class_const:
    case dw_val_class_unsigned_const_implicit:
    case dw_val_class_const_implicit:
    case dw_val_class_range_list:
      /* These are all HOST_WIDE_INT, signed or unsigned.  */
      return a->v.val_unsigned == b->v.val_unsigned;

    case dw_val_class_loc:
      return a->v.val_loc == b->v.val_loc;
    case dw_val_class_loc_list:
      return a->v.val_loc_list == b->v.val_loc_list;
    case dw_val_class_view_list:
      return a->v.val_view_list == b->v.val_view_list;
    case dw_val_class_die_ref:
      return a->v.val_die_ref.die == b->v.val_die_ref.die;
    case dw_val_class_fde_ref:
      return a->v.val_fde_index == b->v.val_fde_index;
    case dw_val_class_symview:
      return strcmp (a->v.val_symbolic_view, b->v.val_symbolic_view) == 0;
    case dw_val_class_lbl_id:
    case dw_val_class_lineptr:
    case dw_val_class_macptr:
    case dw_val_class_loclistsptr:
    case dw_val_class_high_pc:
      return strcmp (a->v.val_lbl_id, b->v.val_lbl_id) == 0;
    case dw_val_class_str:
      return a->v.val_str == b->v.val_str;
    case dw_val_class_flag:
      return a->v.val_flag == b->v.val_flag;
    case dw_val_class_file:
    case dw_val_class_file_implicit:
      return a->v.val_file == b->v.val_file;
    case dw_val_class_decl_ref:
      return a->v.val_decl_ref == b->v.val_decl_ref;
    
    case dw_val_class_const_double:
      return (a->v.val_double.high == b->v.val_double.high
	      && a->v.val_double.low == b->v.val_double.low);

    case dw_val_class_wide_int:
      return *a->v.val_wide == *b->v.val_wide;

    case dw_val_class_vec:
      {
	size_t a_len = a->v.val_vec.elt_size * a->v.val_vec.length;
	size_t b_len = b->v.val_vec.elt_size * b->v.val_vec.length;

	return (a_len == b_len
		&& !memcmp (a->v.val_vec.array, b->v.val_vec.array, a_len));
      }

    case dw_val_class_data8:
      return memcmp (a->v.val_data8, b->v.val_data8, 8) == 0;

    case dw_val_class_vms_delta:
      return (!strcmp (a->v.val_vms_delta.lbl1, b->v.val_vms_delta.lbl1)
	      && !strcmp (a->v.val_vms_delta.lbl2, b->v.val_vms_delta.lbl2));

    case dw_val_class_discr_value:
      return (a->v.val_discr_value.pos == b->v.val_discr_value.pos
	      && a->v.val_discr_value.v.uval == b->v.val_discr_value.v.uval);
    case dw_val_class_discr_list:
      /* It makes no sense comparing two discriminant value lists.  */
      return false;
    }
  gcc_unreachable ();
}

/* Compare two location atoms for exact equality.  */

static bool
loc_descr_equal_p_1 (dw_loc_descr_ref a, dw_loc_descr_ref b)
{
  if (a->dw_loc_opc != b->dw_loc_opc)
    return false;

  /* ??? This is only ever set for DW_OP_constNu, for N equal to the
     address size, but since we always allocate cleared storage it
     should be zero for other types of locations.  */
  if (a->dtprel != b->dtprel)
    return false;

  return (dw_val_equal_p (&a->dw_loc_oprnd1, &b->dw_loc_oprnd1)
	  && dw_val_equal_p (&a->dw_loc_oprnd2, &b->dw_loc_oprnd2));
}

/* Compare two complete location expressions for exact equality.  */

bool
loc_descr_equal_p (dw_loc_descr_ref a, dw_loc_descr_ref b)
{
  while (1)
    {
      if (a == b)
	return true;
      if (a == NULL || b == NULL)
	return false;
      if (!loc_descr_equal_p_1 (a, b))
	return false;

      a = a->dw_loc_next;
      b = b->dw_loc_next;
    }
}


/* Add a constant POLY_OFFSET to a location expression.  */

static void
loc_descr_plus_const (dw_loc_descr_ref *list_head, poly_int64 poly_offset)
{
  dw_loc_descr_ref loc;
  HOST_WIDE_INT *p;

  gcc_assert (*list_head != NULL);

  if (known_eq (poly_offset, 0))
    return;

  /* Find the end of the chain.  */
  for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
    ;

  HOST_WIDE_INT offset;
  if (!poly_offset.is_constant (&offset))
    {
      loc->dw_loc_next = int_loc_descriptor (poly_offset);
      add_loc_descr (&loc->dw_loc_next, new_loc_descr (DW_OP_plus, 0, 0));
      return;
    }

  p = NULL;
  if (loc->dw_loc_opc == DW_OP_fbreg
      || (loc->dw_loc_opc >= DW_OP_breg0 && loc->dw_loc_opc <= DW_OP_breg31))
    p = &loc->dw_loc_oprnd1.v.val_int;
  else if (loc->dw_loc_opc == DW_OP_bregx)
    p = &loc->dw_loc_oprnd2.v.val_int;

  /* If the last operation is fbreg, breg{0..31,x}, optimize by adjusting its
     offset.  Don't optimize if an signed integer overflow would happen.  */
  if (p != NULL
      && ((offset > 0 && *p <= INTTYPE_MAXIMUM (HOST_WIDE_INT) - offset)
	  || (offset < 0 && *p >= INTTYPE_MINIMUM (HOST_WIDE_INT) - offset)))
    *p += offset;

  else if (offset > 0)
    loc->dw_loc_next = new_loc_descr (DW_OP_plus_uconst, offset, 0);

  else
    {
      loc->dw_loc_next
	= uint_loc_descriptor (-(unsigned HOST_WIDE_INT) offset);
      add_loc_descr (&loc->dw_loc_next, new_loc_descr (DW_OP_minus, 0, 0));
    }
}

/* Return a pointer to a newly allocated location description for
   REG and OFFSET.  */

static inline dw_loc_descr_ref
new_reg_loc_descr (unsigned int reg, poly_int64 offset)
{
  HOST_WIDE_INT const_offset;
  if (offset.is_constant (&const_offset))
    {
      if (reg <= 31)
	return new_loc_descr ((enum dwarf_location_atom) (DW_OP_breg0 + reg),
			      const_offset, 0);
      else
	return new_loc_descr (DW_OP_bregx, reg, const_offset);
    }
  else
    {
      dw_loc_descr_ref ret = new_reg_loc_descr (reg, 0);
      loc_descr_plus_const (&ret, offset);
      return ret;
    }
}

/* Add a constant OFFSET to a location list.  */

static void
loc_list_plus_const (dw_loc_list_ref list_head, poly_int64 offset)
{
  dw_loc_list_ref d;
  for (d = list_head; d != NULL; d = d->dw_loc_next)
    loc_descr_plus_const (&d->expr, offset);
}

#define DWARF_REF_SIZE	\
  (dwarf_version == 2 ? DWARF2_ADDR_SIZE : dwarf_offset_size)

/* The number of bits that can be encoded by largest DW_FORM_dataN.
   In DWARF4 and earlier it is DW_FORM_data8 with 64 bits, in DWARF5
   DW_FORM_data16 with 128 bits.  */
#define DWARF_LARGEST_DATA_FORM_BITS \
  (dwarf_version >= 5 ? 128 : 64)

/* Utility inline function for construction of ops that were GNU extension
   before DWARF 5.  */
static inline enum dwarf_location_atom
dwarf_OP (enum dwarf_location_atom op)
{
  switch (op)
    {
    case DW_OP_implicit_pointer:
      if (dwarf_version < 5)
	return DW_OP_GNU_implicit_pointer;
      break;

    case DW_OP_entry_value:
      if (dwarf_version < 5)
	return DW_OP_GNU_entry_value;
      break;

    case DW_OP_const_type:
      if (dwarf_version < 5)
	return DW_OP_GNU_const_type;
      break;

    case DW_OP_regval_type:
      if (dwarf_version < 5)
	return DW_OP_GNU_regval_type;
      break;

    case DW_OP_deref_type:
      if (dwarf_version < 5)
	return DW_OP_GNU_deref_type;
      break;

    case DW_OP_convert:
      if (dwarf_version < 5)
	return DW_OP_GNU_convert;
      break;

    case DW_OP_reinterpret:
      if (dwarf_version < 5)
	return DW_OP_GNU_reinterpret;
      break;

    case DW_OP_addrx:
      if (dwarf_version < 5)
	return DW_OP_GNU_addr_index;
      break;

    case DW_OP_constx:
      if (dwarf_version < 5)
	return DW_OP_GNU_const_index;
      break;

    default:
      break;
    }
  return op;
}

/* Similarly for attributes.  */
static inline enum dwarf_attribute
dwarf_AT (enum dwarf_attribute at)
{
  switch (at)
    {
    case DW_AT_call_return_pc:
      if (dwarf_version < 5)
	return DW_AT_low_pc;
      break;

    case DW_AT_call_tail_call:
      if (dwarf_version < 5)
	return DW_AT_GNU_tail_call;
      break;

    case DW_AT_call_origin:
      if (dwarf_version < 5)
	return DW_AT_abstract_origin;
      break;

    case DW_AT_call_target:
      if (dwarf_version < 5)
	return DW_AT_GNU_call_site_target;
      break;

    case DW_AT_call_target_clobbered:
      if (dwarf_version < 5)
	return DW_AT_GNU_call_site_target_clobbered;
      break;

    case DW_AT_call_parameter:
      if (dwarf_version < 5)
	return DW_AT_abstract_origin;
      break;

    case DW_AT_call_value:
      if (dwarf_version < 5)
	return DW_AT_GNU_call_site_value;
      break;

    case DW_AT_call_data_value:
      if (dwarf_version < 5)
	return DW_AT_GNU_call_site_data_value;
      break;

    case DW_AT_call_all_calls:
      if (dwarf_version < 5)
	return DW_AT_GNU_all_call_sites;
      break;

    case DW_AT_call_all_tail_calls:
      if (dwarf_version < 5)
	return DW_AT_GNU_all_tail_call_sites;
      break;

    case DW_AT_dwo_name:
      if (dwarf_version < 5)
	return DW_AT_GNU_dwo_name;
      break;

    case DW_AT_addr_base:
      if (dwarf_version < 5)
	return DW_AT_GNU_addr_base;
      break;

    default:
      break;
    }
  return at;
}

/* And similarly for tags.  */
static inline enum dwarf_tag
dwarf_TAG (enum dwarf_tag tag)
{
  switch (tag)
    {
    case DW_TAG_call_site:
      if (dwarf_version < 5)
	return DW_TAG_GNU_call_site;
      break;

    case DW_TAG_call_site_parameter:
      if (dwarf_version < 5)
	return DW_TAG_GNU_call_site_parameter;
      break;

    default:
      break;
    }
  return tag;
}

/* And similarly for forms.  */
static inline enum dwarf_form
dwarf_FORM (enum dwarf_form form)
{
  switch (form)
    {
    case DW_FORM_addrx:
      if (dwarf_version < 5)
	return DW_FORM_GNU_addr_index;
      break;

    case DW_FORM_strx:
      if (dwarf_version < 5)
	return DW_FORM_GNU_str_index;
      break;

    default:
      break;
    }
  return form;
}

static unsigned long int get_base_type_offset (dw_die_ref);

/* Return the size of a location descriptor.  */

static unsigned long
size_of_loc_descr (dw_loc_descr_ref loc)
{
  unsigned long size = 1;

  switch (loc->dw_loc_opc)
    {
    case DW_OP_addr:
      size += DWARF2_ADDR_SIZE;
      break;
    case DW_OP_GNU_addr_index:
    case DW_OP_addrx:
    case DW_OP_GNU_const_index:
    case DW_OP_constx:
      gcc_assert (loc->dw_loc_oprnd1.val_entry->index != NO_INDEX_ASSIGNED);
      size += size_of_uleb128 (loc->dw_loc_oprnd1.val_entry->index);
      break;
    case DW_OP_const1u:
    case DW_OP_const1s:
      size += 1;
      break;
    case DW_OP_const2u:
    case DW_OP_const2s:
      size += 2;
      break;
    case DW_OP_const4u:
    case DW_OP_const4s:
      size += 4;
      break;
    case DW_OP_const8u:
    case DW_OP_const8s:
      size += 8;
      break;
    case DW_OP_constu:
      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
      break;
    case DW_OP_consts:
      size += size_of_sleb128 (loc->dw_loc_oprnd1.v.val_int);
      break;
    case DW_OP_pick:
      size += 1;
      break;
    case DW_OP_plus_uconst:
      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
      break;
    case DW_OP_skip:
    case DW_OP_bra:
      size += 2;
      break;
    case DW_OP_breg0:
    case DW_OP_breg1:
    case DW_OP_breg2:
    case DW_OP_breg3:
    case DW_OP_breg4:
    case DW_OP_breg5:
    case DW_OP_breg6:
    case DW_OP_breg7:
    case DW_OP_breg8:
    case DW_OP_breg9:
    case DW_OP_breg10:
    case DW_OP_breg11:
    case DW_OP_breg12:
    case DW_OP_breg13:
    case DW_OP_breg14:
    case DW_OP_breg15:
    case DW_OP_breg16:
    case DW_OP_breg17:
    case DW_OP_breg18:
    case DW_OP_breg19:
    case DW_OP_breg20:
    case DW_OP_breg21:
    case DW_OP_breg22:
    case DW_OP_breg23:
    case DW_OP_breg24:
    case DW_OP_breg25:
    case DW_OP_breg26:
    case DW_OP_breg27:
    case DW_OP_breg28:
    case DW_OP_breg29:
    case DW_OP_breg30:
    case DW_OP_breg31:
      size += size_of_sleb128 (loc->dw_loc_oprnd1.v.val_int);
      break;
    case DW_OP_regx:
      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
      break;
    case DW_OP_fbreg:
      size += size_of_sleb128 (loc->dw_loc_oprnd1.v.val_int);
      break;
    case DW_OP_bregx:
      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
      size += size_of_sleb128 (loc->dw_loc_oprnd2.v.val_int);
      break;
    case DW_OP_piece:
      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
      break;
    case DW_OP_bit_piece:
      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
      size += size_of_uleb128 (loc->dw_loc_oprnd2.v.val_unsigned);
      break;
    case DW_OP_deref_size:
    case DW_OP_xderef_size:
      size += 1;
      break;
    case DW_OP_call2:
      size += 2;
      break;
    case DW_OP_call4:
      size += 4;
      break;
    case DW_OP_call_ref:
    case DW_OP_GNU_variable_value:
      size += DWARF_REF_SIZE;
      break;
    case DW_OP_implicit_value:
      size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned)
	      + loc->dw_loc_oprnd1.v.val_unsigned;
      break;
    case DW_OP_implicit_pointer:
    case DW_OP_GNU_implicit_pointer:
      size += DWARF_REF_SIZE + size_of_sleb128 (loc->dw_loc_oprnd2.v.val_int);
      break;
    case DW_OP_entry_value:
    case DW_OP_GNU_entry_value:
      {
	unsigned long op_size = size_of_locs (loc->dw_loc_oprnd1.v.val_loc);
	size += size_of_uleb128 (op_size) + op_size;
	break;
      }
    case DW_OP_const_type:
    case DW_OP_GNU_const_type:
      {
	unsigned long o
	  = get_base_type_offset (loc->dw_loc_oprnd1.v.val_die_ref.die);
	size += size_of_uleb128 (o) + 1;
	switch (loc->dw_loc_oprnd2.val_class)
	  {
	  case dw_val_class_vec:
	    size += loc->dw_loc_oprnd2.v.val_vec.length
		    * loc->dw_loc_oprnd2.v.val_vec.elt_size;
	    break;
	  case dw_val_class_const:
	    size += HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT;
	    break;
	  case dw_val_class_const_double:
	    size += HOST_BITS_PER_DOUBLE_INT / BITS_PER_UNIT;
	    break;
	  case dw_val_class_wide_int:
	    size += (get_full_len (*loc->dw_loc_oprnd2.v.val_wide)
		     * HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT);
	    break;
	  default:
	    gcc_unreachable ();
	  }
	break;
      }
    case DW_OP_regval_type:
    case DW_OP_GNU_regval_type:
      {
	unsigned long o
	  = get_base_type_offset (loc->dw_loc_oprnd2.v.val_die_ref.die);
	size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned)
		+ size_of_uleb128 (o);
      }
      break;
    case DW_OP_deref_type:
    case DW_OP_GNU_deref_type:
      {
	unsigned long o
	  = get_base_type_offset (loc->dw_loc_oprnd2.v.val_die_ref.die);
	size += 1 + size_of_uleb128 (o);
      }
      break;
    case DW_OP_convert:
    case DW_OP_reinterpret:
    case DW_OP_GNU_convert:
    case DW_OP_GNU_reinterpret:
      if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const)
	size += size_of_uleb128 (loc->dw_loc_oprnd1.v.val_unsigned);
      else
	{
	  unsigned long o
	    = get_base_type_offset (loc->dw_loc_oprnd1.v.val_die_ref.die);
	  size += size_of_uleb128 (o);
	}
      break;
    case DW_OP_GNU_parameter_ref:
      size += 4;
      break;
    default:
      break;
    }

  return size;
}

/* Return the size of a series of location descriptors.  */

unsigned long
size_of_locs (dw_loc_descr_ref loc)
{
  dw_loc_descr_ref l;
  unsigned long size;

  /* If there are no skip or bra opcodes, don't fill in the dw_loc_addr
     field, to avoid writing to a PCH file.  */
  for (size = 0, l = loc; l != NULL; l = l->dw_loc_next)
    {
      if (l->dw_loc_opc == DW_OP_skip || l->dw_loc_opc == DW_OP_bra)
	break;
      size += size_of_loc_descr (l);
    }
  if (! l)
    return size;

  for (size = 0, l = loc; l != NULL; l = l->dw_loc_next)
    {
      l->dw_loc_addr = size;
      size += size_of_loc_descr (l);
    }

  return size;
}

/* Return the size of the value in a DW_AT_discr_value attribute.  */

static int
size_of_discr_value (dw_discr_value *discr_value)
{
  if (discr_value->pos)
    return size_of_uleb128 (discr_value->v.uval);
  else
    return size_of_sleb128 (discr_value->v.sval);
}

/* Return the size of the value in a DW_AT_discr_list attribute.  */

static int
size_of_discr_list (dw_discr_list_ref discr_list)
{
  int size = 0;

  for (dw_discr_list_ref list = discr_list;
       list != NULL;
       list = list->dw_discr_next)
    {
      /* One byte for the discriminant value descriptor, and then one or two
	 LEB128 numbers, depending on whether it's a single case label or a
	 range label.  */
      size += 1;
      size += size_of_discr_value (&list->dw_discr_lower_bound);
      if (list->dw_discr_range != 0)
	size += size_of_discr_value (&list->dw_discr_upper_bound);
    }
  return size;
}

static HOST_WIDE_INT extract_int (const unsigned char *, unsigned);
static void get_ref_die_offset_label (char *, dw_die_ref);
static unsigned long int get_ref_die_offset (dw_die_ref);

/* Output location description stack opcode's operands (if any).
   The for_eh_or_skip parameter controls whether register numbers are
   converted using DWARF2_FRAME_REG_OUT, which is needed in the case that
   hard reg numbers have been processed via DWARF_FRAME_REGNUM (i.e. for unwind
   info).  This should be suppressed for the cases that have not been converted
   (i.e. symbolic debug info), by setting the parameter < 0.  See PR47324.  */

static void
output_loc_operands (dw_loc_descr_ref loc, int for_eh_or_skip)
{
  dw_val_ref val1 = &loc->dw_loc_oprnd1;
  dw_val_ref val2 = &loc->dw_loc_oprnd2;

  switch (loc->dw_loc_opc)
    {
#ifdef DWARF2_DEBUGGING_INFO
    case DW_OP_const2u:
    case DW_OP_const2s:
      dw2_asm_output_data (2, val1->v.val_int, NULL);
      break;
    case DW_OP_const4u:
      if (loc->dtprel)
	{
	  gcc_assert (targetm.asm_out.output_dwarf_dtprel);
	  targetm.asm_out.output_dwarf_dtprel (asm_out_file, 4,
					       val1->v.val_addr);
	  fputc ('\n', asm_out_file);
	  break;
	}
      /* FALLTHRU */
    case DW_OP_const4s:
      dw2_asm_output_data (4, val1->v.val_int, NULL);
      break;
    case DW_OP_const8u:
      if (loc->dtprel)
	{
	  gcc_assert (targetm.asm_out.output_dwarf_dtprel);
	  targetm.asm_out.output_dwarf_dtprel (asm_out_file, 8,
					       val1->v.val_addr);
	  fputc ('\n', asm_out_file);
	  break;
	}
      /* FALLTHRU */
    case DW_OP_const8s:
      gcc_assert (HOST_BITS_PER_WIDE_INT >= 64);
      dw2_asm_output_data (8, val1->v.val_int, NULL);
      break;
    case DW_OP_skip:
    case DW_OP_bra:
      {
	int offset;

	gcc_assert (val1->val_class == dw_val_class_loc);
	offset = val1->v.val_loc->dw_loc_addr - (loc->dw_loc_addr + 3);

	dw2_asm_output_data (2, offset, NULL);
      }
      break;
    case DW_OP_implicit_value:
      dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
      switch (val2->val_class)
	{
	case dw_val_class_const:
	  dw2_asm_output_data (val1->v.val_unsigned, val2->v.val_int, NULL);
	  break;
	case dw_val_class_vec:
	  {
	    unsigned int elt_size = val2->v.val_vec.elt_size;
	    unsigned int len = val2->v.val_vec.length;
	    unsigned int i;
	    unsigned char *p;

	    if (elt_size > sizeof (HOST_WIDE_INT))
	      {
		elt_size /= 2;
		len *= 2;
	      }
	    for (i = 0, p = (unsigned char *) val2->v.val_vec.array;
		 i < len;
		 i++, p += elt_size)
	      dw2_asm_output_data (elt_size, extract_int (p, elt_size),
				   "fp or vector constant word %u", i);
	  }
	  break;
	case dw_val_class_const_double:
	  {
	    unsigned HOST_WIDE_INT first, second;

	    if (WORDS_BIG_ENDIAN)
	      {
		first = val2->v.val_double.high;
		second = val2->v.val_double.low;
	      }
	    else
	      {
		first = val2->v.val_double.low;
		second = val2->v.val_double.high;
	      }
	    dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
				 first, NULL);
	    dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
				 second, NULL);
	  }
	  break;
	case dw_val_class_wide_int:
	  {
	    int i;
	    int len = get_full_len (*val2->v.val_wide);
	    if (WORDS_BIG_ENDIAN)
	      for (i = len - 1; i >= 0; --i)
		dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
				     val2->v.val_wide->elt (i), NULL);
	    else
	      for (i = 0; i < len; ++i)
		dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
				     val2->v.val_wide->elt (i), NULL);
	  }
	  break;
	case dw_val_class_addr:
	  gcc_assert (val1->v.val_unsigned == DWARF2_ADDR_SIZE);
	  dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, val2->v.val_addr, NULL);
	  break;
	default:
	  gcc_unreachable ();
	}
      break;
#else
    case DW_OP_const2u:
    case DW_OP_const2s:
    case DW_OP_const4u:
    case DW_OP_const4s:
    case DW_OP_const8u:
    case DW_OP_const8s:
    case DW_OP_skip:
    case DW_OP_bra:
    case DW_OP_implicit_value:
      /* We currently don't make any attempt to make sure these are
	 aligned properly like we do for the main unwind info, so
	 don't support emitting things larger than a byte if we're
	 only doing unwinding.  */
      gcc_unreachable ();
#endif
    case DW_OP_const1u:
    case DW_OP_const1s:
      dw2_asm_output_data (1, val1->v.val_int, NULL);
      break;
    case DW_OP_constu:
      dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
      break;
    case DW_OP_consts:
      dw2_asm_output_data_sleb128 (val1->v.val_int, NULL);
      break;
    case DW_OP_pick:
      dw2_asm_output_data (1, val1->v.val_int, NULL);
      break;
    case DW_OP_plus_uconst:
      dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
      break;
    case DW_OP_breg0:
    case DW_OP_breg1:
    case DW_OP_breg2:
    case DW_OP_breg3:
    case DW_OP_breg4:
    case DW_OP_breg5:
    case DW_OP_breg6:
    case DW_OP_breg7:
    case DW_OP_breg8:
    case DW_OP_breg9:
    case DW_OP_breg10:
    case DW_OP_breg11:
    case DW_OP_breg12:
    case DW_OP_breg13:
    case DW_OP_breg14:
    case DW_OP_breg15:
    case DW_OP_breg16:
    case DW_OP_breg17:
    case DW_OP_breg18:
    case DW_OP_breg19:
    case DW_OP_breg20:
    case DW_OP_breg21:
    case DW_OP_breg22:
    case DW_OP_breg23:
    case DW_OP_breg24:
    case DW_OP_breg25:
    case DW_OP_breg26:
    case DW_OP_breg27:
    case DW_OP_breg28:
    case DW_OP_breg29:
    case DW_OP_breg30:
    case DW_OP_breg31:
      dw2_asm_output_data_sleb128 (val1->v.val_int, NULL);
      break;
    case DW_OP_regx:
      {
	unsigned r = val1->v.val_unsigned;
	if (for_eh_or_skip >= 0)
	  r = DWARF2_FRAME_REG_OUT (r, for_eh_or_skip);
	gcc_assert (size_of_uleb128 (r) 
		    == size_of_uleb128 (val1->v.val_unsigned));
	dw2_asm_output_data_uleb128 (r, NULL);	
      }
      break;
    case DW_OP_fbreg:
      dw2_asm_output_data_sleb128 (val1->v.val_int, NULL);
      break;
    case DW_OP_bregx:
      {
	unsigned r = val1->v.val_unsigned;
	if (for_eh_or_skip >= 0)
	  r = DWARF2_FRAME_REG_OUT (r, for_eh_or_skip);
	gcc_assert (size_of_uleb128 (r) 
		    == size_of_uleb128 (val1->v.val_unsigned));
	dw2_asm_output_data_uleb128 (r, NULL);	
	dw2_asm_output_data_sleb128 (val2->v.val_int, NULL);
      }
      break;
    case DW_OP_piece:
      dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
      break;
    case DW_OP_bit_piece:
      dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
      dw2_asm_output_data_uleb128 (val2->v.val_unsigned, NULL);
      break;
    case DW_OP_deref_size:
    case DW_OP_xderef_size:
      dw2_asm_output_data (1, val1->v.val_int, NULL);
      break;

    case DW_OP_addr:
      if (loc->dtprel)
	{
	  if (targetm.asm_out.output_dwarf_dtprel)
	    {
	      targetm.asm_out.output_dwarf_dtprel (asm_out_file,
						   DWARF2_ADDR_SIZE,
						   val1->v.val_addr);
	      fputc ('\n', asm_out_file);
	    }
	  else
	    gcc_unreachable ();
	}
      else
	{
#ifdef DWARF2_DEBUGGING_INFO
	  dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, val1->v.val_addr, NULL);
#else
	  gcc_unreachable ();
#endif
	}
      break;

    case DW_OP_GNU_addr_index:
    case DW_OP_addrx:
    case DW_OP_GNU_const_index:
    case DW_OP_constx:
      gcc_assert (loc->dw_loc_oprnd1.val_entry->index != NO_INDEX_ASSIGNED);
      dw2_asm_output_data_uleb128 (loc->dw_loc_oprnd1.val_entry->index,
                                   "(index into .debug_addr)");
      break;

    case DW_OP_call2:
    case DW_OP_call4:
      {
	unsigned long die_offset
	  = get_ref_die_offset (val1->v.val_die_ref.die);
	/* Make sure the offset has been computed and that we can encode it as
	   an operand.  */
	gcc_assert (die_offset > 0
		    && die_offset <= (loc->dw_loc_opc == DW_OP_call2
				     ? 0xffff
				     : 0xffffffff));
	dw2_asm_output_data ((loc->dw_loc_opc == DW_OP_call2) ? 2 : 4,
			     die_offset, NULL);
      }
      break;

    case DW_OP_call_ref:
    case DW_OP_GNU_variable_value:
      {
	char label[MAX_ARTIFICIAL_LABEL_BYTES
		   + HOST_BITS_PER_WIDE_INT / 2 + 2];
	gcc_assert (val1->val_class == dw_val_class_die_ref);
	get_ref_die_offset_label (label, val1->v.val_die_ref.die);
	dw2_asm_output_offset (DWARF_REF_SIZE, label, debug_info_section, NULL);
      }
      break;

    case DW_OP_implicit_pointer:
    case DW_OP_GNU_implicit_pointer:
      {
	char label[MAX_ARTIFICIAL_LABEL_BYTES
		   + HOST_BITS_PER_WIDE_INT / 2 + 2];
	gcc_assert (val1->val_class == dw_val_class_die_ref);
	get_ref_die_offset_label (label, val1->v.val_die_ref.die);
	dw2_asm_output_offset (DWARF_REF_SIZE, label, debug_info_section, NULL);
	dw2_asm_output_data_sleb128 (val2->v.val_int, NULL);
      }
      break;

    case DW_OP_entry_value:
    case DW_OP_GNU_entry_value:
      dw2_asm_output_data_uleb128 (size_of_locs (val1->v.val_loc), NULL);
      output_loc_sequence (val1->v.val_loc, for_eh_or_skip);
      break;

    case DW_OP_const_type:
    case DW_OP_GNU_const_type:
      {
	unsigned long o = get_base_type_offset (val1->v.val_die_ref.die), l;
	gcc_assert (o);
	dw2_asm_output_data_uleb128 (o, NULL);
	switch (val2->val_class)
	  {
	  case dw_val_class_const:
	    l = HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
	    dw2_asm_output_data (1, l, NULL);
	    dw2_asm_output_data (l, val2->v.val_int, NULL);
	    break;
	  case dw_val_class_vec:
	    {
	      unsigned int elt_size = val2->v.val_vec.elt_size;
	      unsigned int len = val2->v.val_vec.length;
	      unsigned int i;
	      unsigned char *p;

	      l = len * elt_size;
	      dw2_asm_output_data (1, l, NULL);
	      if (elt_size > sizeof (HOST_WIDE_INT))
		{
		  elt_size /= 2;
		  len *= 2;
		}
	      for (i = 0, p = (unsigned char *) val2->v.val_vec.array;
		   i < len;
		   i++, p += elt_size)
		dw2_asm_output_data (elt_size, extract_int (p, elt_size),
				     "fp or vector constant word %u", i);
	    }
	    break;
	  case dw_val_class_const_double:
	    {
	      unsigned HOST_WIDE_INT first, second;
	      l = HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;

	      dw2_asm_output_data (1, 2 * l, NULL);
	      if (WORDS_BIG_ENDIAN)
		{
		  first = val2->v.val_double.high;
		  second = val2->v.val_double.low;
		}
	      else
		{
		  first = val2->v.val_double.low;
		  second = val2->v.val_double.high;
		}
	      dw2_asm_output_data (l, first, NULL);
	      dw2_asm_output_data (l, second, NULL);
	    }
	    break;
	  case dw_val_class_wide_int:
	    {
	      int i;
	      int len = get_full_len (*val2->v.val_wide);
	      l = HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;

	      dw2_asm_output_data (1, len * l, NULL);
	      if (WORDS_BIG_ENDIAN)
		for (i = len - 1; i >= 0; --i)
		  dw2_asm_output_data (l, val2->v.val_wide->elt (i), NULL);
	      else
		for (i = 0; i < len; ++i)
		  dw2_asm_output_data (l, val2->v.val_wide->elt (i), NULL);
	    }
	    break;
	  default:
	    gcc_unreachable ();
	  }
      }
      break;
    case DW_OP_regval_type:
    case DW_OP_GNU_regval_type:
      {
	unsigned r = val1->v.val_unsigned;
	unsigned long o = get_base_type_offset (val2->v.val_die_ref.die);
	gcc_assert (o);
	if (for_eh_or_skip >= 0)
	  {
	    r = DWARF2_FRAME_REG_OUT (r, for_eh_or_skip);
	    gcc_assert (size_of_uleb128 (r)
			== size_of_uleb128 (val1->v.val_unsigned));
	  }
	dw2_asm_output_data_uleb128 (r, NULL);
	dw2_asm_output_data_uleb128 (o, NULL);
      }
      break;
    case DW_OP_deref_type:
    case DW_OP_GNU_deref_type:
      {
	unsigned long o = get_base_type_offset (val2->v.val_die_ref.die);
	gcc_assert (o);
	dw2_asm_output_data (1, val1->v.val_int, NULL);
	dw2_asm_output_data_uleb128 (o, NULL);
      }
      break;
    case DW_OP_convert:
    case DW_OP_reinterpret:
    case DW_OP_GNU_convert:
    case DW_OP_GNU_reinterpret:
      if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const)
	dw2_asm_output_data_uleb128 (val1->v.val_unsigned, NULL);
      else
	{
	  unsigned long o = get_base_type_offset (val1->v.val_die_ref.die);
	  gcc_assert (o);
	  dw2_asm_output_data_uleb128 (o, NULL);
	}
      break;

    case DW_OP_GNU_parameter_ref:
      {
	unsigned long o;
	gcc_assert (val1->val_class == dw_val_class_die_ref);
	o = get_ref_die_offset (val1->v.val_die_ref.die);
	dw2_asm_output_data (4, o, NULL);
      }
      break;

    default:
      /* Other codes have no operands.  */
      break;
    }
}

/* Output a sequence of location operations.  
   The for_eh_or_skip parameter controls whether register numbers are
   converted using DWARF2_FRAME_REG_OUT, which is needed in the case that
   hard reg numbers have been processed via DWARF_FRAME_REGNUM (i.e. for unwind
   info).  This should be suppressed for the cases that have not been converted
   (i.e. symbolic debug info), by setting the parameter < 0.  See PR47324.  */

void
output_loc_sequence (dw_loc_descr_ref loc, int for_eh_or_skip)
{
  for (; loc != NULL; loc = loc->dw_loc_next)
    {
      enum dwarf_location_atom opc = loc->dw_loc_opc;
      /* Output the opcode.  */
      if (for_eh_or_skip >= 0 
          && opc >= DW_OP_breg0 && opc <= DW_OP_breg31)
	{
	  unsigned r = (opc - DW_OP_breg0);
	  r = DWARF2_FRAME_REG_OUT (r, for_eh_or_skip);
	  gcc_assert (r <= 31);
	  opc = (enum dwarf_location_atom) (DW_OP_breg0 + r);
	}
      else if (for_eh_or_skip >= 0 
	       && opc >= DW_OP_reg0 && opc <= DW_OP_reg31)
	{
	  unsigned r = (opc - DW_OP_reg0);
	  r = DWARF2_FRAME_REG_OUT (r, for_eh_or_skip);
	  gcc_assert (r <= 31);
	  opc = (enum dwarf_location_atom) (DW_OP_reg0 + r);
	}

      dw2_asm_output_data (1, opc,
			     "%s", dwarf_stack_op_name (opc));

      /* Output the operand(s) (if any).  */
      output_loc_operands (loc, for_eh_or_skip);
    }
}

/* Output location description stack opcode's operands (if any).
   The output is single bytes on a line, suitable for .cfi_escape.  */

static void
output_loc_operands_raw (dw_loc_descr_ref loc)
{
  dw_val_ref val1 = &loc->dw_loc_oprnd1;
  dw_val_ref val2 = &loc->dw_loc_oprnd2;

  switch (loc->dw_loc_opc)
    {
    case DW_OP_addr:
    case DW_OP_GNU_addr_index:
    case DW_OP_addrx:
    case DW_OP_GNU_const_index:
    case DW_OP_constx:
    case DW_OP_implicit_value:
      /* We cannot output addresses in .cfi_escape, only bytes.  */
      gcc_unreachable ();

    case DW_OP_const1u:
    case DW_OP_const1s:
    case DW_OP_pick:
    case DW_OP_deref_size:
    case DW_OP_xderef_size:
      fputc (',', asm_out_file);
      dw2_asm_output_data_raw (1, val1->v.val_int);
      break;

    case DW_OP_const2u:
    case DW_OP_const2s:
      fputc (',', asm_out_file);
      dw2_asm_output_data_raw (2, val1->v.val_int);
      break;

    case DW_OP_const4u:
    case DW_OP_const4s:
      fputc (',', asm_out_file);
      dw2_asm_output_data_raw (4, val1->v.val_int);
      break;

    case DW_OP_const8u:
    case DW_OP_const8s:
      gcc_assert (HOST_BITS_PER_WIDE_INT >= 64);
      fputc (',', asm_out_file);
      dw2_asm_output_data_raw (8, val1->v.val_int);
      break;

    case DW_OP_skip:
    case DW_OP_bra:
      {
	int offset;

	gcc_assert (val1->val_class == dw_val_class_loc);
	offset = val1->v.val_loc->dw_loc_addr - (loc->dw_loc_addr + 3);

        fputc (',', asm_out_file);
	dw2_asm_output_data_raw (2, offset);
      }
      break;

    case DW_OP_regx:
      {
	unsigned r = DWARF2_FRAME_REG_OUT (val1->v.val_unsigned, 1);
	gcc_assert (size_of_uleb128 (r) 
		    == size_of_uleb128 (val1->v.val_unsigned));
	fputc (',', asm_out_file);
	dw2_asm_output_data_uleb128_raw (r);
      }
      break;
      
    case DW_OP_constu:
    case DW_OP_plus_uconst:
    case DW_OP_piece:
      fputc (',', asm_out_file);
      dw2_asm_output_data_uleb128_raw (val1->v.val_unsigned);
      break;

    case DW_OP_bit_piece:
      fputc (',', asm_out_file);
      dw2_asm_output_data_uleb128_raw (val1->v.val_unsigned);
      dw2_asm_output_data_uleb128_raw (val2->v.val_unsigned);
      break;

    case DW_OP_consts:
    case DW_OP_breg0:
    case DW_OP_breg1:
    case DW_OP_breg2:
    case DW_OP_breg3:
    case DW_OP_breg4:
    case DW_OP_breg5:
    case DW_OP_breg6:
    case DW_OP_breg7:
    case DW_OP_breg8:
    case DW_OP_breg9:
    case DW_OP_breg10:
    case DW_OP_breg11:
    case DW_OP_breg12:
    case DW_OP_breg13:
    case DW_OP_breg14:
    case DW_OP_breg15:
    case DW_OP_breg16:
    case DW_OP_breg17:
    case DW_OP_breg18:
    case DW_OP_breg19:
    case DW_OP_breg20:
    case DW_OP_breg21:
    case DW_OP_breg22:
    case DW_OP_breg23:
    case DW_OP_breg24:
    case DW_OP_breg25:
    case DW_OP_breg26:
    case DW_OP_breg27:
    case DW_OP_breg28:
    case DW_OP_breg29:
    case DW_OP_breg30:
    case DW_OP_breg31:
    case DW_OP_fbreg:
      fputc (',', asm_out_file);
      dw2_asm_output_data_sleb128_raw (val1->v.val_int);
      break;

    case DW_OP_bregx:
      {
	unsigned r = DWARF2_FRAME_REG_OUT (val1->v.val_unsigned, 1);
	gcc_assert (size_of_uleb128 (r) 
		    == size_of_uleb128 (val1->v.val_unsigned));
	fputc (',', asm_out_file);
	dw2_asm_output_data_uleb128_raw (r);
	fputc (',', asm_out_file);
	dw2_asm_output_data_sleb128_raw (val2->v.val_int);
      }
      break;

    case DW_OP_implicit_pointer:
    case DW_OP_entry_value:
    case DW_OP_const_type:
    case DW_OP_regval_type:
    case DW_OP_deref_type:
    case DW_OP_convert:
    case DW_OP_reinterpret:
    case DW_OP_GNU_implicit_pointer:
    case DW_OP_GNU_entry_value:
    case DW_OP_GNU_const_type:
    case DW_OP_GNU_regval_type:
    case DW_OP_GNU_deref_type:
    case DW_OP_GNU_convert:
    case DW_OP_GNU_reinterpret:
    case DW_OP_GNU_parameter_ref:
      gcc_unreachable ();
      break;

    default:
      /* Other codes have no operands.  */
      break;
    }
}

void
output_loc_sequence_raw (dw_loc_descr_ref loc)
{
  while (1)
    {
      enum dwarf_location_atom opc = loc->dw_loc_opc;
      /* Output the opcode.  */
      if (opc >= DW_OP_breg0 && opc <= DW_OP_breg31)
	{
	  unsigned r = (opc - DW_OP_breg0);
	  r = DWARF2_FRAME_REG_OUT (r, 1);
	  gcc_assert (r <= 31);
	  opc = (enum dwarf_location_atom) (DW_OP_breg0 + r);
	}
      else if (opc >= DW_OP_reg0 && opc <= DW_OP_reg31)
	{
	  unsigned r = (opc - DW_OP_reg0);
	  r = DWARF2_FRAME_REG_OUT (r, 1);
	  gcc_assert (r <= 31);
	  opc = (enum dwarf_location_atom) (DW_OP_reg0 + r);
	}
      /* Output the opcode.  */
      fprintf (asm_out_file, "%#x", opc);
      output_loc_operands_raw (loc);

      if (!loc->dw_loc_next)
	break;
      loc = loc->dw_loc_next;

      fputc (',', asm_out_file);
    }
}

/* This function builds a dwarf location descriptor sequence from a
   dw_cfa_location, adding the given OFFSET to the result of the
   expression.  */

struct dw_loc_descr_node *
build_cfa_loc (dw_cfa_location *cfa, poly_int64 offset)
{
  struct dw_loc_descr_node *head, *tmp;

  offset += cfa->offset;

  if (cfa->indirect)
    {
      head = new_reg_loc_descr (cfa->reg, cfa->base_offset);
      head->dw_loc_oprnd1.val_class = dw_val_class_const;
      head->dw_loc_oprnd1.val_entry = NULL;
      tmp = new_loc_descr (DW_OP_deref, 0, 0);
      add_loc_descr (&head, tmp);
      loc_descr_plus_const (&head, offset);
    }
  else
    head = new_reg_loc_descr (cfa->reg, offset);

  return head;
}

/* This function builds a dwarf location descriptor sequence for
   the address at OFFSET from the CFA when stack is aligned to
   ALIGNMENT byte.  */

struct dw_loc_descr_node *
build_cfa_aligned_loc (dw_cfa_location *cfa,
		       poly_int64 offset, HOST_WIDE_INT alignment)
{
  struct dw_loc_descr_node *head;
  unsigned int dwarf_fp
    = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);

  /* When CFA is defined as FP+OFFSET, emulate stack alignment.  */
  if (cfa->reg == HARD_FRAME_POINTER_REGNUM && cfa->indirect == 0)
    {
      head = new_reg_loc_descr (dwarf_fp, 0);
      add_loc_descr (&head, int_loc_descriptor (alignment));
      add_loc_descr (&head, new_loc_descr (DW_OP_and, 0, 0));
      loc_descr_plus_const (&head, offset);
    }
  else
    head = new_reg_loc_descr (dwarf_fp, offset);
  return head;
}

/* And now, the support for symbolic debugging information.  */

/* .debug_str support.  */

static void dwarf2out_init (const char *);
static void dwarf2out_finish (const char *);
static void dwarf2out_early_finish (const char *);
static void dwarf2out_assembly_start (void);
static void dwarf2out_define (unsigned int, const char *);
static void dwarf2out_undef (unsigned int, const char *);
static void dwarf2out_start_source_file (unsigned, const char *);
static void dwarf2out_end_source_file (unsigned);
static void dwarf2out_function_decl (tree);
static void dwarf2out_begin_block (unsigned, unsigned);
static void dwarf2out_end_block (unsigned, unsigned);
static bool dwarf2out_ignore_block (const_tree);
static void dwarf2out_set_ignored_loc (unsigned, unsigned, const char *);
static void dwarf2out_early_global_decl (tree);
static void dwarf2out_late_global_decl (tree);
static void dwarf2out_type_decl (tree, int);
static void dwarf2out_imported_module_or_decl (tree, tree, tree, bool, bool);
static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree,
						 dw_die_ref);
static void dwarf2out_abstract_function (tree);
static void dwarf2out_var_location (rtx_insn *);
static void dwarf2out_inline_entry (tree);
static void dwarf2out_size_function (tree);
static void dwarf2out_begin_function (tree);
static void dwarf2out_end_function (unsigned int);
static void dwarf2out_register_main_translation_unit (tree unit);
static void dwarf2out_set_name (tree, tree);
static void dwarf2out_register_external_die (tree decl, const char *sym,
					     unsigned HOST_WIDE_INT off);
static bool dwarf2out_die_ref_for_decl (tree decl, const char **sym,
					unsigned HOST_WIDE_INT *off);

/* The debug hooks structure.  */

const struct gcc_debug_hooks dwarf2_debug_hooks =
{
  dwarf2out_init,
  dwarf2out_finish,
  dwarf2out_early_finish,
  dwarf2out_assembly_start,
  dwarf2out_define,
  dwarf2out_undef,
  dwarf2out_start_source_file,
  dwarf2out_end_source_file,
  dwarf2out_begin_block,
  dwarf2out_end_block,
  dwarf2out_ignore_block,
  dwarf2out_source_line,
  dwarf2out_set_ignored_loc,
  dwarf2out_begin_prologue,
#if VMS_DEBUGGING_INFO
  dwarf2out_vms_end_prologue,
  dwarf2out_vms_begin_epilogue,
#else
  debug_nothing_int_charstar,
  debug_nothing_int_charstar,
#endif
  dwarf2out_end_epilogue,
  dwarf2out_begin_function,
  dwarf2out_end_function,	/* end_function */
  dwarf2out_register_main_translation_unit,
  dwarf2out_function_decl,	/* function_decl */
  dwarf2out_early_global_decl,
  dwarf2out_late_global_decl,
  dwarf2out_type_decl,		/* type_decl */
  dwarf2out_imported_module_or_decl,
  dwarf2out_die_ref_for_decl,
  dwarf2out_register_external_die,
  debug_nothing_tree,		/* deferred_inline_function */
  /* The DWARF 2 backend tries to reduce debugging bloat by not
     emitting the abstract description of inline functions until
     something tries to reference them.  */
  dwarf2out_abstract_function,	/* outlining_inline_function */
  debug_nothing_rtx_code_label,	/* label */
  debug_nothing_int,		/* handle_pch */
  dwarf2out_var_location,
  dwarf2out_inline_entry,	/* inline_entry */
  dwarf2out_size_function,	/* size_function */
  dwarf2out_switch_text_section,
  dwarf2out_set_name,
  1,                            /* start_end_main_source_file */
  TYPE_SYMTAB_IS_DIE            /* tree_type_symtab_field */
};

const struct gcc_debug_hooks dwarf2_lineno_debug_hooks =
{
  dwarf2out_init,
  debug_nothing_charstar,
  debug_nothing_charstar,
  dwarf2out_assembly_start,
  debug_nothing_int_charstar,
  debug_nothing_int_charstar,
  debug_nothing_int_charstar,
  debug_nothing_int,
  debug_nothing_int_int,	         /* begin_block */
  debug_nothing_int_int,	         /* end_block */
  debug_true_const_tree,	         /* ignore_block */
  dwarf2out_source_line,		 /* source_line */
  debug_nothing_int_int_charstar,	 /* set_ignored_loc */
  debug_nothing_int_int_charstar,	 /* begin_prologue */
  debug_nothing_int_charstar,	         /* end_prologue */
  debug_nothing_int_charstar,	         /* begin_epilogue */
  debug_nothing_int_charstar,	         /* end_epilogue */
  debug_nothing_tree,		         /* begin_function */
  debug_nothing_int,		         /* end_function */
  debug_nothing_tree,			 /* register_main_translation_unit */
  debug_nothing_tree,		         /* function_decl */
  debug_nothing_tree,		         /* early_global_decl */
  debug_nothing_tree,		         /* late_global_decl */
  debug_nothing_tree_int,		 /* type_decl */
  debug_nothing_tree_tree_tree_bool_bool,/* imported_module_or_decl */
  debug_false_tree_charstarstar_uhwistar,/* die_ref_for_decl */
  debug_nothing_tree_charstar_uhwi,      /* register_external_die */
  debug_nothing_tree,		         /* deferred_inline_function */
  debug_nothing_tree,		         /* outlining_inline_function */
  debug_nothing_rtx_code_label,	         /* label */
  debug_nothing_int,		         /* handle_pch */
  debug_nothing_rtx_insn,	         /* var_location */
  debug_nothing_tree,	         	 /* inline_entry */
  debug_nothing_tree,			 /* size_function */
  debug_nothing_void,                    /* switch_text_section */
  debug_nothing_tree_tree,		 /* set_name */
  0,                                     /* start_end_main_source_file */
  TYPE_SYMTAB_IS_ADDRESS                 /* tree_type_symtab_field */
};

/* NOTE: In the comments in this file, many references are made to
   "Debugging Information Entries".  This term is abbreviated as `DIE'
   throughout the remainder of this file.  */

/* An internal representation of the DWARF output is built, and then
   walked to generate the DWARF debugging info.  The walk of the internal
   representation is done after the entire program has been compiled.
   The types below are used to describe the internal representation.  */

/* Whether to put type DIEs into their own section .debug_types instead
   of making them part of the .debug_info section.  Only supported for
   Dwarf V4 or higher and the user didn't disable them through
   -fno-debug-types-section.  It is more efficient to put them in a
   separate comdat sections since the linker will then be able to
   remove duplicates.  But not all tools support .debug_types sections
   yet.  For Dwarf V5 or higher .debug_types doesn't exist any more,
   it is DW_UT_type unit type in .debug_info section.  For late LTO
   debug there should be almost no types emitted so avoid enabling
   -fdebug-types-section there.  */

#define use_debug_types (dwarf_version >= 4 \
			 && flag_debug_types_section \
			 && !in_lto_p)

/* Various DIE's use offsets relative to the beginning of the
   .debug_info section to refer to each other.  */

typedef long int dw_offset;

struct comdat_type_node;

/* The entries in the line_info table more-or-less mirror the opcodes
   that are used in the real dwarf line table.  Arrays of these entries
   are collected per section when DWARF2_ASM_LINE_DEBUG_INFO is not
   supported.  */

enum dw_line_info_opcode {
  /* Emit DW_LNE_set_address; the operand is the label index.  */
  LI_set_address,

  /* Emit a row to the matrix with the given line.  This may be done
     via any combination of DW_LNS_copy, DW_LNS_advance_line, and
     special opcodes.  */
  LI_set_line,

  /* Emit a DW_LNS_set_file.  */
  LI_set_file,

  /* Emit a DW_LNS_set_column.  */
  LI_set_column,

  /* Emit a DW_LNS_negate_stmt; the operand is ignored.  */
  LI_negate_stmt,

  /* Emit a DW_LNS_set_prologue_end/epilogue_begin; the operand is ignored.  */
  LI_set_prologue_end,
  LI_set_epilogue_begin,

  /* Emit a DW_LNE_set_discriminator.  */
  LI_set_discriminator,

  /* Output a Fixed Advance PC; the target PC is the label index; the
     base PC is the previous LI_adv_address or LI_set_address entry.
     We only use this when emitting debug views without assembler
     support, at explicit user request.  Ideally, we should only use
     it when the offset might be zero but we can't tell: it's the only
     way to maybe change the PC without resetting the view number.  */
  LI_adv_address
};

typedef struct GTY(()) dw_line_info_struct {
  enum dw_line_info_opcode opcode;
  unsigned int val;
} dw_line_info_entry;


struct GTY(()) dw_line_info_table {
  /* The label that marks the end of this section.  */
  const char *end_label;

  /* The values for the last row of the matrix, as collected in the table.
     These are used to minimize the changes to the next row.  */
  unsigned int file_num;
  unsigned int line_num;
  unsigned int column_num;
  int discrim_num;
  bool is_stmt;
  bool in_use;

  /* This denotes the NEXT view number.

     If it is 0, it is known that the NEXT view will be the first view
     at the given PC.

     If it is -1, we're forcing the view number to be reset, e.g. at a
     function entry.

     The meaning of other nonzero values depends on whether we're
     computing views internally or leaving it for the assembler to do
     so.  If we're emitting them internally, view denotes the view
     number since the last known advance of PC.  If we're leaving it
     for the assembler, it denotes the LVU label number that we're
     going to ask the assembler to assign.  */
  var_loc_view view;

  /* This counts the number of symbolic views emitted in this table
     since the latest view reset.  Its max value, over all tables,
     sets symview_upper_bound.  */
  var_loc_view symviews_since_reset;

#define FORCE_RESET_NEXT_VIEW(x) ((x) = (var_loc_view)-1)
#define RESET_NEXT_VIEW(x) ((x) = (var_loc_view)0)
#define FORCE_RESETTING_VIEW_P(x) ((x) == (var_loc_view)-1)
#define RESETTING_VIEW_P(x) ((x) == (var_loc_view)0 || FORCE_RESETTING_VIEW_P (x))

  vec<dw_line_info_entry, va_gc> *entries;
};

/* This is an upper bound for view numbers that the assembler may
   assign to symbolic views output in this translation.  It is used to
   decide how big a field to use to represent view numbers in
   symview-classed attributes.  */

static var_loc_view symview_upper_bound;

/* If we're keep track of location views and their reset points, and
   INSN is a reset point (i.e., it necessarily advances the PC), mark
   the next view in TABLE as reset.  */

static void
maybe_reset_location_view (rtx_insn *insn, dw_line_info_table *table)
{
  if (!debug_internal_reset_location_views)
    return;

  /* Maybe turn (part of?) this test into a default target hook.  */
  int reset = 0;

  if (targetm.reset_location_view)
    reset = targetm.reset_location_view (insn);

  if (reset)
    ;
  else if (JUMP_TABLE_DATA_P (insn))
    reset = 1;
  else if (GET_CODE (insn) == USE
	   || GET_CODE (insn) == CLOBBER
	   || GET_CODE (insn) == ASM_INPUT
	   || asm_noperands (insn) >= 0)
    ;
  else if (get_attr_min_length (insn) > 0)
    reset = 1;

  if (reset > 0 && !RESETTING_VIEW_P (table->view))
    RESET_NEXT_VIEW (table->view);
}

/* The Debugging Information Entry (DIE) structure.  DIEs form a tree.
   The children of each node form a circular list linked by
   die_sib.  die_child points to the node *before* the "first" child node.  */

typedef struct GTY((chain_circular ("%h.die_sib"), for_user)) die_struct {
  union die_symbol_or_type_node
    {
      const char * GTY ((tag ("0"))) die_symbol;
      comdat_type_node *GTY ((tag ("1"))) die_type_node;
    }
  GTY ((desc ("%0.comdat_type_p"))) die_id;
  vec<dw_attr_node, va_gc> *die_attr;
  dw_die_ref die_parent;
  dw_die_ref die_child;
  dw_die_ref die_sib;
  dw_die_ref die_definition; /* ref from a specification to its definition */
  dw_offset die_offset;
  unsigned long die_abbrev;
  int die_mark;
  unsigned int decl_id;
  enum dwarf_tag die_tag;
  /* Die is used and must not be pruned as unused.  */
  BOOL_BITFIELD die_perennial_p : 1;
  BOOL_BITFIELD comdat_type_p : 1; /* DIE has a type signature */
  /* For an external ref to die_symbol if die_offset contains an extra
     offset to that symbol.  */
  BOOL_BITFIELD with_offset : 1;
  /* Whether this DIE was removed from the DIE tree, for example via
     prune_unused_types.  We don't consider those present from the
     DIE lookup routines.  */
  BOOL_BITFIELD removed : 1;
  /* Lots of spare bits.  */
}
die_node;

/* Set to TRUE while dwarf2out_early_global_decl is running.  */
static bool early_dwarf;
static bool early_dwarf_finished;
class set_early_dwarf {
public:
  bool saved;
  set_early_dwarf () : saved(early_dwarf)
    {
      gcc_assert (! early_dwarf_finished);
      early_dwarf = true;
    }
  ~set_early_dwarf () { early_dwarf = saved; }
};

/* Evaluate 'expr' while 'c' is set to each child of DIE in order.  */
#define FOR_EACH_CHILD(die, c, expr) do {	\
  c = die->die_child;				\
  if (c) do {					\
    c = c->die_sib;				\
    expr;					\
  } while (c != die->die_child);		\
} while (0)

/* The pubname structure */

typedef struct GTY(()) pubname_struct {
  dw_die_ref die;
  const char *name;
}
pubname_entry;


struct GTY(()) dw_ranges {
  const char *label;
  /* If this is positive, it's a block number, otherwise it's a
     bitwise-negated index into dw_ranges_by_label.  */
  int num;
  /* If idx is equal to DW_RANGES_IDX_SKELETON, it should be emitted
     into .debug_rnglists section rather than .debug_rnglists.dwo
     for -gsplit-dwarf and DWARF >= 5.  */
#define DW_RANGES_IDX_SKELETON ((1U << 31) - 1)
  /* Index for the range list for DW_FORM_rnglistx.  */
  unsigned int idx : 31;
  /* True if this range might be possibly in a different section
     from previous entry.  */
  unsigned int maybe_new_sec : 1;
  addr_table_entry *begin_entry;
  addr_table_entry *end_entry;
};

/* A structure to hold a macinfo entry.  */

typedef struct GTY(()) macinfo_struct {
  unsigned char code;
  unsigned HOST_WIDE_INT lineno;
  const char *info;
}
macinfo_entry;


struct GTY(()) dw_ranges_by_label {
  const char *begin;
  const char *end;
};

/* The comdat type node structure.  */
struct GTY(()) comdat_type_node
{
  dw_die_ref root_die;
  dw_die_ref type_die;
  dw_die_ref skeleton_die;
  char signature[DWARF_TYPE_SIGNATURE_SIZE];
  comdat_type_node *next;
};

/* A list of DIEs for which we can't determine ancestry (parent_die
   field) just yet.  Later in dwarf2out_finish we will fill in the
   missing bits.  */
typedef struct GTY(()) limbo_die_struct {
  dw_die_ref die;
  /* The tree for which this DIE was created.  We use this to
     determine ancestry later.  */
  tree created_for;
  struct limbo_die_struct *next;
}
limbo_die_node;

typedef struct skeleton_chain_struct
{
  dw_die_ref old_die;
  dw_die_ref new_die;
  struct skeleton_chain_struct *parent;
}
skeleton_chain_node;

/* Define a macro which returns nonzero for a TYPE_DECL which was
   implicitly generated for a type.

   Note that, unlike the C front-end (which generates a NULL named
   TYPE_DECL node for each complete tagged type, each array type,
   and each function type node created) the C++ front-end generates
   a _named_ TYPE_DECL node for each tagged type node created.
   These TYPE_DECLs have DECL_ARTIFICIAL set, so we know not to
   generate a DW_TAG_typedef DIE for them.  Likewise with the Ada
   front-end, but for each type, tagged or not.  */

#define TYPE_DECL_IS_STUB(decl)				\
  (DECL_NAME (decl) == NULL_TREE			\
   || (DECL_ARTIFICIAL (decl)				\
       && ((decl == TYPE_STUB_DECL (TREE_TYPE (decl)))	\
	   /* This is necessary for stub decls that	\
	      appear in nested inline functions.  */	\
	   || (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE	\
	       && (decl_ultimate_origin (decl)		\
		   == TYPE_STUB_DECL (TREE_TYPE (decl)))))))

/* Information concerning the compilation unit's programming
   language, and compiler version.  */

/* Fixed size portion of the DWARF compilation unit header.  */
#define DWARF_COMPILE_UNIT_HEADER_SIZE \
  (DWARF_INITIAL_LENGTH_SIZE + dwarf_offset_size			\
   + (dwarf_version >= 5 ? 4 : 3))

/* Fixed size portion of the DWARF comdat type unit header.  */
#define DWARF_COMDAT_TYPE_UNIT_HEADER_SIZE \
  (DWARF_COMPILE_UNIT_HEADER_SIZE					\
   + DWARF_TYPE_SIGNATURE_SIZE + dwarf_offset_size)

/* Fixed size portion of the DWARF skeleton compilation unit header.  */
#define DWARF_COMPILE_UNIT_SKELETON_HEADER_SIZE \
  (DWARF_COMPILE_UNIT_HEADER_SIZE + (dwarf_version >= 5 ? 8 : 0))

/* Fixed size portion of public names info.  */
#define DWARF_PUBNAMES_HEADER_SIZE (2 * dwarf_offset_size + 2)

/* Fixed size portion of the address range info.  */
#define DWARF_ARANGES_HEADER_SIZE					\
  (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + dwarf_offset_size + 4,	\
		DWARF2_ADDR_SIZE * 2)					\
   - DWARF_INITIAL_LENGTH_SIZE)

/* Size of padding portion in the address range info.  It must be
   aligned to twice the pointer size.  */
#define DWARF_ARANGES_PAD_SIZE \
  (DWARF_ROUND (DWARF_INITIAL_LENGTH_SIZE + dwarf_offset_size + 4, \
		DWARF2_ADDR_SIZE * 2)				   \
   - (DWARF_INITIAL_LENGTH_SIZE + dwarf_offset_size + 4))

/* Use assembler line directives if available.  */
#ifndef DWARF2_ASM_LINE_DEBUG_INFO
#ifdef HAVE_AS_DWARF2_DEBUG_LINE
#define DWARF2_ASM_LINE_DEBUG_INFO 1
#else
#define DWARF2_ASM_LINE_DEBUG_INFO 0
#endif
#endif

/* Use assembler views in line directives if available.  */
#ifndef DWARF2_ASM_VIEW_DEBUG_INFO
#ifdef HAVE_AS_DWARF2_DEBUG_VIEW
#define DWARF2_ASM_VIEW_DEBUG_INFO 1
#else
#define DWARF2_ASM_VIEW_DEBUG_INFO 0
#endif
#endif

/* Return true if GCC configure detected assembler support for .loc.  */

bool
dwarf2out_default_as_loc_support (void)
{
  return DWARF2_ASM_LINE_DEBUG_INFO;
#if (GCC_VERSION >= 3000)
# undef DWARF2_ASM_LINE_DEBUG_INFO
# pragma GCC poison DWARF2_ASM_LINE_DEBUG_INFO
#endif
}

/* Return true if GCC configure detected assembler support for views
   in .loc directives.  */

bool
dwarf2out_default_as_locview_support (void)
{
  return DWARF2_ASM_VIEW_DEBUG_INFO;
#if (GCC_VERSION >= 3000)
# undef DWARF2_ASM_VIEW_DEBUG_INFO
# pragma GCC poison DWARF2_ASM_VIEW_DEBUG_INFO
#endif
}

/* A bit is set in ZERO_VIEW_P if we are using the assembler-supported
   view computation, and it refers to a view identifier for which we
   will not emit a label because it is known to map to a view number
   zero.  We won't allocate the bitmap if we're not using assembler
   support for location views, but we have to make the variable
   visible for GGC and for code that will be optimized out for lack of
   support but that's still parsed and compiled.  We could abstract it
   out with macros, but it's not worth it.  */
static GTY(()) bitmap zero_view_p;

/* Evaluate to TRUE iff N is known to identify the first location view
   at its PC.  When not using assembler location view computation,
   that must be view number zero.  Otherwise, ZERO_VIEW_P is allocated
   and views label numbers recorded in it are the ones known to be
   zero.  */
#define ZERO_VIEW_P(N) ((N) == (var_loc_view)0				\
			|| (N) == (var_loc_view)-1			\
			|| (zero_view_p					\
			    && bitmap_bit_p (zero_view_p, (N))))

/* Return true iff we're to emit .loc directives for the assembler to
   generate line number sections.

   When we're not emitting views, all we need from the assembler is
   support for .loc directives.

   If we are emitting views, we can only use the assembler's .loc
   support if it also supports views.

   When the compiler is emitting the line number programs and
   computing view numbers itself, it resets view numbers at known PC
   changes and counts from that, and then it emits view numbers as
   literal constants in locviewlists.  There are cases in which the
   compiler is not sure about PC changes, e.g. when extra alignment is
   requested for a label.  In these cases, the compiler may not reset
   the view counter, and the potential PC advance in the line number
   program will use an opcode that does not reset the view counter
   even if the PC actually changes, so that compiler and debug info
   consumer can keep view numbers in sync.

   When the compiler defers view computation to the assembler, it
   emits symbolic view numbers in locviewlists, with the exception of
   views known to be zero (forced resets, or reset after
   compiler-visible PC changes): instead of emitting symbols for
   these, we emit literal zero and assert the assembler agrees with
   the compiler's assessment.  We could use symbolic views everywhere,
   instead of special-casing zero views, but then we'd be unable to
   optimize out locviewlists that contain only zeros.  */

static bool
output_asm_line_debug_info (void)
{
  return (dwarf2out_as_loc_support
	  && (dwarf2out_as_locview_support
	      || !debug_variable_location_views));
}

static bool asm_outputs_debug_line_str (void);

/* Minimum line offset in a special line info. opcode.
   This value was chosen to give a reasonable range of values.  */
#define DWARF_LINE_BASE  -10

/* First special line opcode - leave room for the standard opcodes.  */
#define DWARF_LINE_OPCODE_BASE  ((int)DW_LNS_set_isa + 1)

/* Range of line offsets in a special line info. opcode.  */
#define DWARF_LINE_RANGE  (254-DWARF_LINE_OPCODE_BASE+1)

/* Flag that indicates the initial value of the is_stmt_start flag.
   In the present implementation, we do not mark any lines as
   the beginning of a source statement, because that information
   is not made available by the GCC front-end.  */
#define	DWARF_LINE_DEFAULT_IS_STMT_START 1

/* Maximum number of operations per instruction bundle.  */
#ifndef DWARF_LINE_DEFAULT_MAX_OPS_PER_INSN
#define DWARF_LINE_DEFAULT_MAX_OPS_PER_INSN 1
#endif

/* This location is used by calc_die_sizes() to keep track
   the offset of each DIE within the .debug_info section.  */
static unsigned long next_die_offset;

/* Record the root of the DIE's built for the current compilation unit.  */
static GTY(()) dw_die_ref single_comp_unit_die;

/* A list of type DIEs that have been separated into comdat sections.  */
static GTY(()) comdat_type_node *comdat_type_list;

/* A list of CU DIEs that have been separated.  */
static GTY(()) limbo_die_node *cu_die_list;

/* A list of DIEs with a NULL parent waiting to be relocated.  */
static GTY(()) limbo_die_node *limbo_die_list;

/* A list of DIEs for which we may have to generate
   DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set.  */
static GTY(()) limbo_die_node *deferred_asm_name;

struct dwarf_file_hasher : ggc_ptr_hash<dwarf_file_data>
{
  typedef const char *compare_type;

  static hashval_t hash (dwarf_file_data *);
  static bool equal (dwarf_file_data *, const char *);
};

/* Filenames referenced by this compilation unit.  */
static GTY(()) hash_table<dwarf_file_hasher> *file_table;

struct decl_die_hasher : ggc_ptr_hash<die_node>
{
  typedef tree compare_type;

  static hashval_t hash (die_node *);
  static bool equal (die_node *, tree);
};
/* A hash table of references to DIE's that describe declarations.
   The key is a DECL_UID() which is a unique number identifying each decl.  */
static GTY (()) hash_table<decl_die_hasher> *decl_die_table;

struct GTY ((for_user)) variable_value_struct {
  unsigned int decl_id;
  vec<dw_die_ref, va_gc> *dies;
};

struct variable_value_hasher : ggc_ptr_hash<variable_value_struct>
{
  typedef tree compare_type;

  static hashval_t hash (variable_value_struct *);
  static bool equal (variable_value_struct *, tree);
};
/* A hash table of DIEs that contain DW_OP_GNU_variable_value with
   dw_val_class_decl_ref class, indexed by FUNCTION_DECLs which is
   DECL_CONTEXT of the referenced VAR_DECLs.  */
static GTY (()) hash_table<variable_value_hasher> *variable_value_hash;

struct block_die_hasher : ggc_ptr_hash<die_struct>
{
  static hashval_t hash (die_struct *);
  static bool equal (die_struct *, die_struct *);
};

/* A hash table of references to DIE's that describe COMMON blocks.
   The key is DECL_UID() ^ die_parent.  */
static GTY (()) hash_table<block_die_hasher> *common_block_die_table;

typedef struct GTY(()) die_arg_entry_struct {
    dw_die_ref die;
    tree arg;
} die_arg_entry;


/* Node of the variable location list.  */
struct GTY ((chain_next ("%h.next"))) var_loc_node {
  /* Either NOTE_INSN_VAR_LOCATION, or, for SRA optimized variables,
     EXPR_LIST chain.  For small bitsizes, bitsize is encoded
     in mode of the EXPR_LIST node and first EXPR_LIST operand
     is either NOTE_INSN_VAR_LOCATION for a piece with a known
     location or NULL for padding.  For larger bitsizes,
     mode is 0 and first operand is a CONCAT with bitsize
     as first CONCAT operand and NOTE_INSN_VAR_LOCATION resp.
     NULL as second operand.  */
  rtx GTY (()) loc;
  const char * GTY (()) label;
  struct var_loc_node * GTY (()) next;
  var_loc_view view;
};

/* Variable location list.  */
struct GTY ((for_user)) var_loc_list_def {
  struct var_loc_node * GTY (()) first;

  /* Pointer to the last but one or last element of the
     chained list.  If the list is empty, both first and
     last are NULL, if the list contains just one node
     or the last node certainly is not redundant, it points
     to the last node, otherwise points to the last but one.
     Do not mark it for GC because it is marked through the chain.  */
  struct var_loc_node * GTY ((skip ("%h"))) last;

  /* Pointer to the last element before section switch,
     if NULL, either sections weren't switched or first
     is after section switch.  */
  struct var_loc_node * GTY ((skip ("%h"))) last_before_switch;

  /* DECL_UID of the variable decl.  */
  unsigned int decl_id;
};
typedef struct var_loc_list_def var_loc_list;

/* Call argument location list.  */
struct GTY ((chain_next ("%h.next"))) call_arg_loc_node {
  rtx GTY (()) call_arg_loc_note;
  const char * GTY (()) label;
  tree GTY (()) block;
  bool tail_call_p;
  rtx GTY (()) symbol_ref;
  struct call_arg_loc_node * GTY (()) next;
};


struct decl_loc_hasher : ggc_ptr_hash<var_loc_list>
{
  typedef const_tree compare_type;

  static hashval_t hash (var_loc_list *);
  static bool equal (var_loc_list *, const_tree);
};

/* Table of decl location linked lists.  */
static GTY (()) hash_table<decl_loc_hasher> *decl_loc_table;

/* Head and tail of call_arg_loc chain.  */
static GTY (()) struct call_arg_loc_node *call_arg_locations;
static struct call_arg_loc_node *call_arg_loc_last;

/* Number of call sites in the current function.  */
static int call_site_count = -1;
/* Number of tail call sites in the current function.  */
static int tail_call_site_count = -1;

/* A cached location list.  */
struct GTY ((for_user)) cached_dw_loc_list_def {
  /* The DECL_UID of the decl that this entry describes.  */
  unsigned int decl_id;

  /* The cached location list.  */
  dw_loc_list_ref loc_list;
};
typedef struct cached_dw_loc_list_def cached_dw_loc_list;

struct dw_loc_list_hasher : ggc_ptr_hash<cached_dw_loc_list>
{

  typedef const_tree compare_type;
  
  static hashval_t hash (cached_dw_loc_list *);
  static bool equal (cached_dw_loc_list *, const_tree);
};

/* Table of cached location lists.  */
static GTY (()) hash_table<dw_loc_list_hasher> *cached_dw_loc_list_table;

/* A vector of references to DIE's that are uniquely identified by their tag,
   presence/absence of children DIE's, and list of attribute/value pairs.  */
static GTY(()) vec<dw_die_ref, va_gc> *abbrev_die_table;

/* A hash map to remember the stack usage for DWARF procedures.  The value
   stored is the stack size difference between before the DWARF procedure
   invokation and after it returned.  In other words, for a DWARF procedure
   that consumes N stack slots and that pushes M ones, this stores M - N.  */
static hash_map<dw_die_ref, int> *dwarf_proc_stack_usage_map;

/* A global counter for generating labels for line number data.  */
static unsigned int line_info_label_num;

/* The current table to which we should emit line number information
   for the current function.  This will be set up at the beginning of
   assembly for the function.  */
static GTY(()) dw_line_info_table *cur_line_info_table;

/* The two default tables of line number info.  */
static GTY(()) dw_line_info_table *text_section_line_info;
static GTY(()) dw_line_info_table *cold_text_section_line_info;

/* The set of all non-default tables of line number info.  */
static GTY(()) vec<dw_line_info_table *, va_gc> *separate_line_info;

/* A flag to tell pubnames/types export if there is an info section to
   refer to.  */
static bool info_section_emitted;

/* A pointer to the base of a table that contains a list of publicly
   accessible names.  */
static GTY (()) vec<pubname_entry, va_gc> *pubname_table;

/* A pointer to the base of a table that contains a list of publicly
   accessible types.  */
static GTY (()) vec<pubname_entry, va_gc> *pubtype_table;

/* A pointer to the base of a table that contains a list of macro
   defines/undefines (and file start/end markers).  */
static GTY (()) vec<macinfo_entry, va_gc> *macinfo_table;

/* True if .debug_macinfo or .debug_macros section is going to be
   emitted.  */
#define have_macinfo \
  ((!XCOFF_DEBUGGING_INFO || HAVE_XCOFF_DWARF_EXTRAS) \
   && debug_info_level >= DINFO_LEVEL_VERBOSE \
   && !macinfo_table->is_empty ())

/* Vector of dies for which we should generate .debug_ranges info.  */
static GTY (()) vec<dw_ranges, va_gc> *ranges_table;

/* Vector of pairs of labels referenced in ranges_table.  */
static GTY (()) vec<dw_ranges_by_label, va_gc> *ranges_by_label;

/* Whether we have location lists that need outputting */
static GTY(()) bool have_location_lists;

/* Unique label counter.  */
static GTY(()) unsigned int loclabel_num;

/* Unique label counter for point-of-call tables.  */
static GTY(()) unsigned int poc_label_num;

/* The last file entry emitted by maybe_emit_file().  */
static GTY(()) struct dwarf_file_data * last_emitted_file;

/* Number of internal labels generated by gen_internal_sym().  */
static GTY(()) int label_num;

static GTY(()) vec<die_arg_entry, va_gc> *tmpl_value_parm_die_table;

/* Instances of generic types for which we need to generate debug
   info that describe their generic parameters and arguments. That
   generation needs to happen once all types are properly laid out so
   we do it at the end of compilation.  */
static GTY(()) vec<tree, va_gc> *generic_type_instances;

/* Offset from the "steady-state frame pointer" to the frame base,
   within the current function.  */
static poly_int64 frame_pointer_fb_offset;
static bool frame_pointer_fb_offset_valid;

static vec<dw_die_ref> base_types;

/* Flags to represent a set of attribute classes for attributes that represent
   a scalar value (bounds, pointers, ...).  */
enum dw_scalar_form
{
  dw_scalar_form_constant = 0x01,
  dw_scalar_form_exprloc = 0x02,
  dw_scalar_form_reference = 0x04
};

/* Forward declarations for functions defined in this file.  */

static int is_pseudo_reg (const_rtx);
static tree type_main_variant (tree);
static int is_tagged_type (const_tree);
static const char *dwarf_tag_name (unsigned);
static const char *dwarf_attr_name (unsigned);
static const char *dwarf_form_name (unsigned);
static tree decl_ultimate_origin (const_tree);
static tree decl_class_context (tree);
static void add_dwarf_attr (dw_die_ref, dw_attr_node *);
static inline unsigned int AT_index (dw_attr_node *);
static void add_AT_flag (dw_die_ref, enum dwarf_attribute, unsigned);
static inline unsigned AT_flag (dw_attr_node *);
static void add_AT_int (dw_die_ref, enum dwarf_attribute, HOST_WIDE_INT);
static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned HOST_WIDE_INT);
static void add_AT_double (dw_die_ref, enum dwarf_attribute,
			   HOST_WIDE_INT, unsigned HOST_WIDE_INT);
static inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int,
			       unsigned int, unsigned char *);
static void add_AT_data8 (dw_die_ref, enum dwarf_attribute, unsigned char *);
static void add_AT_string (dw_die_ref, enum dwarf_attribute, const char *);
static inline const char *AT_string (dw_attr_node *);
static enum dwarf_form AT_string_form (dw_attr_node *);
static void add_AT_die_ref (dw_die_ref, enum dwarf_attribute, dw_die_ref);
static void add_AT_specification (dw_die_ref, dw_die_ref);
static inline dw_die_ref AT_ref (dw_attr_node *);
static inline int AT_ref_external (dw_attr_node *);
static inline void set_AT_ref_external (dw_attr_node *, int);
static void add_AT_loc (dw_die_ref, enum dwarf_attribute, dw_loc_descr_ref);
static void add_AT_loc_list (dw_die_ref, enum dwarf_attribute,
			     dw_loc_list_ref);
static inline dw_loc_list_ref AT_loc_list (dw_attr_node *);
static void add_AT_view_list (dw_die_ref, enum dwarf_attribute);
static inline dw_loc_list_ref AT_loc_list (dw_attr_node *);
static addr_table_entry *add_addr_table_entry (void *, enum ate_kind);
static void remove_addr_table_entry (addr_table_entry *);
static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool);
static inline rtx AT_addr (dw_attr_node *);
static void add_AT_symview (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_lbl_id (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_lineptr (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_macptr (dw_die_ref, enum dwarf_attribute, const char *);
static void add_AT_range_list (dw_die_ref, enum dwarf_attribute,
                               unsigned long, bool);
static inline const char *AT_lbl (dw_attr_node *);
static const char *get_AT_low_pc (dw_die_ref);
static bool is_c (void);
static bool is_cxx (void);
static bool is_cxx (const_tree);
static bool is_fortran (void);
static bool is_ada (void);
static bool remove_AT (dw_die_ref, enum dwarf_attribute);
static void remove_child_TAG (dw_die_ref, enum dwarf_tag);
static void add_child_die (dw_die_ref, dw_die_ref);
static dw_die_ref new_die (enum dwarf_tag, dw_die_ref, tree);
static dw_die_ref strip_naming_typedef (tree, dw_die_ref);
static dw_die_ref lookup_type_die_strip_naming_typedef (tree);
static void equate_type_number_to_die (tree, dw_die_ref);
static var_loc_list *lookup_decl_loc (const_tree);
static void equate_decl_number_to_die (tree, dw_die_ref);
static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *, var_loc_view);
static void print_spaces (FILE *);
static void print_die (dw_die_ref, FILE *);
static void loc_checksum (dw_loc_descr_ref, struct md5_ctx *);
static void attr_checksum (dw_attr_node *, struct md5_ctx *, int *);
static void die_checksum (dw_die_ref, struct md5_ctx *, int *);
static void checksum_sleb128 (HOST_WIDE_INT, struct md5_ctx *);
static void checksum_uleb128 (unsigned HOST_WIDE_INT, struct md5_ctx *);
static void loc_checksum_ordered (dw_loc_descr_ref, struct md5_ctx *);
static void attr_checksum_ordered (enum dwarf_tag, dw_attr_node *,
				   struct md5_ctx *, int *);
struct checksum_attributes;
static void collect_checksum_attributes (struct checksum_attributes *, dw_die_ref);
static void die_checksum_ordered (dw_die_ref, struct md5_ctx *, int *);
static void checksum_die_context (dw_die_ref, struct md5_ctx *);
static void generate_type_signature (dw_die_ref, comdat_type_node *);
static int same_loc_p (dw_loc_descr_ref, dw_loc_descr_ref, int *);
static int same_dw_val_p (const dw_val_node *, const dw_val_node *, int *);
static int same_attr_p (dw_attr_node *, dw_attr_node *, int *);
static int same_die_p (dw_die_ref, dw_die_ref, int *);
static int is_type_die (dw_die_ref);
static inline bool is_template_instantiation (dw_die_ref);
static int is_declaration_die (dw_die_ref);
static int should_move_die_to_comdat (dw_die_ref);
static dw_die_ref clone_as_declaration (dw_die_ref);
static dw_die_ref clone_die (dw_die_ref);
static dw_die_ref clone_tree (dw_die_ref);
static dw_die_ref copy_declaration_context (dw_die_ref, dw_die_ref);
static void generate_skeleton_ancestor_tree (skeleton_chain_node *);
static void generate_skeleton_bottom_up (skeleton_chain_node *);
static dw_die_ref generate_skeleton (dw_die_ref);
static dw_die_ref remove_child_or_replace_with_skeleton (dw_die_ref,
                                                         dw_die_ref,
                                                         dw_die_ref);
static void break_out_comdat_types (dw_die_ref);
static void copy_decls_for_unworthy_types (dw_die_ref);

static void add_sibling_attributes (dw_die_ref);
static void output_location_lists (dw_die_ref);
static int constant_size (unsigned HOST_WIDE_INT);
static unsigned long size_of_die (dw_die_ref);
static void calc_die_sizes (dw_die_ref);
static void calc_base_type_die_sizes (void);
static void mark_dies (dw_die_ref);
static void unmark_dies (dw_die_ref);
static void unmark_all_dies (dw_die_ref);
static unsigned long size_of_pubnames (vec<pubname_entry, va_gc> *);
static unsigned long size_of_aranges (void);
static enum dwarf_form value_format (dw_attr_node *);
static void output_value_format (dw_attr_node *);
static void output_abbrev_section (void);
static void output_die_abbrevs (unsigned long, dw_die_ref);
static void output_die (dw_die_ref);
static void output_compilation_unit_header (enum dwarf_unit_type);
static void output_comp_unit (dw_die_ref, int, const unsigned char *);
static void output_comdat_type_unit (comdat_type_node *, bool);
static const char *dwarf2_name (tree, int);
static void add_pubname (tree, dw_die_ref);
static void add_enumerator_pubname (const char *, dw_die_ref);
static void add_pubname_string (const char *, dw_die_ref);
static void add_pubtype (tree, dw_die_ref);
static void output_pubnames (vec<pubname_entry, va_gc> *);
static void output_aranges (void);
static unsigned int add_ranges (const_tree, bool = false);
static void add_ranges_by_labels (dw_die_ref, const char *, const char *,
                                  bool *, bool);
static void output_ranges (void);
static dw_line_info_table *new_line_info_table (void);
static void output_line_info (bool);
static void output_file_names (void);
static int is_base_type (tree);
static dw_die_ref subrange_type_die (tree, tree, tree, tree, dw_die_ref);
static int decl_quals (const_tree);
static dw_die_ref modified_type_die (tree, int, bool, dw_die_ref);
static dw_die_ref generic_parameter_die (tree, tree, bool, dw_die_ref);
static dw_die_ref template_parameter_pack_die (tree, tree, dw_die_ref);
static unsigned int dbx_reg_number (const_rtx);
static void add_loc_descr_op_piece (dw_loc_descr_ref *, int);
static dw_loc_descr_ref reg_loc_descriptor (rtx, enum var_init_status);
static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int,
						enum var_init_status);
static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx,
						     enum var_init_status);
static dw_loc_descr_ref based_loc_descr (rtx, poly_int64,
					 enum var_init_status);
static int is_based_loc (const_rtx);
static bool resolve_one_addr (rtx *);
static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx,
					       enum var_init_status);
static dw_loc_descr_ref loc_descriptor (rtx, machine_mode mode,
					enum var_init_status);
struct loc_descr_context;
static void add_loc_descr_to_each (dw_loc_list_ref list, dw_loc_descr_ref ref);
static void add_loc_list (dw_loc_list_ref *ret, dw_loc_list_ref list);
static dw_loc_list_ref loc_list_from_tree (tree, int,
					   struct loc_descr_context *);
static dw_loc_descr_ref loc_descriptor_from_tree (tree, int,
						  struct loc_descr_context *);
static tree field_type (const_tree);
static unsigned int simple_type_align_in_bits (const_tree);
static unsigned int simple_decl_align_in_bits (const_tree);
static unsigned HOST_WIDE_INT simple_type_size_in_bits (const_tree);
struct vlr_context;
static dw_loc_descr_ref field_byte_offset (const_tree, struct vlr_context *,
					   HOST_WIDE_INT *);
static void add_AT_location_description	(dw_die_ref, enum dwarf_attribute,
					 dw_loc_list_ref);
static void add_data_member_location_attribute (dw_die_ref, tree,
						struct vlr_context *);
static bool add_const_value_attribute (dw_die_ref, rtx);
static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
static void insert_wide_int (const wide_int &, unsigned char *, int);
static unsigned insert_float (const_rtx, unsigned char *);
static rtx rtl_for_decl_location (tree);
static bool add_location_or_const_value_attribute (dw_die_ref, tree, bool);
static bool tree_add_const_value_attribute (dw_die_ref, tree);
static bool tree_add_const_value_attribute_for_decl (dw_die_ref, tree);
static void add_desc_attribute (dw_die_ref, tree);
static void add_gnat_descriptive_type_attribute (dw_die_ref, tree, dw_die_ref);
static void add_comp_dir_attribute (dw_die_ref);
static void add_scalar_info (dw_die_ref, enum dwarf_attribute, tree, int,
			     struct loc_descr_context *);
static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree,
			    struct loc_descr_context *);
static void add_subscript_info (dw_die_ref, tree, bool);
static void add_byte_size_attribute (dw_die_ref, tree);
static void add_alignment_attribute (dw_die_ref, tree);
static void add_bit_offset_attribute (dw_die_ref, tree);
static void add_bit_size_attribute (dw_die_ref, tree);
static void add_prototyped_attribute (dw_die_ref, tree);
static void add_abstract_origin_attribute (dw_die_ref, tree);
static void add_pure_or_virtual_attribute (dw_die_ref, tree);
static void add_src_coords_attributes (dw_die_ref, tree);
static void add_name_and_src_coords_attributes (dw_die_ref, tree, bool = false);
static void add_discr_value (dw_die_ref, dw_discr_value *);
static void add_discr_list (dw_die_ref, dw_discr_list_ref);
static inline dw_discr_list_ref AT_discr_list (dw_attr_node *);
static dw_die_ref scope_die_for (tree, dw_die_ref);
static inline int local_scope_p (dw_die_ref);
static inline int class_scope_p (dw_die_ref);
static inline int class_or_namespace_scope_p (dw_die_ref);
static void add_type_attribute (dw_die_ref, tree, int, bool, dw_die_ref);
static void add_calling_convention_attribute (dw_die_ref, tree);
static const char *type_tag (const_tree);
static tree member_declared_type (const_tree);
#if 0
static const char *decl_start_label (tree);
#endif
static void gen_array_type_die (tree, dw_die_ref);
static void gen_descr_array_type_die (tree, struct array_descr_info *, dw_die_ref);
#if 0
static void gen_entry_point_die (tree, dw_die_ref);
#endif
static dw_die_ref gen_enumeration_type_die (tree, dw_die_ref);
static dw_die_ref gen_formal_parameter_die (tree, tree, bool, dw_die_ref);
static dw_die_ref gen_formal_parameter_pack_die  (tree, tree, dw_die_ref, tree*);
static void gen_unspecified_parameters_die (tree, dw_die_ref);
static void gen_formal_types_die (tree, dw_die_ref);
static void gen_subprogram_die (tree, dw_die_ref);
static void gen_variable_die (tree, tree, dw_die_ref);
static void gen_const_die (tree, dw_die_ref);
static void gen_label_die (tree, dw_die_ref);
static void gen_lexical_block_die (tree, dw_die_ref);
static void gen_inlined_subroutine_die (tree, dw_die_ref);
static void gen_field_die (tree, struct vlr_context *, dw_die_ref);
static void gen_ptr_to_mbr_type_die (tree, dw_die_ref);
static dw_die_ref gen_compile_unit_die (const char *);
static void gen_inheritance_die (tree, tree, tree, dw_die_ref);
static void gen_member_die (tree, dw_die_ref);
static void gen_struct_or_union_type_die (tree, dw_die_ref,
						enum debug_info_usage);
static void gen_subroutine_type_die (tree, dw_die_ref);
static void gen_typedef_die (tree, dw_die_ref);
static void gen_type_die (tree, dw_die_ref);
static void gen_block_die (tree, dw_die_ref);
static void decls_for_scope (tree, dw_die_ref, bool = true);
static bool is_naming_typedef_decl (const_tree);
static inline dw_die_ref get_context_die (tree);
static void gen_namespace_die (tree, dw_die_ref);
static dw_die_ref gen_namelist_decl (tree, dw_die_ref, tree);
static dw_die_ref gen_decl_die (tree, tree, struct vlr_context *, dw_die_ref);
static dw_die_ref force_decl_die (tree);
static dw_die_ref force_type_die (tree);
static dw_die_ref setup_namespace_context (tree, dw_die_ref);
static dw_die_ref declare_in_namespace (tree, dw_die_ref);
static struct dwarf_file_data * lookup_filename (const char *);
static void retry_incomplete_types (void);
static void gen_type_die_for_member (tree, tree, dw_die_ref);
static void gen_generic_params_dies (tree);
static void gen_tagged_type_die (tree, dw_die_ref, enum debug_info_usage);
static void gen_type_die_with_usage (tree, dw_die_ref, enum debug_info_usage);
static void splice_child_die (dw_die_ref, dw_die_ref);
static int file_info_cmp (const void *, const void *);
static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *, var_loc_view,
				     const char *, var_loc_view, const char *);
static void output_loc_list (dw_loc_list_ref);
static char *gen_internal_sym (const char *);
static bool want_pubnames (void);

static void prune_unmark_dies (dw_die_ref);
static void prune_unused_types_mark_generic_parms_dies (dw_die_ref);
static void prune_unused_types_mark (dw_die_ref, int);
static void prune_unused_types_walk (dw_die_ref);
static void prune_unused_types_walk_attribs (dw_die_ref);
static void prune_unused_types_prune (dw_die_ref);
static void prune_unused_types (void);
static int maybe_emit_file (struct dwarf_file_data *fd);
static inline const char *AT_vms_delta1 (dw_attr_node *);
static inline const char *AT_vms_delta2 (dw_attr_node *);
#if VMS_DEBUGGING_INFO
static inline void add_AT_vms_delta (dw_die_ref, enum dwarf_attribute,
				     const char *, const char *);
#endif
static void append_entry_to_tmpl_value_parm_die_table (dw_die_ref, tree);
static void gen_remaining_tmpl_value_param_die_attribute (void);
static bool generic_type_p (tree);
static void schedule_generic_params_dies_gen (tree t);
static void gen_scheduled_generic_parms_dies (void);
static void resolve_variable_values (void);

static const char *comp_dir_string (void);

static void hash_loc_operands (dw_loc_descr_ref, inchash::hash &);

/* enum for tracking thread-local variables whose address is really an offset
   relative to the TLS pointer, which will need link-time relocation, but will
   not need relocation by the DWARF consumer.  */

enum dtprel_bool
{
  dtprel_false = 0,
  dtprel_true = 1
};

/* Return the operator to use for an address of a variable.  For dtprel_true, we
   use DW_OP_const*.  For regular variables, which need both link-time
   relocation and consumer-level relocation (e.g., to account for shared objects
   loaded at a random address), we use DW_OP_addr*.  */

static inline enum dwarf_location_atom
dw_addr_op (enum dtprel_bool dtprel)
{
  if (dtprel == dtprel_true)
    return (dwarf_split_debug_info ? dwarf_OP (DW_OP_constx)
            : (DWARF2_ADDR_SIZE == 4 ? DW_OP_const4u : DW_OP_const8u));
  else
    return dwarf_split_debug_info ? dwarf_OP (DW_OP_addrx) : DW_OP_addr;
}

/* Return a pointer to a newly allocated address location description.  If
   dwarf_split_debug_info is true, then record the address with the appropriate
   relocation.  */
static inline dw_loc_descr_ref
new_addr_loc_descr (rtx addr, enum dtprel_bool dtprel)
{
  dw_loc_descr_ref ref = new_loc_descr (dw_addr_op (dtprel), 0, 0);

  ref->dw_loc_oprnd1.val_class = dw_val_class_addr;
  ref->dw_loc_oprnd1.v.val_addr = addr;
  ref->dtprel = dtprel;
  if (dwarf_split_debug_info)
    ref->dw_loc_oprnd1.val_entry
      = add_addr_table_entry (addr,
			      dtprel ? ate_kind_rtx_dtprel : ate_kind_rtx);
  else
    ref->dw_loc_oprnd1.val_entry = NULL;

  return ref;
}

/* Section names used to hold DWARF debugging information.  */

#ifndef DEBUG_INFO_SECTION
#define DEBUG_INFO_SECTION	".debug_info"
#endif
#ifndef DEBUG_DWO_INFO_SECTION
#define DEBUG_DWO_INFO_SECTION ".debug_info.dwo"
#endif
#ifndef DEBUG_LTO_INFO_SECTION
#define DEBUG_LTO_INFO_SECTION	".gnu.debuglto_.debug_info"
#endif
#ifndef DEBUG_LTO_DWO_INFO_SECTION
#define DEBUG_LTO_DWO_INFO_SECTION ".gnu.debuglto_.debug_info.dwo"
#endif
#ifndef DEBUG_ABBREV_SECTION
#define DEBUG_ABBREV_SECTION	".debug_abbrev"
#endif
#ifndef DEBUG_LTO_ABBREV_SECTION
#define DEBUG_LTO_ABBREV_SECTION ".gnu.debuglto_.debug_abbrev"
#endif
#ifndef DEBUG_DWO_ABBREV_SECTION
#define DEBUG_DWO_ABBREV_SECTION ".debug_abbrev.dwo"
#endif
#ifndef DEBUG_LTO_DWO_ABBREV_SECTION
#define DEBUG_LTO_DWO_ABBREV_SECTION ".gnu.debuglto_.debug_abbrev.dwo"
#endif
#ifndef DEBUG_ARANGES_SECTION
#define DEBUG_ARANGES_SECTION	".debug_aranges"
#endif
#ifndef DEBUG_ADDR_SECTION
#define DEBUG_ADDR_SECTION     ".debug_addr"
#endif
#ifndef DEBUG_MACINFO_SECTION
#define DEBUG_MACINFO_SECTION     ".debug_macinfo"
#endif
#ifndef DEBUG_LTO_MACINFO_SECTION
#define DEBUG_LTO_MACINFO_SECTION      ".gnu.debuglto_.debug_macinfo"
#endif
#ifndef DEBUG_DWO_MACINFO_SECTION
#define DEBUG_DWO_MACINFO_SECTION      ".debug_macinfo.dwo"
#endif
#ifndef DEBUG_LTO_DWO_MACINFO_SECTION
#define DEBUG_LTO_DWO_MACINFO_SECTION  ".gnu.debuglto_.debug_macinfo.dwo"
#endif
#ifndef DEBUG_MACRO_SECTION
#define DEBUG_MACRO_SECTION	".debug_macro"
#endif
#ifndef DEBUG_LTO_MACRO_SECTION
#define DEBUG_LTO_MACRO_SECTION ".gnu.debuglto_.debug_macro"
#endif
#ifndef DEBUG_DWO_MACRO_SECTION
#define DEBUG_DWO_MACRO_SECTION        ".debug_macro.dwo"
#endif
#ifndef DEBUG_LTO_DWO_MACRO_SECTION
#define DEBUG_LTO_DWO_MACRO_SECTION    ".gnu.debuglto_.debug_macro.dwo"
#endif
#ifndef DEBUG_LINE_SECTION
#define DEBUG_LINE_SECTION	".debug_line"
#endif
#ifndef DEBUG_LTO_LINE_SECTION
#define DEBUG_LTO_LINE_SECTION ".gnu.debuglto_.debug_line"
#endif
#ifndef DEBUG_DWO_LINE_SECTION
#define DEBUG_DWO_LINE_SECTION ".debug_line.dwo"
#endif
#ifndef DEBUG_LTO_DWO_LINE_SECTION
#define DEBUG_LTO_DWO_LINE_SECTION ".gnu.debuglto_.debug_line.dwo"
#endif
#ifndef DEBUG_LOC_SECTION
#define DEBUG_LOC_SECTION	".debug_loc"
#endif
#ifndef DEBUG_DWO_LOC_SECTION
#define DEBUG_DWO_LOC_SECTION  ".debug_loc.dwo"
#endif
#ifndef DEBUG_LOCLISTS_SECTION
#define DEBUG_LOCLISTS_SECTION	".debug_loclists"
#endif
#ifndef DEBUG_DWO_LOCLISTS_SECTION
#define DEBUG_DWO_LOCLISTS_SECTION  ".debug_loclists.dwo"
#endif
#ifndef DEBUG_PUBNAMES_SECTION
#define DEBUG_PUBNAMES_SECTION	\
  ((debug_generate_pub_sections == 2) \
   ? ".debug_gnu_pubnames" : ".debug_pubnames")
#endif
#ifndef DEBUG_PUBTYPES_SECTION
#define DEBUG_PUBTYPES_SECTION	\
  ((debug_generate_pub_sections == 2) \
   ? ".debug_gnu_pubtypes" : ".debug_pubtypes")
#endif
#ifndef DEBUG_STR_OFFSETS_SECTION
#define DEBUG_STR_OFFSETS_SECTION ".debug_str_offsets"
#endif
#ifndef DEBUG_DWO_STR_OFFSETS_SECTION
#define DEBUG_DWO_STR_OFFSETS_SECTION ".debug_str_offsets.dwo"
#endif
#ifndef DEBUG_LTO_DWO_STR_OFFSETS_SECTION
#define DEBUG_LTO_DWO_STR_OFFSETS_SECTION ".gnu.debuglto_.debug_str_offsets.dwo"
#endif
#ifndef DEBUG_STR_SECTION
#define DEBUG_STR_SECTION  ".debug_str"
#endif
#ifndef DEBUG_LTO_STR_SECTION
#define DEBUG_LTO_STR_SECTION ".gnu.debuglto_.debug_str"
#endif
#ifndef DEBUG_STR_DWO_SECTION
#define DEBUG_STR_DWO_SECTION   ".debug_str.dwo"
#endif
#ifndef DEBUG_LTO_STR_DWO_SECTION
#define DEBUG_LTO_STR_DWO_SECTION ".gnu.debuglto_.debug_str.dwo"
#endif
#ifndef DEBUG_RANGES_SECTION
#define DEBUG_RANGES_SECTION	".debug_ranges"
#endif
#ifndef DEBUG_RNGLISTS_SECTION
#define DEBUG_RNGLISTS_SECTION	".debug_rnglists"
#endif
#ifndef DEBUG_DWO_RNGLISTS_SECTION
#define DEBUG_DWO_RNGLISTS_SECTION	".debug_rnglists.dwo"
#endif
#ifndef DEBUG_LINE_STR_SECTION
#define DEBUG_LINE_STR_SECTION  ".debug_line_str"
#endif
#ifndef DEBUG_LTO_LINE_STR_SECTION
#define DEBUG_LTO_LINE_STR_SECTION  ".gnu.debuglto_.debug_line_str"
#endif

/* Standard ELF section names for compiled code and data.  */
#ifndef TEXT_SECTION_NAME
#define TEXT_SECTION_NAME	".text"
#endif

/* Section flags for .debug_str section.  */
#define DEBUG_STR_SECTION_FLAGS                                 \
  (HAVE_GAS_SHF_MERGE && flag_merge_debug_strings               \
   ? SECTION_DEBUG | SECTION_MERGE | SECTION_STRINGS | 1        \
   : SECTION_DEBUG)

/* Section flags for .debug_str.dwo section.  */
#define DEBUG_STR_DWO_SECTION_FLAGS (SECTION_DEBUG | SECTION_EXCLUDE)

/* Attribute used to refer to the macro section.  */
#define DEBUG_MACRO_ATTRIBUTE (dwarf_version >= 5 ? DW_AT_macros \
		   : dwarf_strict ? DW_AT_macro_info : DW_AT_GNU_macros)

/* Labels we insert at beginning sections we can reference instead of
   the section names themselves.  */

#ifndef TEXT_SECTION_LABEL
#define TEXT_SECTION_LABEL                 "Ltext"
#endif
#ifndef COLD_TEXT_SECTION_LABEL
#define COLD_TEXT_SECTION_LABEL             "Ltext_cold"
#endif
#ifndef DEBUG_LINE_SECTION_LABEL
#define DEBUG_LINE_SECTION_LABEL           "Ldebug_line"
#endif
#ifndef DEBUG_SKELETON_LINE_SECTION_LABEL
#define DEBUG_SKELETON_LINE_SECTION_LABEL   "Lskeleton_debug_line"
#endif
#ifndef DEBUG_INFO_SECTION_LABEL
#define DEBUG_INFO_SECTION_LABEL           "Ldebug_info"
#endif
#ifndef DEBUG_SKELETON_INFO_SECTION_LABEL
#define DEBUG_SKELETON_INFO_SECTION_LABEL   "Lskeleton_debug_info"
#endif
#ifndef DEBUG_ABBREV_SECTION_LABEL
#define DEBUG_ABBREV_SECTION_LABEL         "Ldebug_abbrev"
#endif
#ifndef DEBUG_SKELETON_ABBREV_SECTION_LABEL
#define DEBUG_SKELETON_ABBREV_SECTION_LABEL "Lskeleton_debug_abbrev"
#endif
#ifndef DEBUG_ADDR_SECTION_LABEL
#define DEBUG_ADDR_SECTION_LABEL           "Ldebug_addr"
#endif
#ifndef DEBUG_LOC_SECTION_LABEL
#define DEBUG_LOC_SECTION_LABEL                    "Ldebug_loc"
#endif
#ifndef DEBUG_RANGES_SECTION_LABEL
#define DEBUG_RANGES_SECTION_LABEL         "Ldebug_ranges"
#endif
#ifndef DEBUG_MACINFO_SECTION_LABEL
#define DEBUG_MACINFO_SECTION_LABEL         "Ldebug_macinfo"
#endif
#ifndef DEBUG_MACRO_SECTION_LABEL
#define DEBUG_MACRO_SECTION_LABEL          "Ldebug_macro"
#endif
#define SKELETON_COMP_DIE_ABBREV 1
#define SKELETON_TYPE_DIE_ABBREV 2

/* Definitions of defaults for formats and names of various special
   (artificial) labels which may be generated within this file (when the -g
   options is used and DWARF2_DEBUGGING_INFO is in effect.
   If necessary, these may be overridden from within the tm.h file, but
   typically, overriding these defaults is unnecessary.  */

static char text_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char text_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char cold_text_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char cold_end_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_skeleton_info_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_skeleton_abbrev_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_addr_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char debug_skeleton_line_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char macinfo_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char loc_section_label[MAX_ARTIFICIAL_LABEL_BYTES];
static char ranges_section_label[2 * MAX_ARTIFICIAL_LABEL_BYTES];
static char ranges_base_label[2 * MAX_ARTIFICIAL_LABEL_BYTES];

#ifndef TEXT_END_LABEL
#define TEXT_END_LABEL		"Letext"
#endif
#ifndef COLD_END_LABEL
#define COLD_END_LABEL          "Letext_cold"
#endif
#ifndef BLOCK_BEGIN_LABEL
#define BLOCK_BEGIN_LABEL	"LBB"
#endif
#ifndef BLOCK_INLINE_ENTRY_LABEL
#define BLOCK_INLINE_ENTRY_LABEL "LBI"
#endif
#ifndef BLOCK_END_LABEL
#define BLOCK_END_LABEL		"LBE"
#endif
#ifndef LINE_CODE_LABEL
#define LINE_CODE_LABEL		"LM"
#endif


/* Return the root of the DIE's built for the current compilation unit.  */
static dw_die_ref
comp_unit_die (void)
{
  if (!single_comp_unit_die)
    single_comp_unit_die = gen_compile_unit_die (NULL);
  return single_comp_unit_die;
}

/* We allow a language front-end to designate a function that is to be
   called to "demangle" any name before it is put into a DIE.  */

static const char *(*demangle_name_func) (const char *);

void
dwarf2out_set_demangle_name_func (const char *(*func) (const char *))
{
  demangle_name_func = func;
}

/* Test if rtl node points to a pseudo register.  */

static inline int
is_pseudo_reg (const_rtx rtl)
{
  return ((REG_P (rtl) && REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
	  || (GET_CODE (rtl) == SUBREG
	      && REGNO (SUBREG_REG (rtl)) >= FIRST_PSEUDO_REGISTER));
}

/* Return a reference to a type, with its const and volatile qualifiers
   removed.  */

static inline tree
type_main_variant (tree type)
{
  type = TYPE_MAIN_VARIANT (type);

  /* ??? There really should be only one main variant among any group of
     variants of a given type (and all of the MAIN_VARIANT values for all
     members of the group should point to that one type) but sometimes the C
     front-end messes this up for array types, so we work around that bug
     here.  */
  if (TREE_CODE (type) == ARRAY_TYPE)
    while (type != TYPE_MAIN_VARIANT (type))
      type = TYPE_MAIN_VARIANT (type);

  return type;
}

/* Return nonzero if the given type node represents a tagged type.  */

static inline int
is_tagged_type (const_tree type)
{
  enum tree_code code = TREE_CODE (type);

  return (code == RECORD_TYPE || code == UNION_TYPE
	  || code == QUAL_UNION_TYPE || code == ENUMERAL_TYPE);
}

/* Set label to debug_info_section_label + die_offset of a DIE reference.  */

static void
get_ref_die_offset_label (char *label, dw_die_ref ref)
{
  sprintf (label, "%s+%ld", debug_info_section_label, ref->die_offset);
}

/* Return die_offset of a DIE reference to a base type.  */

static unsigned long int
get_base_type_offset (dw_die_ref ref)
{
  if (ref->die_offset)
    return ref->die_offset;
  if (comp_unit_die ()->die_abbrev)
    {
      calc_base_type_die_sizes ();
      gcc_assert (ref->die_offset);
    }
  return ref->die_offset;
}

/* Return die_offset of a DIE reference other than base type.  */

static unsigned long int
get_ref_die_offset (dw_die_ref ref)
{
  gcc_assert (ref->die_offset);
  return ref->die_offset;
}

/* Convert a DIE tag into its string name.  */

static const char *
dwarf_tag_name (unsigned int tag)
{
  const char *name = get_DW_TAG_name (tag);

  if (name != NULL)
    return name;

  return "DW_TAG_<unknown>";
}

/* Convert a DWARF attribute code into its string name.  */

static const char *
dwarf_attr_name (unsigned int attr)
{
  const char *name;

  switch (attr)
    {
#if VMS_DEBUGGING_INFO
    case DW_AT_HP_prologue:
      return "DW_AT_HP_prologue";
#else
    case DW_AT_MIPS_loop_unroll_factor:
      return "DW_AT_MIPS_loop_unroll_factor";
#endif

#if VMS_DEBUGGING_INFO
    case DW_AT_HP_epilogue:
      return "DW_AT_HP_epilogue";
#else
    case DW_AT_MIPS_stride:
      return "DW_AT_MIPS_stride";
#endif
    }

  name = get_DW_AT_name (attr);

  if (name != NULL)
    return name;

  return "DW_AT_<unknown>";
}

/* Convert a DWARF value form code into its string name.  */

static const char *
dwarf_form_name (unsigned int form)
{
  const char *name = get_DW_FORM_name (form);

  if (name != NULL)
    return name;

  return "DW_FORM_<unknown>";
}

/* Determine the "ultimate origin" of a decl.  The decl may be an inlined
   instance of an inlined instance of a decl which is local to an inline
   function, so we have to trace all of the way back through the origin chain
   to find out what sort of node actually served as the original seed for the
   given block.  */

static tree
decl_ultimate_origin (const_tree decl)
{
  if (!CODE_CONTAINS_STRUCT (TREE_CODE (decl), TS_DECL_COMMON))
    return NULL_TREE;

  /* DECL_ABSTRACT_ORIGIN can point to itself; ignore that if
     we're trying to output the abstract instance of this function.  */
  if (DECL_ABSTRACT_P (decl) && DECL_ABSTRACT_ORIGIN (decl) == decl)
    return NULL_TREE;

  /* Since the DECL_ABSTRACT_ORIGIN for a DECL is supposed to be the
     most distant ancestor, this should never happen.  */
  gcc_assert (!DECL_FROM_INLINE (DECL_ORIGIN (decl)));

  return DECL_ABSTRACT_ORIGIN (decl);
}

/* Get the class to which DECL belongs, if any.  In g++, the DECL_CONTEXT
   of a virtual function may refer to a base class, so we check the 'this'
   parameter.  */

static tree
decl_class_context (tree decl)
{
  tree context = NULL_TREE;

  if (TREE_CODE (decl) != FUNCTION_DECL || ! DECL_VINDEX (decl))
    context = DECL_CONTEXT (decl);
  else
    context = TYPE_MAIN_VARIANT
      (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)))));

  if (context && !TYPE_P (context))
    context = NULL_TREE;

  return context;
}

/* Add an attribute/value pair to a DIE.  */

static inline void
add_dwarf_attr (dw_die_ref die, dw_attr_node *attr)
{
  /* Maybe this should be an assert?  */
  if (die == NULL)
    return;

  if (flag_checking)
    {
      /* Check we do not add duplicate attrs.  Can't use get_AT here
         because that recurses to the specification/abstract origin DIE.  */
      dw_attr_node *a;
      unsigned ix;
      FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
	gcc_assert (a->dw_attr != attr->dw_attr);
    }

  vec_safe_reserve (die->die_attr, 1);
  vec_safe_push (die->die_attr, *attr);
}

enum dw_val_class
AT_class (dw_attr_node *a)
{
  return a->dw_attr_val.val_class;
}

/* Return the index for any attribute that will be referenced with a
   DW_FORM_addrx/GNU_addr_index or DW_FORM_strx/GNU_str_index.  String
   indices are stored in dw_attr_val.v.val_str for reference counting
   pruning.  */

static inline unsigned int
AT_index (dw_attr_node *a)
{
  if (AT_class (a) == dw_val_class_str)
    return a->dw_attr_val.v.val_str->index;
  else if (a->dw_attr_val.val_entry != NULL)
    return a->dw_attr_val.val_entry->index;
  return NOT_INDEXED;
}

/* Add a flag value attribute to a DIE.  */

static inline void
add_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind, unsigned int flag)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_flag;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_flag = flag;
  add_dwarf_attr (die, &attr);
}

static inline unsigned
AT_flag (dw_attr_node *a)
{
  gcc_assert (a && AT_class (a) == dw_val_class_flag);
  return a->dw_attr_val.v.val_flag;
}

/* Add a signed integer attribute value to a DIE.  */

static inline void
add_AT_int (dw_die_ref die, enum dwarf_attribute attr_kind, HOST_WIDE_INT int_val)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_const;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_int = int_val;
  add_dwarf_attr (die, &attr);
}

HOST_WIDE_INT
AT_int (dw_attr_node *a)
{
  gcc_assert (a && (AT_class (a) == dw_val_class_const
		    || AT_class (a) == dw_val_class_const_implicit));
  return a->dw_attr_val.v.val_int;
}

/* Add an unsigned integer attribute value to a DIE.  */

static inline void
add_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind,
		 unsigned HOST_WIDE_INT unsigned_val)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_unsigned_const;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_unsigned = unsigned_val;
  add_dwarf_attr (die, &attr);
}

unsigned HOST_WIDE_INT
AT_unsigned (dw_attr_node *a)
{
  gcc_assert (a && (AT_class (a) == dw_val_class_unsigned_const
		    || AT_class (a) == dw_val_class_unsigned_const_implicit));
  return a->dw_attr_val.v.val_unsigned;
}

/* Add an unsigned wide integer attribute value to a DIE.  */

static inline void
add_AT_wide (dw_die_ref die, enum dwarf_attribute attr_kind,
	     const wide_int& w)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_wide_int;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_wide = ggc_alloc<wide_int> ();
  *attr.dw_attr_val.v.val_wide = w;
  add_dwarf_attr (die, &attr);
}

/* Add an unsigned double integer attribute value to a DIE.  */

static inline void
add_AT_double (dw_die_ref die, enum dwarf_attribute attr_kind,
	       HOST_WIDE_INT high, unsigned HOST_WIDE_INT low)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_const_double;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_double.high = high;
  attr.dw_attr_val.v.val_double.low = low;
  add_dwarf_attr (die, &attr);
}

/* Add a floating point attribute value to a DIE and return it.  */

static inline void
add_AT_vec (dw_die_ref die, enum dwarf_attribute attr_kind,
	    unsigned int length, unsigned int elt_size, unsigned char *array)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_vec;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_vec.length = length;
  attr.dw_attr_val.v.val_vec.elt_size = elt_size;
  attr.dw_attr_val.v.val_vec.array = array;
  add_dwarf_attr (die, &attr);
}

/* Add an 8-byte data attribute value to a DIE.  */

static inline void
add_AT_data8 (dw_die_ref die, enum dwarf_attribute attr_kind,
              unsigned char data8[8])
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_data8;
  attr.dw_attr_val.val_entry = NULL;
  memcpy (attr.dw_attr_val.v.val_data8, data8, 8);
  add_dwarf_attr (die, &attr);
}

/* Add DW_AT_low_pc and DW_AT_high_pc to a DIE.  When using
   dwarf_split_debug_info, address attributes in dies destined for the
   final executable have force_direct set to avoid using indexed
   references.  */

static inline void
add_AT_low_high_pc (dw_die_ref die, const char *lbl_low, const char *lbl_high,
                    bool force_direct)
{
  dw_attr_node attr;
  char * lbl_id;

  lbl_id = xstrdup (lbl_low);
  attr.dw_attr = DW_AT_low_pc;
  attr.dw_attr_val.val_class = dw_val_class_lbl_id;
  attr.dw_attr_val.v.val_lbl_id = lbl_id;
  if (dwarf_split_debug_info && !force_direct)
    attr.dw_attr_val.val_entry
      = add_addr_table_entry (lbl_id, ate_kind_label);
  else
    attr.dw_attr_val.val_entry = NULL;
  add_dwarf_attr (die, &attr);

  attr.dw_attr = DW_AT_high_pc;
  if (dwarf_version < 4)
    attr.dw_attr_val.val_class = dw_val_class_lbl_id;
  else
    attr.dw_attr_val.val_class = dw_val_class_high_pc;
  lbl_id = xstrdup (lbl_high);
  attr.dw_attr_val.v.val_lbl_id = lbl_id;
  if (attr.dw_attr_val.val_class == dw_val_class_lbl_id
      && dwarf_split_debug_info && !force_direct)
    attr.dw_attr_val.val_entry
      = add_addr_table_entry (lbl_id, ate_kind_label);
  else
    attr.dw_attr_val.val_entry = NULL;
  add_dwarf_attr (die, &attr);
}

/* Hash and equality functions for debug_str_hash.  */

hashval_t
indirect_string_hasher::hash (indirect_string_node *x)
{
  return htab_hash_string (x->str);
}

bool
indirect_string_hasher::equal (indirect_string_node *x1, const char *x2)
{
  return strcmp (x1->str, x2) == 0;
}

/* Add STR to the given string hash table.  */

static struct indirect_string_node *
find_AT_string_in_table (const char *str,
			 hash_table<indirect_string_hasher> *table,
			 enum insert_option insert = INSERT)
{
  struct indirect_string_node *node;

  indirect_string_node **slot
    = table->find_slot_with_hash (str, htab_hash_string (str), insert);
  if (*slot == NULL)
    {
      node = ggc_cleared_alloc<indirect_string_node> ();
      node->str = ggc_strdup (str);
      *slot = node;
    }
  else
    node = *slot;

  node->refcount++;
  return node;
}

/* Add STR to the indirect string hash table.  */

static struct indirect_string_node *
find_AT_string (const char *str, enum insert_option insert = INSERT)
{
  if (! debug_str_hash)
    debug_str_hash = hash_table<indirect_string_hasher>::create_ggc (10);

  return find_AT_string_in_table (str, debug_str_hash, insert);
}

/* Add a string attribute value to a DIE.  */

static inline void
add_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind, const char *str)
{
  dw_attr_node attr;
  struct indirect_string_node *node;

  node = find_AT_string (str);

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_str;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_str = node;
  add_dwarf_attr (die, &attr);
}

static inline const char *
AT_string (dw_attr_node *a)
{
  gcc_assert (a && AT_class (a) == dw_val_class_str);
  return a->dw_attr_val.v.val_str->str;
}

/* Call this function directly to bypass AT_string_form's logic to put
   the string inline in the die. */

static void
set_indirect_string (struct indirect_string_node *node)
{
  char label[MAX_ARTIFICIAL_LABEL_BYTES];
  /* Already indirect is a no op.  */
  if (node->form == DW_FORM_strp
      || node->form == DW_FORM_line_strp
      || node->form == dwarf_FORM (DW_FORM_strx))
    {
      gcc_assert (node->label);
      return;
    }
  ASM_GENERATE_INTERNAL_LABEL (label, "LASF", dw2_string_counter);
  ++dw2_string_counter;
  node->label = xstrdup (label);

  if (!dwarf_split_debug_info)
    {
      node->form = DW_FORM_strp;
      node->index = NOT_INDEXED;
    }
  else
    {
      node->form = dwarf_FORM (DW_FORM_strx);
      node->index = NO_INDEX_ASSIGNED;
    }
}

/* A helper function for dwarf2out_finish, called to reset indirect
   string decisions done for early LTO dwarf output before fat object
   dwarf output.  */

int
reset_indirect_string (indirect_string_node **h, void *)
{
  struct indirect_string_node *node = *h;
  if (node->form == DW_FORM_strp
      || node->form == DW_FORM_line_strp
      || node->form == dwarf_FORM (DW_FORM_strx))
    {
      free (node->label);
      node->label = NULL;
      node->form = (dwarf_form) 0;
      node->index = 0;
    }
  return 1;
}

/* Add a string representing a file or filepath attribute value to a DIE.  */

static inline void
add_filepath_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind,
			const char *str)
{
  if (! asm_outputs_debug_line_str ())
    add_AT_string (die, attr_kind, str);
  else
    {
      dw_attr_node attr;
      struct indirect_string_node *node;

      if (!debug_line_str_hash)
	debug_line_str_hash
	  = hash_table<indirect_string_hasher>::create_ggc (10);

      node = find_AT_string_in_table (str, debug_line_str_hash);
      set_indirect_string (node);
      node->form = DW_FORM_line_strp;

      attr.dw_attr = attr_kind;
      attr.dw_attr_val.val_class = dw_val_class_str;
      attr.dw_attr_val.val_entry = NULL;
      attr.dw_attr_val.v.val_str = node;
      add_dwarf_attr (die, &attr);
    }
}

/* Find out whether a string should be output inline in DIE
   or out-of-line in .debug_str section.  */

static enum dwarf_form
find_string_form (struct indirect_string_node *node)
{
  unsigned int len;

  if (node->form)
    return node->form;

  len = strlen (node->str) + 1;

  /* If the string is shorter or equal to the size of the reference, it is
     always better to put it inline.  */
  if (len <= (unsigned) dwarf_offset_size || node->refcount == 0)
    return node->form = DW_FORM_string;

  /* If we cannot expect the linker to merge strings in .debug_str
     section, only put it into .debug_str if it is worth even in this
     single module.  */
  if (DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET
      || ((debug_str_section->common.flags & SECTION_MERGE) == 0
	  && (len - dwarf_offset_size) * node->refcount <= len))
    return node->form = DW_FORM_string;

  set_indirect_string (node);

  return node->form;
}

/* Find out whether the string referenced from the attribute should be
   output inline in DIE or out-of-line in .debug_str section.  */

static enum dwarf_form
AT_string_form (dw_attr_node *a)
{
  gcc_assert (a && AT_class (a) == dw_val_class_str);
  return find_string_form (a->dw_attr_val.v.val_str);
}

/* Add a DIE reference attribute value to a DIE.  */

static inline void
add_AT_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind, dw_die_ref targ_die)
{
  dw_attr_node attr;
  gcc_checking_assert (targ_die != NULL);

  /* With LTO we can end up trying to reference something we didn't create
     a DIE for.  Avoid crashing later on a NULL referenced DIE.  */
  if (targ_die == NULL)
    return;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_die_ref;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_die_ref.die = targ_die;
  attr.dw_attr_val.v.val_die_ref.external = 0;
  add_dwarf_attr (die, &attr);
}

/* Change DIE reference REF to point to NEW_DIE instead.  */

static inline void
change_AT_die_ref (dw_attr_node *ref, dw_die_ref new_die)
{
  gcc_assert (ref->dw_attr_val.val_class == dw_val_class_die_ref);
  ref->dw_attr_val.v.val_die_ref.die = new_die;
  ref->dw_attr_val.v.val_die_ref.external = 0;
}

/* Add an AT_specification attribute to a DIE, and also make the back
   pointer from the specification to the definition.  */

static inline void
add_AT_specification (dw_die_ref die, dw_die_ref targ_die)
{
  add_AT_die_ref (die, DW_AT_specification, targ_die);
  gcc_assert (!targ_die->die_definition);
  targ_die->die_definition = die;
}

static inline dw_die_ref
AT_ref (dw_attr_node *a)
{
  gcc_assert (a && AT_class (a) == dw_val_class_die_ref);
  return a->dw_attr_val.v.val_die_ref.die;
}

static inline int
AT_ref_external (dw_attr_node *a)
{
  if (a && AT_class (a) == dw_val_class_die_ref)
    return a->dw_attr_val.v.val_die_ref.external;

  return 0;
}

static inline void
set_AT_ref_external (dw_attr_node *a, int i)
{
  gcc_assert (a && AT_class (a) == dw_val_class_die_ref);
  a->dw_attr_val.v.val_die_ref.external = i;
}

/* Add a location description attribute value to a DIE.  */

static inline void
add_AT_loc (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_descr_ref loc)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_loc;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_loc = loc;
  add_dwarf_attr (die, &attr);
}

dw_loc_descr_ref
AT_loc (dw_attr_node *a)
{
  gcc_assert (a && AT_class (a) == dw_val_class_loc);
  return a->dw_attr_val.v.val_loc;
}

static inline void
add_AT_loc_list (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_list_ref loc_list)
{
  dw_attr_node attr;

  if (XCOFF_DEBUGGING_INFO && !HAVE_XCOFF_DWARF_EXTRAS)
    return;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_loc_list;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_loc_list = loc_list;
  add_dwarf_attr (die, &attr);
  have_location_lists = true;
}

static inline dw_loc_list_ref
AT_loc_list (dw_attr_node *a)
{
  gcc_assert (a && AT_class (a) == dw_val_class_loc_list);
  return a->dw_attr_val.v.val_loc_list;
}

/* Add a view list attribute to DIE.  It must have a DW_AT_location
   attribute, because the view list complements the location list.  */

static inline void
add_AT_view_list (dw_die_ref die, enum dwarf_attribute attr_kind)
{
  dw_attr_node attr;

  if (XCOFF_DEBUGGING_INFO && !HAVE_XCOFF_DWARF_EXTRAS)
    return;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_view_list;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_view_list = die;
  add_dwarf_attr (die, &attr);
  gcc_checking_assert (get_AT (die, DW_AT_location));
  gcc_assert (have_location_lists);
}

/* Return a pointer to the location list referenced by the attribute.
   If the named attribute is a view list, look up the corresponding
   DW_AT_location attribute and return its location list.  */

static inline dw_loc_list_ref *
AT_loc_list_ptr (dw_attr_node *a)
{
  gcc_assert (a);
  switch (AT_class (a))
    {
    case dw_val_class_loc_list:
      return &a->dw_attr_val.v.val_loc_list;
    case dw_val_class_view_list:
      {
	dw_attr_node *l;
	l = get_AT (a->dw_attr_val.v.val_view_list, DW_AT_location);
	if (!l)
	  return NULL;
	gcc_checking_assert (l + 1 == a);
	return AT_loc_list_ptr (l);
      }
    default:
      gcc_unreachable ();
    }
}

/* Return the location attribute value associated with a view list
   attribute value.  */

static inline dw_val_node *
view_list_to_loc_list_val_node (dw_val_node *val)
{
  gcc_assert (val->val_class == dw_val_class_view_list);
  dw_attr_node *loc = get_AT (val->v.val_view_list, DW_AT_location);
  if (!loc)
    return NULL;
  gcc_checking_assert (&(loc + 1)->dw_attr_val == val);
  gcc_assert (AT_class (loc) == dw_val_class_loc_list);
  return &loc->dw_attr_val;
}

struct addr_hasher : ggc_ptr_hash<addr_table_entry>
{
  static hashval_t hash (addr_table_entry *);
  static bool equal (addr_table_entry *, addr_table_entry *);
};

/* Table of entries into the .debug_addr section.  */

static GTY (()) hash_table<addr_hasher> *addr_index_table;

/* Hash an address_table_entry.  */

hashval_t
addr_hasher::hash (addr_table_entry *a)
{
  inchash::hash hstate;
  switch (a->kind)
    {
      case ate_kind_rtx:
	hstate.add_int (0);
	break;
      case ate_kind_rtx_dtprel:
	hstate.add_int (1);
	break;
      case ate_kind_label:
        return htab_hash_string (a->addr.label);
      default:
        gcc_unreachable ();
    }
  inchash::add_rtx (a->addr.rtl, hstate);
  return hstate.end ();
}

/* Determine equality for two address_table_entries.  */

bool
addr_hasher::equal (addr_table_entry *a1, addr_table_entry *a2)
{
  if (a1->kind != a2->kind)
    return 0;
  switch (a1->kind)
    {
      case ate_kind_rtx:
      case ate_kind_rtx_dtprel:
        return rtx_equal_p (a1->addr.rtl, a2->addr.rtl);
      case ate_kind_label:
        return strcmp (a1->addr.label, a2->addr.label) == 0;
      default:
        gcc_unreachable ();
    }
}

/* Initialize an addr_table_entry.  */

void
init_addr_table_entry (addr_table_entry *e, enum ate_kind kind, void *addr)
{
  e->kind = kind;
  switch (kind)
    {
      case ate_kind_rtx:
      case ate_kind_rtx_dtprel:
        e->addr.rtl = (rtx) addr;
        break;
      case ate_kind_label:
        e->addr.label = (char *) addr;
        break;
    }
  e->refcount = 0;
  e->index = NO_INDEX_ASSIGNED;
}

/* Add attr to the address table entry to the table.  Defer setting an
   index until output time.  */

static addr_table_entry *
add_addr_table_entry (void *addr, enum ate_kind kind)
{
  addr_table_entry *node;
  addr_table_entry finder;

  gcc_assert (dwarf_split_debug_info);
  if (! addr_index_table)
    addr_index_table = hash_table<addr_hasher>::create_ggc (10);
  init_addr_table_entry (&finder, kind, addr);
  addr_table_entry **slot = addr_index_table->find_slot (&finder, INSERT);

  if (*slot == HTAB_EMPTY_ENTRY)
    {
      node = ggc_cleared_alloc<addr_table_entry> ();
      init_addr_table_entry (node, kind, addr);
      *slot = node;
    }
  else
    node = *slot;

  node->refcount++;
  return node;
}

/* Remove an entry from the addr table by decrementing its refcount.
   Strictly, decrementing the refcount would be enough, but the
   assertion that the entry is actually in the table has found
   bugs.  */

static void
remove_addr_table_entry (addr_table_entry *entry)
{
  gcc_assert (dwarf_split_debug_info && addr_index_table);
  /* After an index is assigned, the table is frozen.  */
  gcc_assert (entry->refcount > 0 && entry->index == NO_INDEX_ASSIGNED);
  entry->refcount--;
}

/* Given a location list, remove all addresses it refers to from the
   address_table.  */

static void
remove_loc_list_addr_table_entries (dw_loc_descr_ref descr)
{
  for (; descr; descr = descr->dw_loc_next)
    if (descr->dw_loc_oprnd1.val_entry != NULL)
      {
        gcc_assert (descr->dw_loc_oprnd1.val_entry->index == NO_INDEX_ASSIGNED);
        remove_addr_table_entry (descr->dw_loc_oprnd1.val_entry);
      }
}

/* A helper function for dwarf2out_finish called through
   htab_traverse.  Assign an addr_table_entry its index.  All entries
   must be collected into the table when this function is called,
   because the indexing code relies on htab_traverse to traverse nodes
   in the same order for each run. */

int
index_addr_table_entry (addr_table_entry **h, unsigned int *index)
{
  addr_table_entry *node = *h;

  /* Don't index unreferenced nodes.  */
  if (node->refcount == 0)
    return 1;

  gcc_assert (node->index == NO_INDEX_ASSIGNED);
  node->index = *index;
  *index += 1;

  return 1;
}

/* Return the tag of a given DIE.  */

enum dwarf_tag
dw_get_die_tag (dw_die_ref die)
{
  return die->die_tag;
}

/* Return a reference to the children list of a given DIE.  */

dw_die_ref
dw_get_die_child (dw_die_ref die)
{
  return die->die_child;
}

/* Return a reference to the sibling of a given DIE.  */

dw_die_ref
dw_get_die_sib (dw_die_ref die)
{
  return die->die_sib;
}

/* Add an address constant attribute value to a DIE.  When using
   dwarf_split_debug_info, address attributes in dies destined for the
   final executable should be direct references--setting the parameter
   force_direct ensures this behavior.  */

static inline void
add_AT_addr (dw_die_ref die, enum dwarf_attribute attr_kind, rtx addr,
             bool force_direct)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_addr;
  attr.dw_attr_val.v.val_addr = addr;
  if (dwarf_split_debug_info && !force_direct)
    attr.dw_attr_val.val_entry = add_addr_table_entry (addr, ate_kind_rtx);
  else
    attr.dw_attr_val.val_entry = NULL;
  add_dwarf_attr (die, &attr);
}

/* Get the RTX from to an address DIE attribute.  */

static inline rtx
AT_addr (dw_attr_node *a)
{
  gcc_assert (a && AT_class (a) == dw_val_class_addr);
  return a->dw_attr_val.v.val_addr;
}

/* Add a file attribute value to a DIE.  */

static inline void
add_AT_file (dw_die_ref die, enum dwarf_attribute attr_kind,
	     struct dwarf_file_data *fd)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_file;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_file = fd;
  add_dwarf_attr (die, &attr);
}

/* Get the dwarf_file_data from a file DIE attribute.  */

static inline struct dwarf_file_data *
AT_file (dw_attr_node *a)
{
  gcc_assert (a && (AT_class (a) == dw_val_class_file
		    || AT_class (a) == dw_val_class_file_implicit));
  return a->dw_attr_val.v.val_file;
}

#if VMS_DEBUGGING_INFO
/* Add a vms delta attribute value to a DIE.  */

static inline void
add_AT_vms_delta (dw_die_ref die, enum dwarf_attribute attr_kind,
		  const char *lbl1, const char *lbl2)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_vms_delta;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_vms_delta.lbl1 = xstrdup (lbl1);
  attr.dw_attr_val.v.val_vms_delta.lbl2 = xstrdup (lbl2);
  add_dwarf_attr (die, &attr);
}
#endif

/* Add a symbolic view identifier attribute value to a DIE.  */

static inline void
add_AT_symview (dw_die_ref die, enum dwarf_attribute attr_kind,
               const char *view_label)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_symview;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_symbolic_view = xstrdup (view_label);
  add_dwarf_attr (die, &attr);
}

/* Add a label identifier attribute value to a DIE.  */

static inline void
add_AT_lbl_id (dw_die_ref die, enum dwarf_attribute attr_kind,
               const char *lbl_id)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_lbl_id;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_lbl_id = xstrdup (lbl_id);
  if (dwarf_split_debug_info)
    attr.dw_attr_val.val_entry
        = add_addr_table_entry (attr.dw_attr_val.v.val_lbl_id,
                                ate_kind_label);
  add_dwarf_attr (die, &attr);
}

/* Add a section offset attribute value to a DIE, an offset into the
   debug_line section.  */

static inline void
add_AT_lineptr (dw_die_ref die, enum dwarf_attribute attr_kind,
		const char *label)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_lineptr;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_lbl_id = xstrdup (label);
  add_dwarf_attr (die, &attr);
}

/* Add a section offset attribute value to a DIE, an offset into the
   debug_macinfo section.  */

static inline void
add_AT_macptr (dw_die_ref die, enum dwarf_attribute attr_kind,
	       const char *label)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_macptr;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_lbl_id = xstrdup (label);
  add_dwarf_attr (die, &attr);
}

/* Add a range_list attribute value to a DIE.  When using
   dwarf_split_debug_info, address attributes in dies destined for the
   final executable should be direct references--setting the parameter
   force_direct ensures this behavior.  */

#define UNRELOCATED_OFFSET ((addr_table_entry *) 1)
#define RELOCATED_OFFSET (NULL)

static void
add_AT_range_list (dw_die_ref die, enum dwarf_attribute attr_kind,
                   long unsigned int offset, bool force_direct)
{
  dw_attr_node attr;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_range_list;
  /* For the range_list attribute, use val_entry to store whether the
     offset should follow split-debug-info or normal semantics.  This
     value is read in output_range_list_offset.  */
  if (dwarf_split_debug_info && !force_direct)
    attr.dw_attr_val.val_entry = UNRELOCATED_OFFSET;
  else
    attr.dw_attr_val.val_entry = RELOCATED_OFFSET;
  attr.dw_attr_val.v.val_offset = offset;
  add_dwarf_attr (die, &attr);
}

/* Return the start label of a delta attribute.  */

static inline const char *
AT_vms_delta1 (dw_attr_node *a)
{
  gcc_assert (a && (AT_class (a) == dw_val_class_vms_delta));
  return a->dw_attr_val.v.val_vms_delta.lbl1;
}

/* Return the end label of a delta attribute.  */

static inline const char *
AT_vms_delta2 (dw_attr_node *a)
{
  gcc_assert (a && (AT_class (a) == dw_val_class_vms_delta));
  return a->dw_attr_val.v.val_vms_delta.lbl2;
}

static inline const char *
AT_lbl (dw_attr_node *a)
{
  gcc_assert (a && (AT_class (a) == dw_val_class_lbl_id
		    || AT_class (a) == dw_val_class_lineptr
		    || AT_class (a) == dw_val_class_macptr
		    || AT_class (a) == dw_val_class_loclistsptr
		    || AT_class (a) == dw_val_class_high_pc));
  return a->dw_attr_val.v.val_lbl_id;
}

/* Get the attribute of type attr_kind.  */

dw_attr_node *
get_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
{
  dw_attr_node *a;
  unsigned ix;
  dw_die_ref spec = NULL;

  if (! die)
    return NULL;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (a->dw_attr == attr_kind)
      return a;
    else if (a->dw_attr == DW_AT_specification
	     || a->dw_attr == DW_AT_abstract_origin)
      spec = AT_ref (a);

  if (spec)
    return get_AT (spec, attr_kind);

  return NULL;
}

/* Returns the parent of the declaration of DIE.  */

static dw_die_ref
get_die_parent (dw_die_ref die)
{
  dw_die_ref t;

  if (!die)
    return NULL;

  if ((t = get_AT_ref (die, DW_AT_abstract_origin))
      || (t = get_AT_ref (die, DW_AT_specification)))
    die = t;

  return die->die_parent;
}

/* Return the "low pc" attribute value, typically associated with a subprogram
   DIE.  Return null if the "low pc" attribute is either not present, or if it
   cannot be represented as an assembler label identifier.  */

static inline const char *
get_AT_low_pc (dw_die_ref die)
{
  dw_attr_node *a = get_AT (die, DW_AT_low_pc);

  return a ? AT_lbl (a) : NULL;
}

/* Return the value of the string attribute designated by ATTR_KIND, or
   NULL if it is not present.  */

const char *
get_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind)
{
  dw_attr_node *a = get_AT (die, attr_kind);

  return a ? AT_string (a) : NULL;
}

/* Return the value of the flag attribute designated by ATTR_KIND, or -1
   if it is not present.  */

int
get_AT_flag (dw_die_ref die, enum dwarf_attribute attr_kind)
{
  dw_attr_node *a = get_AT (die, attr_kind);

  return a ? AT_flag (a) : 0;
}

/* Return the value of the unsigned attribute designated by ATTR_KIND, or 0
   if it is not present.  */

unsigned
get_AT_unsigned (dw_die_ref die, enum dwarf_attribute attr_kind)
{
  dw_attr_node *a = get_AT (die, attr_kind);

  return a ? AT_unsigned (a) : 0;
}

dw_die_ref
get_AT_ref (dw_die_ref die, enum dwarf_attribute attr_kind)
{
  dw_attr_node *a = get_AT (die, attr_kind);

  return a ? AT_ref (a) : NULL;
}

struct dwarf_file_data *
get_AT_file (dw_die_ref die, enum dwarf_attribute attr_kind)
{
  dw_attr_node *a = get_AT (die, attr_kind);

  return a ? AT_file (a) : NULL;
}

/* Return TRUE if the language is C.  */

static inline bool
is_c (void)
{
  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);

  return (lang == DW_LANG_C || lang == DW_LANG_C89 || lang == DW_LANG_C99
	  || lang == DW_LANG_C11 || lang == DW_LANG_ObjC);


}

/* Return TRUE if the language is C++.  */

static inline bool
is_cxx (void)
{
  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);

  return (lang == DW_LANG_C_plus_plus || lang == DW_LANG_ObjC_plus_plus
	  || lang == DW_LANG_C_plus_plus_11 || lang == DW_LANG_C_plus_plus_14);
}

/* Return TRUE if DECL was created by the C++ frontend.  */

static bool
is_cxx (const_tree decl)
{
  if (in_lto_p)
    {
      const_tree context = get_ultimate_context (decl);
      if (context && TRANSLATION_UNIT_LANGUAGE (context))
	return startswith (TRANSLATION_UNIT_LANGUAGE (context), "GNU C++");
    }
  return is_cxx ();
}

/* Return TRUE if the language is Fortran.  */

static inline bool
is_fortran (void)
{
  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);

  return (lang == DW_LANG_Fortran77
	  || lang == DW_LANG_Fortran90
	  || lang == DW_LANG_Fortran95
	  || lang == DW_LANG_Fortran03
	  || lang == DW_LANG_Fortran08);
}

static inline bool
is_fortran (const_tree decl)
{
  if (in_lto_p)
    {
      const_tree context = get_ultimate_context (decl);
      if (context && TRANSLATION_UNIT_LANGUAGE (context))
	return (strncmp (TRANSLATION_UNIT_LANGUAGE (context),
			 "GNU Fortran", 11) == 0
		|| strcmp (TRANSLATION_UNIT_LANGUAGE (context),
			   "GNU F77") == 0);
    }
  return is_fortran ();
}

/* Return TRUE if the language is Ada.  */

static inline bool
is_ada (void)
{
  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);

  return lang == DW_LANG_Ada95 || lang == DW_LANG_Ada83;
}

/* Return TRUE if the language is D.  */

static inline bool
is_dlang (void)
{
  unsigned int lang = get_AT_unsigned (comp_unit_die (), DW_AT_language);

  return lang == DW_LANG_D;
}

/* Remove the specified attribute if present.  Return TRUE if removal
   was successful.  */

static bool
remove_AT (dw_die_ref die, enum dwarf_attribute attr_kind)
{
  dw_attr_node *a;
  unsigned ix;

  if (! die)
    return false;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (a->dw_attr == attr_kind)
      {
	if (AT_class (a) == dw_val_class_str)
	  if (a->dw_attr_val.v.val_str->refcount)
	    a->dw_attr_val.v.val_str->refcount--;

	/* vec::ordered_remove should help reduce the number of abbrevs
	   that are needed.  */
	die->die_attr->ordered_remove (ix);
	return true;
      }
  return false;
}

/* Remove CHILD from its parent.  PREV must have the property that
   PREV->DIE_SIB == CHILD.  Does not alter CHILD.  */

static void
remove_child_with_prev (dw_die_ref child, dw_die_ref prev)
{
  gcc_assert (child->die_parent == prev->die_parent);
  gcc_assert (prev->die_sib == child);
  if (prev == child)
    {
      gcc_assert (child->die_parent->die_child == child);
      prev = NULL;
    }
  else
    prev->die_sib = child->die_sib;
  if (child->die_parent->die_child == child)
    child->die_parent->die_child = prev;
  child->die_sib = NULL;
}

/* Replace OLD_CHILD with NEW_CHILD.  PREV must have the property that
   PREV->DIE_SIB == OLD_CHILD.  Does not alter OLD_CHILD.  */

static void
replace_child (dw_die_ref old_child, dw_die_ref new_child, dw_die_ref prev)
{
  dw_die_ref parent = old_child->die_parent;

  gcc_assert (parent == prev->die_parent);
  gcc_assert (prev->die_sib == old_child);

  new_child->die_parent = parent;
  if (prev == old_child)
    {
      gcc_assert (parent->die_child == old_child);
      new_child->die_sib = new_child;
    }
  else
    {
      prev->die_sib = new_child;
      new_child->die_sib = old_child->die_sib;
    }
  if (old_child->die_parent->die_child == old_child)
    old_child->die_parent->die_child = new_child;
  old_child->die_sib = NULL;
}

/* Move all children from OLD_PARENT to NEW_PARENT.  */

static void
move_all_children (dw_die_ref old_parent, dw_die_ref new_parent)
{
  dw_die_ref c;
  new_parent->die_child = old_parent->die_child;
  old_parent->die_child = NULL;
  FOR_EACH_CHILD (new_parent, c, c->die_parent = new_parent);
}

/* Remove child DIE whose die_tag is TAG.  Do nothing if no child
   matches TAG.  */

static void
remove_child_TAG (dw_die_ref die, enum dwarf_tag tag)
{
  dw_die_ref c;

  c = die->die_child;
  if (c) do {
    dw_die_ref prev = c;
    c = c->die_sib;
    while (c->die_tag == tag)
      {
	remove_child_with_prev (c, prev);
	c->die_parent = NULL;
	/* Might have removed every child.  */
	if (die->die_child == NULL)
	  return;
	c = prev->die_sib;
      }
  } while (c != die->die_child);
}

/* Add a CHILD_DIE as the last child of DIE.  */

static void
add_child_die (dw_die_ref die, dw_die_ref child_die)
{
  /* FIXME this should probably be an assert.  */
  if (! die || ! child_die)
    return;
  gcc_assert (die != child_die);

  child_die->die_parent = die;
  if (die->die_child)
    {
      child_die->die_sib = die->die_child->die_sib;
      die->die_child->die_sib = child_die;
    }
  else
    child_die->die_sib = child_die;
  die->die_child = child_die;
}

/* Like add_child_die, but put CHILD_DIE after AFTER_DIE.  */

static void
add_child_die_after (dw_die_ref die, dw_die_ref child_die,
		     dw_die_ref after_die)
{
  gcc_assert (die
	      && child_die
	      && after_die
	      && die->die_child
	      && die != child_die);

  child_die->die_parent = die;
  child_die->die_sib = after_die->die_sib;
  after_die->die_sib = child_die;
  if (die->die_child == after_die)
    die->die_child = child_die;
}

/* Unassociate CHILD from its parent, and make its parent be
   NEW_PARENT.  */

static void
reparent_child (dw_die_ref child, dw_die_ref new_parent)
{
  for (dw_die_ref p = child->die_parent->die_child; ; p = p->die_sib)
    if (p->die_sib == child)
      {
	remove_child_with_prev (child, p);
	break;
      }
  add_child_die (new_parent, child);
}

/* Move CHILD, which must be a child of PARENT or the DIE for which PARENT
   is the specification, to the end of PARENT's list of children.
   This is done by removing and re-adding it.  */

static void
splice_child_die (dw_die_ref parent, dw_die_ref child)
{
  /* We want the declaration DIE from inside the class, not the
     specification DIE at toplevel.  */
  if (child->die_parent != parent)
    {
      dw_die_ref tmp = get_AT_ref (child, DW_AT_specification);

      if (tmp)
	child = tmp;
    }

  gcc_assert (child->die_parent == parent
	      || (child->die_parent
		  == get_AT_ref (parent, DW_AT_specification)));

  reparent_child (child, parent);
}

/* Create and return a new die with TAG_VALUE as tag.  */
 
dw_die_ref
new_die_raw (enum dwarf_tag tag_value)
{
  dw_die_ref die = ggc_cleared_alloc<die_node> ();
  die->die_tag = tag_value;
  return die;
}

/* Create and return a new die with a parent of PARENT_DIE.  If
   PARENT_DIE is NULL, the new DIE is placed in limbo and an
   associated tree T must be supplied to determine parenthood
   later.  */

static inline dw_die_ref
new_die (enum dwarf_tag tag_value, dw_die_ref parent_die, tree t)
{
  dw_die_ref die = new_die_raw (tag_value);

  if (parent_die != NULL)
    add_child_die (parent_die, die);
  else
    {
      limbo_die_node *limbo_node;

      /* No DIEs created after early dwarf should end up in limbo,
	 because the limbo list should not persist past LTO
	 streaming.  */
      if (tag_value != DW_TAG_compile_unit
	  /* These are allowed because they're generated while
	     breaking out COMDAT units late.  */
	  && tag_value != DW_TAG_type_unit
	  && tag_value != DW_TAG_skeleton_unit
	  && !early_dwarf
	  /* Allow nested functions to live in limbo because they will
	     only temporarily live there, as decls_for_scope will fix
	     them up.  */
	  && (TREE_CODE (t) != FUNCTION_DECL
	      || !decl_function_context (t))
	  /* Same as nested functions above but for types.  Types that
	     are local to a function will be fixed in
	     decls_for_scope.  */
	  && (!RECORD_OR_UNION_TYPE_P (t)
	      || !TYPE_CONTEXT (t)
	      || TREE_CODE (TYPE_CONTEXT (t)) != FUNCTION_DECL)
	  /* FIXME debug-early: Allow late limbo DIE creation for LTO,
	     especially in the ltrans stage, but once we implement LTO
	     dwarf streaming, we should remove this exception.  */
	  && !in_lto_p)
	{
	  fprintf (stderr, "symbol ended up in limbo too late:");
	  debug_generic_stmt (t);
	  gcc_unreachable ();
	}

      limbo_node = ggc_cleared_alloc<limbo_die_node> ();
      limbo_node->die = die;
      limbo_node->created_for = t;
      limbo_node->next = limbo_die_list;
      limbo_die_list = limbo_node;
    }

  return die;
}

/* Return the DIE associated with the given type specifier.  */

dw_die_ref
lookup_type_die (tree type)
{
  dw_die_ref die = TYPE_SYMTAB_DIE (type);
  if (die && die->removed)
    {
      TYPE_SYMTAB_DIE (type) = NULL;
      return NULL;
    }
  return die;
}

/* Given a TYPE_DIE representing the type TYPE, if TYPE is an
   anonymous type named by the typedef TYPE_DIE, return the DIE of the
   anonymous type instead the one of the naming typedef.  */

static inline dw_die_ref
strip_naming_typedef (tree type, dw_die_ref type_die)
{
  if (type
      && TREE_CODE (type) == RECORD_TYPE
      && type_die
      && type_die->die_tag == DW_TAG_typedef
      && is_naming_typedef_decl (TYPE_NAME (type)))
    type_die = get_AT_ref (type_die, DW_AT_type);
  return type_die;
}

/* Like lookup_type_die, but if type is an anonymous type named by a
   typedef[1], return the DIE of the anonymous type instead the one of
   the naming typedef.  This is because in gen_typedef_die, we did
   equate the anonymous struct named by the typedef with the DIE of
   the naming typedef. So by default, lookup_type_die on an anonymous
   struct yields the DIE of the naming typedef.

   [1]: Read the comment of is_naming_typedef_decl to learn about what
   a naming typedef is.  */

static inline dw_die_ref
lookup_type_die_strip_naming_typedef (tree type)
{
  dw_die_ref die = lookup_type_die (type);
  return strip_naming_typedef (type, die);
}

/* Equate a DIE to a given type specifier.  */

static inline void
equate_type_number_to_die (tree type, dw_die_ref type_die)
{
  TYPE_SYMTAB_DIE (type) = type_die;
}

static dw_die_ref maybe_create_die_with_external_ref (tree);
struct GTY(()) sym_off_pair 
{
  const char * GTY((skip)) sym;
  unsigned HOST_WIDE_INT off;
};
static GTY(()) hash_map<tree, sym_off_pair> *external_die_map;

/* Returns a hash value for X (which really is a die_struct).  */

inline hashval_t
decl_die_hasher::hash (die_node *x)
{
  return (hashval_t) x->decl_id;
}

/* Return nonzero if decl_id of die_struct X is the same as UID of decl *Y.  */

inline bool
decl_die_hasher::equal (die_node *x, tree y)
{
  return (x->decl_id == DECL_UID (y));
}

/* Return the DIE associated with a given declaration.  */

dw_die_ref
lookup_decl_die (tree decl)
{
  dw_die_ref *die = decl_die_table->find_slot_with_hash (decl, DECL_UID (decl),
							 NO_INSERT);
  if (!die)
    {
      if (in_lto_p)
	return maybe_create_die_with_external_ref (decl);
      return NULL;
    }
  if ((*die)->removed)
    {
      decl_die_table->clear_slot (die);
      return NULL;
    }
  return *die;
}


/* Return the DIE associated with BLOCK.  */

static inline dw_die_ref
lookup_block_die (tree block)
{
  dw_die_ref die = BLOCK_DIE (block);
  if (!die && in_lto_p)
    return maybe_create_die_with_external_ref (block);
  return die;
}

/* Associate DIE with BLOCK.  */

static inline void
equate_block_to_die (tree block, dw_die_ref die)
{
  BLOCK_DIE (block) = die;
}
#undef BLOCK_DIE


/* For DECL which might have early dwarf output query a SYMBOL + OFFSET
   style reference.  Return true if we found one refering to a DIE for
   DECL, otherwise return false.  */

static bool
dwarf2out_die_ref_for_decl (tree decl, const char **sym,
			    unsigned HOST_WIDE_INT *off)
{
  dw_die_ref die;

  if (in_lto_p)
    {
      /* During WPA stage and incremental linking we use a hash-map
	 to store the decl <-> label + offset map.  */
      if (!external_die_map)
	return false;
      sym_off_pair *desc = external_die_map->get (decl);
      if (!desc)
	return false;
      *sym = desc->sym;
      *off = desc->off;
      return true;
    }

  if (TREE_CODE (decl) == BLOCK)
    die = lookup_block_die (decl);
  else
    die = lookup_decl_die (decl);
  if (!die)
    return false;

  /* Similar to get_ref_die_offset_label, but using the "correct"
     label.  */
  *off = die->die_offset;
  while (die->die_parent)
    die = die->die_parent;
  /* For the containing CU DIE we compute a die_symbol in
     compute_comp_unit_symbol.  */
  gcc_assert (die->die_tag == DW_TAG_compile_unit
	      && die->die_id.die_symbol != NULL);
  *sym = die->die_id.die_symbol;
  return true;
}

/* Add a reference of kind ATTR_KIND to a DIE at SYMBOL + OFFSET to DIE.  */

static void
add_AT_external_die_ref (dw_die_ref die, enum dwarf_attribute attr_kind,
			 const char *symbol, HOST_WIDE_INT offset)
{
  /* Create a fake DIE that contains the reference.  Don't use
     new_die because we don't want to end up in the limbo list.  */
  /* ???  We probably want to share these, thus put a ref to the DIE
     we create here to the external_die_map entry.  */
  dw_die_ref ref = new_die_raw (die->die_tag);
  ref->die_id.die_symbol = symbol;
  ref->die_offset = offset;
  ref->with_offset = 1;
  add_AT_die_ref (die, attr_kind, ref);
}

/* Create a DIE for DECL if required and add a reference to a DIE
   at SYMBOL + OFFSET which contains attributes dumped early.  */

static void
dwarf2out_register_external_die (tree decl, const char *sym,
				 unsigned HOST_WIDE_INT off)
{
  if (debug_info_level == DINFO_LEVEL_NONE)
    return;

  if (!external_die_map)
    external_die_map = hash_map<tree, sym_off_pair>::create_ggc (1000);
  gcc_checking_assert (!external_die_map->get (decl));
  sym_off_pair p = { IDENTIFIER_POINTER (get_identifier (sym)), off };
  external_die_map->put (decl, p);
}

/* If we have a registered external DIE for DECL return a new DIE for
   the concrete instance with an appropriate abstract origin.  */

static dw_die_ref
maybe_create_die_with_external_ref (tree decl)
{
  if (!external_die_map)
    return NULL;
  sym_off_pair *desc = external_die_map->get (decl);
  if (!desc)
    return NULL;

  const char *sym = desc->sym;
  unsigned HOST_WIDE_INT off = desc->off;
  external_die_map->remove (decl);

  in_lto_p = false;
  dw_die_ref die = (TREE_CODE (decl) == BLOCK
		    ? lookup_block_die (decl) : lookup_decl_die (decl));
  gcc_assert (!die);
  in_lto_p = true;

  tree ctx;
  dw_die_ref parent = NULL;
  /* Need to lookup a DIE for the decls context - the containing
     function or translation unit.  */
  if (TREE_CODE (decl) == BLOCK)
    {
      ctx = BLOCK_SUPERCONTEXT (decl);
      /* ???  We do not output DIEs for all scopes thus skip as
	 many DIEs as needed.  */
      while (TREE_CODE (ctx) == BLOCK
	     && !lookup_block_die (ctx))
	ctx = BLOCK_SUPERCONTEXT (ctx);
    }
  else
    ctx = DECL_CONTEXT (decl);
  /* Peel types in the context stack.  */
  while (ctx && TYPE_P (ctx))
    ctx = TYPE_CONTEXT (ctx);
  /* Likewise namespaces in case we do not want to emit DIEs for them.  */
  if (debug_info_level <= DINFO_LEVEL_TERSE)
    while (ctx && TREE_CODE (ctx) == NAMESPACE_DECL)
      ctx = DECL_CONTEXT (ctx);
  if (ctx)
    {
      if (TREE_CODE (ctx) == BLOCK)
	parent = lookup_block_die (ctx);
      else if (TREE_CODE (ctx) == TRANSLATION_UNIT_DECL
	       /* Keep the 1:1 association during WPA.  */
	       && !flag_wpa
	       && flag_incremental_link != INCREMENTAL_LINK_LTO)
	/* Otherwise all late annotations go to the main CU which
	   imports the original CUs.  */
	parent = comp_unit_die ();
      else if (TREE_CODE (ctx) == FUNCTION_DECL
	       && TREE_CODE (decl) != FUNCTION_DECL
	       && TREE_CODE (decl) != PARM_DECL
	       && TREE_CODE (decl) != RESULT_DECL
	       && TREE_CODE (decl) != BLOCK)
	/* Leave function local entities parent determination to when
	   we process scope vars.  */
	;
      else
	parent = lookup_decl_die (ctx);
    }
  else
    /* In some cases the FEs fail to set DECL_CONTEXT properly.
       Handle this case gracefully by globalizing stuff.  */
    parent = comp_unit_die ();
  /* Create a DIE "stub".  */
  switch (TREE_CODE (decl))
    {
    case TRANSLATION_UNIT_DECL:
      {
	die = comp_unit_die ();
	/* We re-target all CU decls to the LTRANS CU DIE, so no need
	   to create a DIE for the original CUs.  */
	return die;
      }
    case NAMESPACE_DECL:
      if (is_fortran (decl))
	die = new_die (DW_TAG_module, parent, decl);
      else
	die = new_die (DW_TAG_namespace, parent, decl);
      break;
    case FUNCTION_DECL:
      die = new_die (DW_TAG_subprogram, parent, decl);
      break;
    case VAR_DECL:
      die = new_die (DW_TAG_variable, parent, decl);
      break;
    case RESULT_DECL:
      die = new_die (DW_TAG_variable, parent, decl);
      break;
    case PARM_DECL:
      die = new_die (DW_TAG_formal_parameter, parent, decl);
      break;
    case CONST_DECL:
      die = new_die (DW_TAG_constant, parent, decl);
      break;
    case LABEL_DECL:
      die = new_die (DW_TAG_label, parent, decl);
      break;
    case BLOCK:
      die = new_die (DW_TAG_lexical_block, parent, decl);
      break;
    default:
      gcc_unreachable ();
    }
  if (TREE_CODE (decl) == BLOCK)
    equate_block_to_die (decl, die);
  else
    equate_decl_number_to_die (decl, die);

  add_desc_attribute (die, decl);

  /* Add a reference to the DIE providing early debug at $sym + off.  */
  add_AT_external_die_ref (die, DW_AT_abstract_origin, sym, off);

  return die;
}

/* Returns a hash value for X (which really is a var_loc_list).  */

inline hashval_t
decl_loc_hasher::hash (var_loc_list *x)
{
  return (hashval_t) x->decl_id;
}

/* Return nonzero if decl_id of var_loc_list X is the same as
   UID of decl *Y.  */

inline bool
decl_loc_hasher::equal (var_loc_list *x, const_tree y)
{
  return (x->decl_id == DECL_UID (y));
}

/* Return the var_loc list associated with a given declaration.  */

static inline var_loc_list *
lookup_decl_loc (const_tree decl)
{
  if (!decl_loc_table)
    return NULL;
  return decl_loc_table->find_with_hash (decl, DECL_UID (decl));
}

/* Returns a hash value for X (which really is a cached_dw_loc_list_list).  */

inline hashval_t
dw_loc_list_hasher::hash (cached_dw_loc_list *x)
{
  return (hashval_t) x->decl_id;
}

/* Return nonzero if decl_id of cached_dw_loc_list X is the same as
   UID of decl *Y.  */

inline bool
dw_loc_list_hasher::equal (cached_dw_loc_list *x, const_tree y)
{
  return (x->decl_id == DECL_UID (y));
}

/* Equate a DIE to a particular declaration.  */

static void
equate_decl_number_to_die (tree decl, dw_die_ref decl_die)
{
  unsigned int decl_id = DECL_UID (decl);

  *decl_die_table->find_slot_with_hash (decl, decl_id, INSERT) = decl_die;
  decl_die->decl_id = decl_id;
}

/* Return how many bits covers PIECE EXPR_LIST.  */

static HOST_WIDE_INT
decl_piece_bitsize (rtx piece)
{
  int ret = (int) GET_MODE (piece);
  if (ret)
    return ret;
  gcc_assert (GET_CODE (XEXP (piece, 0)) == CONCAT
	      && CONST_INT_P (XEXP (XEXP (piece, 0), 0)));
  return INTVAL (XEXP (XEXP (piece, 0), 0));
}

/* Return pointer to the location of location note in PIECE EXPR_LIST.  */

static rtx *
decl_piece_varloc_ptr (rtx piece)
{
  if ((int) GET_MODE (piece))
    return &XEXP (piece, 0);
  else
    return &XEXP (XEXP (piece, 0), 1);
}

/* Create an EXPR_LIST for location note LOC_NOTE covering BITSIZE bits.
   Next is the chain of following piece nodes.  */

static rtx_expr_list *
decl_piece_node (rtx loc_note, HOST_WIDE_INT bitsize, rtx next)
{
  if (bitsize > 0 && bitsize <= (int) MAX_MACHINE_MODE)
    return alloc_EXPR_LIST (bitsize, loc_note, next);
  else
    return alloc_EXPR_LIST (0, gen_rtx_CONCAT (VOIDmode,
					       GEN_INT (bitsize),
					       loc_note), next);
}

/* Return rtx that should be stored into loc field for
   LOC_NOTE and BITPOS/BITSIZE.  */

static rtx
construct_piece_list (rtx loc_note, HOST_WIDE_INT bitpos,
		      HOST_WIDE_INT bitsize)
{
  if (bitsize != -1)
    {
      loc_note = decl_piece_node (loc_note, bitsize, NULL_RTX);
      if (bitpos != 0)
	loc_note = decl_piece_node (NULL_RTX, bitpos, loc_note);
    }
  return loc_note;
}

/* This function either modifies location piece list *DEST in
   place (if SRC and INNER is NULL), or copies location piece list
   *SRC to *DEST while modifying it.  Location BITPOS is modified
   to contain LOC_NOTE, any pieces overlapping it are removed resp.
   not copied and if needed some padding around it is added.
   When modifying in place, DEST should point to EXPR_LIST where
   earlier pieces cover PIECE_BITPOS bits, when copying SRC points
   to the start of the whole list and INNER points to the EXPR_LIST
   where earlier pieces cover PIECE_BITPOS bits.  */

static void
adjust_piece_list (rtx *dest, rtx *src, rtx *inner,
		   HOST_WIDE_INT bitpos, HOST_WIDE_INT piece_bitpos,
		   HOST_WIDE_INT bitsize, rtx loc_note)
{
  HOST_WIDE_INT diff;
  bool copy = inner != NULL;

  if (copy)
    {
      /* First copy all nodes preceding the current bitpos.  */
      while (src != inner)
	{
	  *dest = decl_piece_node (*decl_piece_varloc_ptr (*src),
				   decl_piece_bitsize (*src), NULL_RTX);
	  dest = &XEXP (*dest, 1);
	  src = &XEXP (*src, 1);
	}
    }
  /* Add padding if needed.  */
  if (bitpos != piece_bitpos)
    {
      *dest = decl_piece_node (NULL_RTX, bitpos - piece_bitpos,
			       copy ? NULL_RTX : *dest);
      dest = &XEXP (*dest, 1);
    }
  else if (*dest && decl_piece_bitsize (*dest) == bitsize)
    {
      gcc_assert (!copy);
      /* A piece with correct bitpos and bitsize already exist,
	 just update the location for it and return.  */
      *decl_piece_varloc_ptr (*dest) = loc_note;
      return;
    }
  /* Add the piece that changed.  */
  *dest = decl_piece_node (loc_note, bitsize, copy ? NULL_RTX : *dest);
  dest = &XEXP (*dest, 1);
  /* Skip over pieces that overlap it.  */
  diff = bitpos - piece_bitpos + bitsize;
  if (!copy)
    src = dest;
  while (diff > 0 && *src)
    {
      rtx piece = *src;
      diff -= decl_piece_bitsize (piece);
      if (copy)
	src = &XEXP (piece, 1);
      else
	{
	  *src = XEXP (piece, 1);
	  free_EXPR_LIST_node (piece);
	}
    }
  /* Add padding if needed.  */
  if (diff < 0 && *src)
    {
      if (!copy)
	dest = src;
      *dest = decl_piece_node (NULL_RTX, -diff, copy ? NULL_RTX : *dest);
      dest = &XEXP (*dest, 1);
    }
  if (!copy)
    return;
  /* Finally copy all nodes following it.  */
  while (*src)
    {
      *dest = decl_piece_node (*decl_piece_varloc_ptr (*src),
			       decl_piece_bitsize (*src), NULL_RTX);
      dest = &XEXP (*dest, 1);
      src = &XEXP (*src, 1);
    }
}

/* Add a variable location node to the linked list for DECL.  */

static struct var_loc_node *
add_var_loc_to_decl (tree decl, rtx loc_note, const char *label, var_loc_view view)
{
  unsigned int decl_id;
  var_loc_list *temp;
  struct var_loc_node *loc = NULL;
  HOST_WIDE_INT bitsize = -1, bitpos = -1;

  if (VAR_P (decl) && DECL_HAS_DEBUG_EXPR_P (decl))
    {
      tree realdecl = DECL_DEBUG_EXPR (decl);
      if (handled_component_p (realdecl)
	  || (TREE_CODE (realdecl) == MEM_REF
	      && TREE_CODE (TREE_OPERAND (realdecl, 0)) == ADDR_EXPR))
	{
	  bool reverse;
	  tree innerdecl = get_ref_base_and_extent_hwi (realdecl, &bitpos,
							&bitsize, &reverse);
	  if (!innerdecl
	      || !DECL_P (innerdecl)
	      || DECL_IGNORED_P (innerdecl)
	      || TREE_STATIC (innerdecl)
	      || bitsize == 0
	      || bitpos + bitsize > 256)
	    return NULL;
	  decl = innerdecl;
	}
    }

  decl_id = DECL_UID (decl);
  var_loc_list **slot
    = decl_loc_table->find_slot_with_hash (decl, decl_id, INSERT);
  if (*slot == NULL)
    {
      temp = ggc_cleared_alloc<var_loc_list> ();
      temp->decl_id = decl_id;
      *slot = temp;
    }
  else
    temp = *slot;

  /* For PARM_DECLs try to keep around the original incoming value,
     even if that means we'll emit a zero-range .debug_loc entry.  */
  if (temp->last
      && temp->first == temp->last
      && TREE_CODE (decl) == PARM_DECL
      && NOTE_P (temp->first->loc)
      && NOTE_VAR_LOCATION_DECL (temp->first->loc) == decl
      && DECL_INCOMING_RTL (decl)
      && NOTE_VAR_LOCATION_LOC (temp->first->loc)
      && GET_CODE (NOTE_VAR_LOCATION_LOC (temp->first->loc))
	 == GET_CODE (DECL_INCOMING_RTL (decl))
      && prev_real_insn (as_a<rtx_insn *> (temp->first->loc)) == NULL_RTX
      && (bitsize != -1
	  || !rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->first->loc),
			   NOTE_VAR_LOCATION_LOC (loc_note))
	  || (NOTE_VAR_LOCATION_STATUS (temp->first->loc)
	      != NOTE_VAR_LOCATION_STATUS (loc_note))))
    {
      loc = ggc_cleared_alloc<var_loc_node> ();
      temp->first->next = loc;
      temp->last = loc;
      loc->loc = construct_piece_list (loc_note, bitpos, bitsize);
    }
  else if (temp->last)
    {
      struct var_loc_node *last = temp->last, *unused = NULL;
      rtx *piece_loc = NULL, last_loc_note;
      HOST_WIDE_INT piece_bitpos = 0;
      if (last->next)
	{
	  last = last->next;
	  gcc_assert (last->next == NULL);
	}
      if (bitsize != -1 && GET_CODE (last->loc) == EXPR_LIST)
	{
	  piece_loc = &last->loc;
	  do
	    {
	      HOST_WIDE_INT cur_bitsize = decl_piece_bitsize (*piece_loc);
	      if (piece_bitpos + cur_bitsize > bitpos)
		break;
	      piece_bitpos += cur_bitsize;
	      piece_loc = &XEXP (*piece_loc, 1);
	    }
	  while (*piece_loc);
	}
      /* TEMP->LAST here is either pointer to the last but one or
	 last element in the chained list, LAST is pointer to the
	 last element.  */
      if (label && strcmp (last->label, label) == 0 && last->view == view)
	{
	  /* For SRA optimized variables if there weren't any real
	     insns since last note, just modify the last node.  */
	  if (piece_loc != NULL)
	    {
	      adjust_piece_list (piece_loc, NULL, NULL,
				 bitpos, piece_bitpos, bitsize, loc_note);
	      return NULL;
	    }
	  /* If the last note doesn't cover any instructions, remove it.  */
	  if (temp->last != last)
	    {
	      temp->last->next = NULL;
	      unused = last;
	      last = temp->last;
	      gcc_assert (strcmp (last->label, label) != 0 || last->view != view);
	    }
	  else
	    {
	      gcc_assert (temp->first == temp->last
			  || (temp->first->next == temp->last
			      && TREE_CODE (decl) == PARM_DECL));
	      memset (temp->last, '\0', sizeof (*temp->last));
	      temp->last->loc = construct_piece_list (loc_note, bitpos, bitsize);
	      return temp->last;
	    }
	}
      if (bitsize == -1 && NOTE_P (last->loc))
	last_loc_note = last->loc;
      else if (piece_loc != NULL
	       && *piece_loc != NULL_RTX
	       && piece_bitpos == bitpos
	       && decl_piece_bitsize (*piece_loc) == bitsize)
	last_loc_note = *decl_piece_varloc_ptr (*piece_loc);
      else
	last_loc_note = NULL_RTX;
      /* If the current location is the same as the end of the list,
	 and either both or neither of the locations is uninitialized,
	 we have nothing to do.  */
      if (last_loc_note == NULL_RTX
	  || (!rtx_equal_p (NOTE_VAR_LOCATION_LOC (last_loc_note),
			    NOTE_VAR_LOCATION_LOC (loc_note)))
	  || ((NOTE_VAR_LOCATION_STATUS (last_loc_note)
	       != NOTE_VAR_LOCATION_STATUS (loc_note))
	      && ((NOTE_VAR_LOCATION_STATUS (last_loc_note)
		   == VAR_INIT_STATUS_UNINITIALIZED)
		  || (NOTE_VAR_LOCATION_STATUS (loc_note)
		      == VAR_INIT_STATUS_UNINITIALIZED))))
	{
	  /* Add LOC to the end of list and update LAST.  If the last
	     element of the list has been removed above, reuse its
	     memory for the new node, otherwise allocate a new one.  */
	  if (unused)
	    {
	      loc = unused;
	      memset (loc, '\0', sizeof (*loc));
	    }
	  else
	    loc = ggc_cleared_alloc<var_loc_node> ();
	  if (bitsize == -1 || piece_loc == NULL)
	    loc->loc = construct_piece_list (loc_note, bitpos, bitsize);
	  else
	    adjust_piece_list (&loc->loc, &last->loc, piece_loc,
			       bitpos, piece_bitpos, bitsize, loc_note);
	  last->next = loc;
	  /* Ensure TEMP->LAST will point either to the new last but one
	     element of the chain, or to the last element in it.  */
	  if (last != temp->last)
	    temp->last = last;
	}
      else if (unused)
	ggc_free (unused);
    }
  else
    {
      loc = ggc_cleared_alloc<var_loc_node> ();
      temp->first = loc;
      temp->last = loc;
      loc->loc = construct_piece_list (loc_note, bitpos, bitsize);
    }
  return loc;
}

/* Keep track of the number of spaces used to indent the
   output of the debugging routines that print the structure of
   the DIE internal representation.  */
static int print_indent;

/* Indent the line the number of spaces given by print_indent.  */

static inline void
print_spaces (FILE *outfile)
{
  fprintf (outfile, "%*s", print_indent, "");
}

/* Print a type signature in hex.  */

static inline void
print_signature (FILE *outfile, char *sig)
{
  int i;

  for (i = 0; i < DWARF_TYPE_SIGNATURE_SIZE; i++)
    fprintf (outfile, "%02x", sig[i] & 0xff);
}

static inline void
print_discr_value (FILE *outfile, dw_discr_value *discr_value)
{
  if (discr_value->pos)
    fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, discr_value->v.sval);
  else
    fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, discr_value->v.uval);
}

static void print_loc_descr (dw_loc_descr_ref, FILE *);

/* Print the value associated to the VAL DWARF value node to OUTFILE.  If
   RECURSE, output location descriptor operations.  */

static void
print_dw_val (dw_val_node *val, bool recurse, FILE *outfile)
{
  switch (val->val_class)
    {
    case dw_val_class_addr:
      fprintf (outfile, "address");
      break;
    case dw_val_class_offset:
      fprintf (outfile, "offset");
      break;
    case dw_val_class_loc:
      fprintf (outfile, "location descriptor");
      if (val->v.val_loc == NULL)
	fprintf (outfile, " -> <null>\n");
      else if (recurse)
	{
	  fprintf (outfile, ":\n");
	  print_indent += 4;
	  print_loc_descr (val->v.val_loc, outfile);
	  print_indent -= 4;
	}
      else
	{
	  if (flag_dump_noaddr || flag_dump_unnumbered)
	    fprintf (outfile, " #\n");
	  else
	    fprintf (outfile, " (%p)\n", (void *) val->v.val_loc);
	}
      break;
    case dw_val_class_loc_list:
      fprintf (outfile, "location list -> label:%s",
	       val->v.val_loc_list->ll_symbol);
      break;
    case dw_val_class_view_list:
      val = view_list_to_loc_list_val_node (val);
      fprintf (outfile, "location list with views -> labels:%s and %s",
	       val->v.val_loc_list->ll_symbol,
	       val->v.val_loc_list->vl_symbol);
      break;
    case dw_val_class_range_list:
      fprintf (outfile, "range list");
      break;
    case dw_val_class_const:
    case dw_val_class_const_implicit:
      fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, val->v.val_int);
      break;
    case dw_val_class_unsigned_const:
    case dw_val_class_unsigned_const_implicit:
      fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, val->v.val_unsigned);
      break;
    case dw_val_class_const_double:
      fprintf (outfile, "constant (" HOST_WIDE_INT_PRINT_DEC","\
			HOST_WIDE_INT_PRINT_UNSIGNED")",
	       val->v.val_double.high,
	       val->v.val_double.low);
      break;
    case dw_val_class_wide_int:
      {
	int i = val->v.val_wide->get_len ();
	fprintf (outfile, "constant (");
	gcc_assert (i > 0);
	if (val->v.val_wide->elt (i - 1) == 0)
	  fprintf (outfile, "0x");
	fprintf (outfile, HOST_WIDE_INT_PRINT_HEX,
		 val->v.val_wide->elt (--i));
	while (--i >= 0)
	  fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX,
		   val->v.val_wide->elt (i));
	fprintf (outfile, ")");
	break;
      }
    case dw_val_class_vec:
      fprintf (outfile, "floating-point or vector constant");
      break;
    case dw_val_class_flag:
      fprintf (outfile, "%u", val->v.val_flag);
      break;
    case dw_val_class_die_ref:
      if (val->v.val_die_ref.die != NULL)
	{
	  dw_die_ref die = val->v.val_die_ref.die;

	  if (die->comdat_type_p)
	    {
	      fprintf (outfile, "die -> signature: ");
	      print_signature (outfile,
			       die->die_id.die_type_node->signature);
	    }
	  else if (die->die_id.die_symbol)
	    {
	      fprintf (outfile, "die -> label: %s", die->die_id.die_symbol);
	      if (die->with_offset)
		fprintf (outfile, " + %ld", die->die_offset);
	    }
	  else
	    fprintf (outfile, "die -> %ld", die->die_offset);
	  if (flag_dump_noaddr || flag_dump_unnumbered)
	    fprintf (outfile, " #");
	  else
	    fprintf (outfile, " (%p)", (void *) die);
	}
      else
	fprintf (outfile, "die -> <null>");
      break;
    case dw_val_class_vms_delta:
      fprintf (outfile, "delta: @slotcount(%s-%s)",
	       val->v.val_vms_delta.lbl2, val->v.val_vms_delta.lbl1);
      break;
    case dw_val_class_symview:
      fprintf (outfile, "view: %s", val->v.val_symbolic_view);
      break;
    case dw_val_class_lbl_id:
    case dw_val_class_lineptr:
    case dw_val_class_macptr:
    case dw_val_class_loclistsptr:
    case dw_val_class_high_pc:
      fprintf (outfile, "label: %s", val->v.val_lbl_id);
      break;
    case dw_val_class_str:
      if (val->v.val_str->str != NULL)
	fprintf (outfile, "\"%s\"", val->v.val_str->str);
      else
	fprintf (outfile, "<null>");
      break;
    case dw_val_class_file:
    case dw_val_class_file_implicit:
      fprintf (outfile, "\"%s\" (%d)", val->v.val_file->filename,
	       val->v.val_file->emitted_number);
      break;
    case dw_val_class_data8:
      {
	int i;

	for (i = 0; i < 8; i++)
	  fprintf (outfile, "%02x", val->v.val_data8[i]);
	break;
      }
    case dw_val_class_discr_value:
      print_discr_value (outfile, &val->v.val_discr_value);
      break;
    case dw_val_class_discr_list:
      for (dw_discr_list_ref node = val->v.val_discr_list;
	   node != NULL;
	   node = node->dw_discr_next)
	{
	  if (node->dw_discr_range)
	    {
	      fprintf (outfile, " .. ");
	      print_discr_value (outfile, &node->dw_discr_lower_bound);
	      print_discr_value (outfile, &node->dw_discr_upper_bound);
	    }
	  else
	    print_discr_value (outfile, &node->dw_discr_lower_bound);

	  if (node->dw_discr_next != NULL)
	    fprintf (outfile, " | ");
	}
    default:
      break;
    }
}

/* Likewise, for a DIE attribute.  */

static void
print_attribute (dw_attr_node *a, bool recurse, FILE *outfile)
{
  print_dw_val (&a->dw_attr_val, recurse, outfile);
}


/* Print the list of operands in the LOC location description to OUTFILE.  This
   routine is a debugging aid only.  */

static void
print_loc_descr (dw_loc_descr_ref loc, FILE *outfile)
{
  dw_loc_descr_ref l = loc;

  if (loc == NULL)
    {
      print_spaces (outfile);
      fprintf (outfile, "<null>\n");
      return;
    }

  for (l = loc; l != NULL; l = l->dw_loc_next)
    {
      print_spaces (outfile);
      if (flag_dump_noaddr || flag_dump_unnumbered)
	fprintf (outfile, "#");
      else
	fprintf (outfile, "(%p)", (void *) l);
      fprintf (outfile, " %s",
	       dwarf_stack_op_name (l->dw_loc_opc));
      if (l->dw_loc_oprnd1.val_class != dw_val_class_none)
	{
	  fprintf (outfile, " ");
	  print_dw_val (&l->dw_loc_oprnd1, false, outfile);
	}
      if (l->dw_loc_oprnd2.val_class != dw_val_class_none)
	{
	  fprintf (outfile, ", ");
	  print_dw_val (&l->dw_loc_oprnd2, false, outfile);
	}
      fprintf (outfile, "\n");
    }
}

/* Print the information associated with a given DIE, and its children.
   This routine is a debugging aid only.  */

static void
print_die (dw_die_ref die, FILE *outfile)
{
  dw_attr_node *a;
  dw_die_ref c;
  unsigned ix;

  print_spaces (outfile);
  fprintf (outfile, "DIE %4ld: %s ",
	   die->die_offset, dwarf_tag_name (die->die_tag));
  if (flag_dump_noaddr || flag_dump_unnumbered)
    fprintf (outfile, "#\n");
  else
    fprintf (outfile, "(%p)\n", (void*) die);
  print_spaces (outfile);
  fprintf (outfile, "  abbrev id: %lu", die->die_abbrev);
  fprintf (outfile, " offset: %ld", die->die_offset);
  fprintf (outfile, " mark: %d\n", die->die_mark);

  if (die->comdat_type_p)
    {
      print_spaces (outfile);
      fprintf (outfile, "  signature: ");
      print_signature (outfile, die->die_id.die_type_node->signature);
      fprintf (outfile, "\n");
    }

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    {
      print_spaces (outfile);
      fprintf (outfile, "  %s: ", dwarf_attr_name (a->dw_attr));

      print_attribute (a, true, outfile);
      fprintf (outfile, "\n");
    }

  if (die->die_child != NULL)
    {
      print_indent += 4;
      FOR_EACH_CHILD (die, c, print_die (c, outfile));
      print_indent -= 4;
    }
  if (print_indent == 0)
    fprintf (outfile, "\n");
}

/* Print the list of operations in the LOC location description.  */

DEBUG_FUNCTION void
debug_dwarf_loc_descr (dw_loc_descr_ref loc)
{
  print_loc_descr (loc, stderr);
}

/* Print the information collected for a given DIE.  */

DEBUG_FUNCTION void
debug_dwarf_die (dw_die_ref die)
{
  print_die (die, stderr);
}

DEBUG_FUNCTION void
debug (die_struct &ref)
{
  print_die (&ref, stderr);
}

DEBUG_FUNCTION void
debug (die_struct *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}


/* Print all DWARF information collected for the compilation unit.
   This routine is a debugging aid only.  */

DEBUG_FUNCTION void
debug_dwarf (void)
{
  print_indent = 0;
  print_die (comp_unit_die (), stderr);
}

/* Verify the DIE tree structure.  */

DEBUG_FUNCTION void
verify_die (dw_die_ref die)
{
  gcc_assert (!die->die_mark);
  if (die->die_parent == NULL
      && die->die_sib == NULL)
    return;
  /* Verify the die_sib list is cyclic.  */
  dw_die_ref x = die;
  do
    {
      x->die_mark = 1;
      x = x->die_sib;
    }
  while (x && !x->die_mark);
  gcc_assert (x == die);
  x = die;
  do
    {
      /* Verify all dies have the same parent.  */
      gcc_assert (x->die_parent == die->die_parent);
      if (x->die_child)
	{
	  /* Verify the child has the proper parent and recurse.  */
	  gcc_assert (x->die_child->die_parent == x);
	  verify_die (x->die_child);
	}
      x->die_mark = 0;
      x = x->die_sib;
    }
  while (x && x->die_mark);
}

/* Sanity checks on DIEs.  */

static void
check_die (dw_die_ref die)
{
  unsigned ix;
  dw_attr_node *a;
  bool inline_found = false;
  int n_location = 0, n_low_pc = 0, n_high_pc = 0, n_artificial = 0;
  int n_decl_line = 0, n_decl_column = 0, n_decl_file = 0;
  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    {
      switch (a->dw_attr)
	{
	case DW_AT_inline:
	  if (a->dw_attr_val.v.val_unsigned)
	    inline_found = true;
	  break;
	case DW_AT_location:
	  ++n_location;
	  break;
	case DW_AT_low_pc:
	  ++n_low_pc;
	  break;
	case DW_AT_high_pc:
	  ++n_high_pc;
	  break;
	case DW_AT_artificial:
	  ++n_artificial;
	  break;
        case DW_AT_decl_column:
	  ++n_decl_column;
	  break;
	case DW_AT_decl_line:
	  ++n_decl_line;
	  break;
	case DW_AT_decl_file:
	  ++n_decl_file;
	  break;
	default:
	  break;
	}
    }
  if (n_location > 1 || n_low_pc > 1 || n_high_pc > 1 || n_artificial > 1
      || n_decl_column > 1 || n_decl_line > 1 || n_decl_file > 1)
    {
      fprintf (stderr, "Duplicate attributes in DIE:\n");
      debug_dwarf_die (die);
      gcc_unreachable ();
    }
  if (inline_found)
    {
      /* A debugging information entry that is a member of an abstract
	 instance tree [that has DW_AT_inline] should not contain any
	 attributes which describe aspects of the subroutine which vary
	 between distinct inlined expansions or distinct out-of-line
	 expansions.  */
      FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
	gcc_assert (a->dw_attr != DW_AT_low_pc
		    && a->dw_attr != DW_AT_high_pc
		    && a->dw_attr != DW_AT_location
		    && a->dw_attr != DW_AT_frame_base
		    && a->dw_attr != DW_AT_call_all_calls
		    && a->dw_attr != DW_AT_GNU_all_call_sites);
    }
}

#define CHECKSUM(FOO) md5_process_bytes (&(FOO), sizeof (FOO), ctx)
#define CHECKSUM_BLOCK(FOO, SIZE) md5_process_bytes ((FOO), (SIZE), ctx)
#define CHECKSUM_STRING(FOO) md5_process_bytes ((FOO), strlen (FOO), ctx)

/* Calculate the checksum of a location expression.  */

static inline void
loc_checksum (dw_loc_descr_ref loc, struct md5_ctx *ctx)
{
  int tem;
  inchash::hash hstate;
  hashval_t hash;

  tem = (loc->dtprel << 8) | ((unsigned int) loc->dw_loc_opc);
  CHECKSUM (tem);
  hash_loc_operands (loc, hstate);
  hash = hstate.end();
  CHECKSUM (hash);
}

/* Calculate the checksum of an attribute.  */

static void
attr_checksum (dw_attr_node *at, struct md5_ctx *ctx, int *mark)
{
  dw_loc_descr_ref loc;
  rtx r;

  CHECKSUM (at->dw_attr);

  /* We don't care that this was compiled with a different compiler
     snapshot; if the output is the same, that's what matters.  */
  if (at->dw_attr == DW_AT_producer)
    return;

  switch (AT_class (at))
    {
    case dw_val_class_const:
    case dw_val_class_const_implicit:
      CHECKSUM (at->dw_attr_val.v.val_int);
      break;
    case dw_val_class_unsigned_const:
    case dw_val_class_unsigned_const_implicit:
      CHECKSUM (at->dw_attr_val.v.val_unsigned);
      break;
    case dw_val_class_const_double:
      CHECKSUM (at->dw_attr_val.v.val_double);
      break;
    case dw_val_class_wide_int:
      CHECKSUM_BLOCK (at->dw_attr_val.v.val_wide->get_val (),
		      get_full_len (*at->dw_attr_val.v.val_wide)
		      * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
      break;
    case dw_val_class_vec:
      CHECKSUM_BLOCK (at->dw_attr_val.v.val_vec.array,
		      (at->dw_attr_val.v.val_vec.length
		       * at->dw_attr_val.v.val_vec.elt_size));
      break;
    case dw_val_class_flag:
      CHECKSUM (at->dw_attr_val.v.val_flag);
      break;
    case dw_val_class_str:
      CHECKSUM_STRING (AT_string (at));
      break;

    case dw_val_class_addr:
      r = AT_addr (at);
      gcc_assert (GET_CODE (r) == SYMBOL_REF);
      CHECKSUM_STRING (XSTR (r, 0));
      break;

    case dw_val_class_offset:
      CHECKSUM (at->dw_attr_val.v.val_offset);
      break;

    case dw_val_class_loc:
      for (loc = AT_loc (at); loc; loc = loc->dw_loc_next)
	loc_checksum (loc, ctx);
      break;

    case dw_val_class_die_ref:
      die_checksum (AT_ref (at), ctx, mark);
      break;

    case dw_val_class_fde_ref:
    case dw_val_class_vms_delta:
    case dw_val_class_symview:
    case dw_val_class_lbl_id:
    case dw_val_class_lineptr:
    case dw_val_class_macptr:
    case dw_val_class_loclistsptr:
    case dw_val_class_high_pc:
      break;

    case dw_val_class_file:
    case dw_val_class_file_implicit:
      CHECKSUM_STRING (AT_file (at)->filename);
      break;

    case dw_val_class_data8:
      CHECKSUM (at->dw_attr_val.v.val_data8);
      break;

    default:
      break;
    }
}

/* Calculate the checksum of a DIE.  */

static void
die_checksum (dw_die_ref die, struct md5_ctx *ctx, int *mark)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;

  /* To avoid infinite recursion.  */
  if (die->die_mark)
    {
      CHECKSUM (die->die_mark);
      return;
    }
  die->die_mark = ++(*mark);

  CHECKSUM (die->die_tag);

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    attr_checksum (a, ctx, mark);

  FOR_EACH_CHILD (die, c, die_checksum (c, ctx, mark));
}

#undef CHECKSUM
#undef CHECKSUM_BLOCK
#undef CHECKSUM_STRING

/* For DWARF-4 types, include the trailing NULL when checksumming strings.  */
#define CHECKSUM(FOO) md5_process_bytes (&(FOO), sizeof (FOO), ctx)
#define CHECKSUM_BLOCK(FOO, SIZE) md5_process_bytes ((FOO), (SIZE), ctx)
#define CHECKSUM_STRING(FOO) md5_process_bytes ((FOO), strlen (FOO) + 1, ctx)
#define CHECKSUM_SLEB128(FOO) checksum_sleb128 ((FOO), ctx)
#define CHECKSUM_ULEB128(FOO) checksum_uleb128 ((FOO), ctx)
#define CHECKSUM_ATTR(FOO) \
  if (FOO) attr_checksum_ordered (die->die_tag, (FOO), ctx, mark)

/* Calculate the checksum of a number in signed LEB128 format.  */

static void
checksum_sleb128 (HOST_WIDE_INT value, struct md5_ctx *ctx)
{
  unsigned char byte;
  bool more;

  while (1)
    {
      byte = (value & 0x7f);
      value >>= 7;
      more = !((value == 0 && (byte & 0x40) == 0)
		|| (value == -1 && (byte & 0x40) != 0));
      if (more)
	byte |= 0x80;
      CHECKSUM (byte);
      if (!more)
	break;
    }
}

/* Calculate the checksum of a number in unsigned LEB128 format.  */

static void
checksum_uleb128 (unsigned HOST_WIDE_INT value, struct md5_ctx *ctx)
{
  while (1)
    {
      unsigned char byte = (value & 0x7f);
      value >>= 7;
      if (value != 0)
	/* More bytes to follow.  */
	byte |= 0x80;
      CHECKSUM (byte);
      if (value == 0)
	break;
    }
}

/* Checksum the context of the DIE.  This adds the names of any
   surrounding namespaces or structures to the checksum.  */

static void
checksum_die_context (dw_die_ref die, struct md5_ctx *ctx)
{
  const char *name;
  dw_die_ref spec;
  int tag = die->die_tag;

  if (tag != DW_TAG_namespace
      && tag != DW_TAG_structure_type
      && tag != DW_TAG_class_type)
    return;

  name = get_AT_string (die, DW_AT_name);

  spec = get_AT_ref (die, DW_AT_specification);
  if (spec != NULL)
    die = spec;

  if (die->die_parent != NULL)
    checksum_die_context (die->die_parent, ctx);

  CHECKSUM_ULEB128 ('C');
  CHECKSUM_ULEB128 (tag);
  if (name != NULL)
    CHECKSUM_STRING (name);
}

/* Calculate the checksum of a location expression.  */

static inline void
loc_checksum_ordered (dw_loc_descr_ref loc, struct md5_ctx *ctx)
{
  /* Special case for lone DW_OP_plus_uconst: checksum as if the location
     were emitted as a DW_FORM_sdata instead of a location expression.  */
  if (loc->dw_loc_opc == DW_OP_plus_uconst && loc->dw_loc_next == NULL)
    {
      CHECKSUM_ULEB128 (DW_FORM_sdata);
      CHECKSUM_SLEB128 ((HOST_WIDE_INT) loc->dw_loc_oprnd1.v.val_unsigned);
      return;
    }

  /* Otherwise, just checksum the raw location expression.  */
  while (loc != NULL)
    {
      inchash::hash hstate;
      hashval_t hash;

      CHECKSUM_ULEB128 (loc->dtprel);
      CHECKSUM_ULEB128 (loc->dw_loc_opc);
      hash_loc_operands (loc, hstate);
      hash = hstate.end ();
      CHECKSUM (hash);
      loc = loc->dw_loc_next;
    }
}

/* Calculate the checksum of an attribute.  */

static void
attr_checksum_ordered (enum dwarf_tag tag, dw_attr_node *at,
		       struct md5_ctx *ctx, int *mark)
{
  dw_loc_descr_ref loc;
  rtx r;

  if (AT_class (at) == dw_val_class_die_ref)
    {
      dw_die_ref target_die = AT_ref (at);

      /* For pointer and reference types, we checksum only the (qualified)
	 name of the target type (if there is a name).  For friend entries,
	 we checksum only the (qualified) name of the target type or function.
	 This allows the checksum to remain the same whether the target type
	 is complete or not.  */
      if ((at->dw_attr == DW_AT_type
	   && (tag == DW_TAG_pointer_type
	       || tag == DW_TAG_reference_type
	       || tag == DW_TAG_rvalue_reference_type
	       || tag == DW_TAG_ptr_to_member_type))
	  || (at->dw_attr == DW_AT_friend
	      && tag == DW_TAG_friend))
	{
	  dw_attr_node *name_attr = get_AT (target_die, DW_AT_name);

	  if (name_attr != NULL)
	    {
	      dw_die_ref decl = get_AT_ref (target_die, DW_AT_specification);

	      if (decl == NULL)
		decl = target_die;
	      CHECKSUM_ULEB128 ('N');
	      CHECKSUM_ULEB128 (at->dw_attr);
	      if (decl->die_parent != NULL)
		checksum_die_context (decl->die_parent, ctx);
	      CHECKSUM_ULEB128 ('E');
	      CHECKSUM_STRING (AT_string (name_attr));
	      return;
	    }
	}

      /* For all other references to another DIE, we check to see if the
         target DIE has already been visited.  If it has, we emit a
         backward reference; if not, we descend recursively.  */
      if (target_die->die_mark > 0)
        {
	  CHECKSUM_ULEB128 ('R');
	  CHECKSUM_ULEB128 (at->dw_attr);
	  CHECKSUM_ULEB128 (target_die->die_mark);
        }
      else
        {
	  dw_die_ref decl = get_AT_ref (target_die, DW_AT_specification);

	  if (decl == NULL)
	    decl = target_die;
	  target_die->die_mark = ++(*mark);
	  CHECKSUM_ULEB128 ('T');
	  CHECKSUM_ULEB128 (at->dw_attr);
	  if (decl->die_parent != NULL)
	    checksum_die_context (decl->die_parent, ctx);
	  die_checksum_ordered (target_die, ctx, mark);
        }
      return;
    }

  CHECKSUM_ULEB128 ('A');
  CHECKSUM_ULEB128 (at->dw_attr);

  switch (AT_class (at))
    {
    case dw_val_class_const:
    case dw_val_class_const_implicit:
      CHECKSUM_ULEB128 (DW_FORM_sdata);
      CHECKSUM_SLEB128 (at->dw_attr_val.v.val_int);
      break;

    case dw_val_class_unsigned_const:
    case dw_val_class_unsigned_const_implicit:
      CHECKSUM_ULEB128 (DW_FORM_sdata);
      CHECKSUM_SLEB128 ((int) at->dw_attr_val.v.val_unsigned);
      break;

    case dw_val_class_const_double:
      CHECKSUM_ULEB128 (DW_FORM_block);
      CHECKSUM_ULEB128 (sizeof (at->dw_attr_val.v.val_double));
      CHECKSUM (at->dw_attr_val.v.val_double);
      break;

    case dw_val_class_wide_int:
      CHECKSUM_ULEB128 (DW_FORM_block);
      CHECKSUM_ULEB128 (get_full_len (*at->dw_attr_val.v.val_wide)
			* HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT);
      CHECKSUM_BLOCK (at->dw_attr_val.v.val_wide->get_val (),
		      get_full_len (*at->dw_attr_val.v.val_wide)
		      * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
      break;

    case dw_val_class_vec:
      CHECKSUM_ULEB128 (DW_FORM_block);
      CHECKSUM_ULEB128 (at->dw_attr_val.v.val_vec.length
			* at->dw_attr_val.v.val_vec.elt_size);
      CHECKSUM_BLOCK (at->dw_attr_val.v.val_vec.array,
		      (at->dw_attr_val.v.val_vec.length
		       * at->dw_attr_val.v.val_vec.elt_size));
      break;

    case dw_val_class_flag:
      CHECKSUM_ULEB128 (DW_FORM_flag);
      CHECKSUM_ULEB128 (at->dw_attr_val.v.val_flag ? 1 : 0);
      break;

    case dw_val_class_str:
      CHECKSUM_ULEB128 (DW_FORM_string);
      CHECKSUM_STRING (AT_string (at));
      break;

    case dw_val_class_addr:
      r = AT_addr (at);
      gcc_assert (GET_CODE (r) == SYMBOL_REF);
      CHECKSUM_ULEB128 (DW_FORM_string);
      CHECKSUM_STRING (XSTR (r, 0));
      break;

    case dw_val_class_offset:
      CHECKSUM_ULEB128 (DW_FORM_sdata);
      CHECKSUM_ULEB128 (at->dw_attr_val.v.val_offset);
      break;

    case dw_val_class_loc:
      for (loc = AT_loc (at); loc; loc = loc->dw_loc_next)
	loc_checksum_ordered (loc, ctx);
      break;

    case dw_val_class_fde_ref:
    case dw_val_class_symview:
    case dw_val_class_lbl_id:
    case dw_val_class_lineptr:
    case dw_val_class_macptr:
    case dw_val_class_loclistsptr:
    case dw_val_class_high_pc:
      break;

    case dw_val_class_file:
    case dw_val_class_file_implicit:
      CHECKSUM_ULEB128 (DW_FORM_string);
      CHECKSUM_STRING (AT_file (at)->filename);
      break;

    case dw_val_class_data8:
      CHECKSUM (at->dw_attr_val.v.val_data8);
      break;

    default:
      break;
    }
}

struct checksum_attributes
{
  dw_attr_node *at_name;
  dw_attr_node *at_type;
  dw_attr_node *at_friend;
  dw_attr_node *at_accessibility;
  dw_attr_node *at_address_class;
  dw_attr_node *at_alignment;
  dw_attr_node *at_allocated;
  dw_attr_node *at_artificial;
  dw_attr_node *at_associated;
  dw_attr_node *at_binary_scale;
  dw_attr_node *at_bit_offset;
  dw_attr_node *at_bit_size;
  dw_attr_node *at_bit_stride;
  dw_attr_node *at_byte_size;
  dw_attr_node *at_byte_stride;
  dw_attr_node *at_const_value;
  dw_attr_node *at_containing_type;
  dw_attr_node *at_count;
  dw_attr_node *at_data_location;
  dw_attr_node *at_data_member_location;
  dw_attr_node *at_decimal_scale;
  dw_attr_node *at_decimal_sign;
  dw_attr_node *at_default_value;
  dw_attr_node *at_digit_count;
  dw_attr_node *at_discr;
  dw_attr_node *at_discr_list;
  dw_attr_node *at_discr_value;
  dw_attr_node *at_encoding;
  dw_attr_node *at_endianity;
  dw_attr_node *at_explicit;
  dw_attr_node *at_is_optional;
  dw_attr_node *at_location;
  dw_attr_node *at_lower_bound;
  dw_attr_node *at_mutable;
  dw_attr_node *at_ordering;
  dw_attr_node *at_picture_string;
  dw_attr_node *at_prototyped;
  dw_attr_node *at_small;
  dw_attr_node *at_segment;
  dw_attr_node *at_string_length;
  dw_attr_node *at_string_length_bit_size;
  dw_attr_node *at_string_length_byte_size;
  dw_attr_node *at_threads_scaled;
  dw_attr_node *at_upper_bound;
  dw_attr_node *at_use_location;
  dw_attr_node *at_use_UTF8;
  dw_attr_node *at_variable_parameter;
  dw_attr_node *at_virtuality;
  dw_attr_node *at_visibility;
  dw_attr_node *at_vtable_elem_location;
};

/* Collect the attributes that we will want to use for the checksum.  */

static void
collect_checksum_attributes (struct checksum_attributes *attrs, dw_die_ref die)
{
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    {
      switch (a->dw_attr)
        {
        case DW_AT_name:
          attrs->at_name = a;
          break;
        case DW_AT_type:
          attrs->at_type = a;
          break;
        case DW_AT_friend:
          attrs->at_friend = a;
          break;
        case DW_AT_accessibility:
          attrs->at_accessibility = a;
          break;
        case DW_AT_address_class:
          attrs->at_address_class = a;
          break;
	case DW_AT_alignment:
	  attrs->at_alignment = a;
	  break;
        case DW_AT_allocated:
          attrs->at_allocated = a;
          break;
        case DW_AT_artificial:
          attrs->at_artificial = a;
          break;
        case DW_AT_associated:
          attrs->at_associated = a;
          break;
        case DW_AT_binary_scale:
          attrs->at_binary_scale = a;
          break;
        case DW_AT_bit_offset:
          attrs->at_bit_offset = a;
          break;
        case DW_AT_bit_size:
          attrs->at_bit_size = a;
          break;
        case DW_AT_bit_stride:
          attrs->at_bit_stride = a;
          break;
        case DW_AT_byte_size:
          attrs->at_byte_size = a;
          break;
        case DW_AT_byte_stride:
          attrs->at_byte_stride = a;
          break;
        case DW_AT_const_value:
          attrs->at_const_value = a;
          break;
        case DW_AT_containing_type:
          attrs->at_containing_type = a;
          break;
        case DW_AT_count:
          attrs->at_count = a;
          break;
        case DW_AT_data_location:
          attrs->at_data_location = a;
          break;
        case DW_AT_data_member_location:
          attrs->at_data_member_location = a;
          break;
        case DW_AT_decimal_scale:
          attrs->at_decimal_scale = a;
          break;
        case DW_AT_decimal_sign:
          attrs->at_decimal_sign = a;
          break;
        case DW_AT_default_value:
          attrs->at_default_value = a;
          break;
        case DW_AT_digit_count:
          attrs->at_digit_count = a;
          break;
        case DW_AT_discr:
          attrs->at_discr = a;
          break;
        case DW_AT_discr_list:
          attrs->at_discr_list = a;
          break;
        case DW_AT_discr_value:
          attrs->at_discr_value = a;
          break;
        case DW_AT_encoding:
          attrs->at_encoding = a;
          break;
        case DW_AT_endianity:
          attrs->at_endianity = a;
          break;
        case DW_AT_explicit:
          attrs->at_explicit = a;
          break;
        case DW_AT_is_optional:
          attrs->at_is_optional = a;
          break;
        case DW_AT_location:
          attrs->at_location = a;
          break;
        case DW_AT_lower_bound:
          attrs->at_lower_bound = a;
          break;
        case DW_AT_mutable:
          attrs->at_mutable = a;
          break;
        case DW_AT_ordering:
          attrs->at_ordering = a;
          break;
        case DW_AT_picture_string:
          attrs->at_picture_string = a;
          break;
        case DW_AT_prototyped:
          attrs->at_prototyped = a;
          break;
        case DW_AT_small:
          attrs->at_small = a;
          break;
        case DW_AT_segment:
          attrs->at_segment = a;
          break;
        case DW_AT_string_length:
          attrs->at_string_length = a;
          break;
	case DW_AT_string_length_bit_size:
	  attrs->at_string_length_bit_size = a;
	  break;
	case DW_AT_string_length_byte_size:
	  attrs->at_string_length_byte_size = a;
	  break;
        case DW_AT_threads_scaled:
          attrs->at_threads_scaled = a;
          break;
        case DW_AT_upper_bound:
          attrs->at_upper_bound = a;
          break;
        case DW_AT_use_location:
          attrs->at_use_location = a;
          break;
        case DW_AT_use_UTF8:
          attrs->at_use_UTF8 = a;
          break;
        case DW_AT_variable_parameter:
          attrs->at_variable_parameter = a;
          break;
        case DW_AT_virtuality:
          attrs->at_virtuality = a;
          break;
        case DW_AT_visibility:
          attrs->at_visibility = a;
          break;
        case DW_AT_vtable_elem_location:
          attrs->at_vtable_elem_location = a;
          break;
        default:
          break;
        }
    }
}

/* Calculate the checksum of a DIE, using an ordered subset of attributes.  */

static void
die_checksum_ordered (dw_die_ref die, struct md5_ctx *ctx, int *mark)
{
  dw_die_ref c;
  dw_die_ref decl;
  struct checksum_attributes attrs;

  CHECKSUM_ULEB128 ('D');
  CHECKSUM_ULEB128 (die->die_tag);

  memset (&attrs, 0, sizeof (attrs));

  decl = get_AT_ref (die, DW_AT_specification);
  if (decl != NULL)
    collect_checksum_attributes (&attrs, decl);
  collect_checksum_attributes (&attrs, die);

  CHECKSUM_ATTR (attrs.at_name);
  CHECKSUM_ATTR (attrs.at_accessibility);
  CHECKSUM_ATTR (attrs.at_address_class);
  CHECKSUM_ATTR (attrs.at_allocated);
  CHECKSUM_ATTR (attrs.at_artificial);
  CHECKSUM_ATTR (attrs.at_associated);
  CHECKSUM_ATTR (attrs.at_binary_scale);
  CHECKSUM_ATTR (attrs.at_bit_offset);
  CHECKSUM_ATTR (attrs.at_bit_size);
  CHECKSUM_ATTR (attrs.at_bit_stride);
  CHECKSUM_ATTR (attrs.at_byte_size);
  CHECKSUM_ATTR (attrs.at_byte_stride);
  CHECKSUM_ATTR (attrs.at_const_value);
  CHECKSUM_ATTR (attrs.at_containing_type);
  CHECKSUM_ATTR (attrs.at_count);
  CHECKSUM_ATTR (attrs.at_data_location);
  CHECKSUM_ATTR (attrs.at_data_member_location);
  CHECKSUM_ATTR (attrs.at_decimal_scale);
  CHECKSUM_ATTR (attrs.at_decimal_sign);
  CHECKSUM_ATTR (attrs.at_default_value);
  CHECKSUM_ATTR (attrs.at_digit_count);
  CHECKSUM_ATTR (attrs.at_discr);
  CHECKSUM_ATTR (attrs.at_discr_list);
  CHECKSUM_ATTR (attrs.at_discr_value);
  CHECKSUM_ATTR (attrs.at_encoding);
  CHECKSUM_ATTR (attrs.at_endianity);
  CHECKSUM_ATTR (attrs.at_explicit);
  CHECKSUM_ATTR (attrs.at_is_optional);
  CHECKSUM_ATTR (attrs.at_location);
  CHECKSUM_ATTR (attrs.at_lower_bound);
  CHECKSUM_ATTR (attrs.at_mutable);
  CHECKSUM_ATTR (attrs.at_ordering);
  CHECKSUM_ATTR (attrs.at_picture_string);
  CHECKSUM_ATTR (attrs.at_prototyped);
  CHECKSUM_ATTR (attrs.at_small);
  CHECKSUM_ATTR (attrs.at_segment);
  CHECKSUM_ATTR (attrs.at_string_length);
  CHECKSUM_ATTR (attrs.at_string_length_bit_size);
  CHECKSUM_ATTR (attrs.at_string_length_byte_size);
  CHECKSUM_ATTR (attrs.at_threads_scaled);
  CHECKSUM_ATTR (attrs.at_upper_bound);
  CHECKSUM_ATTR (attrs.at_use_location);
  CHECKSUM_ATTR (attrs.at_use_UTF8);
  CHECKSUM_ATTR (attrs.at_variable_parameter);
  CHECKSUM_ATTR (attrs.at_virtuality);
  CHECKSUM_ATTR (attrs.at_visibility);
  CHECKSUM_ATTR (attrs.at_vtable_elem_location);
  CHECKSUM_ATTR (attrs.at_type);
  CHECKSUM_ATTR (attrs.at_friend);
  CHECKSUM_ATTR (attrs.at_alignment);

  /* Checksum the child DIEs.  */
  c = die->die_child;
  if (c) do {
    dw_attr_node *name_attr;

    c = c->die_sib;
    name_attr = get_AT (c, DW_AT_name);
    if (is_template_instantiation (c))
      {
	/* Ignore instantiations of member type and function templates.  */
      }
    else if (name_attr != NULL
	     && (is_type_die (c) || c->die_tag == DW_TAG_subprogram))
      {
	/* Use a shallow checksum for named nested types and member
	   functions.  */
        CHECKSUM_ULEB128 ('S');
        CHECKSUM_ULEB128 (c->die_tag);
        CHECKSUM_STRING (AT_string (name_attr));
      }
    else
      {
	/* Use a deep checksum for other children.  */
        /* Mark this DIE so it gets processed when unmarking.  */
        if (c->die_mark == 0)
          c->die_mark = -1;
        die_checksum_ordered (c, ctx, mark);
      }
  } while (c != die->die_child);

  CHECKSUM_ULEB128 (0);
}

/* Add a type name and tag to a hash.  */
static void
die_odr_checksum (int tag, const char *name, md5_ctx *ctx)
{
  CHECKSUM_ULEB128 (tag);
  CHECKSUM_STRING (name);
}

#undef CHECKSUM
#undef CHECKSUM_STRING
#undef CHECKSUM_ATTR
#undef CHECKSUM_LEB128
#undef CHECKSUM_ULEB128

/* Generate the type signature for DIE.  This is computed by generating an
   MD5 checksum over the DIE's tag, its relevant attributes, and its
   children.  Attributes that are references to other DIEs are processed
   by recursion, using the MARK field to prevent infinite recursion.
   If the DIE is nested inside a namespace or another type, we also
   need to include that context in the signature.  The lower 64 bits
   of the resulting MD5 checksum comprise the signature.  */

static void
generate_type_signature (dw_die_ref die, comdat_type_node *type_node)
{
  int mark;
  const char *name;
  unsigned char checksum[16];
  struct md5_ctx ctx;
  dw_die_ref decl;
  dw_die_ref parent;

  name = get_AT_string (die, DW_AT_name);
  decl = get_AT_ref (die, DW_AT_specification);
  parent = get_die_parent (die);

  /* First, compute a signature for just the type name (and its surrounding
     context, if any.  This is stored in the type unit DIE for link-time
     ODR (one-definition rule) checking.  */

  if (is_cxx () && name != NULL)
    {
      md5_init_ctx (&ctx);

      /* Checksum the names of surrounding namespaces and structures.  */
      if (parent != NULL)
        checksum_die_context (parent, &ctx);

      /* Checksum the current DIE. */
      die_odr_checksum (die->die_tag, name, &ctx);
      md5_finish_ctx (&ctx, checksum);

      add_AT_data8 (type_node->root_die, DW_AT_GNU_odr_signature, &checksum[8]);
    }

  /* Next, compute the complete type signature.  */

  md5_init_ctx (&ctx);
  mark = 1;
  die->die_mark = mark;

  /* Checksum the names of surrounding namespaces and structures.  */
  if (parent != NULL)
    checksum_die_context (parent, &ctx);

  /* Checksum the DIE and its children.  */
  die_checksum_ordered (die, &ctx, &mark);
  unmark_all_dies (die);
  md5_finish_ctx (&ctx, checksum);

  /* Store the signature in the type node and link the type DIE and the
     type node together.  */
  memcpy (type_node->signature, &checksum[16 - DWARF_TYPE_SIGNATURE_SIZE],
          DWARF_TYPE_SIGNATURE_SIZE);
  die->comdat_type_p = true;
  die->die_id.die_type_node = type_node;
  type_node->type_die = die;

  /* If the DIE is a specification, link its declaration to the type node
     as well.  */
  if (decl != NULL)
    {
      decl->comdat_type_p = true;
      decl->die_id.die_type_node = type_node;
    }
}

/* Do the location expressions look same?  */
static inline int
same_loc_p (dw_loc_descr_ref loc1, dw_loc_descr_ref loc2, int *mark)
{
  return loc1->dw_loc_opc == loc2->dw_loc_opc
	 && same_dw_val_p (&loc1->dw_loc_oprnd1, &loc2->dw_loc_oprnd1, mark)
	 && same_dw_val_p (&loc1->dw_loc_oprnd2, &loc2->dw_loc_oprnd2, mark);
}

/* Do the values look the same?  */
static int
same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark)
{
  dw_loc_descr_ref loc1, loc2;
  rtx r1, r2;

  if (v1->val_class != v2->val_class)
    return 0;

  switch (v1->val_class)
    {
    case dw_val_class_const:
    case dw_val_class_const_implicit:
      return v1->v.val_int == v2->v.val_int;
    case dw_val_class_unsigned_const:
    case dw_val_class_unsigned_const_implicit:
      return v1->v.val_unsigned == v2->v.val_unsigned;
    case dw_val_class_const_double:
      return v1->v.val_double.high == v2->v.val_double.high
	     && v1->v.val_double.low == v2->v.val_double.low;
    case dw_val_class_wide_int:
      return *v1->v.val_wide == *v2->v.val_wide;
    case dw_val_class_vec:
      if (v1->v.val_vec.length != v2->v.val_vec.length
	  || v1->v.val_vec.elt_size != v2->v.val_vec.elt_size)
	return 0;
      if (memcmp (v1->v.val_vec.array, v2->v.val_vec.array,
		  v1->v.val_vec.length * v1->v.val_vec.elt_size))
	return 0;
      return 1;
    case dw_val_class_flag:
      return v1->v.val_flag == v2->v.val_flag;
    case dw_val_class_str:
      return !strcmp (v1->v.val_str->str, v2->v.val_str->str);

    case dw_val_class_addr:
      r1 = v1->v.val_addr;
      r2 = v2->v.val_addr;
      if (GET_CODE (r1) != GET_CODE (r2))
	return 0;
      return !rtx_equal_p (r1, r2);

    case dw_val_class_offset:
      return v1->v.val_offset == v2->v.val_offset;

    case dw_val_class_loc:
      for (loc1 = v1->v.val_loc, loc2 = v2->v.val_loc;
	   loc1 && loc2;
	   loc1 = loc1->dw_loc_next, loc2 = loc2->dw_loc_next)
	if (!same_loc_p (loc1, loc2, mark))
	  return 0;
      return !loc1 && !loc2;

    case dw_val_class_die_ref:
      return same_die_p (v1->v.val_die_ref.die, v2->v.val_die_ref.die, mark);

    case dw_val_class_symview:
      return strcmp (v1->v.val_symbolic_view, v2->v.val_symbolic_view) == 0;

    case dw_val_class_fde_ref:
    case dw_val_class_vms_delta:
    case dw_val_class_lbl_id:
    case dw_val_class_lineptr:
    case dw_val_class_macptr:
    case dw_val_class_loclistsptr:
    case dw_val_class_high_pc:
      return 1;

    case dw_val_class_file:
    case dw_val_class_file_implicit:
      return v1->v.val_file == v2->v.val_file;

    case dw_val_class_data8:
      return !memcmp (v1->v.val_data8, v2->v.val_data8, 8);

    default:
      return 1;
    }
}

/* Do the attributes look the same?  */

static int
same_attr_p (dw_attr_node *at1, dw_attr_node *at2, int *mark)
{
  if (at1->dw_attr != at2->dw_attr)
    return 0;

  /* We don't care that this was compiled with a different compiler
     snapshot; if the output is the same, that's what matters. */
  if (at1->dw_attr == DW_AT_producer)
    return 1;

  return same_dw_val_p (&at1->dw_attr_val, &at2->dw_attr_val, mark);
}

/* Do the dies look the same?  */

static int
same_die_p (dw_die_ref die1, dw_die_ref die2, int *mark)
{
  dw_die_ref c1, c2;
  dw_attr_node *a1;
  unsigned ix;

  /* To avoid infinite recursion.  */
  if (die1->die_mark)
    return die1->die_mark == die2->die_mark;
  die1->die_mark = die2->die_mark = ++(*mark);

  if (die1->die_tag != die2->die_tag)
    return 0;

  if (vec_safe_length (die1->die_attr) != vec_safe_length (die2->die_attr))
    return 0;

  FOR_EACH_VEC_SAFE_ELT (die1->die_attr, ix, a1)
    if (!same_attr_p (a1, &(*die2->die_attr)[ix], mark))
      return 0;

  c1 = die1->die_child;
  c2 = die2->die_child;
  if (! c1)
    {
      if (c2)
	return 0;
    }
  else
    for (;;)
      {
	if (!same_die_p (c1, c2, mark))
	  return 0;
	c1 = c1->die_sib;
	c2 = c2->die_sib;
	if (c1 == die1->die_child)
	  {
	    if (c2 == die2->die_child)
	      break;
	    else
	      return 0;
	  }
    }

  return 1;
}

/* Calculate the MD5 checksum of the compilation unit DIE UNIT_DIE and its
   children, and set die_symbol.  */

static void
compute_comp_unit_symbol (dw_die_ref unit_die)
{
  const char *die_name = get_AT_string (unit_die, DW_AT_name);
  const char *base = die_name ? lbasename (die_name) : "anonymous";
  char *name = XALLOCAVEC (char, strlen (base) + 64);
  char *p;
  int i, mark;
  unsigned char checksum[16];
  struct md5_ctx ctx;

  /* Compute the checksum of the DIE, then append part of it as hex digits to
     the name filename of the unit.  */

  md5_init_ctx (&ctx);
  mark = 0;
  die_checksum (unit_die, &ctx, &mark);
  unmark_all_dies (unit_die);
  md5_finish_ctx (&ctx, checksum);

  /* When we this for comp_unit_die () we have a DW_AT_name that might
     not start with a letter but with anything valid for filenames and
     clean_symbol_name doesn't fix that up.  Prepend 'g' if the first
     character is not a letter.  */
  sprintf (name, "%s%s.", ISALPHA (*base) ? "" : "g", base);
  clean_symbol_name (name);

  p = name + strlen (name);
  for (i = 0; i < 4; i++)
    {
      sprintf (p, "%.2x", checksum[i]);
      p += 2;
    }

  unit_die->die_id.die_symbol = xstrdup (name);
}

/* Returns nonzero if DIE represents a type, in the sense of TYPE_P.  */

static int
is_type_die (dw_die_ref die)
{
  switch (die->die_tag)
    {
    case DW_TAG_array_type:
    case DW_TAG_class_type:
    case DW_TAG_interface_type:
    case DW_TAG_enumeration_type:
    case DW_TAG_pointer_type:
    case DW_TAG_reference_type:
    case DW_TAG_rvalue_reference_type:
    case DW_TAG_string_type:
    case DW_TAG_structure_type:
    case DW_TAG_subroutine_type:
    case DW_TAG_union_type:
    case DW_TAG_ptr_to_member_type:
    case DW_TAG_set_type:
    case DW_TAG_subrange_type:
    case DW_TAG_base_type:
    case DW_TAG_const_type:
    case DW_TAG_file_type:
    case DW_TAG_packed_type:
    case DW_TAG_volatile_type:
    case DW_TAG_typedef:
      return 1;
    default:
      return 0;
    }
}

/* Returns true iff C is a compile-unit DIE.  */

static inline bool
is_cu_die (dw_die_ref c)
{
  return c && (c->die_tag == DW_TAG_compile_unit
	       || c->die_tag == DW_TAG_skeleton_unit);
}

/* Returns true iff C is a unit DIE of some sort.  */

static inline bool
is_unit_die (dw_die_ref c)
{
  return c && (c->die_tag == DW_TAG_compile_unit
	       || c->die_tag == DW_TAG_partial_unit
	       || c->die_tag == DW_TAG_type_unit
	       || c->die_tag == DW_TAG_skeleton_unit);
}

/* Returns true iff C is a namespace DIE.  */

static inline bool
is_namespace_die (dw_die_ref c)
{
  return c && c->die_tag == DW_TAG_namespace;
}

/* Return non-zero if this DIE is a template parameter.  */

static inline bool
is_template_parameter (dw_die_ref die)
{
  switch (die->die_tag)
    {
    case DW_TAG_template_type_param:
    case DW_TAG_template_value_param:
    case DW_TAG_GNU_template_template_param:
    case DW_TAG_GNU_template_parameter_pack:
      return true;
    default:
      return false;
    }
}

/* Return non-zero if this DIE represents a template instantiation.  */

static inline bool
is_template_instantiation (dw_die_ref die)
{
  dw_die_ref c;

  if (!is_type_die (die) && die->die_tag != DW_TAG_subprogram)
    return false;
  FOR_EACH_CHILD (die, c, if (is_template_parameter (c)) return true);
  return false;
}

static char *
gen_internal_sym (const char *prefix)
{
  char buf[MAX_ARTIFICIAL_LABEL_BYTES];

  ASM_GENERATE_INTERNAL_LABEL (buf, prefix, label_num++);
  return xstrdup (buf);
}

/* Return non-zero if this DIE is a declaration.  */

static int
is_declaration_die (dw_die_ref die)
{
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (a->dw_attr == DW_AT_declaration)
      return 1;

  return 0;
}

/* Return non-zero if this DIE is nested inside a subprogram.  */

static int
is_nested_in_subprogram (dw_die_ref die)
{
  dw_die_ref decl = get_AT_ref (die, DW_AT_specification);

  if (decl == NULL)
    decl = die;
  return local_scope_p (decl);
}

/* Return non-zero if this DIE contains a defining declaration of a
   subprogram.  */

static int
contains_subprogram_definition (dw_die_ref die)
{
  dw_die_ref c;

  if (die->die_tag == DW_TAG_subprogram && ! is_declaration_die (die))
    return 1;
  FOR_EACH_CHILD (die, c, if (contains_subprogram_definition (c)) return 1);
  return 0;
}

/* Return non-zero if this is a type DIE that should be moved to a
   COMDAT .debug_types section or .debug_info section with DW_UT_*type
   unit type.  */

static int
should_move_die_to_comdat (dw_die_ref die)
{
  switch (die->die_tag)
    {
    case DW_TAG_class_type:
    case DW_TAG_structure_type:
    case DW_TAG_enumeration_type:
    case DW_TAG_union_type:
      /* Don't move declarations, inlined instances, types nested in a
	 subprogram, or types that contain subprogram definitions.  */
      if (is_declaration_die (die)
          || get_AT (die, DW_AT_abstract_origin)
          || is_nested_in_subprogram (die)
          || contains_subprogram_definition (die))
        return 0;
      return 1;
    case DW_TAG_array_type:
    case DW_TAG_interface_type:
    case DW_TAG_pointer_type:
    case DW_TAG_reference_type:
    case DW_TAG_rvalue_reference_type:
    case DW_TAG_string_type:
    case DW_TAG_subroutine_type:
    case DW_TAG_ptr_to_member_type:
    case DW_TAG_set_type:
    case DW_TAG_subrange_type:
    case DW_TAG_base_type:
    case DW_TAG_const_type:
    case DW_TAG_file_type:
    case DW_TAG_packed_type:
    case DW_TAG_volatile_type:
    case DW_TAG_typedef:
    default:
      return 0;
    }
}

/* Make a clone of DIE.  */

static dw_die_ref
clone_die (dw_die_ref die)
{
  dw_die_ref clone = new_die_raw (die->die_tag);
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    add_dwarf_attr (clone, a);

  return clone;
}

/* Make a clone of the tree rooted at DIE.  */

static dw_die_ref
clone_tree (dw_die_ref die)
{
  dw_die_ref c;
  dw_die_ref clone = clone_die (die);

  FOR_EACH_CHILD (die, c, add_child_die (clone, clone_tree (c)));

  return clone;
}

/* Make a clone of DIE as a declaration.  */

static dw_die_ref
clone_as_declaration (dw_die_ref die)
{
  dw_die_ref clone;
  dw_die_ref decl;
  dw_attr_node *a;
  unsigned ix;

  /* If the DIE is already a declaration, just clone it.  */
  if (is_declaration_die (die))
    return clone_die (die);

  /* If the DIE is a specification, just clone its declaration DIE.  */
  decl = get_AT_ref (die, DW_AT_specification);
  if (decl != NULL)
    {
      clone = clone_die (decl);
      if (die->comdat_type_p)
	add_AT_die_ref (clone, DW_AT_signature, die);
      return clone;
    }

  clone = new_die_raw (die->die_tag);

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    {
      /* We don't want to copy over all attributes.
         For example we don't want DW_AT_byte_size because otherwise we will no
         longer have a declaration and GDB will treat it as a definition.  */

      switch (a->dw_attr)
        {
        case DW_AT_abstract_origin:
        case DW_AT_artificial:
        case DW_AT_containing_type:
        case DW_AT_external:
        case DW_AT_name:
        case DW_AT_type:
        case DW_AT_virtuality:
        case DW_AT_linkage_name:
        case DW_AT_MIPS_linkage_name:
          add_dwarf_attr (clone, a);
          break;
        case DW_AT_byte_size:
	case DW_AT_alignment:
        default:
          break;
        }
    }

  if (die->comdat_type_p)
    add_AT_die_ref (clone, DW_AT_signature, die);

  add_AT_flag (clone, DW_AT_declaration, 1);
  return clone;
}


/* Structure to map a DIE in one CU to its copy in a comdat type unit.  */

struct decl_table_entry
{
  dw_die_ref orig;
  dw_die_ref copy;
};

/* Helpers to manipulate hash table of copied declarations.  */

/* Hashtable helpers.  */

struct decl_table_entry_hasher : free_ptr_hash <decl_table_entry>
{
  typedef die_struct *compare_type;
  static inline hashval_t hash (const decl_table_entry *);
  static inline bool equal (const decl_table_entry *, const die_struct *);
};

inline hashval_t
decl_table_entry_hasher::hash (const decl_table_entry *entry)
{
  return htab_hash_pointer (entry->orig);
}

inline bool
decl_table_entry_hasher::equal (const decl_table_entry *entry1,
				const die_struct *entry2)
{
  return entry1->orig == entry2;
}

typedef hash_table<decl_table_entry_hasher> decl_hash_type;

/* Copy DIE and its ancestors, up to, but not including, the compile unit
   or type unit entry, to a new tree.  Adds the new tree to UNIT and returns
   a pointer to the copy of DIE.  If DECL_TABLE is provided, it is used
   to check if the ancestor has already been copied into UNIT.  */

static dw_die_ref
copy_ancestor_tree (dw_die_ref unit, dw_die_ref die,
		    decl_hash_type *decl_table)
{
  dw_die_ref parent = die->die_parent;
  dw_die_ref new_parent = unit;
  dw_die_ref copy;
  decl_table_entry **slot = NULL;
  struct decl_table_entry *entry = NULL;

  /* If DIE refers to a stub unfold that so we get the appropriate
     DIE registered as orig in decl_table.  */
  if (dw_die_ref c = get_AT_ref (die, DW_AT_signature))
    die = c;

  if (decl_table)
    {
      /* Check if the entry has already been copied to UNIT.  */
      slot = decl_table->find_slot_with_hash (die, htab_hash_pointer (die),
					      INSERT);
      if (*slot != HTAB_EMPTY_ENTRY)
        {
          entry = *slot;
          return entry->copy;
        }

      /* Record in DECL_TABLE that DIE has been copied to UNIT.  */
      entry = XCNEW (struct decl_table_entry);
      entry->orig = die;
      entry->copy = NULL;
      *slot = entry;
    }

  if (parent != NULL)
    {
      dw_die_ref spec = get_AT_ref (parent, DW_AT_specification);
      if (spec != NULL)
        parent = spec;
      if (!is_unit_die (parent))
        new_parent = copy_ancestor_tree (unit, parent, decl_table);
    }

  copy = clone_as_declaration (die);
  add_child_die (new_parent, copy);

  if (decl_table)
    {
      /* Record the pointer to the copy.  */
      entry->copy = copy;
    }

  return copy;
}
/* Copy the declaration context to the new type unit DIE.  This includes
   any surrounding namespace or type declarations.  If the DIE has an
   AT_specification attribute, it also includes attributes and children
   attached to the specification, and returns a pointer to the original
   parent of the declaration DIE.  Returns NULL otherwise.  */

static dw_die_ref
copy_declaration_context (dw_die_ref unit, dw_die_ref die)
{
  dw_die_ref decl;
  dw_die_ref new_decl;
  dw_die_ref orig_parent = NULL;

  decl = get_AT_ref (die, DW_AT_specification);
  if (decl == NULL)
    decl = die;
  else
    {
      unsigned ix;
      dw_die_ref c;
      dw_attr_node *a;

      /* The original DIE will be changed to a declaration, and must
         be moved to be a child of the original declaration DIE.  */
      orig_parent = decl->die_parent;

      /* Copy the type node pointer from the new DIE to the original
         declaration DIE so we can forward references later.  */
      decl->comdat_type_p = true;
      decl->die_id.die_type_node = die->die_id.die_type_node;

      remove_AT (die, DW_AT_specification);

      FOR_EACH_VEC_SAFE_ELT (decl->die_attr, ix, a)
        {
          if (a->dw_attr != DW_AT_name
              && a->dw_attr != DW_AT_declaration
              && a->dw_attr != DW_AT_external)
            add_dwarf_attr (die, a);
        }

      FOR_EACH_CHILD (decl, c, add_child_die (die, clone_tree (c)));
    }

  if (decl->die_parent != NULL
      && !is_unit_die (decl->die_parent))
    {
      new_decl = copy_ancestor_tree (unit, decl, NULL);
      if (new_decl != NULL)
        {
          remove_AT (new_decl, DW_AT_signature);
          add_AT_specification (die, new_decl);
        }
    }

  return orig_parent;
}

/* Generate the skeleton ancestor tree for the given NODE, then clone
   the DIE and add the clone into the tree.  */

static void
generate_skeleton_ancestor_tree (skeleton_chain_node *node)
{
  if (node->new_die != NULL)
    return;

  node->new_die = clone_as_declaration (node->old_die);

  if (node->parent != NULL)
    {
      generate_skeleton_ancestor_tree (node->parent);
      add_child_die (node->parent->new_die, node->new_die);
    }
}

/* Generate a skeleton tree of DIEs containing any declarations that are
   found in the original tree.  We traverse the tree looking for declaration
   DIEs, and construct the skeleton from the bottom up whenever we find one.  */

static void
generate_skeleton_bottom_up (skeleton_chain_node *parent)
{
  skeleton_chain_node node;
  dw_die_ref c;
  dw_die_ref first;
  dw_die_ref prev = NULL;
  dw_die_ref next = NULL;

  node.parent = parent;

  first = c = parent->old_die->die_child;
  if (c)
    next = c->die_sib;
  if (c) do {
    if (prev == NULL || prev->die_sib == c)
      prev = c;
    c = next;
    next = (c == first ? NULL : c->die_sib);
    node.old_die = c;
    node.new_die = NULL;
    if (is_declaration_die (c))
      {
	if (is_template_instantiation (c))
	  {
	    /* Instantiated templates do not need to be cloned into the
	       type unit.  Just move the DIE and its children back to
	       the skeleton tree (in the main CU).  */
	    remove_child_with_prev (c, prev);
	    add_child_die (parent->new_die, c);
	    c = prev;
	  }
	else if (c->comdat_type_p)
	  {
	    /* This is the skeleton of earlier break_out_comdat_types
	       type.  Clone the existing DIE, but keep the children
	       under the original (which is in the main CU).  */
	    dw_die_ref clone = clone_die (c);

	    replace_child (c, clone, prev);
	    generate_skeleton_ancestor_tree (parent);
	    add_child_die (parent->new_die, c);
	    c = clone;
	    continue;
	  }
	else
	  {
	    /* Clone the existing DIE, move the original to the skeleton
	       tree (which is in the main CU), and put the clone, with
	       all the original's children, where the original came from
	       (which is about to be moved to the type unit).  */
	    dw_die_ref clone = clone_die (c);
	    move_all_children (c, clone);

	    /* If the original has a DW_AT_object_pointer attribute,
	       it would now point to a child DIE just moved to the
	       cloned tree, so we need to remove that attribute from
	       the original.  */
	    remove_AT (c, DW_AT_object_pointer);

	    replace_child (c, clone, prev);
	    generate_skeleton_ancestor_tree (parent);
	    add_child_die (parent->new_die, c);
	    node.old_die = clone;
	    node.new_die = c;
	    c = clone;
	  }
      }
    generate_skeleton_bottom_up (&node);
  } while (next != NULL);
}

/* Wrapper function for generate_skeleton_bottom_up.  */

static dw_die_ref
generate_skeleton (dw_die_ref die)
{
  skeleton_chain_node node;

  node.old_die = die;
  node.new_die = NULL;
  node.parent = NULL;

  /* If this type definition is nested inside another type,
     and is not an instantiation of a template, always leave
     at least a declaration in its place.  */
  if (die->die_parent != NULL
      && is_type_die (die->die_parent)
      && !is_template_instantiation (die))
    node.new_die = clone_as_declaration (die);

  generate_skeleton_bottom_up (&node);
  return node.new_die;
}

/* Remove the CHILD DIE from its parent, possibly replacing it with a cloned
   declaration.  The original DIE is moved to a new compile unit so that
   existing references to it follow it to the new location.  If any of the
   original DIE's descendants is a declaration, we need to replace the
   original DIE with a skeleton tree and move the declarations back into the
   skeleton tree.  */

static dw_die_ref
remove_child_or_replace_with_skeleton (dw_die_ref unit, dw_die_ref child,
				       dw_die_ref prev)
{
  dw_die_ref skeleton, orig_parent;

  /* Copy the declaration context to the type unit DIE.  If the returned
     ORIG_PARENT is not NULL, the skeleton needs to be added as a child of
     that DIE.  */
  orig_parent = copy_declaration_context (unit, child);

  skeleton = generate_skeleton (child);
  if (skeleton == NULL)
    remove_child_with_prev (child, prev);
  else
    {
      skeleton->comdat_type_p = true;
      skeleton->die_id.die_type_node = child->die_id.die_type_node;

      /* If the original DIE was a specification, we need to put
         the skeleton under the parent DIE of the declaration.
	 This leaves the original declaration in the tree, but
	 it will be pruned later since there are no longer any
	 references to it.  */
      if (orig_parent != NULL)
	{
	  remove_child_with_prev (child, prev);
	  add_child_die (orig_parent, skeleton);
	}
      else
	replace_child (child, skeleton, prev);
    }

  return skeleton;
}

static void
copy_dwarf_procs_ref_in_attrs (dw_die_ref die,
			       comdat_type_node *type_node,
			       hash_map<dw_die_ref, dw_die_ref> &copied_dwarf_procs);

/* Helper for copy_dwarf_procs_ref_in_dies.  Make a copy of the DIE DWARF
   procedure, put it under TYPE_NODE and return the copy.  Continue looking for
   DWARF procedure references in the DW_AT_location attribute.  */

static dw_die_ref
copy_dwarf_procedure (dw_die_ref die,
		      comdat_type_node *type_node,
		      hash_map<dw_die_ref, dw_die_ref> &copied_dwarf_procs)
{
  gcc_assert (die->die_tag == DW_TAG_dwarf_procedure);

  /* DWARF procedures are not supposed to have children...  */
  gcc_assert (die->die_child == NULL);

  /* ... and they are supposed to have only one attribute: DW_AT_location.  */
  gcc_assert (vec_safe_length (die->die_attr) == 1
	      && ((*die->die_attr)[0].dw_attr == DW_AT_location));

  /* Do not copy more than once DWARF procedures.  */
  bool existed;
  dw_die_ref &die_copy = copied_dwarf_procs.get_or_insert (die, &existed);
  if (existed)
    return die_copy;

  die_copy = clone_die (die);
  add_child_die (type_node->root_die, die_copy);
  copy_dwarf_procs_ref_in_attrs (die_copy, type_node, copied_dwarf_procs);
  return die_copy;
}

/* Helper for copy_dwarf_procs_ref_in_dies.  Look for references to DWARF
   procedures in DIE's attributes.  */

static void
copy_dwarf_procs_ref_in_attrs (dw_die_ref die,
			       comdat_type_node *type_node,
			       hash_map<dw_die_ref, dw_die_ref> &copied_dwarf_procs)
{
  dw_attr_node *a;
  unsigned i;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, i, a)
    {
      dw_loc_descr_ref loc;

      if (a->dw_attr_val.val_class != dw_val_class_loc)
	continue;

      for (loc = a->dw_attr_val.v.val_loc; loc != NULL; loc = loc->dw_loc_next)
	{
	  switch (loc->dw_loc_opc)
	    {
	    case DW_OP_call2:
	    case DW_OP_call4:
	    case DW_OP_call_ref:
	      gcc_assert (loc->dw_loc_oprnd1.val_class
			  == dw_val_class_die_ref);
	      loc->dw_loc_oprnd1.v.val_die_ref.die
	        = copy_dwarf_procedure (loc->dw_loc_oprnd1.v.val_die_ref.die,
					type_node,
					copied_dwarf_procs);

	    default:
	      break;
	    }
	}
    }
}

/* Copy DWARF procedures that are referenced by the DIE tree to TREE_NODE and
   rewrite references to point to the copies.

   References are looked for in DIE's attributes and recursively in all its
   children attributes that are location descriptions. COPIED_DWARF_PROCS is a
   mapping from old DWARF procedures to their copy. It is used not to copy
   twice the same DWARF procedure under TYPE_NODE.  */

static void
copy_dwarf_procs_ref_in_dies (dw_die_ref die,
			      comdat_type_node *type_node,
			      hash_map<dw_die_ref, dw_die_ref> &copied_dwarf_procs)
{
  dw_die_ref c;

  copy_dwarf_procs_ref_in_attrs (die, type_node, copied_dwarf_procs);
  FOR_EACH_CHILD (die, c, copy_dwarf_procs_ref_in_dies (c,
							type_node,
							copied_dwarf_procs));
}

/* Traverse the DIE and set up additional .debug_types or .debug_info
   DW_UT_*type sections for each type worthy of being placed in a COMDAT
   section.  */

static void
break_out_comdat_types (dw_die_ref die)
{
  dw_die_ref c;
  dw_die_ref first;
  dw_die_ref prev = NULL;
  dw_die_ref next = NULL;
  dw_die_ref unit = NULL;

  first = c = die->die_child;
  if (c)
    next = c->die_sib;
  if (c) do {
    if (prev == NULL || prev->die_sib == c)
      prev = c;
    c = next;
    next = (c == first ? NULL : c->die_sib);
    if (should_move_die_to_comdat (c))
      {
        dw_die_ref replacement;
	comdat_type_node *type_node;

        /* Break out nested types into their own type units.  */
        break_out_comdat_types (c);

        /* Create a new type unit DIE as the root for the new tree.  */
        unit = new_die (DW_TAG_type_unit, NULL, NULL);
        add_AT_unsigned (unit, DW_AT_language,
                         get_AT_unsigned (comp_unit_die (), DW_AT_language));

	/* Add the new unit's type DIE into the comdat type list.  */
        type_node = ggc_cleared_alloc<comdat_type_node> ();
        type_node->root_die = unit;
        type_node->next = comdat_type_list;
        comdat_type_list = type_node;

        /* Generate the type signature.  */
        generate_type_signature (c, type_node);

        /* Copy the declaration context, attributes, and children of the
           declaration into the new type unit DIE, then remove this DIE
	   from the main CU (or replace it with a skeleton if necessary).  */
	replacement = remove_child_or_replace_with_skeleton (unit, c, prev);
	type_node->skeleton_die = replacement;

        /* Add the DIE to the new compunit.  */
	add_child_die (unit, c);

	/* Types can reference DWARF procedures for type size or data location
	   expressions.  Calls in DWARF expressions cannot target procedures
	   that are not in the same section.  So we must copy DWARF procedures
	   along with this type and then rewrite references to them.  */
	hash_map<dw_die_ref, dw_die_ref> copied_dwarf_procs;
	copy_dwarf_procs_ref_in_dies (c, type_node, copied_dwarf_procs);

        if (replacement != NULL)
          c = replacement;
      }
    else if (c->die_tag == DW_TAG_namespace
             || c->die_tag == DW_TAG_class_type
             || c->die_tag == DW_TAG_structure_type
             || c->die_tag == DW_TAG_union_type)
      {
        /* Look for nested types that can be broken out.  */
        break_out_comdat_types (c);
      }
  } while (next != NULL);
}

/* Like clone_tree, but copy DW_TAG_subprogram DIEs as declarations.
   Enter all the cloned children into the hash table decl_table.  */

static dw_die_ref
clone_tree_partial (dw_die_ref die, decl_hash_type *decl_table)
{
  dw_die_ref c;
  dw_die_ref clone;
  struct decl_table_entry *entry;
  decl_table_entry **slot;

  if (die->die_tag == DW_TAG_subprogram)
    clone = clone_as_declaration (die);
  else
    clone = clone_die (die);

  slot = decl_table->find_slot_with_hash (die,
					  htab_hash_pointer (die), INSERT);

  /* Assert that DIE isn't in the hash table yet.  If it would be there
     before, the ancestors would be necessarily there as well, therefore
     clone_tree_partial wouldn't be called.  */
  gcc_assert (*slot == HTAB_EMPTY_ENTRY);

  entry = XCNEW (struct decl_table_entry);
  entry->orig = die;
  entry->copy = clone;
  *slot = entry;

  if (die->die_tag != DW_TAG_subprogram)
    FOR_EACH_CHILD (die, c,
		    add_child_die (clone, clone_tree_partial (c, decl_table)));

  return clone;
}

/* Walk the DIE and its children, looking for references to incomplete
   or trivial types that are unmarked (i.e., that are not in the current
   type_unit).  */

static void
copy_decls_walk (dw_die_ref unit, dw_die_ref die, decl_hash_type *decl_table)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    {
      if (AT_class (a) == dw_val_class_die_ref)
        {
          dw_die_ref targ = AT_ref (a);
          decl_table_entry **slot;
          struct decl_table_entry *entry;

          if (targ->die_mark != 0 || targ->comdat_type_p)
            continue;

          slot = decl_table->find_slot_with_hash (targ,
						  htab_hash_pointer (targ),
						  INSERT);

          if (*slot != HTAB_EMPTY_ENTRY)
            {
              /* TARG has already been copied, so we just need to
                 modify the reference to point to the copy.  */
              entry = *slot;
              a->dw_attr_val.v.val_die_ref.die = entry->copy;
            }
          else
            {
              dw_die_ref parent = unit;
	      dw_die_ref copy = clone_die (targ);

              /* Record in DECL_TABLE that TARG has been copied.
                 Need to do this now, before the recursive call,
                 because DECL_TABLE may be expanded and SLOT
                 would no longer be a valid pointer.  */
              entry = XCNEW (struct decl_table_entry);
              entry->orig = targ;
              entry->copy = copy;
              *slot = entry;

	      /* If TARG is not a declaration DIE, we need to copy its
	         children.  */
	      if (!is_declaration_die (targ))
		{
		  FOR_EACH_CHILD (
		      targ, c,
		      add_child_die (copy,
				     clone_tree_partial (c, decl_table)));
		}

              /* Make sure the cloned tree is marked as part of the
                 type unit.  */
              mark_dies (copy);

              /* If TARG has surrounding context, copy its ancestor tree
                 into the new type unit.  */
              if (targ->die_parent != NULL
		  && !is_unit_die (targ->die_parent))
                parent = copy_ancestor_tree (unit, targ->die_parent,
                                             decl_table);

              add_child_die (parent, copy);
              a->dw_attr_val.v.val_die_ref.die = copy;

              /* Make sure the newly-copied DIE is walked.  If it was
                 installed in a previously-added context, it won't
                 get visited otherwise.  */
              if (parent != unit)
		{
		  /* Find the highest point of the newly-added tree,
		     mark each node along the way, and walk from there.  */
		  parent->die_mark = 1;
		  while (parent->die_parent
		  	 && parent->die_parent->die_mark == 0)
		    {
		      parent = parent->die_parent;
		      parent->die_mark = 1;
		    }
		  copy_decls_walk (unit, parent, decl_table);
		}
            }
        }
    }

  FOR_EACH_CHILD (die, c, copy_decls_walk (unit, c, decl_table));
}

/* Collect skeleton dies in DIE created by break_out_comdat_types already
   and record them in DECL_TABLE.  */

static void
collect_skeleton_dies (dw_die_ref die, decl_hash_type *decl_table)
{
  dw_die_ref c;

  if (dw_attr_node *a = get_AT (die, DW_AT_signature))
    {
      dw_die_ref targ = AT_ref (a);
      gcc_assert (targ->die_mark == 0 && targ->comdat_type_p);
      decl_table_entry **slot
        = decl_table->find_slot_with_hash (targ,
					   htab_hash_pointer (targ),
					   INSERT);
      gcc_assert (*slot == HTAB_EMPTY_ENTRY);
      /* Record in DECL_TABLE that TARG has been already copied
	 by remove_child_or_replace_with_skeleton.  */
      decl_table_entry *entry = XCNEW (struct decl_table_entry);
      entry->orig = targ;
      entry->copy = die;
      *slot = entry;
    }
  FOR_EACH_CHILD (die, c, collect_skeleton_dies (c, decl_table));
}

/* Copy declarations for "unworthy" types into the new comdat section.
   Incomplete types, modified types, and certain other types aren't broken
   out into comdat sections of their own, so they don't have a signature,
   and we need to copy the declaration into the same section so that we
   don't have an external reference.  */

static void
copy_decls_for_unworthy_types (dw_die_ref unit)
{
  mark_dies (unit);
  decl_hash_type decl_table (10);
  collect_skeleton_dies (unit, &decl_table);
  copy_decls_walk (unit, unit, &decl_table);
  unmark_dies (unit);
}

/* Traverse the DIE and add a sibling attribute if it may have the
   effect of speeding up access to siblings.  To save some space,
   avoid generating sibling attributes for DIE's without children.  */

static void
add_sibling_attributes (dw_die_ref die)
{
  dw_die_ref c;

  if (! die->die_child)
    return;

  if (die->die_parent && die != die->die_parent->die_child)
    add_AT_die_ref (die, DW_AT_sibling, die->die_sib);

  FOR_EACH_CHILD (die, c, add_sibling_attributes (c));
}

/* Output all location lists for the DIE and its children.  */

static void
output_location_lists (dw_die_ref die)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_loc_list)
      output_loc_list (AT_loc_list (a));

  FOR_EACH_CHILD (die, c, output_location_lists (c));
}

/* During assign_location_list_indexes and output_loclists_offset the
   current index, after it the number of assigned indexes (i.e. how
   large the .debug_loclists* offset table should be).  */
static unsigned int loc_list_idx;

/* Output all location list offsets for the DIE and its children.  */

static void
output_loclists_offsets (dw_die_ref die)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_loc_list)
      {
	dw_loc_list_ref l = AT_loc_list (a);
	if (l->offset_emitted)
	  continue;
	dw2_asm_output_delta (dwarf_offset_size, l->ll_symbol,
			      loc_section_label, NULL);
	gcc_assert (l->hash == loc_list_idx);
	loc_list_idx++;
	l->offset_emitted = true;
      }

  FOR_EACH_CHILD (die, c, output_loclists_offsets (c));
}

/* Recursively set indexes of location lists.  */

static void
assign_location_list_indexes (dw_die_ref die)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_loc_list)
      {
	dw_loc_list_ref list = AT_loc_list (a);
	if (!list->num_assigned)
	  {
	    list->num_assigned = true;
	    list->hash = loc_list_idx++;
	  }
      }

  FOR_EACH_CHILD (die, c, assign_location_list_indexes (c));
}

/* We want to limit the number of external references, because they are
   larger than local references: a relocation takes multiple words, and
   even a sig8 reference is always eight bytes, whereas a local reference
   can be as small as one byte (though DW_FORM_ref is usually 4 in GCC).
   So if we encounter multiple external references to the same type DIE, we
   make a local typedef stub for it and redirect all references there.

   This is the element of the hash table for keeping track of these
   references.  */

struct external_ref
{
  dw_die_ref type;
  dw_die_ref stub;
  unsigned n_refs;
};

/* Hashtable helpers.  */

struct external_ref_hasher : free_ptr_hash <external_ref>
{
  static inline hashval_t hash (const external_ref *);
  static inline bool equal (const external_ref *, const external_ref *);
};

inline hashval_t
external_ref_hasher::hash (const external_ref *r)
{
  dw_die_ref die = r->type;
  hashval_t h = 0;

  /* We can't use the address of the DIE for hashing, because
     that will make the order of the stub DIEs non-deterministic.  */
  if (! die->comdat_type_p)
    /* We have a symbol; use it to compute a hash.  */
    h = htab_hash_string (die->die_id.die_symbol);
  else
    {
      /* We have a type signature; use a subset of the bits as the hash.
	 The 8-byte signature is at least as large as hashval_t.  */
      comdat_type_node *type_node = die->die_id.die_type_node;
      memcpy (&h, type_node->signature, sizeof (h));
    }
  return h;
}

inline bool
external_ref_hasher::equal (const external_ref *r1, const external_ref *r2)
{
  return r1->type == r2->type;
}

typedef hash_table<external_ref_hasher> external_ref_hash_type;

/* Return a pointer to the external_ref for references to DIE.  */

static struct external_ref *
lookup_external_ref (external_ref_hash_type *map, dw_die_ref die)
{
  struct external_ref ref, *ref_p;
  external_ref **slot;

  ref.type = die;
  slot = map->find_slot (&ref, INSERT);
  if (*slot != HTAB_EMPTY_ENTRY)
    return *slot;

  ref_p = XCNEW (struct external_ref);
  ref_p->type = die;
  *slot = ref_p;
  return ref_p;
}

/* Subroutine of optimize_external_refs, below.

   If we see a type skeleton, record it as our stub.  If we see external
   references, remember how many we've seen.  */

static void
optimize_external_refs_1 (dw_die_ref die, external_ref_hash_type *map)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;
  struct external_ref *ref_p;

  if (is_type_die (die)
      && (c = get_AT_ref (die, DW_AT_signature)))
    {
      /* This is a local skeleton; use it for local references.  */
      ref_p = lookup_external_ref (map, c);
      ref_p->stub = die;
    }

  /* Scan the DIE references, and remember any that refer to DIEs from
     other CUs (i.e. those which are not marked).  */
  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_die_ref
	&& (c = AT_ref (a))->die_mark == 0
	&& is_type_die (c))
      {
	ref_p = lookup_external_ref (map, c);
	ref_p->n_refs++;
      }

  FOR_EACH_CHILD (die, c, optimize_external_refs_1 (c, map));
}

/* htab_traverse callback function for optimize_external_refs, below.  SLOT
   points to an external_ref, DATA is the CU we're processing.  If we don't
   already have a local stub, and we have multiple refs, build a stub.  */

int
dwarf2_build_local_stub (external_ref **slot, dw_die_ref data)
{
  struct external_ref *ref_p = *slot;

  if (ref_p->stub == NULL && ref_p->n_refs > 1 && !dwarf_strict)
    {
      /* We have multiple references to this type, so build a small stub.
	 Both of these forms are a bit dodgy from the perspective of the
	 DWARF standard, since technically they should have names.  */
      dw_die_ref cu = data;
      dw_die_ref type = ref_p->type;
      dw_die_ref stub = NULL;

      if (type->comdat_type_p)
	{
	  /* If we refer to this type via sig8, use AT_signature.  */
	  stub = new_die (type->die_tag, cu, NULL_TREE);
	  add_AT_die_ref (stub, DW_AT_signature, type);
	}
      else
	{
	  /* Otherwise, use a typedef with no name.  */
	  stub = new_die (DW_TAG_typedef, cu, NULL_TREE);
	  add_AT_die_ref (stub, DW_AT_type, type);
	}

      stub->die_mark++;
      ref_p->stub = stub;
    }
  return 1;
}

/* DIE is a unit; look through all the DIE references to see if there are
   any external references to types, and if so, create local stubs for
   them which will be applied in build_abbrev_table.  This is useful because
   references to local DIEs are smaller.  */

static external_ref_hash_type *
optimize_external_refs (dw_die_ref die)
{
  external_ref_hash_type *map = new external_ref_hash_type (10);
  optimize_external_refs_1 (die, map);
  map->traverse <dw_die_ref, dwarf2_build_local_stub> (die);
  return map;
}

/* The following 3 variables are temporaries that are computed only during the
   build_abbrev_table call and used and released during the following
   optimize_abbrev_table call.  */

/* First abbrev_id that can be optimized based on usage.  */
static unsigned int abbrev_opt_start;

/* Maximum abbrev_id of a base type plus one (we can't optimize DIEs with
   abbrev_id smaller than this, because they must be already sized
   during build_abbrev_table).  */
static unsigned int abbrev_opt_base_type_end;

/* Vector of usage counts during build_abbrev_table.  Indexed by
   abbrev_id - abbrev_opt_start.  */
static vec<unsigned int> abbrev_usage_count;

/* Vector of all DIEs added with die_abbrev >= abbrev_opt_start.  */
static vec<dw_die_ref> sorted_abbrev_dies;

/* The format of each DIE (and its attribute value pairs) is encoded in an
   abbreviation table.  This routine builds the abbreviation table and assigns
   a unique abbreviation id for each abbreviation entry.  The children of each
   die are visited recursively.  */

static void
build_abbrev_table (dw_die_ref die, external_ref_hash_type *extern_map)
{
  unsigned int abbrev_id = 0;
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;
  dw_die_ref abbrev;

  /* Scan the DIE references, and replace any that refer to
     DIEs from other CUs (i.e. those which are not marked) with
     the local stubs we built in optimize_external_refs.  */
  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_die_ref
	&& (c = AT_ref (a))->die_mark == 0)
      {
	struct external_ref *ref_p;
	gcc_assert (AT_ref (a)->comdat_type_p || AT_ref (a)->die_id.die_symbol);

	if (is_type_die (c)
	    && (ref_p = lookup_external_ref (extern_map, c))
	    && ref_p->stub && ref_p->stub != die)
	  {
	    gcc_assert (a->dw_attr != DW_AT_signature);
	    change_AT_die_ref (a, ref_p->stub);
	  }
	else
	  /* We aren't changing this reference, so mark it external.  */
	  set_AT_ref_external (a, 1);
      }

  FOR_EACH_VEC_SAFE_ELT (abbrev_die_table, abbrev_id, abbrev)
    {
      dw_attr_node *die_a, *abbrev_a;
      unsigned ix;
      bool ok = true;

      if (abbrev_id == 0)
	continue;
      if (abbrev->die_tag != die->die_tag)
	continue;
      if ((abbrev->die_child != NULL) != (die->die_child != NULL))
	continue;

      if (vec_safe_length (abbrev->die_attr) != vec_safe_length (die->die_attr))
	continue;

      FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, die_a)
	{
	  abbrev_a = &(*abbrev->die_attr)[ix];
	  if ((abbrev_a->dw_attr != die_a->dw_attr)
	      || (value_format (abbrev_a) != value_format (die_a)))
	    {
	      ok = false;
	      break;
	    }
	}
      if (ok)
	break;
    }

  if (abbrev_id >= vec_safe_length (abbrev_die_table))
    {
      vec_safe_push (abbrev_die_table, die);
      if (abbrev_opt_start)
	abbrev_usage_count.safe_push (0);
    }
  if (abbrev_opt_start && abbrev_id >= abbrev_opt_start)
    {
      abbrev_usage_count[abbrev_id - abbrev_opt_start]++;
      sorted_abbrev_dies.safe_push (die);
    }

  die->die_abbrev = abbrev_id;
  FOR_EACH_CHILD (die, c, build_abbrev_table (c, extern_map));
}

/* Callback function for sorted_abbrev_dies vector sorting.  We sort
   by die_abbrev's usage count, from the most commonly used
   abbreviation to the least.  */

static int
die_abbrev_cmp (const void *p1, const void *p2)
{
  dw_die_ref die1 = *(const dw_die_ref *) p1;
  dw_die_ref die2 = *(const dw_die_ref *) p2;

  gcc_checking_assert (die1->die_abbrev >= abbrev_opt_start);
  gcc_checking_assert (die2->die_abbrev >= abbrev_opt_start);

  if (die1->die_abbrev >= abbrev_opt_base_type_end
      && die2->die_abbrev >= abbrev_opt_base_type_end)
    {
      if (abbrev_usage_count[die1->die_abbrev - abbrev_opt_start]
	  > abbrev_usage_count[die2->die_abbrev - abbrev_opt_start])
	return -1;
      if (abbrev_usage_count[die1->die_abbrev - abbrev_opt_start]
	  < abbrev_usage_count[die2->die_abbrev - abbrev_opt_start])
	return 1;
    }

  /* Stabilize the sort.  */
  if (die1->die_abbrev < die2->die_abbrev)
    return -1;
  if (die1->die_abbrev > die2->die_abbrev)
    return 1;

  return 0;
}

/* Convert dw_val_class_const and dw_val_class_unsigned_const class attributes
   of DIEs in between sorted_abbrev_dies[first_id] and abbrev_dies[end_id - 1]
   into dw_val_class_const_implicit or
   dw_val_class_unsigned_const_implicit.  */

static void
optimize_implicit_const (unsigned int first_id, unsigned int end,
			 vec<bool> &implicit_consts)
{
  /* It never makes sense if there is just one DIE using the abbreviation.  */
  if (end < first_id + 2)
    return;

  dw_attr_node *a;
  unsigned ix, i;
  dw_die_ref die = sorted_abbrev_dies[first_id];
  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (implicit_consts[ix])
      {
	enum dw_val_class new_class = dw_val_class_none;
	switch (AT_class (a))
	  {
	  case dw_val_class_unsigned_const:
	    if ((HOST_WIDE_INT) AT_unsigned (a) < 0)
	      continue;

	    /* The .debug_abbrev section will grow by
	       size_of_sleb128 (AT_unsigned (a)) and we avoid the constants
	       in all the DIEs using that abbreviation.  */
	    if (constant_size (AT_unsigned (a)) * (end - first_id)
		<= (unsigned) size_of_sleb128 (AT_unsigned (a)))
	      continue;

	    new_class = dw_val_class_unsigned_const_implicit;
	    break;

	  case dw_val_class_const:
	    new_class = dw_val_class_const_implicit;
	    break;

	  case dw_val_class_file:
	    new_class = dw_val_class_file_implicit;
	    break;

	  default:
	    continue;
	  }
	for (i = first_id; i < end; i++)
	  (*sorted_abbrev_dies[i]->die_attr)[ix].dw_attr_val.val_class
	    = new_class;
      }
}

/* Attempt to optimize abbreviation table from abbrev_opt_start
   abbreviation above.  */

static void
optimize_abbrev_table (void)
{
  if (abbrev_opt_start
      && vec_safe_length (abbrev_die_table) > abbrev_opt_start
      && (dwarf_version >= 5 || vec_safe_length (abbrev_die_table) > 127))
    {
      auto_vec<bool, 32> implicit_consts;
      sorted_abbrev_dies.qsort (die_abbrev_cmp);

      unsigned int abbrev_id = abbrev_opt_start - 1;
      unsigned int first_id = ~0U;
      unsigned int last_abbrev_id = 0;
      unsigned int i;
      dw_die_ref die;
      if (abbrev_opt_base_type_end > abbrev_opt_start)
	abbrev_id = abbrev_opt_base_type_end - 1;
      /* Reassign abbreviation ids from abbrev_opt_start above, so that
	 most commonly used abbreviations come first.  */
      FOR_EACH_VEC_ELT (sorted_abbrev_dies, i, die)
	{
	  dw_attr_node *a;
	  unsigned ix;

	  /* If calc_base_type_die_sizes has been called, the CU and
	     base types after it can't be optimized, because we've already
	     calculated their DIE offsets.  We've sorted them first.  */
	  if (die->die_abbrev < abbrev_opt_base_type_end)
	    continue;
	  if (die->die_abbrev != last_abbrev_id)
	    {
	      last_abbrev_id = die->die_abbrev;
	      if (dwarf_version >= 5 && first_id != ~0U)
		optimize_implicit_const (first_id, i, implicit_consts);
	      abbrev_id++;
	      (*abbrev_die_table)[abbrev_id] = die;
	      if (dwarf_version >= 5)
		{
		  first_id = i;
		  implicit_consts.truncate (0);

		  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
		    switch (AT_class (a))
		      {
		      case dw_val_class_const:
		      case dw_val_class_unsigned_const:
		      case dw_val_class_file:
			implicit_consts.safe_push (true);
			break;
		      default:
			implicit_consts.safe_push (false);
			break;
		      }
		}
	    }
	  else if (dwarf_version >= 5)
	    {
	      FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
		if (!implicit_consts[ix])
		  continue;
		else
		  {
		    dw_attr_node *other_a
		      = &(*(*abbrev_die_table)[abbrev_id]->die_attr)[ix];
		    if (!dw_val_equal_p (&a->dw_attr_val,
					 &other_a->dw_attr_val))
		      implicit_consts[ix] = false;
		  }
	    }
	  die->die_abbrev = abbrev_id;
	}
      gcc_assert (abbrev_id == vec_safe_length (abbrev_die_table) - 1);
      if (dwarf_version >= 5 && first_id != ~0U)
	optimize_implicit_const (first_id, i, implicit_consts);
    }

  abbrev_opt_start = 0;
  abbrev_opt_base_type_end = 0;
  abbrev_usage_count.release ();
  sorted_abbrev_dies.release ();
}

/* Return the power-of-two number of bytes necessary to represent VALUE.  */

static int
constant_size (unsigned HOST_WIDE_INT value)
{
  int log;

  if (value == 0)
    log = 0;
  else
    log = floor_log2 (value);

  log = log / 8;
  log = 1 << (floor_log2 (log) + 1);

  return log;
}

/* Return the size of a DIE as it is represented in the
   .debug_info section.  */

static unsigned long
size_of_die (dw_die_ref die)
{
  unsigned long size = 0;
  dw_attr_node *a;
  unsigned ix;
  enum dwarf_form form;

  size += size_of_uleb128 (die->die_abbrev);
  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    {
      switch (AT_class (a))
	{
	case dw_val_class_addr:
          if (dwarf_split_debug_info && AT_index (a) != NOT_INDEXED)
            {
              gcc_assert (AT_index (a) != NO_INDEX_ASSIGNED);
              size += size_of_uleb128 (AT_index (a));
            }
          else
            size += DWARF2_ADDR_SIZE;
	  break;
	case dw_val_class_offset:
	  size += dwarf_offset_size;
	  break;
	case dw_val_class_loc:
	  {
	    unsigned long lsize = size_of_locs (AT_loc (a));

	    /* Block length.  */
	    if (dwarf_version >= 4)
	      size += size_of_uleb128 (lsize);
	    else
	      size += constant_size (lsize);
	    size += lsize;
	  }
	  break;
	case dw_val_class_loc_list:
	  if (dwarf_split_debug_info && dwarf_version >= 5)
	    {
	      gcc_assert (AT_loc_list (a)->num_assigned);
	      size += size_of_uleb128 (AT_loc_list (a)->hash);
	    }
          else
            size += dwarf_offset_size;
	  break;
	case dw_val_class_view_list:
	  size += dwarf_offset_size;
	  break;
	case dw_val_class_range_list:
	  if (value_format (a) == DW_FORM_rnglistx)
	    {
	      gcc_assert (rnglist_idx);
	      dw_ranges *r = &(*ranges_table)[a->dw_attr_val.v.val_offset];
	      size += size_of_uleb128 (r->idx);
	    }
	  else
	    size += dwarf_offset_size;
	  break;
	case dw_val_class_const:
	  size += size_of_sleb128 (AT_int (a));
	  break;
	case dw_val_class_unsigned_const:
	  {
	    int csize = constant_size (AT_unsigned (a));
	    if (dwarf_version == 3
		&& a->dw_attr == DW_AT_data_member_location
		&& csize >= 4)
	      size += size_of_uleb128 (AT_unsigned (a));
	    else
	      size += csize;
	  }
	  break;
	case dw_val_class_symview:
	  if (symview_upper_bound <= 0xff)
	    size += 1;
	  else if (symview_upper_bound <= 0xffff)
	    size += 2;
	  else if (symview_upper_bound <= 0xffffffff)
	    size += 4;
	  else
	    size += 8;
	  break;
	case dw_val_class_const_implicit:
	case dw_val_class_unsigned_const_implicit:
	case dw_val_class_file_implicit:
	  /* These occupy no size in the DIE, just an extra sleb128 in
	     .debug_abbrev.  */
	  break;
	case dw_val_class_const_double:
	  size += HOST_BITS_PER_DOUBLE_INT / HOST_BITS_PER_CHAR;
	  if (HOST_BITS_PER_WIDE_INT >= DWARF_LARGEST_DATA_FORM_BITS)
	    size++; /* block */
	  break;
	case dw_val_class_wide_int:
	  size += (get_full_len (*a->dw_attr_val.v.val_wide)
		   * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
	  if (get_full_len (*a->dw_attr_val.v.val_wide)
	      * HOST_BITS_PER_WIDE_INT > DWARF_LARGEST_DATA_FORM_BITS)
	    size++; /* block */
	  break;
	case dw_val_class_vec:
	  size += constant_size (a->dw_attr_val.v.val_vec.length
				 * a->dw_attr_val.v.val_vec.elt_size)
		  + a->dw_attr_val.v.val_vec.length
		    * a->dw_attr_val.v.val_vec.elt_size; /* block */
	  break;
	case dw_val_class_flag:
	  if (dwarf_version >= 4)
	    /* Currently all add_AT_flag calls pass in 1 as last argument,
	       so DW_FORM_flag_present can be used.  If that ever changes,
	       we'll need to use DW_FORM_flag and have some optimization
	       in build_abbrev_table that will change those to
	       DW_FORM_flag_present if it is set to 1 in all DIEs using
	       the same abbrev entry.  */
	    gcc_assert (a->dw_attr_val.v.val_flag == 1);
	  else
	    size += 1;
	  break;
	case dw_val_class_die_ref:
	  if (AT_ref_external (a))
	    {
	      /* In DWARF4, we use DW_FORM_ref_sig8; for earlier versions
		 we use DW_FORM_ref_addr.  In DWARF2, DW_FORM_ref_addr
		 is sized by target address length, whereas in DWARF3
		 it's always sized as an offset.  */
	      if (AT_ref (a)->comdat_type_p)
		size += DWARF_TYPE_SIGNATURE_SIZE;
	      else if (dwarf_version == 2)
		size += DWARF2_ADDR_SIZE;
	      else
		size += dwarf_offset_size;
	    }
	  else
	    size += dwarf_offset_size;
	  break;
	case dw_val_class_fde_ref:
	  size += dwarf_offset_size;
	  break;
	case dw_val_class_lbl_id:
          if (dwarf_split_debug_info && AT_index (a) != NOT_INDEXED)
            {
              gcc_assert (AT_index (a) != NO_INDEX_ASSIGNED);
              size += size_of_uleb128 (AT_index (a));
            }
          else
            size += DWARF2_ADDR_SIZE;
	  break;
	case dw_val_class_lineptr:
	case dw_val_class_macptr:
	case dw_val_class_loclistsptr:
	  size += dwarf_offset_size;
	  break;
	case dw_val_class_str:
          form = AT_string_form (a);
	  if (form == DW_FORM_strp || form == DW_FORM_line_strp)
	    size += dwarf_offset_size;
	  else if (form == dwarf_FORM (DW_FORM_strx))
	    size += size_of_uleb128 (AT_index (a));
	  else
	    size += strlen (a->dw_attr_val.v.val_str->str) + 1;
	  break;
	case dw_val_class_file:
	  size += constant_size (maybe_emit_file (a->dw_attr_val.v.val_file));
	  break;
	case dw_val_class_data8:
	  size += 8;
	  break;
	case dw_val_class_vms_delta:
	  size += dwarf_offset_size;
	  break;
	case dw_val_class_high_pc:
	  size += DWARF2_ADDR_SIZE;
	  break;
	case dw_val_class_discr_value:
	  size += size_of_discr_value (&a->dw_attr_val.v.val_discr_value);
	  break;
	case dw_val_class_discr_list:
	    {
	      unsigned block_size = size_of_discr_list (AT_discr_list (a));

	      /* This is a block, so we have the block length and then its
		 data.  */
	      size += constant_size (block_size) + block_size;
	    }
	  break;
	default:
	  gcc_unreachable ();
	}
    }

  return size;
}

/* Size the debugging information associated with a given DIE.  Visits the
   DIE's children recursively.  Updates the global variable next_die_offset, on
   each time through.  Uses the current value of next_die_offset to update the
   die_offset field in each DIE.  */

static void
calc_die_sizes (dw_die_ref die)
{
  dw_die_ref c;

  gcc_assert (die->die_offset == 0
	      || (unsigned long int) die->die_offset == next_die_offset);
  die->die_offset = next_die_offset;
  next_die_offset += size_of_die (die);

  FOR_EACH_CHILD (die, c, calc_die_sizes (c));

  if (die->die_child != NULL)
    /* Count the null byte used to terminate sibling lists.  */
    next_die_offset += 1;
}

/* Size just the base type children at the start of the CU.
   This is needed because build_abbrev needs to size locs
   and sizing of type based stack ops needs to know die_offset
   values for the base types.  */

static void
calc_base_type_die_sizes (void)
{
  unsigned long die_offset = (dwarf_split_debug_info
			      ? DWARF_COMPILE_UNIT_SKELETON_HEADER_SIZE
			      : DWARF_COMPILE_UNIT_HEADER_SIZE);
  unsigned int i;
  dw_die_ref base_type;
#if ENABLE_ASSERT_CHECKING
  dw_die_ref prev = comp_unit_die ()->die_child;
#endif

  die_offset += size_of_die (comp_unit_die ());
  for (i = 0; base_types.iterate (i, &base_type); i++)
    {
#if ENABLE_ASSERT_CHECKING
      gcc_assert (base_type->die_offset == 0
		  && prev->die_sib == base_type
		  && base_type->die_child == NULL
		  && base_type->die_abbrev);
      prev = base_type;
#endif
      if (abbrev_opt_start
	  && base_type->die_abbrev >= abbrev_opt_base_type_end)
	abbrev_opt_base_type_end = base_type->die_abbrev + 1;
      base_type->die_offset = die_offset;
      die_offset += size_of_die (base_type);
    }
}

/* Set the marks for a die and its children.  We do this so
   that we know whether or not a reference needs to use FORM_ref_addr; only
   DIEs in the same CU will be marked.  We used to clear out the offset
   and use that as the flag, but ran into ordering problems.  */

static void
mark_dies (dw_die_ref die)
{
  dw_die_ref c;

  gcc_assert (!die->die_mark);

  die->die_mark = 1;
  FOR_EACH_CHILD (die, c, mark_dies (c));
}

/* Clear the marks for a die and its children.  */

static void
unmark_dies (dw_die_ref die)
{
  dw_die_ref c;

  if (! use_debug_types)
    gcc_assert (die->die_mark);

  die->die_mark = 0;
  FOR_EACH_CHILD (die, c, unmark_dies (c));
}

/* Clear the marks for a die, its children and referred dies.  */

static void
unmark_all_dies (dw_die_ref die)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;

  if (!die->die_mark)
    return;
  die->die_mark = 0;

  FOR_EACH_CHILD (die, c, unmark_all_dies (c));

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_die_ref)
      unmark_all_dies (AT_ref (a));
}

/* Calculate if the entry should appear in the final output file.  It may be
   from a pruned a type.  */

static bool
include_pubname_in_output (vec<pubname_entry, va_gc> *table, pubname_entry *p)
{
  /* By limiting gnu pubnames to definitions only, gold can generate a
     gdb index without entries for declarations, which don't include
     enough information to be useful.  */
  if (debug_generate_pub_sections == 2 && is_declaration_die (p->die))
    return false;

  if (table == pubname_table)
    {
      /* Enumerator names are part of the pubname table, but the
         parent DW_TAG_enumeration_type die may have been pruned.
         Don't output them if that is the case.  */
      if (p->die->die_tag == DW_TAG_enumerator &&
          (p->die->die_parent == NULL
           || !p->die->die_parent->die_perennial_p))
        return false;

      /* Everything else in the pubname table is included.  */
      return true;
    }

  /* The pubtypes table shouldn't include types that have been
     pruned.  */
  return (p->die->die_offset != 0
          || !flag_eliminate_unused_debug_types);
}

/* Return the size of the .debug_pubnames or .debug_pubtypes table
   generated for the compilation unit.  */

static unsigned long
size_of_pubnames (vec<pubname_entry, va_gc> *names)
{
  unsigned long size;
  unsigned i;
  pubname_entry *p;
  int space_for_flags = (debug_generate_pub_sections == 2) ? 1 : 0;

  size = DWARF_PUBNAMES_HEADER_SIZE;
  FOR_EACH_VEC_ELT (*names, i, p)
    if (include_pubname_in_output (names, p))
      size += strlen (p->name) + dwarf_offset_size + 1 + space_for_flags;

  size += dwarf_offset_size;
  return size;
}

/* Return the size of the information in the .debug_aranges section.  */

static unsigned long
size_of_aranges (void)
{
  unsigned long size;

  size = DWARF_ARANGES_HEADER_SIZE;

  /* Count the address/length pair for this compilation unit.  */
  if (switch_text_ranges)
    size += 2 * DWARF2_ADDR_SIZE
	    * (vec_safe_length (switch_text_ranges) / 2 + 1);
  if (switch_cold_ranges)
    size += 2 * DWARF2_ADDR_SIZE
	    * (vec_safe_length (switch_cold_ranges) / 2 + 1);
  if (have_multiple_function_sections)
    {
      unsigned fde_idx;
      dw_fde_ref fde;

      FOR_EACH_VEC_ELT (*fde_vec, fde_idx, fde)
	{
	  if (fde->ignored_debug)
	    continue;
	  if (!fde->in_std_section)
	    size += 2 * DWARF2_ADDR_SIZE;
	  if (fde->dw_fde_second_begin && !fde->second_in_std_section)
	    size += 2 * DWARF2_ADDR_SIZE;
	}
    }

  /* Count the two zero words used to terminated the address range table.  */
  size += 2 * DWARF2_ADDR_SIZE;
  return size;
}

/* Select the encoding of an attribute value.  */

static enum dwarf_form
value_format (dw_attr_node *a)
{
  switch (AT_class (a))
    {
    case dw_val_class_addr:
      /* Only very few attributes allow DW_FORM_addr.  */
      switch (a->dw_attr)
	{
	case DW_AT_low_pc:
	case DW_AT_high_pc:
	case DW_AT_entry_pc:
	case DW_AT_trampoline:
          return (AT_index (a) == NOT_INDEXED
                  ? DW_FORM_addr : dwarf_FORM (DW_FORM_addrx));
	default:
	  break;
	}
      switch (DWARF2_ADDR_SIZE)
	{
	case 1:
	  return DW_FORM_data1;
	case 2:
	  return DW_FORM_data2;
	case 4:
	  return DW_FORM_data4;
	case 8:
	  return DW_FORM_data8;
	default:
	  gcc_unreachable ();
	}
    case dw_val_class_loc_list:
      if (dwarf_split_debug_info
	  && dwarf_version >= 5
	  && AT_loc_list (a)->num_assigned)
	return DW_FORM_loclistx;
      /* FALLTHRU */
    case dw_val_class_view_list:
    case dw_val_class_range_list:
      /* For range lists in DWARF 5, use DW_FORM_rnglistx from .debug_info.dwo
	 but in .debug_info use DW_FORM_sec_offset, which is shorter if we
	 care about sizes of .debug* sections in shared libraries and
	 executables and don't take into account relocations that affect just
	 relocatable objects - for DW_FORM_rnglistx we'd have to emit offset
	 table in the .debug_rnglists section.  */
      if (dwarf_split_debug_info
	  && dwarf_version >= 5
	  && AT_class (a) == dw_val_class_range_list
	  && rnglist_idx
	  && a->dw_attr_val.val_entry != RELOCATED_OFFSET)
	return DW_FORM_rnglistx;
      if (dwarf_version >= 4)
	return DW_FORM_sec_offset;
      /* FALLTHRU */
    case dw_val_class_vms_delta:
    case dw_val_class_offset:
      switch (dwarf_offset_size)
	{
	case 4:
	  return DW_FORM_data4;
	case 8:
	  return DW_FORM_data8;
	default:
	  gcc_unreachable ();
	}
    case dw_val_class_loc:
      if (dwarf_version >= 4)
	return DW_FORM_exprloc;
      switch (constant_size (size_of_locs (AT_loc (a))))
	{
	case 1:
	  return DW_FORM_block1;
	case 2:
	  return DW_FORM_block2;
	case 4:
	  return DW_FORM_block4;
	default:
	  gcc_unreachable ();
	}
    case dw_val_class_const:
      return DW_FORM_sdata;
    case dw_val_class_unsigned_const:
      switch (constant_size (AT_unsigned (a)))
	{
	case 1:
	  return DW_FORM_data1;
	case 2:
	  return DW_FORM_data2;
	case 4:
	  /* In DWARF3 DW_AT_data_member_location with
	     DW_FORM_data4 or DW_FORM_data8 is a loclistptr, not
	     constant, so we need to use DW_FORM_udata if we need
	     a large constant.  */
	  if (dwarf_version == 3 && a->dw_attr == DW_AT_data_member_location)
	    return DW_FORM_udata;
	  return DW_FORM_data4;
	case 8:
	  if (dwarf_version == 3 && a->dw_attr == DW_AT_data_member_location)
	    return DW_FORM_udata;
	  return DW_FORM_data8;
	default:
	  gcc_unreachable ();
	}
    case dw_val_class_const_implicit:
    case dw_val_class_unsigned_const_implicit:
    case dw_val_class_file_implicit:
      return DW_FORM_implicit_const;
    case dw_val_class_const_double:
      switch (HOST_BITS_PER_WIDE_INT)
	{
	case 8:
	  return DW_FORM_data2;
	case 16:
	  return DW_FORM_data4;
	case 32:
	  return DW_FORM_data8;
	case 64:
	  if (dwarf_version >= 5)
	    return DW_FORM_data16;
	  /* FALLTHRU */
	default:
	  return DW_FORM_block1;
	}
    case dw_val_class_wide_int:
      switch (get_full_len (*a->dw_attr_val.v.val_wide) * HOST_BITS_PER_WIDE_INT)
	{
	case 8:
	  return DW_FORM_data1;
	case 16:
	  return DW_FORM_data2;
	case 32:
	  return DW_FORM_data4;
	case 64:
	  return DW_FORM_data8;
	case 128:
	  if (dwarf_version >= 5)
	    return DW_FORM_data16;
	  /* FALLTHRU */
	default:
	  return DW_FORM_block1;
	}
    case dw_val_class_symview:
      /* ??? We might use uleb128, but then we'd have to compute
	 .debug_info offsets in the assembler.  */
      if (symview_upper_bound <= 0xff)
	return DW_FORM_data1;
      else if (symview_upper_bound <= 0xffff)
	return DW_FORM_data2;
      else if (symview_upper_bound <= 0xffffffff)
	return DW_FORM_data4;
      else
	return DW_FORM_data8;
    case dw_val_class_vec:
      switch (constant_size (a->dw_attr_val.v.val_vec.length
			     * a->dw_attr_val.v.val_vec.elt_size))
	{
	case 1:
	  return DW_FORM_block1;
	case 2:
	  return DW_FORM_block2;
	case 4:
	  return DW_FORM_block4;
	default:
	  gcc_unreachable ();
	}
    case dw_val_class_flag:
      if (dwarf_version >= 4)
	{
	  /* Currently all add_AT_flag calls pass in 1 as last argument,
	     so DW_FORM_flag_present can be used.  If that ever changes,
	     we'll need to use DW_FORM_flag and have some optimization
	     in build_abbrev_table that will change those to
	     DW_FORM_flag_present if it is set to 1 in all DIEs using
	     the same abbrev entry.  */
	  gcc_assert (a->dw_attr_val.v.val_flag == 1);
	  return DW_FORM_flag_present;
	}
      return DW_FORM_flag;
    case dw_val_class_die_ref:
      if (AT_ref_external (a))
	{
	  if (AT_ref (a)->comdat_type_p)
	    return DW_FORM_ref_sig8;
	  else
	    return DW_FORM_ref_addr;
	}
      else
	return DW_FORM_ref;
    case dw_val_class_fde_ref:
      return DW_FORM_data;
    case dw_val_class_lbl_id:
      return (AT_index (a) == NOT_INDEXED
              ? DW_FORM_addr : dwarf_FORM (DW_FORM_addrx));
    case dw_val_class_lineptr:
    case dw_val_class_macptr:
    case dw_val_class_loclistsptr:
      return dwarf_version >= 4 ? DW_FORM_sec_offset : DW_FORM_data;
    case dw_val_class_str:
      return AT_string_form (a);
    case dw_val_class_file:
      switch (constant_size (maybe_emit_file (a->dw_attr_val.v.val_file)))
	{
	case 1:
	  return DW_FORM_data1;
	case 2:
	  return DW_FORM_data2;
	case 4:
	  return DW_FORM_data4;
	default:
	  gcc_unreachable ();
	}

    case dw_val_class_data8:
      return DW_FORM_data8;

    case dw_val_class_high_pc:
      switch (DWARF2_ADDR_SIZE)
	{
	case 1:
	  return DW_FORM_data1;
	case 2:
	  return DW_FORM_data2;
	case 4:
	  return DW_FORM_data4;
	case 8:
	  return DW_FORM_data8;
	default:
	  gcc_unreachable ();
	}

    case dw_val_class_discr_value:
      return (a->dw_attr_val.v.val_discr_value.pos
	      ? DW_FORM_udata
	      : DW_FORM_sdata);
    case dw_val_class_discr_list:
      switch (constant_size (size_of_discr_list (AT_discr_list (a))))
	{
	case 1:
	  return DW_FORM_block1;
	case 2:
	  return DW_FORM_block2;
	case 4:
	  return DW_FORM_block4;
	default:
	  gcc_unreachable ();
	}

    default:
      gcc_unreachable ();
    }
}

/* Output the encoding of an attribute value.  */

static void
output_value_format (dw_attr_node *a)
{
  enum dwarf_form form = value_format (a);

  dw2_asm_output_data_uleb128 (form, "(%s)", dwarf_form_name (form));
}

/* Given a die and id, produce the appropriate abbreviations.  */

static void
output_die_abbrevs (unsigned long abbrev_id, dw_die_ref abbrev)
{
  unsigned ix;
  dw_attr_node *a_attr;

  dw2_asm_output_data_uleb128 (abbrev_id, "(abbrev code)");
  dw2_asm_output_data_uleb128 (abbrev->die_tag, "(TAG: %s)",
                               dwarf_tag_name (abbrev->die_tag));

  if (abbrev->die_child != NULL)
    dw2_asm_output_data (1, DW_children_yes, "DW_children_yes");
  else
    dw2_asm_output_data (1, DW_children_no, "DW_children_no");

  for (ix = 0; vec_safe_iterate (abbrev->die_attr, ix, &a_attr); ix++)
    {
      dw2_asm_output_data_uleb128 (a_attr->dw_attr, "(%s)",
                                   dwarf_attr_name (a_attr->dw_attr));
      output_value_format (a_attr);
      if (value_format (a_attr) == DW_FORM_implicit_const)
	{
	  if (AT_class (a_attr) == dw_val_class_file_implicit)
	    {
	      int f = maybe_emit_file (a_attr->dw_attr_val.v.val_file);
	      const char *filename = a_attr->dw_attr_val.v.val_file->filename;
	      dw2_asm_output_data_sleb128 (f, "(%s)", filename);
	    }
	  else
	    dw2_asm_output_data_sleb128 (a_attr->dw_attr_val.v.val_int, NULL);
	}
    }

  dw2_asm_output_data (1, 0, NULL);
  dw2_asm_output_data (1, 0, NULL);
}


/* Output the .debug_abbrev section which defines the DIE abbreviation
   table.  */

static void
output_abbrev_section (void)
{
  unsigned int abbrev_id;
  dw_die_ref abbrev;

  FOR_EACH_VEC_SAFE_ELT (abbrev_die_table, abbrev_id, abbrev)
    if (abbrev_id != 0)
      output_die_abbrevs (abbrev_id, abbrev);

  /* Terminate the table.  */
  dw2_asm_output_data (1, 0, NULL);
}

/* Return a new location list, given the begin and end range, and the
   expression.  */

static inline dw_loc_list_ref
new_loc_list (dw_loc_descr_ref expr, const char *begin, var_loc_view vbegin,
	      const char *end, var_loc_view vend,
	      const char *section)
{
  dw_loc_list_ref retlist = ggc_cleared_alloc<dw_loc_list_node> ();

  retlist->begin = begin;
  retlist->begin_entry = NULL;
  retlist->end = end;
  retlist->end_entry = NULL;
  retlist->expr = expr;
  retlist->section = section;
  retlist->vbegin = vbegin;
  retlist->vend = vend;

  return retlist;
}

/* Return true iff there's any nonzero view number in the loc list.

   ??? When views are not enabled, we'll often extend a single range
   to the entire function, so that we emit a single location
   expression rather than a location list.  With views, even with a
   single range, we'll output a list if start or end have a nonzero
   view.  If we change this, we may want to stop splitting a single
   range in dw_loc_list just because of a nonzero view, even if it
   straddles across hot/cold partitions.  */

static bool
loc_list_has_views (dw_loc_list_ref list)
{
  if (!debug_variable_location_views)
    return false;

  for (dw_loc_list_ref loc = list;
       loc != NULL; loc = loc->dw_loc_next)
    if (!ZERO_VIEW_P (loc->vbegin) || !ZERO_VIEW_P (loc->vend))
      return true;

  return false;
}

/* Generate a new internal symbol for this location list node, if it
   hasn't got one yet.  */

static inline void
gen_llsym (dw_loc_list_ref list)
{
  gcc_assert (!list->ll_symbol);
  list->ll_symbol = gen_internal_sym ("LLST");

  if (!loc_list_has_views (list))
    return;

  if (dwarf2out_locviews_in_attribute ())
    {
      /* Use the same label_num for the view list.  */
      label_num--;
      list->vl_symbol = gen_internal_sym ("LVUS");
    }
  else
    list->vl_symbol = list->ll_symbol;
}

/* Generate a symbol for the list, but only if we really want to emit
   it as a list.  */

static inline void
maybe_gen_llsym (dw_loc_list_ref list)
{
  if (!list || (!list->dw_loc_next && !loc_list_has_views (list)))
    return;

  gen_llsym (list);
}

/* Determine whether or not to skip loc_list entry CURR.  If SIZEP is
   NULL, don't consider size of the location expression.  If we're not
   to skip it, and SIZEP is non-null, store the size of CURR->expr's
   representation in *SIZEP.  */

static bool
skip_loc_list_entry (dw_loc_list_ref curr, unsigned long *sizep = NULL)
{
  /* Don't output an entry that starts and ends at the same address.  */
  if (strcmp (curr->begin, curr->end) == 0
      && curr->vbegin == curr->vend && !curr->force)
    return true;

  if (!sizep)
    return false;

  unsigned long size = size_of_locs (curr->expr);

  /* If the expression is too large, drop it on the floor.  We could
     perhaps put it into DW_TAG_dwarf_procedure and refer to that
     in the expression, but >= 64KB expressions for a single value
     in a single range are unlikely very useful.  */
  if (dwarf_version < 5 && size > 0xffff)
    return true;

  *sizep = size;

  return false;
}

/* Output a view pair loclist entry for CURR, if it requires one.  */

static void
dwarf2out_maybe_output_loclist_view_pair (dw_loc_list_ref curr)
{
  if (!dwarf2out_locviews_in_loclist ())
    return;

  if (ZERO_VIEW_P (curr->vbegin) && ZERO_VIEW_P (curr->vend))
    return;

#ifdef DW_LLE_view_pair
  dw2_asm_output_data (1, DW_LLE_view_pair, "DW_LLE_view_pair");

  if (dwarf2out_as_locview_support)
    {
      if (ZERO_VIEW_P (curr->vbegin))
	dw2_asm_output_data_uleb128 (0, "Location view begin");
      else
	{
	  char label[MAX_ARTIFICIAL_LABEL_BYTES];
	  ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vbegin);
	  dw2_asm_output_symname_uleb128 (label, "Location view begin");
	}

      if (ZERO_VIEW_P (curr->vend))
	dw2_asm_output_data_uleb128 (0, "Location view end");
      else
	{
	  char label[MAX_ARTIFICIAL_LABEL_BYTES];
	  ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vend);
	  dw2_asm_output_symname_uleb128 (label, "Location view end");
	}
    }
  else
    {
      dw2_asm_output_data_uleb128 (curr->vbegin, "Location view begin");
      dw2_asm_output_data_uleb128 (curr->vend, "Location view end");
    }
#endif /* DW_LLE_view_pair */

  return;
}

/* Output the location list given to us.  */

static void
output_loc_list (dw_loc_list_ref list_head)
{
  int vcount = 0, lcount = 0;

  if (list_head->emitted)
    return;
  list_head->emitted = true;

  if (list_head->vl_symbol && dwarf2out_locviews_in_attribute ())
    {
      ASM_OUTPUT_LABEL (asm_out_file, list_head->vl_symbol);

      for (dw_loc_list_ref curr = list_head; curr != NULL;
	   curr = curr->dw_loc_next)
	{
	  unsigned long size;

	  if (skip_loc_list_entry (curr, &size))
	    continue;

	  vcount++;

	  /* ?? dwarf_split_debug_info?  */
	  if (dwarf2out_as_locview_support)
	    {
	      char label[MAX_ARTIFICIAL_LABEL_BYTES];

	      if (!ZERO_VIEW_P (curr->vbegin))
		{
		  ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vbegin);
		  dw2_asm_output_symname_uleb128 (label,
						  "View list begin (%s)",
						  list_head->vl_symbol);
		}
	      else
		dw2_asm_output_data_uleb128 (0,
					     "View list begin (%s)",
					     list_head->vl_symbol);

	      if (!ZERO_VIEW_P (curr->vend))
		{
		  ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vend);
		  dw2_asm_output_symname_uleb128 (label,
						  "View list end (%s)",
						  list_head->vl_symbol);
		}
	      else
		dw2_asm_output_data_uleb128 (0,
					     "View list end (%s)",
					     list_head->vl_symbol);
	    }
	  else
	    {
	      dw2_asm_output_data_uleb128 (curr->vbegin,
					   "View list begin (%s)",
					   list_head->vl_symbol);
	      dw2_asm_output_data_uleb128 (curr->vend,
					   "View list end (%s)",
					   list_head->vl_symbol);
	    }
	}
    }

  ASM_OUTPUT_LABEL (asm_out_file, list_head->ll_symbol);

  const char *last_section = NULL;
  const char *base_label = NULL;

  /* Walk the location list, and output each range + expression.  */
  for (dw_loc_list_ref curr = list_head; curr != NULL;
       curr = curr->dw_loc_next)
    {
      unsigned long size;

      /* Skip this entry?  If we skip it here, we must skip it in the
	 view list above as well. */
      if (skip_loc_list_entry (curr, &size))
	continue;

      lcount++;

      if (dwarf_version >= 5)
	{
	  if (dwarf_split_debug_info && HAVE_AS_LEB128)
	    {
	      dwarf2out_maybe_output_loclist_view_pair (curr);
	      /* For -gsplit-dwarf, emit DW_LLE_startx_length, which has
		 uleb128 index into .debug_addr and uleb128 length.  */
	      dw2_asm_output_data (1, DW_LLE_startx_length,
				   "DW_LLE_startx_length (%s)",
				   list_head->ll_symbol);
	      dw2_asm_output_data_uleb128 (curr->begin_entry->index,
					   "Location list range start index "
					   "(%s)", curr->begin);
	      dw2_asm_output_delta_uleb128 (curr->end, curr->begin,
					    "Location list length (%s)",
					    list_head->ll_symbol);
	    }
	  else if (dwarf_split_debug_info)
	    {
	      dwarf2out_maybe_output_loclist_view_pair (curr);
	      /* For -gsplit-dwarf without usable .uleb128 support, emit
		 DW_LLE_startx_endx, which has two uleb128 indexes into
		 .debug_addr.  */
	      dw2_asm_output_data (1, DW_LLE_startx_endx,
				   "DW_LLE_startx_endx (%s)",
				   list_head->ll_symbol);
	      dw2_asm_output_data_uleb128 (curr->begin_entry->index,
					   "Location list range start index "
					   "(%s)", curr->begin);
	      dw2_asm_output_data_uleb128 (curr->end_entry->index,
					   "Location list range end index "
					   "(%s)", curr->end);
	    }
	  else if (!have_multiple_function_sections && HAVE_AS_LEB128)
	    {
	      dwarf2out_maybe_output_loclist_view_pair (curr);
	      /* If all code is in .text section, the base address is
		 already provided by the CU attributes.  Use
		 DW_LLE_offset_pair where both addresses are uleb128 encoded
		 offsets against that base.  */
	      dw2_asm_output_data (1, DW_LLE_offset_pair,
				   "DW_LLE_offset_pair (%s)",
				   list_head->ll_symbol);
	      dw2_asm_output_delta_uleb128 (curr->begin, curr->section,
					    "Location list begin address (%s)",
					    list_head->ll_symbol);
	      dw2_asm_output_delta_uleb128 (curr->end, curr->section,
					    "Location list end address (%s)",
					    list_head->ll_symbol);
	    }
	  else if (HAVE_AS_LEB128)
	    {
	      /* Otherwise, find out how many consecutive entries could share
		 the same base entry.  If just one, emit DW_LLE_start_length,
		 otherwise emit DW_LLE_base_address for the base address
		 followed by a series of DW_LLE_offset_pair.  */
	      if (last_section == NULL || curr->section != last_section)
		{
		  dw_loc_list_ref curr2;
		  for (curr2 = curr->dw_loc_next; curr2 != NULL;
		       curr2 = curr2->dw_loc_next)
		    {
		      if (strcmp (curr2->begin, curr2->end) == 0
			  && !curr2->force)
			continue;
		      break;
		    }
		  if (curr2 == NULL || curr->section != curr2->section)
		    last_section = NULL;
		  else
		    {
		      last_section = curr->section;
		      base_label = curr->begin;
		      dw2_asm_output_data (1, DW_LLE_base_address,
					   "DW_LLE_base_address (%s)",
					   list_head->ll_symbol);
		      dw2_asm_output_addr (DWARF2_ADDR_SIZE, base_label,
					   "Base address (%s)",
					   list_head->ll_symbol);
		    }
		}
	      /* Only one entry with the same base address.  Use
		 DW_LLE_start_length with absolute address and uleb128
		 length.  */
	      if (last_section == NULL)
		{
		  dwarf2out_maybe_output_loclist_view_pair (curr);
		  dw2_asm_output_data (1, DW_LLE_start_length,
				       "DW_LLE_start_length (%s)",
				       list_head->ll_symbol);
		  dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->begin,
				       "Location list begin address (%s)",
				       list_head->ll_symbol);
		  dw2_asm_output_delta_uleb128 (curr->end, curr->begin,
						"Location list length "
						"(%s)", list_head->ll_symbol);
		}
	      /* Otherwise emit DW_LLE_offset_pair, relative to above emitted
		 DW_LLE_base_address.  */
	      else
		{
		  dwarf2out_maybe_output_loclist_view_pair (curr);
		  dw2_asm_output_data (1, DW_LLE_offset_pair,
				       "DW_LLE_offset_pair (%s)",
				       list_head->ll_symbol);
		  dw2_asm_output_delta_uleb128 (curr->begin, base_label,
						"Location list begin address "
						"(%s)", list_head->ll_symbol);
		  dw2_asm_output_delta_uleb128 (curr->end, base_label,
						"Location list end address "
						"(%s)", list_head->ll_symbol);
		}
	    }
	  /* The assembler does not support .uleb128 directive.  Emit
	     DW_LLE_start_end with a pair of absolute addresses.  */
	  else
	    {
	      dwarf2out_maybe_output_loclist_view_pair (curr);
	      dw2_asm_output_data (1, DW_LLE_start_end,
				   "DW_LLE_start_end (%s)",
				   list_head->ll_symbol);
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->begin,
				   "Location list begin address (%s)",
				   list_head->ll_symbol);
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->end,
				   "Location list end address (%s)",
				   list_head->ll_symbol);
	    }
	}
      else if (dwarf_split_debug_info)
	{
	  /* For -gsplit-dwarf -gdwarf-{2,3,4} emit index into .debug_addr
	     and 4 byte length.  */
	  dw2_asm_output_data (1, DW_LLE_GNU_start_length_entry,
			       "Location list start/length entry (%s)",
			       list_head->ll_symbol);
	  dw2_asm_output_data_uleb128 (curr->begin_entry->index,
				       "Location list range start index (%s)",
				       curr->begin);
	  /* The length field is 4 bytes.  If we ever need to support
	     an 8-byte length, we can add a new DW_LLE code or fall back
	     to DW_LLE_GNU_start_end_entry.  */
	  dw2_asm_output_delta (4, curr->end, curr->begin,
				"Location list range length (%s)",
				list_head->ll_symbol);
	}
      else if (!have_multiple_function_sections)
	{
	  /* Pair of relative addresses against start of text section.  */
	  dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->begin, curr->section,
				"Location list begin address (%s)",
				list_head->ll_symbol);
	  dw2_asm_output_delta (DWARF2_ADDR_SIZE, curr->end, curr->section,
				"Location list end address (%s)",
				list_head->ll_symbol);
	}
      else
	{
	  /* Pair of absolute addresses.  */
	  dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->begin,
			       "Location list begin address (%s)",
			       list_head->ll_symbol);
	  dw2_asm_output_addr (DWARF2_ADDR_SIZE, curr->end,
			       "Location list end address (%s)",
			       list_head->ll_symbol);
	}

      /* Output the block length for this list of location operations.  */
      if (dwarf_version >= 5)
	dw2_asm_output_data_uleb128 (size, "Location expression size");
      else
	{
	  gcc_assert (size <= 0xffff);
	  dw2_asm_output_data (2, size, "Location expression size");
	}

      output_loc_sequence (curr->expr, -1);
    }

  /* And finally list termination.  */
  if (dwarf_version >= 5)
    dw2_asm_output_data (1, DW_LLE_end_of_list,
			 "DW_LLE_end_of_list (%s)", list_head->ll_symbol);
  else if (dwarf_split_debug_info)
    dw2_asm_output_data (1, DW_LLE_GNU_end_of_list_entry,
			 "Location list terminator (%s)",
			 list_head->ll_symbol);
  else
    {
      dw2_asm_output_data (DWARF2_ADDR_SIZE, 0,
			   "Location list terminator begin (%s)",
			   list_head->ll_symbol);
      dw2_asm_output_data (DWARF2_ADDR_SIZE, 0,
			   "Location list terminator end (%s)",
			   list_head->ll_symbol);
    }

  gcc_assert (!list_head->vl_symbol
	      || vcount == lcount * (dwarf2out_locviews_in_attribute () ? 1 : 0));
}

/* Output a range_list offset into the .debug_ranges or .debug_rnglists
   section.  Emit a relocated reference if val_entry is NULL, otherwise,
   emit an indirect reference.  */

static void
output_range_list_offset (dw_attr_node *a)
{
  const char *name = dwarf_attr_name (a->dw_attr);

  if (a->dw_attr_val.val_entry == RELOCATED_OFFSET)
    {
      if (dwarf_version >= 5)
	{
	  dw_ranges *r = &(*ranges_table)[a->dw_attr_val.v.val_offset];
	  dw2_asm_output_offset (dwarf_offset_size, r->label,
				 debug_ranges_section, "%s", name);
	}
      else
	{
	  char *p = strchr (ranges_section_label, '\0');
	  sprintf (p, "+" HOST_WIDE_INT_PRINT_HEX,
		   a->dw_attr_val.v.val_offset * 2 * DWARF2_ADDR_SIZE);
	  dw2_asm_output_offset (dwarf_offset_size, ranges_section_label,
				 debug_ranges_section, "%s", name);
	  *p = '\0';
	}
    }
  else if (dwarf_version >= 5)
    {
      dw_ranges *r = &(*ranges_table)[a->dw_attr_val.v.val_offset];
      gcc_assert (rnglist_idx);
      dw2_asm_output_data_uleb128 (r->idx, "%s", name);
    }
  else
    dw2_asm_output_data (dwarf_offset_size,
			 a->dw_attr_val.v.val_offset * 2 * DWARF2_ADDR_SIZE,
                         "%s (offset from %s)", name, ranges_section_label);
}

/* Output the offset into the debug_loc section.  */

static void
output_loc_list_offset (dw_attr_node *a)
{
  char *sym = AT_loc_list (a)->ll_symbol;

  gcc_assert (sym);
  if (!dwarf_split_debug_info)
    dw2_asm_output_offset (dwarf_offset_size, sym, debug_loc_section,
                           "%s", dwarf_attr_name (a->dw_attr));
  else if (dwarf_version >= 5)
    {
      gcc_assert (AT_loc_list (a)->num_assigned);
      dw2_asm_output_data_uleb128 (AT_loc_list (a)->hash, "%s (%s)",
				   dwarf_attr_name (a->dw_attr),
				   sym);
    }
  else
    dw2_asm_output_delta (dwarf_offset_size, sym, loc_section_label,
			  "%s", dwarf_attr_name (a->dw_attr));
}

/* Output the offset into the debug_loc section.  */

static void
output_view_list_offset (dw_attr_node *a)
{
  char *sym = (*AT_loc_list_ptr (a))->vl_symbol;

  gcc_assert (sym);
  if (dwarf_split_debug_info)
    dw2_asm_output_delta (dwarf_offset_size, sym, loc_section_label,
                          "%s", dwarf_attr_name (a->dw_attr));
  else
    dw2_asm_output_offset (dwarf_offset_size, sym, debug_loc_section,
                           "%s", dwarf_attr_name (a->dw_attr));
}

/* Output an attribute's index or value appropriately.  */

static void
output_attr_index_or_value (dw_attr_node *a)
{
  const char *name = dwarf_attr_name (a->dw_attr);

  if (dwarf_split_debug_info && AT_index (a) != NOT_INDEXED)
    {
      dw2_asm_output_data_uleb128 (AT_index (a), "%s", name);
      return;
    }
  switch (AT_class (a))
    {
    case dw_val_class_addr:
      dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, AT_addr (a), "%s", name);
      break;
    case dw_val_class_high_pc:
    case dw_val_class_lbl_id:
      dw2_asm_output_addr (DWARF2_ADDR_SIZE, AT_lbl (a), "%s", name);
      break;
    default:
      gcc_unreachable ();
    }
}

/* Output a type signature.  */

static inline void
output_signature (const char *sig, const char *name)
{
  int i;

  for (i = 0; i < DWARF_TYPE_SIGNATURE_SIZE; i++)
    dw2_asm_output_data (1, sig[i], i == 0 ? "%s" : NULL, name);
}

/* Output a discriminant value.  */

static inline void
output_discr_value (dw_discr_value *discr_value, const char *name)
{
  if (discr_value->pos)
    dw2_asm_output_data_uleb128 (discr_value->v.uval, "%s", name);
  else
    dw2_asm_output_data_sleb128 (discr_value->v.sval, "%s", name);
}

/* Output the DIE and its attributes.  Called recursively to generate
   the definitions of each child DIE.  */

static void
output_die (dw_die_ref die)
{
  dw_attr_node *a;
  dw_die_ref c;
  unsigned long size;
  unsigned ix;

  dw2_asm_output_data_uleb128 (die->die_abbrev, "(DIE (%#lx) %s)",
			       (unsigned long)die->die_offset,
			       dwarf_tag_name (die->die_tag));

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    {
      const char *name = dwarf_attr_name (a->dw_attr);

      switch (AT_class (a))
	{
	case dw_val_class_addr:
          output_attr_index_or_value (a);
	  break;

	case dw_val_class_offset:
	  dw2_asm_output_data (dwarf_offset_size, a->dw_attr_val.v.val_offset,
			       "%s", name);
	  break;

	case dw_val_class_range_list:
          output_range_list_offset (a);
	  break;

	case dw_val_class_loc:
	  size = size_of_locs (AT_loc (a));

	  /* Output the block length for this list of location operations.  */
	  if (dwarf_version >= 4)
	    dw2_asm_output_data_uleb128 (size, "%s", name);
	  else
	    dw2_asm_output_data (constant_size (size), size, "%s", name);

	  output_loc_sequence (AT_loc (a), -1);
	  break;

	case dw_val_class_const:
	  /* ??? It would be slightly more efficient to use a scheme like is
	     used for unsigned constants below, but gdb 4.x does not sign
	     extend.  Gdb 5.x does sign extend.  */
	  dw2_asm_output_data_sleb128 (AT_int (a), "%s", name);
	  break;

	case dw_val_class_unsigned_const:
	  {
	    int csize = constant_size (AT_unsigned (a));
	    if (dwarf_version == 3
		&& a->dw_attr == DW_AT_data_member_location
		&& csize >= 4)
	      dw2_asm_output_data_uleb128 (AT_unsigned (a), "%s", name);
	    else
	      dw2_asm_output_data (csize, AT_unsigned (a), "%s", name);
	  }
	  break;

	case dw_val_class_symview:
	  {
	    int vsize;
	    if (symview_upper_bound <= 0xff)
	      vsize = 1;
	    else if (symview_upper_bound <= 0xffff)
	      vsize = 2;
	    else if (symview_upper_bound <= 0xffffffff)
	      vsize = 4;
	    else
	      vsize = 8;
	    dw2_asm_output_addr (vsize, a->dw_attr_val.v.val_symbolic_view,
				 "%s", name);
	  }
	  break;

	case dw_val_class_const_implicit:
	  if (flag_debug_asm)
	    fprintf (asm_out_file, "\t\t\t%s %s ("
				   HOST_WIDE_INT_PRINT_DEC ")\n",
		     ASM_COMMENT_START, name, AT_int (a));
	  break;

	case dw_val_class_unsigned_const_implicit:
	  if (flag_debug_asm)
	    fprintf (asm_out_file, "\t\t\t%s %s ("
				   HOST_WIDE_INT_PRINT_HEX ")\n",
		     ASM_COMMENT_START, name, AT_unsigned (a));
	  break;

	case dw_val_class_const_double:
	  {
	    unsigned HOST_WIDE_INT first, second;

	    if (HOST_BITS_PER_WIDE_INT >= DWARF_LARGEST_DATA_FORM_BITS)
	      dw2_asm_output_data (1,
				   HOST_BITS_PER_DOUBLE_INT
				   / HOST_BITS_PER_CHAR,
				   NULL);

	    if (WORDS_BIG_ENDIAN)
	      {
		first = a->dw_attr_val.v.val_double.high;
		second = a->dw_attr_val.v.val_double.low;
	      }
	    else
	      {
		first = a->dw_attr_val.v.val_double.low;
		second = a->dw_attr_val.v.val_double.high;
	      }

	    dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
                                 first, "%s", name);
	    dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
				 second, NULL);
	  }
	  break;

	case dw_val_class_wide_int:
	  {
	    int i;
	    int len = get_full_len (*a->dw_attr_val.v.val_wide);
	    int l = HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR;
	    if (len * HOST_BITS_PER_WIDE_INT > DWARF_LARGEST_DATA_FORM_BITS)
	      dw2_asm_output_data (1, get_full_len (*a->dw_attr_val.v.val_wide)
				      * l, NULL);

	    if (WORDS_BIG_ENDIAN)
	      for (i = len - 1; i >= 0; --i)
		{
		  dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i),
				       "%s", name);
		  name = "";
		}
	    else
	      for (i = 0; i < len; ++i)
		{
		  dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i),
				       "%s", name);
		  name = "";
		}
	  }
	  break;

	case dw_val_class_vec:
	  {
	    unsigned int elt_size = a->dw_attr_val.v.val_vec.elt_size;
	    unsigned int len = a->dw_attr_val.v.val_vec.length;
	    unsigned int i;
	    unsigned char *p;

	    dw2_asm_output_data (constant_size (len * elt_size),
				 len * elt_size, "%s", name);
	    if (elt_size > sizeof (HOST_WIDE_INT))
	      {
		elt_size /= 2;
		len *= 2;
	      }
	    for (i = 0, p = (unsigned char *) a->dw_attr_val.v.val_vec.array;
		 i < len;
		 i++, p += elt_size)
	      dw2_asm_output_data (elt_size, extract_int (p, elt_size),
				   "fp or vector constant word %u", i);
	    break;
	  }

	case dw_val_class_flag:
	  if (dwarf_version >= 4)
	    {
	      /* Currently all add_AT_flag calls pass in 1 as last argument,
		 so DW_FORM_flag_present can be used.  If that ever changes,
		 we'll need to use DW_FORM_flag and have some optimization
		 in build_abbrev_table that will change those to
		 DW_FORM_flag_present if it is set to 1 in all DIEs using
		 the same abbrev entry.  */
	      gcc_assert (AT_flag (a) == 1);
	      if (flag_debug_asm)
		fprintf (asm_out_file, "\t\t\t%s %s\n",
			 ASM_COMMENT_START, name);
	      break;
	    }
	  dw2_asm_output_data (1, AT_flag (a), "%s", name);
	  break;

	case dw_val_class_loc_list:
	  output_loc_list_offset (a);
	  break;

	case dw_val_class_view_list:
	  output_view_list_offset (a);
	  break;

	case dw_val_class_die_ref:
	  if (AT_ref_external (a))
	    {
	      if (AT_ref (a)->comdat_type_p)
	        {
		  comdat_type_node *type_node
		    = AT_ref (a)->die_id.die_type_node;

	          gcc_assert (type_node);
	          output_signature (type_node->signature, name);
	        }
	      else
	        {
		  const char *sym = AT_ref (a)->die_id.die_symbol;
		  int size;

		  gcc_assert (sym);
		  /* In DWARF2, DW_FORM_ref_addr is sized by target address
		     length, whereas in DWARF3 it's always sized as an
		     offset.  */
		  if (dwarf_version == 2)
		    size = DWARF2_ADDR_SIZE;
		  else
		    size = dwarf_offset_size;
		  /* ???  We cannot unconditionally output die_offset if
		     non-zero - others might create references to those
		     DIEs via symbols.
		     And we do not clear its DIE offset after outputting it
		     (and the label refers to the actual DIEs, not the
		     DWARF CU unit header which is when using label + offset
		     would be the correct thing to do).
		     ???  This is the reason for the with_offset flag.  */
		  if (AT_ref (a)->with_offset)
		    dw2_asm_output_offset (size, sym, AT_ref (a)->die_offset,
					   debug_info_section, "%s", name);
		  else
		    dw2_asm_output_offset (size, sym, debug_info_section, "%s",
					   name);
		}
	    }
	  else
	    {
	      gcc_assert (AT_ref (a)->die_offset);
	      dw2_asm_output_data (dwarf_offset_size, AT_ref (a)->die_offset,
				   "%s", name);
	    }
	  break;

	case dw_val_class_fde_ref:
	  {
	    char l1[MAX_ARTIFICIAL_LABEL_BYTES];

	    ASM_GENERATE_INTERNAL_LABEL (l1, FDE_LABEL,
					 a->dw_attr_val.v.val_fde_index * 2);
	    dw2_asm_output_offset (dwarf_offset_size, l1, debug_frame_section,
				   "%s", name);
	  }
	  break;

	case dw_val_class_vms_delta:
#ifdef ASM_OUTPUT_DWARF_VMS_DELTA
	  dw2_asm_output_vms_delta (dwarf_offset_size,
				    AT_vms_delta2 (a), AT_vms_delta1 (a),
				    "%s", name);
#else
	  dw2_asm_output_delta (dwarf_offset_size,
				AT_vms_delta2 (a), AT_vms_delta1 (a),
				"%s", name);
#endif
	  break;

	case dw_val_class_lbl_id:
	  output_attr_index_or_value (a);
	  break;

	case dw_val_class_lineptr:
	  dw2_asm_output_offset (dwarf_offset_size, AT_lbl (a),
				 debug_line_section, "%s", name);
	  break;

	case dw_val_class_macptr:
	  dw2_asm_output_offset (dwarf_offset_size, AT_lbl (a),
				 debug_macinfo_section, "%s", name);
	  break;

	case dw_val_class_loclistsptr:
	  dw2_asm_output_offset (dwarf_offset_size, AT_lbl (a),
				 debug_loc_section, "%s", name);
	  break;

	case dw_val_class_str:
          if (a->dw_attr_val.v.val_str->form == DW_FORM_strp)
            dw2_asm_output_offset (dwarf_offset_size,
                                   a->dw_attr_val.v.val_str->label,
                                   debug_str_section,
                                   "%s: \"%s\"", name, AT_string (a));
	  else if (a->dw_attr_val.v.val_str->form == DW_FORM_line_strp)
	    dw2_asm_output_offset (dwarf_offset_size,
				   a->dw_attr_val.v.val_str->label,
				   debug_line_str_section,
				   "%s: \"%s\"", name, AT_string (a));
          else if (a->dw_attr_val.v.val_str->form == dwarf_FORM (DW_FORM_strx))
            dw2_asm_output_data_uleb128 (AT_index (a),
                                         "%s: \"%s\"", name, AT_string (a));
          else
	    dw2_asm_output_nstring (AT_string (a), -1, "%s", name);
	  break;

	case dw_val_class_file:
	  {
	    int f = maybe_emit_file (a->dw_attr_val.v.val_file);

	    dw2_asm_output_data (constant_size (f), f, "%s (%s)", name,
				 a->dw_attr_val.v.val_file->filename);
	    break;
	  }

	case dw_val_class_file_implicit:
	  if (flag_debug_asm)
	    fprintf (asm_out_file, "\t\t\t%s %s (%d, %s)\n",
		     ASM_COMMENT_START, name,
		     maybe_emit_file (a->dw_attr_val.v.val_file),
		     a->dw_attr_val.v.val_file->filename);
	  break;

	case dw_val_class_data8:
	  {
	    int i;

	    for (i = 0; i < 8; i++)
	      dw2_asm_output_data (1, a->dw_attr_val.v.val_data8[i],
				   i == 0 ? "%s" : NULL, name);
	    break;
	  }

	case dw_val_class_high_pc:
	  dw2_asm_output_delta (DWARF2_ADDR_SIZE, AT_lbl (a),
				get_AT_low_pc (die), "DW_AT_high_pc");
	  break;

	case dw_val_class_discr_value:
	  output_discr_value (&a->dw_attr_val.v.val_discr_value, name);
	  break;

	case dw_val_class_discr_list:
	  {
	    dw_discr_list_ref list = AT_discr_list (a);
	    const int size = size_of_discr_list (list);

	    /* This is a block, so output its length first.  */
	    dw2_asm_output_data (constant_size (size), size,
				 "%s: block size", name);

	    for (; list != NULL; list = list->dw_discr_next)
	      {
		/* One byte for the discriminant value descriptor, and then as
		   many LEB128 numbers as required.  */
		if (list->dw_discr_range)
		  dw2_asm_output_data (1, DW_DSC_range,
				       "%s: DW_DSC_range", name);
		else
		  dw2_asm_output_data (1, DW_DSC_label,
				       "%s: DW_DSC_label", name);

		output_discr_value (&list->dw_discr_lower_bound, name);
		if (list->dw_discr_range)
		  output_discr_value (&list->dw_discr_upper_bound, name);
	      }
	    break;
	  }

	default:
	  gcc_unreachable ();
	}
    }

  FOR_EACH_CHILD (die, c, output_die (c));

  /* Add null byte to terminate sibling list.  */
  if (die->die_child != NULL)
    dw2_asm_output_data (1, 0, "end of children of DIE %#lx",
			 (unsigned long) die->die_offset);
}

/* Output the dwarf version number.  */

static void
output_dwarf_version ()
{
  /* ??? For now, if -gdwarf-6 is specified, we output version 5 with
     views in loclist.  That will change eventually.  */
  if (dwarf_version == 6)
    {
      static bool once;
      if (!once)
	{
	  warning (0, "%<-gdwarf-6%> is output as version 5 with "
		   "incompatibilities");
	  once = true;
	}
      dw2_asm_output_data (2, 5, "DWARF version number");
    }
  else
    dw2_asm_output_data (2, dwarf_version, "DWARF version number");
}

/* Output the compilation unit that appears at the beginning of the
   .debug_info section, and precedes the DIE descriptions.  */

static void
output_compilation_unit_header (enum dwarf_unit_type ut)
{
  if (!XCOFF_DEBUGGING_INFO)
    {
      if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
	dw2_asm_output_data (4, 0xffffffff,
	  "Initial length escape value indicating 64-bit DWARF extension");
      dw2_asm_output_data (dwarf_offset_size,
			   next_die_offset - DWARF_INITIAL_LENGTH_SIZE,
			   "Length of Compilation Unit Info");
    }

  output_dwarf_version ();
  if (dwarf_version >= 5)
    {
      const char *name;
      switch (ut)
	{
	case DW_UT_compile: name = "DW_UT_compile"; break;
	case DW_UT_type: name = "DW_UT_type"; break;
	case DW_UT_split_compile: name = "DW_UT_split_compile"; break;
	case DW_UT_split_type: name = "DW_UT_split_type"; break;
	default: gcc_unreachable ();
	}
      dw2_asm_output_data (1, ut, "%s", name);
      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
    }
  dw2_asm_output_offset (dwarf_offset_size, abbrev_section_label,
			 debug_abbrev_section,
			 "Offset Into Abbrev. Section");
  if (dwarf_version < 5)
    dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
}

/* Output the compilation unit DIE and its children.  */

static void
output_comp_unit (dw_die_ref die, int output_if_empty,
		  const unsigned char *dwo_id)
{
  const char *secname, *oldsym;
  char *tmp;

  /* Unless we are outputting main CU, we may throw away empty ones.  */
  if (!output_if_empty && die->die_child == NULL)
    return;

  /* Even if there are no children of this DIE, we must output the information
     about the compilation unit.  Otherwise, on an empty translation unit, we
     will generate a present, but empty, .debug_info section.  IRIX 6.5 `nm'
     will then complain when examining the file.  First mark all the DIEs in
     this CU so we know which get local refs.  */
  mark_dies (die);

  external_ref_hash_type *extern_map = optimize_external_refs (die);

  /* For now, optimize only the main CU, in order to optimize the rest
     we'd need to see all of them earlier.  Leave the rest for post-linking
     tools like DWZ.  */
  if (die == comp_unit_die ())
    abbrev_opt_start = vec_safe_length (abbrev_die_table);

  build_abbrev_table (die, extern_map);

  optimize_abbrev_table ();

  delete extern_map;

  /* Initialize the beginning DIE offset - and calculate sizes/offsets.  */
  next_die_offset = (dwo_id
		     ? DWARF_COMPILE_UNIT_SKELETON_HEADER_SIZE
		     : DWARF_COMPILE_UNIT_HEADER_SIZE);
  calc_die_sizes (die);

  oldsym = die->die_id.die_symbol;
  if (oldsym && die->comdat_type_p)
    {
      tmp = XALLOCAVEC (char, strlen (oldsym) + 24);

      sprintf (tmp, ".gnu.linkonce.wi.%s", oldsym);
      secname = tmp;
      die->die_id.die_symbol = NULL;
      switch_to_section (get_section (secname, SECTION_DEBUG, NULL));
    }
  else
    {
      switch_to_section (debug_info_section);
      ASM_OUTPUT_LABEL (asm_out_file, debug_info_section_label);
      info_section_emitted = true;
    }

  /* For LTO cross unit DIE refs we want a symbol on the start of the
     debuginfo section, not on the CU DIE.  */
  if ((flag_generate_lto || flag_generate_offload) && oldsym)
    {
      /* ???  No way to get visibility assembled without a decl.  */
      tree decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
			      get_identifier (oldsym), char_type_node);
      TREE_PUBLIC (decl) = true;
      TREE_STATIC (decl) = true;
      DECL_ARTIFICIAL (decl) = true;
      DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN;
      DECL_VISIBILITY_SPECIFIED (decl) = true;
      targetm.asm_out.assemble_visibility (decl, VISIBILITY_HIDDEN);
#ifdef ASM_WEAKEN_LABEL
      /* We prefer a .weak because that handles duplicates from duplicate
         archive members in a graceful way.  */
      ASM_WEAKEN_LABEL (asm_out_file, oldsym);
#else
      targetm.asm_out.globalize_label (asm_out_file, oldsym);
#endif
      ASM_OUTPUT_LABEL (asm_out_file, oldsym);
    }

  /* Output debugging information.  */
  output_compilation_unit_header (dwo_id
				  ? DW_UT_split_compile : DW_UT_compile);
  if (dwarf_version >= 5)
    {
      if (dwo_id != NULL)
	for (int i = 0; i < 8; i++)
	  dw2_asm_output_data (1, dwo_id[i], i == 0 ? "DWO id" : NULL);
    }
  output_die (die);

  /* Leave the marks on the main CU, so we can check them in
     output_pubnames.  */
  if (oldsym)
    {
      unmark_dies (die);
      die->die_id.die_symbol = oldsym;
    }
}

/* Whether to generate the DWARF accelerator tables in .debug_pubnames
   and .debug_pubtypes.  This is configured per-target, but can be
   overridden by the -gpubnames or -gno-pubnames options.  */

static inline bool
want_pubnames (void)
{
  if (debug_info_level <= DINFO_LEVEL_TERSE
      /* Names and types go to the early debug part only.  */
      || in_lto_p)
    return false;
  if (debug_generate_pub_sections != -1)
    return debug_generate_pub_sections;
  return targetm.want_debug_pub_sections;
}

/* Add the DW_AT_GNU_pubnames and DW_AT_GNU_pubtypes attributes.  */

static void
add_AT_pubnames (dw_die_ref die)
{
  if (want_pubnames ())
    add_AT_flag (die, DW_AT_GNU_pubnames, 1);
}

/* Add a string attribute value to a skeleton DIE.  */

static inline void
add_skeleton_AT_string (dw_die_ref die, enum dwarf_attribute attr_kind,
                        const char *str)
{
  dw_attr_node attr;
  struct indirect_string_node *node;

  if (! skeleton_debug_str_hash)
    skeleton_debug_str_hash
      = hash_table<indirect_string_hasher>::create_ggc (10);

  node = find_AT_string_in_table (str, skeleton_debug_str_hash);
  find_string_form (node);
  if (node->form == dwarf_FORM (DW_FORM_strx))
    node->form = DW_FORM_strp;

  attr.dw_attr = attr_kind;
  attr.dw_attr_val.val_class = dw_val_class_str;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_str = node;
  add_dwarf_attr (die, &attr);
}

/* Helper function to generate top-level dies for skeleton debug_info and
   debug_types.  */

static void
add_top_level_skeleton_die_attrs (dw_die_ref die)
{
  const char *dwo_file_name = concat (aux_base_name, ".dwo", NULL);
  const char *comp_dir = comp_dir_string ();

  add_skeleton_AT_string (die, dwarf_AT (DW_AT_dwo_name), dwo_file_name);
  if (comp_dir != NULL)
    add_skeleton_AT_string (die, DW_AT_comp_dir, comp_dir);
  add_AT_pubnames (die);
  if (addr_index_table != NULL && addr_index_table->size () > 0)
    add_AT_lineptr (die, dwarf_AT (DW_AT_addr_base), debug_addr_section_label);
}

/* Output skeleton debug sections that point to the dwo file.  */

static void
output_skeleton_debug_sections (dw_die_ref comp_unit,
				const unsigned char *dwo_id)
{
  /* These attributes will be found in the full debug_info section.  */
  remove_AT (comp_unit, DW_AT_producer);
  remove_AT (comp_unit, DW_AT_language);

  switch_to_section (debug_skeleton_info_section);
  ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_info_section_label);

  /* Produce the skeleton compilation-unit header.  This one differs enough from
     a normal CU header that it's better not to call output_compilation_unit
     header.  */
  if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
    dw2_asm_output_data (4, 0xffffffff,
			 "Initial length escape value indicating 64-bit "
			 "DWARF extension");

  dw2_asm_output_data (dwarf_offset_size,
		       DWARF_COMPILE_UNIT_SKELETON_HEADER_SIZE
                       - DWARF_INITIAL_LENGTH_SIZE
                       + size_of_die (comp_unit),
                      "Length of Compilation Unit Info");
  output_dwarf_version ();
  if (dwarf_version >= 5)
    {
      dw2_asm_output_data (1, DW_UT_skeleton, "DW_UT_skeleton");
      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
    }
  dw2_asm_output_offset (dwarf_offset_size, debug_skeleton_abbrev_section_label,
			 debug_skeleton_abbrev_section,
                         "Offset Into Abbrev. Section");
  if (dwarf_version < 5)
    dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Pointer Size (in bytes)");
  else
    for (int i = 0; i < 8; i++)
      dw2_asm_output_data (1, dwo_id[i], i == 0 ? "DWO id" : NULL);

  comp_unit->die_abbrev = SKELETON_COMP_DIE_ABBREV;
  output_die (comp_unit);

  /* Build the skeleton debug_abbrev section.  */
  switch_to_section (debug_skeleton_abbrev_section);
  ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_abbrev_section_label);

  output_die_abbrevs (SKELETON_COMP_DIE_ABBREV, comp_unit);

  dw2_asm_output_data (1, 0, "end of skeleton .debug_abbrev");
}

/* Output a comdat type unit DIE and its children.  */

static void
output_comdat_type_unit (comdat_type_node *node,
			 bool early_lto_debug ATTRIBUTE_UNUSED)
{
  const char *secname;
  char *tmp;
  int i;
#if defined (OBJECT_FORMAT_ELF)
  tree comdat_key;
#endif

  /* First mark all the DIEs in this CU so we know which get local refs.  */
  mark_dies (node->root_die);

  external_ref_hash_type *extern_map = optimize_external_refs (node->root_die);

  build_abbrev_table (node->root_die, extern_map);

  delete extern_map;
  extern_map = NULL;

  /* Initialize the beginning DIE offset - and calculate sizes/offsets.  */
  next_die_offset = DWARF_COMDAT_TYPE_UNIT_HEADER_SIZE;
  calc_die_sizes (node->root_die);

#if defined (OBJECT_FORMAT_ELF)
  if (dwarf_version >= 5)
    {
      if (!dwarf_split_debug_info)
	secname = early_lto_debug ? DEBUG_LTO_INFO_SECTION : DEBUG_INFO_SECTION;
      else
	secname = (early_lto_debug
		   ? DEBUG_LTO_DWO_INFO_SECTION : DEBUG_DWO_INFO_SECTION);
    }
  else if (!dwarf_split_debug_info)
    secname = early_lto_debug ? ".gnu.debuglto_.debug_types" : ".debug_types";
  else
    secname = (early_lto_debug
	       ? ".gnu.debuglto_.debug_types.dwo" : ".debug_types.dwo");

  tmp = XALLOCAVEC (char, 4 + DWARF_TYPE_SIGNATURE_SIZE * 2);
  sprintf (tmp, dwarf_version >= 5 ? "wi." : "wt.");
  for (i = 0; i < DWARF_TYPE_SIGNATURE_SIZE; i++)
    sprintf (tmp + 3 + i * 2, "%02x", node->signature[i] & 0xff);
  comdat_key = get_identifier (tmp);
  targetm.asm_out.named_section (secname,
                                 SECTION_DEBUG | SECTION_LINKONCE,
                                 comdat_key);
#else
  tmp = XALLOCAVEC (char, 18 + DWARF_TYPE_SIGNATURE_SIZE * 2);
  sprintf (tmp, (dwarf_version >= 5
		 ? ".gnu.linkonce.wi." : ".gnu.linkonce.wt."));
  for (i = 0; i < DWARF_TYPE_SIGNATURE_SIZE; i++)
    sprintf (tmp + 17 + i * 2, "%02x", node->signature[i] & 0xff);
  secname = tmp;
  switch_to_section (get_section (secname, SECTION_DEBUG, NULL));
#endif

  /* Output debugging information.  */
  output_compilation_unit_header (dwarf_split_debug_info
				  ? DW_UT_split_type : DW_UT_type);
  output_signature (node->signature, "Type Signature");
  dw2_asm_output_data (dwarf_offset_size, node->type_die->die_offset,
		       "Offset to Type DIE");
  output_die (node->root_die);

  unmark_dies (node->root_die);
}

/* Return the DWARF2/3 pubname associated with a decl.  */

static const char *
dwarf2_name (tree decl, int scope)
{
  if (DECL_NAMELESS (decl))
    return NULL;
  return lang_hooks.dwarf_name (decl, scope ? 1 : 0);
}

/* Add a new entry to .debug_pubnames if appropriate.  */

static void
add_pubname_string (const char *str, dw_die_ref die)
{
  pubname_entry e;

  e.die = die;
  e.name = xstrdup (str);
  vec_safe_push (pubname_table, e);
}

static void
add_pubname (tree decl, dw_die_ref die)
{
  if (!want_pubnames ())
    return;

  /* Don't add items to the table when we expect that the consumer will have
     just read the enclosing die.  For example, if the consumer is looking at a
     class_member, it will either be inside the class already, or will have just
     looked up the class to find the member.  Either way, searching the class is
     faster than searching the index.  */
  if ((TREE_PUBLIC (decl) && !class_scope_p (die->die_parent))
      || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent))
    {
      const char *name = dwarf2_name (decl, 1);

      if (name)
	add_pubname_string (name, die);
    }
}

/* Add an enumerator to the pubnames section.  */

static void
add_enumerator_pubname (const char *scope_name, dw_die_ref die)
{
  pubname_entry e;

  gcc_assert (scope_name);
  e.name = concat (scope_name, get_AT_string (die, DW_AT_name), NULL);
  e.die = die;
  vec_safe_push (pubname_table, e);
}

/* Add a new entry to .debug_pubtypes if appropriate.  */

static void
add_pubtype (tree decl, dw_die_ref die)
{
  pubname_entry e;

  if (!want_pubnames ())
    return;

  if ((TREE_PUBLIC (decl)
       || is_cu_die (die->die_parent) || is_namespace_die (die->die_parent))
      && (die->die_tag == DW_TAG_typedef || COMPLETE_TYPE_P (decl)))
    {
      tree scope = NULL;
      const char *scope_name = "";
      const char *sep = is_cxx () ? "::" : ".";
      const char *name;

      scope = TYPE_P (decl) ? TYPE_CONTEXT (decl) : NULL;
      if (scope && TREE_CODE (scope) == NAMESPACE_DECL)
        {
          scope_name = lang_hooks.dwarf_name (scope, 1);
          if (scope_name != NULL && scope_name[0] != '\0')
            scope_name = concat (scope_name, sep, NULL);
          else
            scope_name = "";
	}

      if (TYPE_P (decl))
        name = type_tag (decl);
      else
        name = lang_hooks.dwarf_name (decl, 1);

      /* If we don't have a name for the type, there's no point in adding
	 it to the table.  */
      if (name != NULL && name[0] != '\0')
        {
          e.die = die;
          e.name = concat (scope_name, name, NULL);
          vec_safe_push (pubtype_table, e);
        }

      /* Although it might be more consistent to add the pubinfo for the
         enumerators as their dies are created, they should only be added if the
         enum type meets the criteria above.  So rather than re-check the parent
         enum type whenever an enumerator die is created, just output them all
         here.  This isn't protected by the name conditional because anonymous
         enums don't have names.  */
      if (die->die_tag == DW_TAG_enumeration_type)
        {
          dw_die_ref c;

          FOR_EACH_CHILD (die, c, add_enumerator_pubname (scope_name, c));
        }
    }
}

/* Output a single entry in the pubnames table.  */

static void
output_pubname (dw_offset die_offset, pubname_entry *entry)
{
  dw_die_ref die = entry->die;
  int is_static = get_AT_flag (die, DW_AT_external) ? 0 : 1;

  dw2_asm_output_data (dwarf_offset_size, die_offset, "DIE offset");

  if (debug_generate_pub_sections == 2)
    {
      /* This logic follows gdb's method for determining the value of the flag
         byte.  */
      uint32_t flags = GDB_INDEX_SYMBOL_KIND_NONE;
      switch (die->die_tag)
      {
        case DW_TAG_typedef:
        case DW_TAG_base_type:
        case DW_TAG_subrange_type:
          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
          break;
        case DW_TAG_enumerator:
          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
	  if (!is_cxx ())
	    GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
          break;
        case DW_TAG_subprogram:
          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
                                          GDB_INDEX_SYMBOL_KIND_FUNCTION);
          if (!is_ada ())
            GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
          break;
        case DW_TAG_constant:
          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
          break;
        case DW_TAG_variable:
          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags,
                                          GDB_INDEX_SYMBOL_KIND_VARIABLE);
          GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, is_static);
          break;
        case DW_TAG_namespace:
        case DW_TAG_imported_declaration:
          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
          break;
        case DW_TAG_class_type:
        case DW_TAG_interface_type:
        case DW_TAG_structure_type:
        case DW_TAG_union_type:
        case DW_TAG_enumeration_type:
          GDB_INDEX_SYMBOL_KIND_SET_VALUE(flags, GDB_INDEX_SYMBOL_KIND_TYPE);
	  if (!is_cxx ())
	    GDB_INDEX_SYMBOL_STATIC_SET_VALUE(flags, 1);
          break;
        default:
          /* An unusual tag.  Leave the flag-byte empty.  */
          break;
      }
      dw2_asm_output_data (1, flags >> GDB_INDEX_CU_BITSIZE,
                           "GDB-index flags");
    }

  dw2_asm_output_nstring (entry->name, -1, "external name");
}


/* Output the public names table used to speed up access to externally
   visible names; or the public types table used to find type definitions.  */

static void
output_pubnames (vec<pubname_entry, va_gc> *names)
{
  unsigned i;
  unsigned long pubnames_length = size_of_pubnames (names);
  pubname_entry *pub;

  if (!XCOFF_DEBUGGING_INFO)
    {
      if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
	dw2_asm_output_data (4, 0xffffffff,
	  "Initial length escape value indicating 64-bit DWARF extension");
      dw2_asm_output_data (dwarf_offset_size, pubnames_length,
			   "Pub Info Length");
    }

  /* Version number for pubnames/pubtypes is independent of dwarf version.  */
  dw2_asm_output_data (2, 2, "DWARF pubnames/pubtypes version");

  if (dwarf_split_debug_info)
    dw2_asm_output_offset (dwarf_offset_size, debug_skeleton_info_section_label,
                           debug_skeleton_info_section,
                           "Offset of Compilation Unit Info");
  else
    dw2_asm_output_offset (dwarf_offset_size, debug_info_section_label,
                           debug_info_section,
                           "Offset of Compilation Unit Info");
  dw2_asm_output_data (dwarf_offset_size, next_die_offset,
		       "Compilation Unit Length");

  FOR_EACH_VEC_ELT (*names, i, pub)
    {
      if (include_pubname_in_output (names, pub))
	{
	  dw_offset die_offset = pub->die->die_offset;

          /* We shouldn't see pubnames for DIEs outside of the main CU.  */
          if (names == pubname_table && pub->die->die_tag != DW_TAG_enumerator)
            gcc_assert (pub->die->die_mark);

	  /* If we're putting types in their own .debug_types sections,
	     the .debug_pubtypes table will still point to the compile
	     unit (not the type unit), so we want to use the offset of
	     the skeleton DIE (if there is one).  */
	  if (pub->die->comdat_type_p && names == pubtype_table)
	    {
	      comdat_type_node *type_node = pub->die->die_id.die_type_node;

	      if (type_node != NULL)
	        die_offset = (type_node->skeleton_die != NULL
			      ? type_node->skeleton_die->die_offset
			      : comp_unit_die ()->die_offset);
	    }

          output_pubname (die_offset, pub);
	}
    }

  dw2_asm_output_data (dwarf_offset_size, 0, NULL);
}

/* Output public names and types tables if necessary.  */

static void
output_pubtables (void)
{
  if (!want_pubnames () || !info_section_emitted)
    return;

  switch_to_section (debug_pubnames_section);
  output_pubnames (pubname_table);
  /* ??? Only defined by DWARF3, but emitted by Darwin for DWARF2.
     It shouldn't hurt to emit it always, since pure DWARF2 consumers
     simply won't look for the section.  */
  switch_to_section (debug_pubtypes_section);
  output_pubnames (pubtype_table);
}


/* Output the information that goes into the .debug_aranges table.
   Namely, define the beginning and ending address range of the
   text section generated for this compilation unit.  */

static void
output_aranges (void)
{
  unsigned i;
  unsigned long aranges_length = size_of_aranges ();
  
  if (!XCOFF_DEBUGGING_INFO)
    {
      if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
	dw2_asm_output_data (4, 0xffffffff,
	  "Initial length escape value indicating 64-bit DWARF extension");
      dw2_asm_output_data (dwarf_offset_size, aranges_length,
			   "Length of Address Ranges Info");
    }

  /* Version number for aranges is still 2, even up to DWARF5.  */
  dw2_asm_output_data (2, 2, "DWARF aranges version");
  if (dwarf_split_debug_info)
    dw2_asm_output_offset (dwarf_offset_size, debug_skeleton_info_section_label,
                           debug_skeleton_info_section,
                           "Offset of Compilation Unit Info");
  else
    dw2_asm_output_offset (dwarf_offset_size, debug_info_section_label,
                           debug_info_section,
                           "Offset of Compilation Unit Info");
  dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Size of Address");
  dw2_asm_output_data (1, 0, "Size of Segment Descriptor");

  /* We need to align to twice the pointer size here.  */
  if (DWARF_ARANGES_PAD_SIZE)
    {
      /* Pad using a 2 byte words so that padding is correct for any
	 pointer size.  */
      dw2_asm_output_data (2, 0, "Pad to %d byte boundary",
			   2 * DWARF2_ADDR_SIZE);
      for (i = 2; i < (unsigned) DWARF_ARANGES_PAD_SIZE; i += 2)
	dw2_asm_output_data (2, 0, NULL);
    }

  /* It is necessary not to output these entries if the sections were
     not used; if the sections were not used, the length will be 0 and
     the address may end up as 0 if the section is discarded by ld
     --gc-sections, leaving an invalid (0, 0) entry that can be
     confused with the terminator.  */
  if (switch_text_ranges)
    {
      const char *prev_loc = text_section_label;
      const char *loc;
      unsigned idx;

      FOR_EACH_VEC_ELT (*switch_text_ranges, idx, loc)
	if (prev_loc)
	  {
	    dw2_asm_output_addr (DWARF2_ADDR_SIZE, prev_loc, "Address");
	    dw2_asm_output_delta (DWARF2_ADDR_SIZE, loc, prev_loc, "Length");
	    prev_loc = NULL;
	  }
	else
	  prev_loc = loc;

      if (prev_loc)
	{
	  dw2_asm_output_addr (DWARF2_ADDR_SIZE, prev_loc, "Address");
	  dw2_asm_output_delta (DWARF2_ADDR_SIZE, text_end_label,
				prev_loc, "Length");
	}
    }

  if (switch_cold_ranges)
    {
      const char *prev_loc = cold_text_section_label;
      const char *loc;
      unsigned idx;

      FOR_EACH_VEC_ELT (*switch_cold_ranges, idx, loc)
	if (prev_loc)
	  {
	    dw2_asm_output_addr (DWARF2_ADDR_SIZE, prev_loc, "Address");
	    dw2_asm_output_delta (DWARF2_ADDR_SIZE, loc, prev_loc, "Length");
	    prev_loc = NULL;
	  }
	else
	  prev_loc = loc;

      if (prev_loc)
	{
	  dw2_asm_output_addr (DWARF2_ADDR_SIZE, prev_loc, "Address");
	  dw2_asm_output_delta (DWARF2_ADDR_SIZE, cold_end_label,
				prev_loc, "Length");
	}
    }

  if (have_multiple_function_sections)
    {
      unsigned fde_idx;
      dw_fde_ref fde;

      FOR_EACH_VEC_ELT (*fde_vec, fde_idx, fde)
	{
	  if (fde->ignored_debug)
	    continue;
	  if (!fde->in_std_section)
	    {
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_begin,
				   "Address");
	      dw2_asm_output_delta (DWARF2_ADDR_SIZE, fde->dw_fde_end,
				    fde->dw_fde_begin, "Length");
	    }
	  if (fde->dw_fde_second_begin && !fde->second_in_std_section)
	    {
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, fde->dw_fde_second_begin,
				   "Address");
	      dw2_asm_output_delta (DWARF2_ADDR_SIZE, fde->dw_fde_second_end,
				    fde->dw_fde_second_begin, "Length");
	    }
	}
    }

  /* Output the terminator words.  */
  dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL);
  dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL);
}

/* Add a new entry to .debug_ranges.  Return its index into
   ranges_table vector.  */

static unsigned int
add_ranges_num (int num, bool maybe_new_sec)
{
  dw_ranges r = { NULL, num, 0, maybe_new_sec, NULL, NULL };
  vec_safe_push (ranges_table, r);
  return vec_safe_length (ranges_table) - 1;
}

/* Add a new entry to .debug_ranges corresponding to a block, or a
   range terminator if BLOCK is NULL.  MAYBE_NEW_SEC is true if
   this entry might be in a different section from previous range.  */

static unsigned int
add_ranges (const_tree block, bool maybe_new_sec)
{
  return add_ranges_num (block ? BLOCK_NUMBER (block) : 0, maybe_new_sec);
}

/* Note that (*rnglist_table)[offset] is either a head of a rnglist
   chain, or middle entry of a chain that will be directly referred to.  */

static void
note_rnglist_head (unsigned int offset)
{
  if (dwarf_version < 5 || (*ranges_table)[offset].label)
    return;
  (*ranges_table)[offset].label = gen_internal_sym ("LLRL");
}

/* Add a new entry to .debug_ranges corresponding to a pair of labels.
   When using dwarf_split_debug_info, address attributes in dies destined
   for the final executable should be direct references--setting the
   parameter force_direct ensures this behavior.  */

static void
add_ranges_by_labels (dw_die_ref die, const char *begin, const char *end,
                      bool *added, bool force_direct)
{
  unsigned int in_use = vec_safe_length (ranges_by_label);
  unsigned int offset;
  dw_ranges_by_label rbl = { begin, end };
  vec_safe_push (ranges_by_label, rbl);
  offset = add_ranges_num (-(int)in_use - 1, true);
  if (!*added)
    {
      add_AT_range_list (die, DW_AT_ranges, offset, force_direct);
      *added = true;
      note_rnglist_head (offset);
      if (dwarf_split_debug_info && force_direct)
	(*ranges_table)[offset].idx = DW_RANGES_IDX_SKELETON;
    }
}

/* Emit .debug_ranges section.  */

static void
output_ranges (void)
{
  unsigned i;
  static const char *const start_fmt = "Offset %#x";
  const char *fmt = start_fmt;
  dw_ranges *r;

  switch_to_section (debug_ranges_section);
  ASM_OUTPUT_LABEL (asm_out_file, ranges_section_label);
  FOR_EACH_VEC_SAFE_ELT (ranges_table, i, r)
    {
      int block_num = r->num;

      if (block_num > 0)
	{
	  char blabel[MAX_ARTIFICIAL_LABEL_BYTES];
	  char elabel[MAX_ARTIFICIAL_LABEL_BYTES];

	  ASM_GENERATE_INTERNAL_LABEL (blabel, BLOCK_BEGIN_LABEL, block_num);
	  ASM_GENERATE_INTERNAL_LABEL (elabel, BLOCK_END_LABEL, block_num);

	  /* If all code is in the text section, then the compilation
	     unit base address defaults to DW_AT_low_pc, which is the
	     base of the text section.  */
	  if (!have_multiple_function_sections)
	    {
	      dw2_asm_output_delta (DWARF2_ADDR_SIZE, blabel,
				    text_section_label,
				    fmt, i * 2 * DWARF2_ADDR_SIZE);
	      dw2_asm_output_delta (DWARF2_ADDR_SIZE, elabel,
				    text_section_label, NULL);
	    }

	  /* Otherwise, the compilation unit base address is zero,
	     which allows us to use absolute addresses, and not worry
	     about whether the target supports cross-section
	     arithmetic.  */
	  else
	    {
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, blabel,
				   fmt, i * 2 * DWARF2_ADDR_SIZE);
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, elabel, NULL);
	    }

	  fmt = NULL;
	}

      /* Negative block_num stands for an index into ranges_by_label.  */
      else if (block_num < 0)
	{
	  int lab_idx = - block_num - 1;

	  if (!have_multiple_function_sections)
	    {
	      gcc_unreachable ();
#if 0
	      /* If we ever use add_ranges_by_labels () for a single
		 function section, all we have to do is to take out
		 the #if 0 above.  */
	      dw2_asm_output_delta (DWARF2_ADDR_SIZE,
				    (*ranges_by_label)[lab_idx].begin,
				    text_section_label,
				    fmt, i * 2 * DWARF2_ADDR_SIZE);
	      dw2_asm_output_delta (DWARF2_ADDR_SIZE,
				    (*ranges_by_label)[lab_idx].end,
				    text_section_label, NULL);
#endif
	    }
	  else
	    {
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE,
				   (*ranges_by_label)[lab_idx].begin,
				   fmt, i * 2 * DWARF2_ADDR_SIZE);
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE,
				   (*ranges_by_label)[lab_idx].end,
				   NULL);
	    }
	}
      else
	{
	  dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL);
	  dw2_asm_output_data (DWARF2_ADDR_SIZE, 0, NULL);
	  fmt = start_fmt;
	}
    }
}

/* Non-zero if .debug_line_str should be used for .debug_line section
   strings or strings that are likely shareable with those.  */
#define DWARF5_USE_DEBUG_LINE_STR \
  (!DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET		\
   && (DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) != 0		\
   /* FIXME: there is no .debug_line_str.dwo section,		\
      for -gsplit-dwarf we should use DW_FORM_strx instead.  */	\
   && !dwarf_split_debug_info)


/* Returns TRUE if we are outputting DWARF5 and the assembler supports
   DWARF5 .debug_line tables using .debug_line_str or we generate
   it ourselves, except for split-dwarf which doesn't have a
   .debug_line_str.  */
static bool
asm_outputs_debug_line_str (void)
{
  if (dwarf_version >= 5
      && ! output_asm_line_debug_info ()
      && DWARF5_USE_DEBUG_LINE_STR)
    return true;
  else
    {
#if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
      return !dwarf_split_debug_info && dwarf_version >= 5;
#else
      return false;
#endif
    }
}

/* Return true if it is beneficial to use DW_RLE_base_address{,x}.
   I is index of the following range.  */

static bool
use_distinct_base_address_for_range (unsigned int i)
{
  if (i >= vec_safe_length (ranges_table))
    return false;

  dw_ranges *r2 = &(*ranges_table)[i];
  /* Use DW_RLE_base_address{,x} if there is a next range in the
     range list and is guaranteed to be in the same section.  */
  return r2->num != 0 && r2->label == NULL && !r2->maybe_new_sec;
}

/* Assign .debug_rnglists indexes and unique indexes into the debug_addr
   section when needed.  */

static void
index_rnglists (void)
{
  unsigned i;
  dw_ranges *r;
  bool base = false;

  FOR_EACH_VEC_SAFE_ELT (ranges_table, i, r)
    {
      if (r->label && r->idx != DW_RANGES_IDX_SKELETON)
	r->idx = rnglist_idx++;

      if (!have_multiple_function_sections)
	continue;
      int block_num = r->num;
      if (HAVE_AS_LEB128 && (r->label || r->maybe_new_sec))
	base = false;
      if (block_num > 0)
	{
	  char blabel[MAX_ARTIFICIAL_LABEL_BYTES];
	  char elabel[MAX_ARTIFICIAL_LABEL_BYTES];

	  ASM_GENERATE_INTERNAL_LABEL (blabel, BLOCK_BEGIN_LABEL, block_num);
	  ASM_GENERATE_INTERNAL_LABEL (elabel, BLOCK_END_LABEL, block_num);

	  if (HAVE_AS_LEB128)
	    {
	      if (!base && use_distinct_base_address_for_range (i + 1))
		{
		  r->begin_entry = add_addr_table_entry (xstrdup (blabel),
							 ate_kind_label);
		  base = true;
		}
	      if (base)
		/* If we have a base, no need for further
		   begin_entry/end_entry, as DW_RLE_offset_pair will be
		   used.  */
		continue;
	      r->begin_entry
		= add_addr_table_entry (xstrdup (blabel), ate_kind_label);
	      /* No need for end_entry, DW_RLE_start{,x}_length will use
		 length as opposed to a pair of addresses.  */
	    }
	  else
	    {
	      r->begin_entry
		= add_addr_table_entry (xstrdup (blabel), ate_kind_label);
	      r->end_entry
		= add_addr_table_entry (xstrdup (elabel), ate_kind_label);
	    }
	}

      /* Negative block_num stands for an index into ranges_by_label.  */
      else if (block_num < 0)
	{
	  int lab_idx = - block_num - 1;
	  const char *blabel = (*ranges_by_label)[lab_idx].begin;
	  const char *elabel = (*ranges_by_label)[lab_idx].end;

	  r->begin_entry
	    = add_addr_table_entry (xstrdup (blabel), ate_kind_label);
	  if (!HAVE_AS_LEB128)
	    r->end_entry
	      = add_addr_table_entry (xstrdup (elabel), ate_kind_label);
	}
    }
}

/* Emit .debug_rnglists or (when DWO is true) .debug_rnglists.dwo section.  */

static bool
output_rnglists (unsigned generation, bool dwo)
{
  unsigned i;
  dw_ranges *r;
  char l1[MAX_ARTIFICIAL_LABEL_BYTES];
  char l2[MAX_ARTIFICIAL_LABEL_BYTES];
  char basebuf[MAX_ARTIFICIAL_LABEL_BYTES];

  if (dwo)
    switch_to_section (debug_ranges_dwo_section);
  else
    {
      switch_to_section (debug_ranges_section);
      ASM_OUTPUT_LABEL (asm_out_file, ranges_section_label);
    }
  /* There are up to 4 unique ranges labels per generation.
     See also init_sections_and_labels.  */
  ASM_GENERATE_INTERNAL_LABEL (l1, DEBUG_RANGES_SECTION_LABEL,
			       2 + 2 * dwo + generation * 6);
  ASM_GENERATE_INTERNAL_LABEL (l2, DEBUG_RANGES_SECTION_LABEL,
			       3 + 2 * dwo + generation * 6);
  if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
    dw2_asm_output_data (4, 0xffffffff,
			 "Initial length escape value indicating "
			 "64-bit DWARF extension");
  dw2_asm_output_delta (dwarf_offset_size, l2, l1,
			"Length of Range Lists");
  ASM_OUTPUT_LABEL (asm_out_file, l1);
  output_dwarf_version ();
  dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size");
  dw2_asm_output_data (1, 0, "Segment Size");
  /* Emit the offset table only for -gsplit-dwarf.  If we don't care
     about relocation sizes and primarily care about the size of .debug*
     sections in linked shared libraries and executables, then
     the offset table plus corresponding DW_FORM_rnglistx uleb128 indexes
     into it are usually larger than just DW_FORM_sec_offset offsets
     into the .debug_rnglists section.  */
  dw2_asm_output_data (4, dwo ? rnglist_idx : 0,
		       "Offset Entry Count");
  if (dwo)
    {
      ASM_OUTPUT_LABEL (asm_out_file, ranges_base_label);
      FOR_EACH_VEC_SAFE_ELT (ranges_table, i, r)
	if (r->label && r->idx != DW_RANGES_IDX_SKELETON)
	  dw2_asm_output_delta (dwarf_offset_size, r->label,
				ranges_base_label, NULL);
    }

  const char *lab = "";
  const char *base = NULL;
  bool skipping = false;
  bool ret = false;
  FOR_EACH_VEC_SAFE_ELT (ranges_table, i, r)
    {
      int block_num = r->num;

      if (r->label)
	{
	  if (dwarf_split_debug_info
	      && (r->idx == DW_RANGES_IDX_SKELETON) == dwo)
	    {
	      ret = true;
	      skipping = true;
	      continue;
	    }
	  ASM_OUTPUT_LABEL (asm_out_file, r->label);
	  lab = r->label;
	}
      if (skipping)
	{
	  if (block_num == 0)
	    skipping = false;
	  continue;
	}
      if (HAVE_AS_LEB128 && (r->label || r->maybe_new_sec))
	base = NULL;
      if (block_num > 0)
	{
	  char blabel[MAX_ARTIFICIAL_LABEL_BYTES];
	  char elabel[MAX_ARTIFICIAL_LABEL_BYTES];

	  ASM_GENERATE_INTERNAL_LABEL (blabel, BLOCK_BEGIN_LABEL, block_num);
	  ASM_GENERATE_INTERNAL_LABEL (elabel, BLOCK_END_LABEL, block_num);

	  if (HAVE_AS_LEB128)
	    {
	      /* If all code is in the text section, then the compilation
		 unit base address defaults to DW_AT_low_pc, which is the
		 base of the text section.  */
	      if (!have_multiple_function_sections)
		{
		  dw2_asm_output_data (1, DW_RLE_offset_pair,
				       "DW_RLE_offset_pair (%s)", lab);
		  dw2_asm_output_delta_uleb128 (blabel, text_section_label,
						"Range begin address (%s)", lab);
		  dw2_asm_output_delta_uleb128 (elabel, text_section_label,
						"Range end address (%s)", lab);
		  continue;
		}
	      if (base == NULL && use_distinct_base_address_for_range (i + 1))
		{
		  if (dwarf_split_debug_info)
		    {
		      dw2_asm_output_data (1, DW_RLE_base_addressx,
					   "DW_RLE_base_addressx (%s)", lab);
		      dw2_asm_output_data_uleb128 (r->begin_entry->index,
						   "Base address index (%s)",
						   blabel);
		    }
		  else
		    {
		      dw2_asm_output_data (1, DW_RLE_base_address,
					   "DW_RLE_base_address (%s)", lab);
		      dw2_asm_output_addr (DWARF2_ADDR_SIZE, blabel,
					   "Base address (%s)", lab);
		    }
		  strcpy (basebuf, blabel);
		  base = basebuf;
		}
	      if (base)
		{
		  dw2_asm_output_data (1, DW_RLE_offset_pair,
				       "DW_RLE_offset_pair (%s)", lab);
		  dw2_asm_output_delta_uleb128 (blabel, base,
						"Range begin address (%s)", lab);
		  dw2_asm_output_delta_uleb128 (elabel, base,
						"Range end address (%s)", lab);
		  continue;
		}
	      if (dwarf_split_debug_info)
		{
		  dw2_asm_output_data (1, DW_RLE_startx_length,
				       "DW_RLE_startx_length (%s)", lab);
		  dw2_asm_output_data_uleb128 (r->begin_entry->index,
					       "Range begin address index "
					       "(%s)", blabel);
		}
	      else
		{
		  dw2_asm_output_data (1, DW_RLE_start_length,
				       "DW_RLE_start_length (%s)", lab);
		  dw2_asm_output_addr (DWARF2_ADDR_SIZE, blabel,
				       "Range begin address (%s)", lab);
		}
	      dw2_asm_output_delta_uleb128 (elabel, blabel,
					    "Range length (%s)", lab);
	    }
	  else if (dwarf_split_debug_info)
	    {
	      dw2_asm_output_data (1, DW_RLE_startx_endx,
				   "DW_RLE_startx_endx (%s)", lab);
	      dw2_asm_output_data_uleb128 (r->begin_entry->index,
					   "Range begin address index "
					   "(%s)", blabel);
	      dw2_asm_output_data_uleb128 (r->end_entry->index,
					   "Range end address index "
					   "(%s)", elabel);
	    }
	  else
	    {
	      dw2_asm_output_data (1, DW_RLE_start_end,
				   "DW_RLE_start_end (%s)", lab);
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, blabel,
				   "Range begin address (%s)", lab);
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, elabel,
				   "Range end address (%s)", lab);
	    }
	}

      /* Negative block_num stands for an index into ranges_by_label.  */
      else if (block_num < 0)
	{
	  int lab_idx = - block_num - 1;
	  const char *blabel = (*ranges_by_label)[lab_idx].begin;
	  const char *elabel = (*ranges_by_label)[lab_idx].end;

	  if (!have_multiple_function_sections)
	    gcc_unreachable ();
	  if (HAVE_AS_LEB128)
	    {
	      if (dwarf_split_debug_info)
		{
		  dw2_asm_output_data (1, DW_RLE_startx_length,
				       "DW_RLE_startx_length (%s)", lab);
		  dw2_asm_output_data_uleb128 (r->begin_entry->index,
					       "Range begin address index "
					       "(%s)", blabel);
		}
	      else
		{
		  dw2_asm_output_data (1, DW_RLE_start_length,
				       "DW_RLE_start_length (%s)", lab);
		  dw2_asm_output_addr (DWARF2_ADDR_SIZE, blabel,
				       "Range begin address (%s)", lab);
		}
	      dw2_asm_output_delta_uleb128 (elabel, blabel,
					    "Range length (%s)", lab);
	    }
	  else if (dwarf_split_debug_info)
	    {
	      dw2_asm_output_data (1, DW_RLE_startx_endx,
				   "DW_RLE_startx_endx (%s)", lab);
	      dw2_asm_output_data_uleb128 (r->begin_entry->index,
					   "Range begin address index "
					   "(%s)", blabel);
	      dw2_asm_output_data_uleb128 (r->end_entry->index,
					   "Range end address index "
					   "(%s)", elabel);
	    }
	  else
	    {
	      dw2_asm_output_data (1, DW_RLE_start_end,
				   "DW_RLE_start_end (%s)", lab);
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, blabel,
				   "Range begin address (%s)", lab);
	      dw2_asm_output_addr (DWARF2_ADDR_SIZE, elabel,
				   "Range end address (%s)", lab);
	    }
	}
      else
	dw2_asm_output_data (1, DW_RLE_end_of_list,
			     "DW_RLE_end_of_list (%s)", lab);
    }
  ASM_OUTPUT_LABEL (asm_out_file, l2);
  return ret;
}

/* Data structure containing information about input files.  */
struct file_info
{
  const char *path;	/* Complete file name.  */
  const char *fname;	/* File name part.  */
  int length;		/* Length of entire string.  */
  struct dwarf_file_data * file_idx;	/* Index in input file table.  */
  int dir_idx;		/* Index in directory table.  */
};

/* Data structure containing information about directories with source
   files.  */
struct dir_info
{
  const char *path;	/* Path including directory name.  */
  int length;		/* Path length.  */
  int prefix;		/* Index of directory entry which is a prefix.  */
  int count;		/* Number of files in this directory.  */
  int dir_idx;		/* Index of directory used as base.  */
};

/* Callback function for file_info comparison.  We sort by looking at
   the directories in the path.  */

static int
file_info_cmp (const void *p1, const void *p2)
{
  const struct file_info *const s1 = (const struct file_info *) p1;
  const struct file_info *const s2 = (const struct file_info *) p2;
  const unsigned char *cp1;
  const unsigned char *cp2;

  /* Take care of file names without directories.  We need to make sure that
     we return consistent values to qsort since some will get confused if
     we return the same value when identical operands are passed in opposite
     orders.  So if neither has a directory, return 0 and otherwise return
     1 or -1 depending on which one has the directory.  We want the one with
     the directory to sort after the one without, so all no directory files
     are at the start (normally only the compilation unit file).  */
  if ((s1->path == s1->fname || s2->path == s2->fname))
    return (s2->path == s2->fname) - (s1->path == s1->fname);

  cp1 = (const unsigned char *) s1->path;
  cp2 = (const unsigned char *) s2->path;

  while (1)
    {
      ++cp1;
      ++cp2;
      /* Reached the end of the first path?  If so, handle like above,
	 but now we want longer directory prefixes before shorter ones.  */
      if ((cp1 == (const unsigned char *) s1->fname)
	  || (cp2 == (const unsigned char *) s2->fname))
	return ((cp1 == (const unsigned char *) s1->fname)
		- (cp2 == (const unsigned char *) s2->fname));

      /* Character of current path component the same?  */
      else if (*cp1 != *cp2)
	return *cp1 - *cp2;
    }
}

struct file_name_acquire_data
{
  struct file_info *files;
  int used_files;
  int max_files;
};

/* Traversal function for the hash table.  */

int
file_name_acquire (dwarf_file_data **slot, file_name_acquire_data *fnad)
{
  struct dwarf_file_data *d = *slot;
  struct file_info *fi;
  const char *f;

  gcc_assert (fnad->max_files >= d->emitted_number);

  if (! d->emitted_number)
    return 1;

  gcc_assert (fnad->max_files != fnad->used_files);

  fi = fnad->files + fnad->used_files++;

  f = d->filename;

  /* Skip all leading "./".  */
  while (f[0] == '.' && IS_DIR_SEPARATOR (f[1]))
    f += 2;

  /* Create a new array entry.  */
  fi->path = f;
  fi->length = strlen (f);
  fi->file_idx = d;

  /* Search for the file name part.  */
  f = strrchr (f, DIR_SEPARATOR);
#if defined (DIR_SEPARATOR_2)
  {
    const char *g = strrchr (fi->path, DIR_SEPARATOR_2);

    if (g != NULL)
      {
	if (f == NULL || f < g)
	  f = g;
      }
  }
#endif

  fi->fname = f == NULL ? fi->path : f + 1;
  return 1;
}

/* Helper function for output_file_names.  Emit a FORM encoded
   string STR, with assembly comment start ENTRY_KIND and
   index IDX */

static void
output_line_string (enum dwarf_form form, const char *str,
		    const char *entry_kind, unsigned int idx)
{
  switch (form)
    {
    case DW_FORM_string:
      dw2_asm_output_nstring (str, -1, "%s: %#x", entry_kind, idx);
      break;
    case DW_FORM_line_strp:
      if (!debug_line_str_hash)
	debug_line_str_hash
	  = hash_table<indirect_string_hasher>::create_ggc (10);

      struct indirect_string_node *node;
      node = find_AT_string_in_table (str, debug_line_str_hash);
      set_indirect_string (node);
      node->form = form;
      dw2_asm_output_offset (dwarf_offset_size, node->label,
			     debug_line_str_section, "%s: %#x: \"%s\"",
			     entry_kind, 0, node->str);
      break;
    default:
      gcc_unreachable ();
    }
}

/* Output the directory table and the file name table.  We try to minimize
   the total amount of memory needed.  A heuristic is used to avoid large
   slowdowns with many input files.  */

static void
output_file_names (void)
{
  struct file_name_acquire_data fnad;
  int numfiles;
  struct file_info *files;
  struct dir_info *dirs;
  int *saved;
  int *savehere;
  int *backmap;
  int ndirs;
  int idx_offset;
  int i;

  if (!last_emitted_file)
    {
      if (dwarf_version >= 5)
	{
	  const char *comp_dir = comp_dir_string ();
	  if (comp_dir == NULL)
	    comp_dir = "";
	  dw2_asm_output_data (1, 1, "Directory entry format count");
	  enum dwarf_form str_form = DW_FORM_string;
	  if (DWARF5_USE_DEBUG_LINE_STR)
	    str_form = DW_FORM_line_strp;
	  dw2_asm_output_data_uleb128 (DW_LNCT_path, "DW_LNCT_path");
	  dw2_asm_output_data_uleb128 (str_form, "%s",
				       get_DW_FORM_name (str_form));
	  dw2_asm_output_data_uleb128 (1, "Directories count");
	  if (str_form == DW_FORM_string)
	    dw2_asm_output_nstring (comp_dir, -1, "Directory Entry: %#x", 0);
	  else
	    output_line_string (str_form, comp_dir, "Directory Entry", 0);
	  const char *filename0 = get_AT_string (comp_unit_die (), DW_AT_name);
	  if (filename0 == NULL)
	    filename0 = "";
#ifdef VMS_DEBUGGING_INFO
	  dw2_asm_output_data (1, 4, "File name entry format count");
#else
	  dw2_asm_output_data (1, 2, "File name entry format count");
#endif
	  dw2_asm_output_data_uleb128 (DW_LNCT_path, "DW_LNCT_path");
	  dw2_asm_output_data_uleb128 (str_form, "%s",
				       get_DW_FORM_name (str_form));
	  dw2_asm_output_data_uleb128 (DW_LNCT_directory_index,
				       "DW_LNCT_directory_index");
	  dw2_asm_output_data_uleb128 (DW_FORM_data1, "%s",
				       get_DW_FORM_name (DW_FORM_data1));
#ifdef VMS_DEBUGGING_INFO
	  dw2_asm_output_data_uleb128 (DW_LNCT_timestamp, "DW_LNCT_timestamp");
	  dw2_asm_output_data_uleb128 (DW_FORM_udata, "DW_FORM_udata");
	  dw2_asm_output_data_uleb128 (DW_LNCT_size, "DW_LNCT_size");
	  dw2_asm_output_data_uleb128 (DW_FORM_udata, "DW_FORM_udata");
#endif
	  dw2_asm_output_data_uleb128 (1, "File names count");

	  output_line_string (str_form, filename0, "File Entry", 0);
	  dw2_asm_output_data (1, 0, NULL);
#ifdef VMS_DEBUGGING_INFO
	  dw2_asm_output_data_uleb128 (0, NULL);
	  dw2_asm_output_data_uleb128 (0, NULL);
#endif
	}
      else
	{
	  dw2_asm_output_data (1, 0, "End directory table");
	  dw2_asm_output_data (1, 0, "End file name table");
	}
      return;
    }

  numfiles = last_emitted_file->emitted_number;

  /* Allocate the various arrays we need.  */
  files = XALLOCAVEC (struct file_info, numfiles);
  dirs = XALLOCAVEC (struct dir_info, numfiles);

  fnad.files = files;
  fnad.used_files = 0;
  fnad.max_files = numfiles;
  file_table->traverse<file_name_acquire_data *, file_name_acquire> (&fnad);
  gcc_assert (fnad.used_files == fnad.max_files);

  qsort (files, numfiles, sizeof (files[0]), file_info_cmp);

  /* Find all the different directories used.  */
  dirs[0].path = files[0].path;
  dirs[0].length = files[0].fname - files[0].path;
  dirs[0].prefix = -1;
  dirs[0].count = 1;
  dirs[0].dir_idx = 0;
  files[0].dir_idx = 0;
  ndirs = 1;

  for (i = 1; i < numfiles; i++)
    if (files[i].fname - files[i].path == dirs[ndirs - 1].length
	&& memcmp (dirs[ndirs - 1].path, files[i].path,
		   dirs[ndirs - 1].length) == 0)
      {
	/* Same directory as last entry.  */
	files[i].dir_idx = ndirs - 1;
	++dirs[ndirs - 1].count;
      }
    else
      {
	int j;

	/* This is a new directory.  */
	dirs[ndirs].path = files[i].path;
	dirs[ndirs].length = files[i].fname - files[i].path;
	dirs[ndirs].count = 1;
	dirs[ndirs].dir_idx = ndirs;
	files[i].dir_idx = ndirs;

	/* Search for a prefix.  */
	dirs[ndirs].prefix = -1;
	for (j = 0; j < ndirs; j++)
	  if (dirs[j].length < dirs[ndirs].length
	      && dirs[j].length > 1
	      && (dirs[ndirs].prefix == -1
		  || dirs[j].length > dirs[dirs[ndirs].prefix].length)
	      && memcmp (dirs[j].path, dirs[ndirs].path, dirs[j].length) == 0)
	    dirs[ndirs].prefix = j;

	++ndirs;
      }

  /* Now to the actual work.  We have to find a subset of the directories which
     allow expressing the file name using references to the directory table
     with the least amount of characters.  We do not do an exhaustive search
     where we would have to check out every combination of every single
     possible prefix.  Instead we use a heuristic which provides nearly optimal
     results in most cases and never is much off.  */
  saved = XALLOCAVEC (int, ndirs);
  savehere = XALLOCAVEC (int, ndirs);

  memset (saved, '\0', ndirs * sizeof (saved[0]));
  for (i = 0; i < ndirs; i++)
    {
      int j;
      int total;

      /* We can always save some space for the current directory.  But this
	 does not mean it will be enough to justify adding the directory.  */
      savehere[i] = dirs[i].length;
      total = (savehere[i] - saved[i]) * dirs[i].count;

      for (j = i + 1; j < ndirs; j++)
	{
	  savehere[j] = 0;
	  if (saved[j] < dirs[i].length)
	    {
	      /* Determine whether the dirs[i] path is a prefix of the
		 dirs[j] path.  */
	      int k;

	      k = dirs[j].prefix;
	      while (k != -1 && k != (int) i)
		k = dirs[k].prefix;

	      if (k == (int) i)
		{
		  /* Yes it is.  We can possibly save some memory by
		     writing the filenames in dirs[j] relative to
		     dirs[i].  */
		  savehere[j] = dirs[i].length;
		  total += (savehere[j] - saved[j]) * dirs[j].count;
		}
	    }
	}

      /* Check whether we can save enough to justify adding the dirs[i]
	 directory.  */
      if (total > dirs[i].length + 1)
	{
	  /* It's worthwhile adding.  */
	  for (j = i; j < ndirs; j++)
	    if (savehere[j] > 0)
	      {
		/* Remember how much we saved for this directory so far.  */
		saved[j] = savehere[j];

		/* Remember the prefix directory.  */
		dirs[j].dir_idx = i;
	      }
	}
    }

  /* Emit the directory name table.  */
  idx_offset = dirs[0].length > 0 ? 1 : 0;
  enum dwarf_form str_form = DW_FORM_string;
  enum dwarf_form idx_form = DW_FORM_udata;
  if (dwarf_version >= 5)
    {
      const char *comp_dir = comp_dir_string ();
      if (comp_dir == NULL)
	comp_dir = "";
      dw2_asm_output_data (1, 1, "Directory entry format count");
      if (DWARF5_USE_DEBUG_LINE_STR)
	str_form = DW_FORM_line_strp;
      dw2_asm_output_data_uleb128 (DW_LNCT_path, "DW_LNCT_path");
      dw2_asm_output_data_uleb128 (str_form, "%s",
				   get_DW_FORM_name (str_form));
      dw2_asm_output_data_uleb128 (ndirs + idx_offset, "Directories count");
      if (str_form == DW_FORM_string)
	{
	  dw2_asm_output_nstring (comp_dir, -1, "Directory Entry: %#x", 0);
	  for (i = 1 - idx_offset; i < ndirs; i++)
	    dw2_asm_output_nstring (dirs[i].path,
				    dirs[i].length
				    - !DWARF2_DIR_SHOULD_END_WITH_SEPARATOR,
				    "Directory Entry: %#x", i + idx_offset);
	}
      else
	{
	  output_line_string (str_form, comp_dir, "Directory Entry", 0);
	  for (i = 1 - idx_offset; i < ndirs; i++)
	    {
	      const char *str
		= ggc_alloc_string (dirs[i].path,
				    dirs[i].length
				    - !DWARF2_DIR_SHOULD_END_WITH_SEPARATOR);
	      output_line_string (str_form, str, "Directory Entry",
				  (unsigned) i + idx_offset);
	    }
	}
    }
  else
    {
      for (i = 1 - idx_offset; i < ndirs; i++)
	dw2_asm_output_nstring (dirs[i].path,
				dirs[i].length
				- !DWARF2_DIR_SHOULD_END_WITH_SEPARATOR,
				"Directory Entry: %#x", i + idx_offset);

      dw2_asm_output_data (1, 0, "End directory table");
    }

  /* We have to emit them in the order of emitted_number since that's
     used in the debug info generation.  To do this efficiently we
     generate a back-mapping of the indices first.  */
  backmap = XALLOCAVEC (int, numfiles);
  for (i = 0; i < numfiles; i++)
    backmap[files[i].file_idx->emitted_number - 1] = i;

  if (dwarf_version >= 5)
    {
      const char *filename0 = get_AT_string (comp_unit_die (), DW_AT_name);
      if (filename0 == NULL)
	filename0 = "";
      /* DW_LNCT_directory_index can use DW_FORM_udata, DW_FORM_data1 and
	 DW_FORM_data2.  Choose one based on the number of directories
	 and how much space would they occupy in each encoding.
	 If we have at most 256 directories, all indexes fit into
	 a single byte, so DW_FORM_data1 is most compact (if there
	 are at most 128 directories, DW_FORM_udata would be as
	 compact as that, but not shorter and slower to decode).  */
      if (ndirs + idx_offset <= 256)
	idx_form = DW_FORM_data1;
      /* If there are more than 65536 directories, we have to use
	 DW_FORM_udata, DW_FORM_data2 can't refer to them.
	 Otherwise, compute what space would occupy if all the indexes
	 used DW_FORM_udata - sum - and compare that to how large would
	 be DW_FORM_data2 encoding, and pick the more efficient one.  */
      else if (ndirs + idx_offset <= 65536)
	{
	  unsigned HOST_WIDE_INT sum = 1;
	  for (i = 0; i < numfiles; i++)
	    {
	      int file_idx = backmap[i];
	      int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;
	      sum += size_of_uleb128 (dir_idx);
	    }
	  if (sum >= HOST_WIDE_INT_UC (2) * (numfiles + 1))
	    idx_form = DW_FORM_data2;
	}
#ifdef VMS_DEBUGGING_INFO
      dw2_asm_output_data (1, 4, "File name entry format count");
#else
      dw2_asm_output_data (1, 2, "File name entry format count");
#endif
      dw2_asm_output_data_uleb128 (DW_LNCT_path, "DW_LNCT_path");
      dw2_asm_output_data_uleb128 (str_form, "%s",
				   get_DW_FORM_name (str_form));
      dw2_asm_output_data_uleb128 (DW_LNCT_directory_index,
				   "DW_LNCT_directory_index");
      dw2_asm_output_data_uleb128 (idx_form, "%s",
				   get_DW_FORM_name (idx_form));
#ifdef VMS_DEBUGGING_INFO
      dw2_asm_output_data_uleb128 (DW_LNCT_timestamp, "DW_LNCT_timestamp");
      dw2_asm_output_data_uleb128 (DW_FORM_udata, "DW_FORM_udata");
      dw2_asm_output_data_uleb128 (DW_LNCT_size, "DW_LNCT_size");
      dw2_asm_output_data_uleb128 (DW_FORM_udata, "DW_FORM_udata");
#endif
      dw2_asm_output_data_uleb128 (numfiles + 1, "File names count");

      output_line_string (str_form, filename0, "File Entry", 0);

      /* Include directory index.  */
      if (idx_form != DW_FORM_udata)
	dw2_asm_output_data (idx_form == DW_FORM_data1 ? 1 : 2,
			     0, NULL);
      else
	dw2_asm_output_data_uleb128 (0, NULL);

#ifdef VMS_DEBUGGING_INFO
      dw2_asm_output_data_uleb128 (0, NULL);
      dw2_asm_output_data_uleb128 (0, NULL);
#endif
    }

  /* Now write all the file names.  */
  for (i = 0; i < numfiles; i++)
    {
      int file_idx = backmap[i];
      int dir_idx = dirs[files[file_idx].dir_idx].dir_idx;

#ifdef VMS_DEBUGGING_INFO
#define MAX_VMS_VERSION_LEN 6 /* ";32768" */

      /* Setting these fields can lead to debugger miscomparisons,
         but VMS Debug requires them to be set correctly.  */

      int ver;
      long long cdt;
      long siz;
      int maxfilelen = (strlen (files[file_idx].path)
			+ dirs[dir_idx].length
			+ MAX_VMS_VERSION_LEN + 1);
      char *filebuf = XALLOCAVEC (char, maxfilelen);

      vms_file_stats_name (files[file_idx].path, 0, 0, 0, &ver);
      snprintf (filebuf, maxfilelen, "%s;%d",
	        files[file_idx].path + dirs[dir_idx].length, ver);

      output_line_string (str_form, filebuf, "File Entry", (unsigned) i + 1);

      /* Include directory index.  */
      if (dwarf_version >= 5 && idx_form != DW_FORM_udata)
	dw2_asm_output_data (idx_form == DW_FORM_data1 ? 1 : 2,
			     dir_idx + idx_offset, NULL);
      else
	dw2_asm_output_data_uleb128 (dir_idx + idx_offset, NULL);

      /* Modification time.  */
      dw2_asm_output_data_uleb128 ((vms_file_stats_name (files[file_idx].path,
							 &cdt, 0, 0, 0) == 0)
				   ? cdt : 0, NULL);

      /* File length in bytes.  */
      dw2_asm_output_data_uleb128 ((vms_file_stats_name (files[file_idx].path,
							 0, &siz, 0, 0) == 0)
				   ? siz : 0, NULL);
#else
      output_line_string (str_form,
			  files[file_idx].path + dirs[dir_idx].length,
			  "File Entry", (unsigned) i + 1);

      /* Include directory index.  */
      if (dwarf_version >= 5 && idx_form != DW_FORM_udata)
	dw2_asm_output_data (idx_form == DW_FORM_data1 ? 1 : 2,
			     dir_idx + idx_offset, NULL);
      else
	dw2_asm_output_data_uleb128 (dir_idx + idx_offset, NULL);

      if (dwarf_version >= 5)
	continue;

      /* Modification time.  */
      dw2_asm_output_data_uleb128 (0, NULL);

      /* File length in bytes.  */
      dw2_asm_output_data_uleb128 (0, NULL);
#endif /* VMS_DEBUGGING_INFO */
    }

  if (dwarf_version < 5)
    dw2_asm_output_data (1, 0, "End file name table");
}


/* Output one line number table into the .debug_line section.  */

static void
output_one_line_info_table (dw_line_info_table *table)
{
  char line_label[MAX_ARTIFICIAL_LABEL_BYTES];
  unsigned int current_line = 1;
  bool current_is_stmt = DWARF_LINE_DEFAULT_IS_STMT_START;
  dw_line_info_entry *ent, *prev_addr;
  size_t i;
  unsigned int view;

  view = 0;

  FOR_EACH_VEC_SAFE_ELT (table->entries, i, ent)
    {
      switch (ent->opcode)
	{
	case LI_set_address:
	  /* ??? Unfortunately, we have little choice here currently, and
	     must always use the most general form.  GCC does not know the
	     address delta itself, so we can't use DW_LNS_advance_pc.  Many
	     ports do have length attributes which will give an upper bound
	     on the address range.  We could perhaps use length attributes
	     to determine when it is safe to use DW_LNS_fixed_advance_pc.  */
	  ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, ent->val);

	  view = 0;

	  /* This can handle any delta.  This takes
	     4+DWARF2_ADDR_SIZE bytes.  */
	  dw2_asm_output_data (1, 0, "set address %s%s", line_label,
			       debug_variable_location_views
			       ? ", reset view to 0" : "");
	  dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
	  dw2_asm_output_data (1, DW_LNE_set_address, NULL);
	  dw2_asm_output_addr (DWARF2_ADDR_SIZE, line_label, NULL);

	  prev_addr = ent;
	  break;

	case LI_adv_address:
	  {
	    ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, ent->val);
	    char prev_label[MAX_ARTIFICIAL_LABEL_BYTES];
	    ASM_GENERATE_INTERNAL_LABEL (prev_label, LINE_CODE_LABEL, prev_addr->val);

	    view++;

	    dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, "fixed advance PC, increment view to %i", view);
	    dw2_asm_output_delta (2, line_label, prev_label,
				  "from %s to %s", prev_label, line_label);

	    prev_addr = ent;
	    break;
	  }

	case LI_set_line:
	  if (ent->val == current_line)
	    {
	      /* We still need to start a new row, so output a copy insn.  */
	      dw2_asm_output_data (1, DW_LNS_copy,
				   "copy line %u", current_line);
	    }
	  else
	    {
	      int line_offset = ent->val - current_line;
	      int line_delta = line_offset - DWARF_LINE_BASE;

	      current_line = ent->val;
	      if (line_delta >= 0 && line_delta < (DWARF_LINE_RANGE - 1))
		{
		  /* This can handle deltas from -10 to 234, using the current
		     definitions of DWARF_LINE_BASE and DWARF_LINE_RANGE.
		     This takes 1 byte.  */
		  dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE + line_delta,
				       "line %u", current_line);
		}
	      else
		{
		  /* This can handle any delta.  This takes at least 4 bytes,
		     depending on the value being encoded.  */
		  dw2_asm_output_data (1, DW_LNS_advance_line,
				       "advance to line %u", current_line);
		  dw2_asm_output_data_sleb128 (line_offset, NULL);
		  dw2_asm_output_data (1, DW_LNS_copy, NULL);
		}
	    }
	  break;

	case LI_set_file:
	  dw2_asm_output_data (1, DW_LNS_set_file, "set file %u", ent->val);
	  dw2_asm_output_data_uleb128 (ent->val, "%u", ent->val);
	  break;

	case LI_set_column:
	  dw2_asm_output_data (1, DW_LNS_set_column, "column %u", ent->val);
	  dw2_asm_output_data_uleb128 (ent->val, "%u", ent->val);
	  break;

	case LI_negate_stmt:
	  current_is_stmt = !current_is_stmt;
	  dw2_asm_output_data (1, DW_LNS_negate_stmt,
			       "is_stmt %d", current_is_stmt);
	  break;

	case LI_set_prologue_end:
	  dw2_asm_output_data (1, DW_LNS_set_prologue_end,
			       "set prologue end");
	  break;
	  
	case LI_set_epilogue_begin:
	  dw2_asm_output_data (1, DW_LNS_set_epilogue_begin,
			       "set epilogue begin");
	  break;

	case LI_set_discriminator:
	  dw2_asm_output_data (1, 0, "discriminator %u", ent->val);
	  dw2_asm_output_data_uleb128 (1 + size_of_uleb128 (ent->val), NULL);
	  dw2_asm_output_data (1, DW_LNE_set_discriminator, NULL);
	  dw2_asm_output_data_uleb128 (ent->val, NULL);
	  break;
	}
    }

  /* Emit debug info for the address of the end of the table.  */
  dw2_asm_output_data (1, 0, "set address %s", table->end_label);
  dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL);
  dw2_asm_output_data (1, DW_LNE_set_address, NULL);
  dw2_asm_output_addr (DWARF2_ADDR_SIZE, table->end_label, NULL);

  dw2_asm_output_data (1, 0, "end sequence");
  dw2_asm_output_data_uleb128 (1, NULL);
  dw2_asm_output_data (1, DW_LNE_end_sequence, NULL);
}

static unsigned int output_line_info_generation;

/* Output the source line number correspondence information.  This
   information goes into the .debug_line section.  */

static void
output_line_info (bool prologue_only)
{
  char l1[MAX_ARTIFICIAL_LABEL_BYTES], l2[MAX_ARTIFICIAL_LABEL_BYTES];
  char p1[MAX_ARTIFICIAL_LABEL_BYTES], p2[MAX_ARTIFICIAL_LABEL_BYTES];
  bool saw_one = false;
  int opc;

  ASM_GENERATE_INTERNAL_LABEL (l1, LINE_NUMBER_BEGIN_LABEL,
			       output_line_info_generation);
  ASM_GENERATE_INTERNAL_LABEL (l2, LINE_NUMBER_END_LABEL,
			       output_line_info_generation);
  ASM_GENERATE_INTERNAL_LABEL (p1, LN_PROLOG_AS_LABEL,
			       output_line_info_generation);
  ASM_GENERATE_INTERNAL_LABEL (p2, LN_PROLOG_END_LABEL,
			       output_line_info_generation++);

  if (!XCOFF_DEBUGGING_INFO)
    {
      if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
	dw2_asm_output_data (4, 0xffffffff,
	  "Initial length escape value indicating 64-bit DWARF extension");
      dw2_asm_output_delta (dwarf_offset_size, l2, l1,
			    "Length of Source Line Info");
    }

  ASM_OUTPUT_LABEL (asm_out_file, l1);

  output_dwarf_version ();
  if (dwarf_version >= 5)
    {
      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size");
      dw2_asm_output_data (1, 0, "Segment Size");
    }
  dw2_asm_output_delta (dwarf_offset_size, p2, p1, "Prolog Length");
  ASM_OUTPUT_LABEL (asm_out_file, p1);

  /* Define the architecture-dependent minimum instruction length (in bytes).
     In this implementation of DWARF, this field is used for information
     purposes only.  Since GCC generates assembly language, we have no
     a priori knowledge of how many instruction bytes are generated for each
     source line, and therefore can use only the DW_LNE_set_address and
     DW_LNS_fixed_advance_pc line information commands.  Accordingly, we fix
     this as '1', which is "correct enough" for all architectures,
     and don't let the target override.  */
  dw2_asm_output_data (1, 1, "Minimum Instruction Length");

  if (dwarf_version >= 4)
    dw2_asm_output_data (1, DWARF_LINE_DEFAULT_MAX_OPS_PER_INSN,
			 "Maximum Operations Per Instruction");
  dw2_asm_output_data (1, DWARF_LINE_DEFAULT_IS_STMT_START,
		       "Default is_stmt_start flag");
  dw2_asm_output_data (1, DWARF_LINE_BASE,
		       "Line Base Value (Special Opcodes)");
  dw2_asm_output_data (1, DWARF_LINE_RANGE,
		       "Line Range Value (Special Opcodes)");
  dw2_asm_output_data (1, DWARF_LINE_OPCODE_BASE,
		       "Special Opcode Base");

  for (opc = 1; opc < DWARF_LINE_OPCODE_BASE; opc++)
    {
      int n_op_args;
      switch (opc)
	{
	case DW_LNS_advance_pc:
	case DW_LNS_advance_line:
	case DW_LNS_set_file:
	case DW_LNS_set_column:
	case DW_LNS_fixed_advance_pc:
	case DW_LNS_set_isa:
	  n_op_args = 1;
	  break;
	default:
	  n_op_args = 0;
	  break;
	}

      dw2_asm_output_data (1, n_op_args, "opcode: %#x has %d args",
			   opc, n_op_args);
    }

  /* Write out the information about the files we use.  */
  output_file_names ();
  ASM_OUTPUT_LABEL (asm_out_file, p2);
  if (prologue_only)
    {
      /* Output the marker for the end of the line number info.  */
      ASM_OUTPUT_LABEL (asm_out_file, l2);
      return;
    }

  if (separate_line_info)
    {
      dw_line_info_table *table;
      size_t i;

      FOR_EACH_VEC_ELT (*separate_line_info, i, table)
	if (table->in_use)
	  {
	    output_one_line_info_table (table);
	    saw_one = true;
	  }
    }
  if (cold_text_section_line_info && cold_text_section_line_info->in_use)
    {
      output_one_line_info_table (cold_text_section_line_info);
      saw_one = true;
    }

  /* ??? Some Darwin linkers crash on a .debug_line section with no
     sequences.  Further, merely a DW_LNE_end_sequence entry is not
     sufficient -- the address column must also be initialized.
     Make sure to output at least one set_address/end_sequence pair,
     choosing .text since that section is always present.  */
  if (text_section_line_info->in_use || !saw_one)
    output_one_line_info_table (text_section_line_info);

  /* Output the marker for the end of the line number info.  */
  ASM_OUTPUT_LABEL (asm_out_file, l2);
}

/* Return true if DW_AT_endianity should be emitted according to REVERSE.  */

static inline bool
need_endianity_attribute_p (bool reverse)
{
  return reverse && (dwarf_version >= 3 || !dwarf_strict);
}

/* Given a pointer to a tree node for some base type, return a pointer to
   a DIE that describes the given type.  REVERSE is true if the type is
   to be interpreted in the reverse storage order wrt the target order.

   This routine must only be called for GCC type nodes that correspond to
   Dwarf base (fundamental) types.  */

dw_die_ref
base_type_die (tree type, bool reverse)
{
  dw_die_ref base_type_result;
  enum dwarf_type encoding;
  bool fpt_used = false;
  struct fixed_point_type_info fpt_info;
  tree type_bias = NULL_TREE;

  /* If this is a subtype that should not be emitted as a subrange type,
     use the base type.  See subrange_type_for_debug_p.  */
  if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
    type = TREE_TYPE (type);

  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
      if ((dwarf_version >= 4 || !dwarf_strict)
	  && TYPE_NAME (type)
	  && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
	  && DECL_IS_UNDECLARED_BUILTIN (TYPE_NAME (type))
	  && DECL_NAME (TYPE_NAME (type)))
	{
	  const char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
	  if (strcmp (name, "char16_t") == 0
	      || strcmp (name, "char32_t") == 0)
	    {
	      encoding = DW_ATE_UTF;
	      break;
	    }
	}
      if ((dwarf_version >= 3 || !dwarf_strict)
	  && lang_hooks.types.get_fixed_point_type_info)
	{
	  memset (&fpt_info, 0, sizeof (fpt_info));
	  if (lang_hooks.types.get_fixed_point_type_info (type, &fpt_info))
	    {
	      fpt_used = true;
	      encoding = ((TYPE_UNSIGNED (type))
			  ? DW_ATE_unsigned_fixed
			  : DW_ATE_signed_fixed);
	      break;
	    }
	}
      if (TYPE_STRING_FLAG (type))
	{
	  if (TYPE_UNSIGNED (type))
	    encoding = DW_ATE_unsigned_char;
	  else
	    encoding = DW_ATE_signed_char;
	}
      else if (TYPE_UNSIGNED (type))
	encoding = DW_ATE_unsigned;
      else
	encoding = DW_ATE_signed;

      if (!dwarf_strict
	  && lang_hooks.types.get_type_bias)
	type_bias = lang_hooks.types.get_type_bias (type);
      break;

    case REAL_TYPE:
      if (DECIMAL_FLOAT_MODE_P (TYPE_MODE (type)))
	{
	  if (dwarf_version >= 3 || !dwarf_strict)
	    encoding = DW_ATE_decimal_float;
	  else
	    encoding = DW_ATE_lo_user;
	}
      else
	encoding = DW_ATE_float;
      break;

    case FIXED_POINT_TYPE:
      if (!(dwarf_version >= 3 || !dwarf_strict))
	encoding = DW_ATE_lo_user;
      else if (TYPE_UNSIGNED (type))
	encoding = DW_ATE_unsigned_fixed;
      else
	encoding = DW_ATE_signed_fixed;
      break;

      /* Dwarf2 doesn't know anything about complex ints, so use
	 a user defined type for it.  */
    case COMPLEX_TYPE:
      if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
	encoding = DW_ATE_complex_float;
      else
	encoding = DW_ATE_lo_user;
      break;

    case BOOLEAN_TYPE:
      /* GNU FORTRAN/Ada/C++ BOOLEAN type.  */
      encoding = DW_ATE_boolean;
      break;

    default:
      /* No other TREE_CODEs are Dwarf fundamental types.  */
      gcc_unreachable ();
    }

  base_type_result = new_die_raw (DW_TAG_base_type);

  add_AT_unsigned (base_type_result, DW_AT_byte_size,
		   int_size_in_bytes (type));
  add_AT_unsigned (base_type_result, DW_AT_encoding, encoding);

  if (need_endianity_attribute_p (reverse))
    add_AT_unsigned (base_type_result, DW_AT_endianity,
		     BYTES_BIG_ENDIAN ? DW_END_little : DW_END_big);

  add_alignment_attribute (base_type_result, type);

  if (fpt_used)
    {
      switch (fpt_info.scale_factor_kind)
	{
	case fixed_point_scale_factor_binary:
	  add_AT_int (base_type_result, DW_AT_binary_scale,
		      fpt_info.scale_factor.binary);
	  break;

	case fixed_point_scale_factor_decimal:
	  add_AT_int (base_type_result, DW_AT_decimal_scale,
		      fpt_info.scale_factor.decimal);
	  break;

	case fixed_point_scale_factor_arbitrary:
	  /* Arbitrary scale factors cannot be described in standard DWARF.  */
	  if (!dwarf_strict)
	    {
	      /* Describe the scale factor as a rational constant.  */
	      const dw_die_ref scale_factor
		= new_die (DW_TAG_constant, comp_unit_die (), type);

	      add_scalar_info (scale_factor, DW_AT_GNU_numerator,
			       fpt_info.scale_factor.arbitrary.numerator,
			       dw_scalar_form_constant, NULL);
	      add_scalar_info (scale_factor, DW_AT_GNU_denominator,
			       fpt_info.scale_factor.arbitrary.denominator,
			       dw_scalar_form_constant, NULL);

	      add_AT_die_ref (base_type_result, DW_AT_small, scale_factor);
	    }
	  break;

	default:
	  gcc_unreachable ();
	}
    }

  if (type_bias)
    add_scalar_info (base_type_result, DW_AT_GNU_bias, type_bias,
		     dw_scalar_form_constant
		     | dw_scalar_form_exprloc
		     | dw_scalar_form_reference,
		     NULL);

  return base_type_result;
}

/* A C++ function with deduced return type can have a TEMPLATE_TYPE_PARM
   named 'auto' in its type: return true for it, false otherwise.  */

static inline bool
is_cxx_auto (tree type)
{
  if (is_cxx ())
    {
      tree name = TYPE_IDENTIFIER (type);
      if (name == get_identifier ("auto")
	  || name == get_identifier ("decltype(auto)"))
	return true;
    }
  return false;
}

/* Given a pointer to an arbitrary ..._TYPE tree node, return nonzero if the
   given input type is a Dwarf "fundamental" type.  Otherwise return null.  */

static inline int
is_base_type (tree type)
{
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
    case REAL_TYPE:
    case FIXED_POINT_TYPE:
    case COMPLEX_TYPE:
    case BOOLEAN_TYPE:
      return 1;

    case VOID_TYPE:
    case OPAQUE_TYPE:
    case ARRAY_TYPE:
    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
    case ENUMERAL_TYPE:
    case FUNCTION_TYPE:
    case METHOD_TYPE:
    case POINTER_TYPE:
    case REFERENCE_TYPE:
    case NULLPTR_TYPE:
    case OFFSET_TYPE:
    case LANG_TYPE:
    case VECTOR_TYPE:
      return 0;

    default:
      if (is_cxx_auto (type))
	return 0;
      gcc_unreachable ();
    }

  return 0;
}

/* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
   node, return the size in bits for the type if it is a constant, or else
   return the alignment for the type if the type's size is not constant, or
   else return BITS_PER_WORD if the type actually turns out to be an
   ERROR_MARK node.  */

static inline unsigned HOST_WIDE_INT
simple_type_size_in_bits (const_tree type)
{
  if (TREE_CODE (type) == ERROR_MARK)
    return BITS_PER_WORD;
  else if (TYPE_SIZE (type) == NULL_TREE)
    return 0;
  else if (tree_fits_uhwi_p (TYPE_SIZE (type)))
    return tree_to_uhwi (TYPE_SIZE (type));
  else
    return TYPE_ALIGN (type);
}

/* Similarly, but return an offset_int instead of UHWI.  */

static inline offset_int
offset_int_type_size_in_bits (const_tree type)
{
  if (TREE_CODE (type) == ERROR_MARK)
    return BITS_PER_WORD;
  else if (TYPE_SIZE (type) == NULL_TREE)
    return 0;
  else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
    return wi::to_offset (TYPE_SIZE (type));
  else
    return TYPE_ALIGN (type);
}

/*  Given a pointer to a tree node for a subrange type, return a pointer
    to a DIE that describes the given type.  */

static dw_die_ref
subrange_type_die (tree type, tree low, tree high, tree bias,
		   dw_die_ref context_die)
{
  dw_die_ref subrange_die;
  const HOST_WIDE_INT size_in_bytes = int_size_in_bytes (type);

  if (context_die == NULL)
    context_die = comp_unit_die ();

  subrange_die = new_die (DW_TAG_subrange_type, context_die, type);

  if (int_size_in_bytes (TREE_TYPE (type)) != size_in_bytes)
    {
      /* The size of the subrange type and its base type do not match,
	 so we need to generate a size attribute for the subrange type.  */
      add_AT_unsigned (subrange_die, DW_AT_byte_size, size_in_bytes);
    }

  add_alignment_attribute (subrange_die, type);

  if (low)
    add_bound_info (subrange_die, DW_AT_lower_bound, low, NULL);
  if (high)
    add_bound_info (subrange_die, DW_AT_upper_bound, high, NULL);
  if (bias && !dwarf_strict)
    add_scalar_info (subrange_die, DW_AT_GNU_bias, bias,
		     dw_scalar_form_constant
		     | dw_scalar_form_exprloc
		     | dw_scalar_form_reference,
		     NULL);

  return subrange_die;
}

/* Returns the (const and/or volatile) cv_qualifiers associated with
   the decl node.  This will normally be augmented with the
   cv_qualifiers of the underlying type in add_type_attribute.  */

static int
decl_quals (const_tree decl)
{
  return ((TREE_READONLY (decl)
	   /* The C++ front-end correctly marks reference-typed
	      variables as readonly, but from a language (and debug
	      info) standpoint they are not const-qualified.  */
	   && TREE_CODE (TREE_TYPE (decl)) != REFERENCE_TYPE
	   ? TYPE_QUAL_CONST : TYPE_UNQUALIFIED)
	  | (TREE_THIS_VOLATILE (decl)
	     ? TYPE_QUAL_VOLATILE : TYPE_UNQUALIFIED));
}

/* Determine the TYPE whose qualifiers match the largest strict subset
   of the given TYPE_QUALS, and return its qualifiers.  Ignore all
   qualifiers outside QUAL_MASK.  */

static int
get_nearest_type_subqualifiers (tree type, int type_quals, int qual_mask)
{
  tree t;
  int best_rank = 0, best_qual = 0, max_rank;

  type_quals &= qual_mask;
  max_rank = popcount_hwi (type_quals) - 1;

  for (t = TYPE_MAIN_VARIANT (type); t && best_rank < max_rank;
       t = TYPE_NEXT_VARIANT (t))
    {
      int q = TYPE_QUALS (t) & qual_mask;

      if ((q & type_quals) == q && q != type_quals
	  && check_base_type (t, type))
	{
	  int rank = popcount_hwi (q);

	  if (rank > best_rank)
	    {
	      best_rank = rank;
	      best_qual = q;
	    }
	}
    }

  return best_qual;
}

struct dwarf_qual_info_t { int q; enum dwarf_tag t; };
static const dwarf_qual_info_t dwarf_qual_info[] =
{
  { TYPE_QUAL_CONST, DW_TAG_const_type },
  { TYPE_QUAL_VOLATILE, DW_TAG_volatile_type },
  { TYPE_QUAL_RESTRICT, DW_TAG_restrict_type },
  { TYPE_QUAL_ATOMIC, DW_TAG_atomic_type }
};
static const unsigned int dwarf_qual_info_size
  = sizeof (dwarf_qual_info) / sizeof (dwarf_qual_info[0]);

/* If DIE is a qualified DIE of some base DIE with the same parent,
   return the base DIE, otherwise return NULL.  Set MASK to the
   qualifiers added compared to the returned DIE.  */

static dw_die_ref
qualified_die_p (dw_die_ref die, int *mask, unsigned int depth)
{
  unsigned int i;
  for (i = 0; i < dwarf_qual_info_size; i++)
    if (die->die_tag == dwarf_qual_info[i].t)
      break;
  if (i == dwarf_qual_info_size)
    return NULL;
  if (vec_safe_length (die->die_attr) != 1)
    return NULL;
  dw_die_ref type = get_AT_ref (die, DW_AT_type);
  if (type == NULL || type->die_parent != die->die_parent)
    return NULL;
  *mask |= dwarf_qual_info[i].q;
  if (depth)
    {
      dw_die_ref ret = qualified_die_p (type, mask, depth - 1);
      if (ret)
	return ret;
    }
  return type;
}

/* Given a pointer to an arbitrary ..._TYPE tree node, return a debugging
   entry that chains the modifiers specified by CV_QUALS in front of the
   given type.  REVERSE is true if the type is to be interpreted in the
   reverse storage order wrt the target order.  */

static dw_die_ref
modified_type_die (tree type, int cv_quals, bool reverse,
		   dw_die_ref context_die)
{
  enum tree_code code = TREE_CODE (type);
  dw_die_ref mod_type_die;
  dw_die_ref sub_die = NULL;
  tree item_type = NULL;
  tree qualified_type;
  tree name, low, high;
  dw_die_ref mod_scope;
  struct array_descr_info info;
  /* Only these cv-qualifiers are currently handled.  */
  const int cv_qual_mask = (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE
			    | TYPE_QUAL_RESTRICT | TYPE_QUAL_ATOMIC | 
			    ENCODE_QUAL_ADDR_SPACE(~0U));
  const bool reverse_base_type
    = need_endianity_attribute_p (reverse) && is_base_type (type);

  if (code == ERROR_MARK)
    return NULL;

  if (lang_hooks.types.get_debug_type)
    {
      tree debug_type = lang_hooks.types.get_debug_type (type);

      if (debug_type != NULL_TREE && debug_type != type)
	return modified_type_die (debug_type, cv_quals, reverse, context_die);
    }

  cv_quals &= cv_qual_mask;

  /* Don't emit DW_TAG_restrict_type for DWARFv2, since it is a type
     tag modifier (and not an attribute) old consumers won't be able
     to handle it.  */
  if (dwarf_version < 3)
    cv_quals &= ~TYPE_QUAL_RESTRICT;

  /* Likewise for DW_TAG_atomic_type for DWARFv5.  */
  if (dwarf_version < 5)
    cv_quals &= ~TYPE_QUAL_ATOMIC;

  /* See if we already have the appropriately qualified variant of
     this type.  */
  qualified_type = get_qualified_type (type, cv_quals);

  if (qualified_type == sizetype)
    {
      /* Try not to expose the internal sizetype type's name.  */
      if (TYPE_NAME (qualified_type)
	  && TREE_CODE (TYPE_NAME (qualified_type)) == TYPE_DECL)
	{
	  tree t = TREE_TYPE (TYPE_NAME (qualified_type));

	  gcc_checking_assert (TREE_CODE (t) == INTEGER_TYPE
			       && (TYPE_PRECISION (t)
				   == TYPE_PRECISION (qualified_type))
			       && (TYPE_UNSIGNED (t)
				   == TYPE_UNSIGNED (qualified_type)));
	  qualified_type = t;
	}
      else if (qualified_type == sizetype
	       && TREE_CODE (sizetype) == TREE_CODE (size_type_node)
	       && TYPE_PRECISION (sizetype) == TYPE_PRECISION (size_type_node)
	       && TYPE_UNSIGNED (sizetype) == TYPE_UNSIGNED (size_type_node))
	qualified_type = size_type_node;
      if (type == sizetype)
	type = qualified_type;
    }

  /* If we do, then we can just use its DIE, if it exists.  */
  if (qualified_type)
    {
      mod_type_die = lookup_type_die (qualified_type);

      /* DW_AT_endianity doesn't come from a qualifier on the type, so it is
	 dealt with specially: the DIE with the attribute, if it exists, is
	 placed immediately after the regular DIE for the same base type.  */
      if (mod_type_die
	  && (!reverse_base_type
	      || ((mod_type_die = mod_type_die->die_sib) != NULL
		  && get_AT_unsigned (mod_type_die, DW_AT_endianity))))
	return mod_type_die;
    }

  name = qualified_type ? TYPE_NAME (qualified_type) : NULL;

  /* Handle C typedef types.  */
  if (name
      && TREE_CODE (name) == TYPE_DECL
      && DECL_ORIGINAL_TYPE (name)
      && !DECL_ARTIFICIAL (name))
    {
      tree dtype = TREE_TYPE (name);

      /* Skip the typedef for base types with DW_AT_endianity, no big deal.  */
      if (qualified_type == dtype && !reverse_base_type)
	{
	  tree origin = decl_ultimate_origin (name);

	  /* Typedef variants that have an abstract origin don't get their own
	     type DIE (see gen_typedef_die), so fall back on the ultimate
	     abstract origin instead.  */
	  if (origin != NULL && origin != name)
	    return modified_type_die (TREE_TYPE (origin), cv_quals, reverse,
				      context_die);

	  /* For a named type, use the typedef.  */
	  gen_type_die (qualified_type, context_die);
	  return lookup_type_die (qualified_type);
	}
      else
	{
	  int dquals = TYPE_QUALS_NO_ADDR_SPACE (dtype);
	  dquals &= cv_qual_mask;
	  if ((dquals & ~cv_quals) != TYPE_UNQUALIFIED
	      || (cv_quals == dquals && DECL_ORIGINAL_TYPE (name) != type))
	    /* cv-unqualified version of named type.  Just use
	       the unnamed type to which it refers.  */
	    return modified_type_die (DECL_ORIGINAL_TYPE (name), cv_quals,
				      reverse, context_die);
	  /* Else cv-qualified version of named type; fall through.  */
	}
    }

  mod_scope = scope_die_for (type, context_die);

  if (cv_quals)
    {
      int sub_quals = 0, first_quals = 0;
      unsigned i;
      dw_die_ref first = NULL, last = NULL;

      /* Determine a lesser qualified type that most closely matches
	 this one.  Then generate DW_TAG_* entries for the remaining
	 qualifiers.  */
      sub_quals = get_nearest_type_subqualifiers (type, cv_quals,
						  cv_qual_mask);
      if (sub_quals && use_debug_types)
	{
	  bool needed = false;
	  /* If emitting type units, make sure the order of qualifiers
	     is canonical.  Thus, start from unqualified type if
	     an earlier qualifier is missing in sub_quals, but some later
	     one is present there.  */
	  for (i = 0; i < dwarf_qual_info_size; i++)
	    if (dwarf_qual_info[i].q & cv_quals & ~sub_quals)
	      needed = true;
	    else if (needed && (dwarf_qual_info[i].q & cv_quals))
	      {
		sub_quals = 0;
		break;
	      }
	}
      mod_type_die = modified_type_die (type, sub_quals, reverse, context_die);
      if (mod_scope && mod_type_die && mod_type_die->die_parent == mod_scope)
	{
	  /* As not all intermediate qualified DIEs have corresponding
	     tree types, ensure that qualified DIEs in the same scope
	     as their DW_AT_type are emitted after their DW_AT_type,
	     only with other qualified DIEs for the same type possibly
	     in between them.  Determine the range of such qualified
	     DIEs now (first being the base type, last being corresponding
	     last qualified DIE for it).  */
	  unsigned int count = 0;
	  first = qualified_die_p (mod_type_die, &first_quals,
				   dwarf_qual_info_size);
	  if (first == NULL)
	    first = mod_type_die;
	  gcc_assert ((first_quals & ~sub_quals) == 0);
	  for (count = 0, last = first;
	       count < (1U << dwarf_qual_info_size);
	       count++, last = last->die_sib)
	    {
	      int quals = 0;
	      if (last == mod_scope->die_child)
		break;
	      if (qualified_die_p (last->die_sib, &quals, dwarf_qual_info_size)
		  != first)
		break;
	    }
	}

      for (i = 0; i < dwarf_qual_info_size; i++)
	if (dwarf_qual_info[i].q & cv_quals & ~sub_quals)
	  {
	    dw_die_ref d;
	    if (first && first != last)
	      {
		for (d = first->die_sib; ; d = d->die_sib)
		  {
		    int quals = 0;
		    qualified_die_p (d, &quals, dwarf_qual_info_size);
		    if (quals == (first_quals | dwarf_qual_info[i].q))
		      break;
		    if (d == last)
		      {
			d = NULL;
			break;
		      }
		  }
		if (d)
		  {
		    mod_type_die = d;
		    continue;
		  }
	      }
	    if (first)
	      {
		d = new_die_raw (dwarf_qual_info[i].t);
		add_child_die_after (mod_scope, d, last);
		last = d;
	      }
	    else
	      d = new_die (dwarf_qual_info[i].t, mod_scope, type);
	    if (mod_type_die)
	      add_AT_die_ref (d, DW_AT_type, mod_type_die);
	    mod_type_die = d;
	    first_quals |= dwarf_qual_info[i].q;
	  }
    }
  else if (code == POINTER_TYPE || code == REFERENCE_TYPE)
    {
      dwarf_tag tag = DW_TAG_pointer_type;
      if (code == REFERENCE_TYPE)
	{
	  if (TYPE_REF_IS_RVALUE (type) && dwarf_version >= 4)
	    tag = DW_TAG_rvalue_reference_type;
	  else
	    tag = DW_TAG_reference_type;
	}
      mod_type_die = new_die (tag, mod_scope, type);

      add_AT_unsigned (mod_type_die, DW_AT_byte_size,
		       simple_type_size_in_bits (type) / BITS_PER_UNIT);
      add_alignment_attribute (mod_type_die, type);
      item_type = TREE_TYPE (type);

      addr_space_t as = TYPE_ADDR_SPACE (item_type);
      if (!ADDR_SPACE_GENERIC_P (as))
	{
	  int action = targetm.addr_space.debug (as);
	  if (action >= 0)
	    {
	      /* Positive values indicate an address_class.  */
	      add_AT_unsigned (mod_type_die, DW_AT_address_class, action);
	    }
	  else
	    {
	      /* Negative values indicate an (inverted) segment base reg.  */
	      dw_loc_descr_ref d
		= one_reg_loc_descriptor (~action, VAR_INIT_STATUS_INITIALIZED);
	      add_AT_loc (mod_type_die, DW_AT_segment, d);
	    }
	}
    }
  else if (code == ARRAY_TYPE
	   || (lang_hooks.types.get_array_descr_info
	       && lang_hooks.types.get_array_descr_info (type, &info)))
    {
      gen_type_die (type, context_die);
      return lookup_type_die (type);
    }
  else if (code == INTEGER_TYPE
	   && TREE_TYPE (type) != NULL_TREE
	   && subrange_type_for_debug_p (type, &low, &high))
    {
      tree bias = NULL_TREE;
      if (lang_hooks.types.get_type_bias)
	bias = lang_hooks.types.get_type_bias (type);
      mod_type_die = subrange_type_die (type, low, high, bias, context_die);
      item_type = TREE_TYPE (type);
    }
  else if (is_base_type (type))
    {
      mod_type_die = base_type_die (type, reverse);

      /* The DIE with DW_AT_endianity is placed right after the naked DIE.  */
      if (reverse_base_type)
	{
	  dw_die_ref after_die
	    = modified_type_die (type, cv_quals, false, context_die);
	  add_child_die_after (comp_unit_die (), mod_type_die, after_die);
	}
      else
	add_child_die (comp_unit_die (), mod_type_die);

      add_pubtype (type, mod_type_die);
    }
  else
    {
      gen_type_die (type, context_die);

      /* We have to get the type_main_variant here (and pass that to the
	 `lookup_type_die' routine) because the ..._TYPE node we have
	 might simply be a *copy* of some original type node (where the
	 copy was created to help us keep track of typedef names) and
	 that copy might have a different TYPE_UID from the original
	 ..._TYPE node.  */
      if (code == FUNCTION_TYPE || code == METHOD_TYPE)
	{
	  /* For function/method types, can't just use type_main_variant here,
	     because that can have different ref-qualifiers for C++,
	     but try to canonicalize.  */
	  tree main = TYPE_MAIN_VARIANT (type);
	  for (tree t = main; t; t = TYPE_NEXT_VARIANT (t))
	    if (TYPE_QUALS_NO_ADDR_SPACE (t) == 0
		&& check_base_type (t, main)
		&& check_lang_type (t, type))
	      return lookup_type_die (t);
	  return lookup_type_die (type);
	}
      /* Vectors have the debugging information in the type,
	 not the main variant.  */
      else if (code == VECTOR_TYPE)
	return lookup_type_die (type);
      else
	return lookup_type_die (type_main_variant (type));
    }

  /* Builtin types don't have a DECL_ORIGINAL_TYPE.  For those,
     don't output a DW_TAG_typedef, since there isn't one in the
     user's program; just attach a DW_AT_name to the type.
     Don't attach a DW_AT_name to DW_TAG_const_type or DW_TAG_volatile_type
     if the base type already has the same name.  */
  if (name
      && ((TREE_CODE (name) != TYPE_DECL
	   && (qualified_type == TYPE_MAIN_VARIANT (type)
	       || (cv_quals == TYPE_UNQUALIFIED)))
	  || (TREE_CODE (name) == TYPE_DECL
	      && TREE_TYPE (name) == qualified_type
	      && DECL_NAME (name))))
    {
      if (TREE_CODE (name) == TYPE_DECL)
	/* Could just call add_name_and_src_coords_attributes here,
	   but since this is a builtin type it doesn't have any
	   useful source coordinates anyway.  */
	name = DECL_NAME (name);
      add_name_attribute (mod_type_die, IDENTIFIER_POINTER (name));
    }
  /* This probably indicates a bug.  */
  else if (mod_type_die && mod_type_die->die_tag == DW_TAG_base_type)
    {
      name = TYPE_IDENTIFIER (type);
      add_name_attribute (mod_type_die,
			  name ? IDENTIFIER_POINTER (name) : "__unknown__");
    }

  if (qualified_type && !reverse_base_type)
    equate_type_number_to_die (qualified_type, mod_type_die);

  if (item_type)
    /* We must do this after the equate_type_number_to_die call, in case
       this is a recursive type.  This ensures that the modified_type_die
       recursion will terminate even if the type is recursive.  Recursive
       types are possible in Ada.  */
    sub_die = modified_type_die (item_type,
				 TYPE_QUALS_NO_ADDR_SPACE (item_type),
				 reverse,
				 context_die);

  if (sub_die != NULL)
    add_AT_die_ref (mod_type_die, DW_AT_type, sub_die);

  add_gnat_descriptive_type_attribute (mod_type_die, type, context_die);
  if (TYPE_ARTIFICIAL (type))
    add_AT_flag (mod_type_die, DW_AT_artificial, 1);

  return mod_type_die;
}

/* Generate DIEs for the generic parameters of T.
   T must be either a generic type or a generic function.
   See http://gcc.gnu.org/wiki/TemplateParmsDwarf for more.  */

static void
gen_generic_params_dies (tree t)
{
  tree parms, args;
  int parms_num, i;
  dw_die_ref die = NULL;
  int non_default;

  if (!t || (TYPE_P (t) && !COMPLETE_TYPE_P (t)))
    return;

  if (TYPE_P (t))
    die = lookup_type_die (t);
  else if (DECL_P (t))
    die = lookup_decl_die (t);

  gcc_assert (die);

  parms = lang_hooks.get_innermost_generic_parms (t);
  if (!parms)
    /* T has no generic parameter. It means T is neither a generic type
       or function. End of story.  */
    return;

  parms_num = TREE_VEC_LENGTH (parms);
  args = lang_hooks.get_innermost_generic_args (t);
  if (TREE_CHAIN (args) && TREE_CODE (TREE_CHAIN (args)) == INTEGER_CST)
    non_default = int_cst_value (TREE_CHAIN (args));
  else
    non_default = TREE_VEC_LENGTH (args);
  for (i = 0; i < parms_num; i++)
    {
      tree parm, arg, arg_pack_elems;
      dw_die_ref parm_die;

      parm = TREE_VEC_ELT (parms, i);
      arg = TREE_VEC_ELT (args, i);
      arg_pack_elems = lang_hooks.types.get_argument_pack_elems (arg);
      gcc_assert (parm && TREE_VALUE (parm) && arg);

      if (parm && TREE_VALUE (parm) && arg)
	{
	  /* If PARM represents a template parameter pack,
	     emit a DW_TAG_GNU_template_parameter_pack DIE, followed
	     by DW_TAG_template_*_parameter DIEs for the argument
	     pack elements of ARG. Note that ARG would then be
	     an argument pack.  */
	  if (arg_pack_elems)
	    parm_die = template_parameter_pack_die (TREE_VALUE (parm),
						    arg_pack_elems,
						    die);
	  else
	    parm_die = generic_parameter_die (TREE_VALUE (parm), arg,
					      true /* emit name */, die);
	  if (i >= non_default)
	    add_AT_flag (parm_die, DW_AT_default_value, 1);
	}
    }
}

/* Create and return a DIE for PARM which should be
   the representation of a generic type parameter.
   For instance, in the C++ front end, PARM would be a template parameter.
   ARG is the argument to PARM.
   EMIT_NAME_P if tree, the DIE will have DW_AT_name attribute set to the
   name of the PARM.
   PARENT_DIE is the parent DIE which the new created DIE should be added to,
   as a child node.  */

static dw_die_ref
generic_parameter_die (tree parm, tree arg,
		       bool emit_name_p,
		       dw_die_ref parent_die)
{
  dw_die_ref tmpl_die = NULL;
  const char *name = NULL;

  /* C++20 accepts class literals as template parameters, and var
     decls with initializers represent them.  The VAR_DECLs would be
     rejected, but we can take the DECL_INITIAL constructor and
     attempt to expand it.  */
  if (arg && VAR_P (arg))
    arg = DECL_INITIAL (arg);

  if (!parm || !DECL_NAME (parm) || !arg)
    return NULL;

  /* We support non-type generic parameters and arguments,
     type generic parameters and arguments, as well as
     generic generic parameters (a.k.a. template template parameters in C++)
     and arguments.  */
  if (TREE_CODE (parm) == PARM_DECL)
    /* PARM is a nontype generic parameter  */
    tmpl_die = new_die (DW_TAG_template_value_param, parent_die, parm);
  else if (TREE_CODE (parm) == TYPE_DECL)
    /* PARM is a type generic parameter.  */
    tmpl_die = new_die (DW_TAG_template_type_param, parent_die, parm);
  else if (lang_hooks.decls.generic_generic_parameter_decl_p (parm))
    /* PARM is a generic generic parameter.
       Its DIE is a GNU extension. It shall have a
       DW_AT_name attribute to represent the name of the template template
       parameter, and a DW_AT_GNU_template_name attribute to represent the
       name of the template template argument.  */
    tmpl_die = new_die (DW_TAG_GNU_template_template_param,
			parent_die, parm);
  else
    gcc_unreachable ();

  if (tmpl_die)
    {
      tree tmpl_type;

      /* If PARM is a generic parameter pack, it means we are
         emitting debug info for a template argument pack element.
	 In other terms, ARG is a template argument pack element.
	 In that case, we don't emit any DW_AT_name attribute for
	 the die.  */
      if (emit_name_p)
	{
	  name = IDENTIFIER_POINTER (DECL_NAME (parm));
	  gcc_assert (name);
	  add_AT_string (tmpl_die, DW_AT_name, name);
	}

      if (!lang_hooks.decls.generic_generic_parameter_decl_p (parm))
	{
	  /* DWARF3, 5.6.8 says if PARM is a non-type generic parameter
	     TMPL_DIE should have a child DW_AT_type attribute that is set
	     to the type of the argument to PARM, which is ARG.
	     If PARM is a type generic parameter, TMPL_DIE should have a
	     child DW_AT_type that is set to ARG.  */
	  tmpl_type = TYPE_P (arg) ? arg : TREE_TYPE (arg);
	  add_type_attribute (tmpl_die, tmpl_type,
			      (TREE_THIS_VOLATILE (tmpl_type)
			       ? TYPE_QUAL_VOLATILE : TYPE_UNQUALIFIED),
			      false, parent_die);
	}
      else
	{
	  /* So TMPL_DIE is a DIE representing a
	     a generic generic template parameter, a.k.a template template
	     parameter in C++ and arg is a template.  */

	  /* The DW_AT_GNU_template_name attribute of the DIE must be set
	     to the name of the argument.  */
	  name = dwarf2_name (TYPE_P (arg) ? TYPE_NAME (arg) : arg, 1);
	  if (name)
	    add_AT_string (tmpl_die, DW_AT_GNU_template_name, name);
	}

      if (TREE_CODE (parm) == PARM_DECL)
	/* So PARM is a non-type generic parameter.
	   DWARF3 5.6.8 says we must set a DW_AT_const_value child
	   attribute of TMPL_DIE which value represents the value
	   of ARG.
	   We must be careful here:
	   The value of ARG might reference some function decls.
	   We might currently be emitting debug info for a generic
	   type and types are emitted before function decls, we don't
	   know if the function decls referenced by ARG will actually be
	   emitted after cgraph computations.
	   So must defer the generation of the DW_AT_const_value to
	   after cgraph is ready.  */
	append_entry_to_tmpl_value_parm_die_table (tmpl_die, arg);
    }

  return tmpl_die;
}

/* Generate and return a  DW_TAG_GNU_template_parameter_pack DIE representing.
   PARM_PACK must be a template parameter pack. The returned DIE
   will be child DIE of PARENT_DIE.  */

static dw_die_ref
template_parameter_pack_die (tree parm_pack,
			     tree parm_pack_args,
			     dw_die_ref parent_die)
{
  dw_die_ref die;
  int j;

  gcc_assert (parent_die && parm_pack);

  die = new_die (DW_TAG_GNU_template_parameter_pack, parent_die, parm_pack);
  add_name_and_src_coords_attributes (die, parm_pack);
  for (j = 0; j < TREE_VEC_LENGTH (parm_pack_args); j++)
    generic_parameter_die (parm_pack,
			   TREE_VEC_ELT (parm_pack_args, j),
			   false /* Don't emit DW_AT_name */,
			   die);
  return die;
}

/* Return the DBX register number described by a given RTL node.  */

static unsigned int
dbx_reg_number (const_rtx rtl)
{
  unsigned regno = REGNO (rtl);

  gcc_assert (regno < FIRST_PSEUDO_REGISTER);

#ifdef LEAF_REG_REMAP
  if (crtl->uses_only_leaf_regs)
    {
      int leaf_reg = LEAF_REG_REMAP (regno);
      if (leaf_reg != -1)
	regno = (unsigned) leaf_reg;
    }
#endif

  regno = DBX_REGISTER_NUMBER (regno);
  gcc_assert (regno != INVALID_REGNUM);
  return regno;
}

/* Optionally add a DW_OP_piece term to a location description expression.
   DW_OP_piece is only added if the location description expression already
   doesn't end with DW_OP_piece.  */

static void
add_loc_descr_op_piece (dw_loc_descr_ref *list_head, int size)
{
  dw_loc_descr_ref loc;

  if (*list_head != NULL)
    {
      /* Find the end of the chain.  */
      for (loc = *list_head; loc->dw_loc_next != NULL; loc = loc->dw_loc_next)
	;

      if (loc->dw_loc_opc != DW_OP_piece)
	loc->dw_loc_next = new_loc_descr (DW_OP_piece, size, 0);
    }
}

/* Return a location descriptor that designates a machine register or
   zero if there is none.  */

static dw_loc_descr_ref
reg_loc_descriptor (rtx rtl, enum var_init_status initialized)
{
  rtx regs;

  if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
    return 0;

  /* We only use "frame base" when we're sure we're talking about the
     post-prologue local stack frame.  We do this by *not* running
     register elimination until this point, and recognizing the special
     argument pointer and soft frame pointer rtx's.
     Use DW_OP_fbreg offset DW_OP_stack_value in this case.  */
  if ((rtl == arg_pointer_rtx || rtl == frame_pointer_rtx)
      && eliminate_regs (rtl, VOIDmode, NULL_RTX) != rtl)
    {
      dw_loc_descr_ref result = NULL;

      if (dwarf_version >= 4 || !dwarf_strict)
	{
	  result = mem_loc_descriptor (rtl, GET_MODE (rtl), VOIDmode,
				       initialized);
	  if (result)
	    add_loc_descr (&result,
			   new_loc_descr (DW_OP_stack_value, 0, 0));
	}
      return result;
    }

  regs = targetm.dwarf_register_span (rtl);

  if (REG_NREGS (rtl) > 1 || regs)
    return multiple_reg_loc_descriptor (rtl, regs, initialized);
  else
    {
      unsigned int dbx_regnum = dbx_reg_number (rtl);
      if (dbx_regnum == IGNORED_DWARF_REGNUM)
	return 0;
      return one_reg_loc_descriptor (dbx_regnum, initialized);
    }
}

/* Return a location descriptor that designates a machine register for
   a given hard register number.  */

static dw_loc_descr_ref
one_reg_loc_descriptor (unsigned int regno, enum var_init_status initialized)
{
  dw_loc_descr_ref reg_loc_descr;

  if (regno <= 31)
    reg_loc_descr
      = new_loc_descr ((enum dwarf_location_atom) (DW_OP_reg0 + regno), 0, 0);
  else
    reg_loc_descr = new_loc_descr (DW_OP_regx, regno, 0);

  if (initialized == VAR_INIT_STATUS_UNINITIALIZED)
    add_loc_descr (&reg_loc_descr, new_loc_descr (DW_OP_GNU_uninit, 0, 0));

  return reg_loc_descr;
}

/* Given an RTL of a register, return a location descriptor that
   designates a value that spans more than one register.  */

static dw_loc_descr_ref
multiple_reg_loc_descriptor (rtx rtl, rtx regs,
			     enum var_init_status initialized)
{
  int size, i;
  dw_loc_descr_ref loc_result = NULL;

  /* Simple, contiguous registers.  */
  if (regs == NULL_RTX)
    {
      unsigned reg = REGNO (rtl);
      int nregs;

#ifdef LEAF_REG_REMAP
      if (crtl->uses_only_leaf_regs)
	{
	  int leaf_reg = LEAF_REG_REMAP (reg);
	  if (leaf_reg != -1)
	    reg = (unsigned) leaf_reg;
	}
#endif

      gcc_assert ((unsigned) DBX_REGISTER_NUMBER (reg) == dbx_reg_number (rtl));
      nregs = REG_NREGS (rtl);

      /* At present we only track constant-sized pieces.  */
      if (!GET_MODE_SIZE (GET_MODE (rtl)).is_constant (&size))
	return NULL;
      size /= nregs;

      loc_result = NULL;
      while (nregs--)
	{
	  dw_loc_descr_ref t;

	  t = one_reg_loc_descriptor (DBX_REGISTER_NUMBER (reg),
				      VAR_INIT_STATUS_INITIALIZED);
	  add_loc_descr (&loc_result, t);
	  add_loc_descr_op_piece (&loc_result, size);
	  ++reg;
	}
      return loc_result;
    }

  /* Now onto stupid register sets in non contiguous locations.  */

  gcc_assert (GET_CODE (regs) == PARALLEL);

  /* At present we only track constant-sized pieces.  */
  if (!GET_MODE_SIZE (GET_MODE (XVECEXP (regs, 0, 0))).is_constant (&size))
    return NULL;
  loc_result = NULL;

  for (i = 0; i < XVECLEN (regs, 0); ++i)
    {
      dw_loc_descr_ref t;

      t = one_reg_loc_descriptor (dbx_reg_number (XVECEXP (regs, 0, i)),
				  VAR_INIT_STATUS_INITIALIZED);
      add_loc_descr (&loc_result, t);
      add_loc_descr_op_piece (&loc_result, size);
    }

  if (loc_result && initialized == VAR_INIT_STATUS_UNINITIALIZED)
    add_loc_descr (&loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));
  return loc_result;
}

static unsigned long size_of_int_loc_descriptor (HOST_WIDE_INT);

/* Return a location descriptor that designates a constant i,
   as a compound operation from constant (i >> shift), constant shift
   and DW_OP_shl.  */

static dw_loc_descr_ref
int_shift_loc_descriptor (HOST_WIDE_INT i, int shift)
{
  dw_loc_descr_ref ret = int_loc_descriptor (i >> shift);
  add_loc_descr (&ret, int_loc_descriptor (shift));
  add_loc_descr (&ret, new_loc_descr (DW_OP_shl, 0, 0));
  return ret;
}

/* Return a location descriptor that designates constant POLY_I.  */

static dw_loc_descr_ref
int_loc_descriptor (poly_int64 poly_i)
{
  enum dwarf_location_atom op;

  HOST_WIDE_INT i;
  if (!poly_i.is_constant (&i))
    {
      /* Create location descriptions for the non-constant part and
	 add any constant offset at the end.  */
      dw_loc_descr_ref ret = NULL;
      HOST_WIDE_INT constant = poly_i.coeffs[0];
      for (unsigned int j = 1; j < NUM_POLY_INT_COEFFS; ++j)
	{
	  HOST_WIDE_INT coeff = poly_i.coeffs[j];
	  if (coeff != 0)
	    {
	      dw_loc_descr_ref start = ret;
	      unsigned int factor;
	      int bias;
	      unsigned int regno = targetm.dwarf_poly_indeterminate_value
		(j, &factor, &bias);

	      /* Add COEFF * ((REGNO / FACTOR) - BIAS) to the value:
		 add COEFF * (REGNO / FACTOR) now and subtract
		 COEFF * BIAS from the final constant part.  */
	      constant -= coeff * bias;
	      add_loc_descr (&ret, new_reg_loc_descr (regno, 0));
	      if (coeff % factor == 0)
		coeff /= factor;
	      else
		{
		  int amount = exact_log2 (factor);
		  gcc_assert (amount >= 0);
		  add_loc_descr (&ret, int_loc_descriptor (amount));
		  add_loc_descr (&ret, new_loc_descr (DW_OP_shr, 0, 0));
		}
	      if (coeff != 1)
		{
		  add_loc_descr (&ret, int_loc_descriptor (coeff));
		  add_loc_descr (&ret, new_loc_descr (DW_OP_mul, 0, 0));
		}
	      if (start)
		add_loc_descr (&ret, new_loc_descr (DW_OP_plus, 0, 0));
	    }
	}
      loc_descr_plus_const (&ret, constant);
      return ret;
    }

  /* Pick the smallest representation of a constant, rather than just
     defaulting to the LEB encoding.  */
  if (i >= 0)
    {
      int clz = clz_hwi (i);
      int ctz = ctz_hwi (i);
      if (i <= 31)
	op = (enum dwarf_location_atom) (DW_OP_lit0 + i);
      else if (i <= 0xff)
	op = DW_OP_const1u;
      else if (i <= 0xffff)
	op = DW_OP_const2u;
      else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 5
	       && clz + 5 + 255 >= HOST_BITS_PER_WIDE_INT)
	/* DW_OP_litX DW_OP_litY DW_OP_shl takes just 3 bytes and
	   DW_OP_litX DW_OP_const1u Y DW_OP_shl takes just 4 bytes,
	   while DW_OP_const4u is 5 bytes.  */
	return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 5);
      else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 8
	       && clz + 8 + 31 >= HOST_BITS_PER_WIDE_INT)
	/* DW_OP_const1u X DW_OP_litY DW_OP_shl takes just 4 bytes,
	   while DW_OP_const4u is 5 bytes.  */
	return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 8);

      else if (DWARF2_ADDR_SIZE == 4 && i > 0x7fffffff
	       && size_of_int_loc_descriptor ((HOST_WIDE_INT) (int32_t) i)
		  <= 4)
	{
	  /* As i >= 2**31, the double cast above will yield a negative number.
	     Since wrapping is defined in DWARF expressions we can output big
	     positive integers as small negative ones, regardless of the size
	     of host wide ints.

	     Here, since the evaluator will handle 32-bit values and since i >=
	     2**31, we know it's going to be interpreted as a negative literal:
	     store it this way if we can do better than 5 bytes this way.  */
	  return int_loc_descriptor ((HOST_WIDE_INT) (int32_t) i);
	}
      else if (HOST_BITS_PER_WIDE_INT == 32 || i <= 0xffffffff)
	op = DW_OP_const4u;

      /* Past this point, i >= 0x100000000 and thus DW_OP_constu will take at
	 least 6 bytes: see if we can do better before falling back to it.  */
      else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 8
	       && clz + 8 + 255 >= HOST_BITS_PER_WIDE_INT)
	/* DW_OP_const1u X DW_OP_const1u Y DW_OP_shl takes just 5 bytes.  */
	return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 8);
      else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 16
	       && clz + 16 + (size_of_uleb128 (i) > 5 ? 255 : 31)
		  >= HOST_BITS_PER_WIDE_INT)
	/* DW_OP_const2u X DW_OP_litY DW_OP_shl takes just 5 bytes,
	   DW_OP_const2u X DW_OP_const1u Y DW_OP_shl takes 6 bytes.  */
	return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 16);
      else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 32
	       && clz + 32 + 31 >= HOST_BITS_PER_WIDE_INT
	       && size_of_uleb128 (i) > 6)
	/* DW_OP_const4u X DW_OP_litY DW_OP_shl takes just 7 bytes.  */
	return int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT - clz - 32);
      else
	op = DW_OP_constu;
    }
  else
    {
      if (i >= -0x80)
	op = DW_OP_const1s;
      else if (i >= -0x8000)
	op = DW_OP_const2s;
      else if (HOST_BITS_PER_WIDE_INT == 32 || i >= -0x80000000)
	{
	  if (size_of_int_loc_descriptor (i) < 5)
	    {
	      dw_loc_descr_ref ret = int_loc_descriptor (-i);
	      add_loc_descr (&ret, new_loc_descr (DW_OP_neg, 0, 0));
	      return ret;
	    }
	  op = DW_OP_const4s;
	}
      else
	{
	  if (size_of_int_loc_descriptor (i)
	      < (unsigned long) 1 + size_of_sleb128 (i))
	    {
	      dw_loc_descr_ref ret = int_loc_descriptor (-i);
	      add_loc_descr (&ret, new_loc_descr (DW_OP_neg, 0, 0));
	      return ret;
	    }
	  op = DW_OP_consts;
	}
    }

  return new_loc_descr (op, i, 0);
}

/* Likewise, for unsigned constants.  */

static dw_loc_descr_ref
uint_loc_descriptor (unsigned HOST_WIDE_INT i)
{
  const unsigned HOST_WIDE_INT max_int = INTTYPE_MAXIMUM (HOST_WIDE_INT);
  const unsigned HOST_WIDE_INT max_uint
    = INTTYPE_MAXIMUM (unsigned HOST_WIDE_INT);

  /* If possible, use the clever signed constants handling.  */
  if (i <= max_int)
    return int_loc_descriptor ((HOST_WIDE_INT) i);

  /* Here, we are left with positive numbers that cannot be represented as
     HOST_WIDE_INT, i.e.:
         max (HOST_WIDE_INT) < i <= max (unsigned HOST_WIDE_INT)

     Using DW_OP_const4/8/./u operation to encode them consumes a lot of bytes
     whereas may be better to output a negative integer: thanks to integer
     wrapping, we know that:
         x = x - 2 ** DWARF2_ADDR_SIZE
	   = x - 2 * (max (HOST_WIDE_INT) + 1)
     So numbers close to max (unsigned HOST_WIDE_INT) could be represented as
     small negative integers.  Let's try that in cases it will clearly improve
     the encoding: there is no gain turning DW_OP_const4u into
     DW_OP_const4s.  */
  if (DWARF2_ADDR_SIZE * 8 == HOST_BITS_PER_WIDE_INT
      && ((DWARF2_ADDR_SIZE == 4 && i > max_uint - 0x8000)
	  || (DWARF2_ADDR_SIZE == 8 && i > max_uint - 0x80000000)))
    {
      const unsigned HOST_WIDE_INT first_shift = i - max_int - 1;

      /* Now, -1 <  first_shift <= max (HOST_WIDE_INT)
	 i.e.  0 <= first_shift <= max (HOST_WIDE_INT).  */
      const HOST_WIDE_INT second_shift
        = (HOST_WIDE_INT) first_shift - (HOST_WIDE_INT) max_int - 1;

      /* So we finally have:
	      -max (HOST_WIDE_INT) - 1 <= second_shift <= -1.
	 i.e.  min (HOST_WIDE_INT)     <= second_shift <  0.  */
      return int_loc_descriptor (second_shift);
    }

  /* Last chance: fallback to a simple constant operation.  */
  return new_loc_descr
     ((HOST_BITS_PER_WIDE_INT == 32 || i <= 0xffffffff)
      ? DW_OP_const4u
      : DW_OP_const8u,
      i, 0);
}

/* Generate and return a location description that computes the unsigned
   comparison of the two stack top entries (a OP b where b is the top-most
   entry and a is the second one).  The KIND of comparison can be LT_EXPR,
   LE_EXPR, GT_EXPR or GE_EXPR.  */

static dw_loc_descr_ref
uint_comparison_loc_list (enum tree_code kind)
{
  enum dwarf_location_atom op, flip_op;
  dw_loc_descr_ref ret, bra_node, jmp_node, tmp;

  switch (kind)
    {
    case LT_EXPR:
      op = DW_OP_lt;
      break;
    case LE_EXPR:
      op = DW_OP_le;
      break;
    case GT_EXPR:
      op = DW_OP_gt;
      break;
    case GE_EXPR:
      op = DW_OP_ge;
      break;
    default:
      gcc_unreachable ();
    }

  bra_node = new_loc_descr (DW_OP_bra, 0, 0);
  jmp_node = new_loc_descr (DW_OP_skip, 0, 0);

  /* Until DWARFv4, operations all work on signed integers.  It is nevertheless
     possible to perform unsigned comparisons: we just have to distinguish
     three cases:

       1. when a and b have the same sign (as signed integers); then we should
	  return: a OP(signed) b;

       2. when a is a negative signed integer while b is a positive one, then a
	  is a greater unsigned integer than b; likewise when a and b's roles
	  are flipped.

     So first, compare the sign of the two operands.  */
  ret = new_loc_descr (DW_OP_over, 0, 0);
  add_loc_descr (&ret, new_loc_descr (DW_OP_over, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_xor, 0, 0));
  /* If they have different signs (i.e. they have different sign bits), then
     the stack top value has now the sign bit set and thus it's smaller than
     zero.  */
  add_loc_descr (&ret, new_loc_descr (DW_OP_lit0, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_lt, 0, 0));
  add_loc_descr (&ret, bra_node);

  /* We are in case 1.  At this point, we know both operands have the same
     sign, to it's safe to use the built-in signed comparison.  */
  add_loc_descr (&ret, new_loc_descr (op, 0, 0));
  add_loc_descr (&ret, jmp_node);

  /* We are in case 2.  Here, we know both operands do not have the same sign,
     so we have to flip the signed comparison.  */
  flip_op = (kind == LT_EXPR || kind == LE_EXPR) ? DW_OP_gt : DW_OP_lt;
  tmp = new_loc_descr (flip_op, 0, 0);
  bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
  bra_node->dw_loc_oprnd1.v.val_loc = tmp;
  add_loc_descr (&ret, tmp);

  /* This dummy operation is necessary to make the two branches join.  */
  tmp = new_loc_descr (DW_OP_nop, 0, 0);
  jmp_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
  jmp_node->dw_loc_oprnd1.v.val_loc = tmp;
  add_loc_descr (&ret, tmp);

  return ret;
}

/* Likewise, but takes the location description lists (might be destructive on
   them).  Return NULL if either is NULL or if concatenation fails.  */

static dw_loc_list_ref
loc_list_from_uint_comparison (dw_loc_list_ref left, dw_loc_list_ref right,
			       enum tree_code kind)
{
  if (left == NULL || right == NULL)
    return NULL;

  add_loc_list (&left, right);
  if (left == NULL)
    return NULL;

  add_loc_descr_to_each (left, uint_comparison_loc_list (kind));
  return left;
}

/* Return size_of_locs (int_shift_loc_descriptor (i, shift))
   without actually allocating it.  */

static unsigned long
size_of_int_shift_loc_descriptor (HOST_WIDE_INT i, int shift)
{
  return size_of_int_loc_descriptor (i >> shift)
	 + size_of_int_loc_descriptor (shift)
	 + 1;
}

/* Return size_of_locs (int_loc_descriptor (i)) without
   actually allocating it.  */

static unsigned long
size_of_int_loc_descriptor (HOST_WIDE_INT i)
{
  unsigned long s;

  if (i >= 0)
    {
      int clz, ctz;
      if (i <= 31)
	return 1;
      else if (i <= 0xff)
	return 2;
      else if (i <= 0xffff)
	return 3;
      clz = clz_hwi (i);
      ctz = ctz_hwi (i);
      if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 5
	  && clz + 5 + 255 >= HOST_BITS_PER_WIDE_INT)
	return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
						    - clz - 5);
      else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 8
	       && clz + 8 + 31 >= HOST_BITS_PER_WIDE_INT)
	return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
						    - clz - 8);
      else if (DWARF2_ADDR_SIZE == 4 && i > 0x7fffffff
	       && size_of_int_loc_descriptor ((HOST_WIDE_INT) (int32_t) i)
		  <= 4)
	return size_of_int_loc_descriptor ((HOST_WIDE_INT) (int32_t) i);
      else if (HOST_BITS_PER_WIDE_INT == 32 || i <= 0xffffffff)
	return 5;
      s = size_of_uleb128 ((unsigned HOST_WIDE_INT) i);
      if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 8
	  && clz + 8 + 255 >= HOST_BITS_PER_WIDE_INT)
	return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
						    - clz - 8);
      else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 16
	       && clz + 16 + (s > 5 ? 255 : 31) >= HOST_BITS_PER_WIDE_INT)
	return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
						    - clz - 16);
      else if (clz + ctz >= HOST_BITS_PER_WIDE_INT - 32
	       && clz + 32 + 31 >= HOST_BITS_PER_WIDE_INT
	       && s > 6)
	return size_of_int_shift_loc_descriptor (i, HOST_BITS_PER_WIDE_INT
						    - clz - 32);
      else
	return 1 + s;
    }
  else
    {
      if (i >= -0x80)
	return 2;
      else if (i >= -0x8000)
	return 3;
      else if (HOST_BITS_PER_WIDE_INT == 32 || i >= -0x80000000)
	{
	  if (-(unsigned HOST_WIDE_INT) i != (unsigned HOST_WIDE_INT) i)
	    {
	      s = size_of_int_loc_descriptor (-i) + 1;
	      if (s < 5)
		return s;
	    }
	  return 5;
	}
      else
	{
	  unsigned long r = 1 + size_of_sleb128 (i);
	  if (-(unsigned HOST_WIDE_INT) i != (unsigned HOST_WIDE_INT) i)
	    {
	      s = size_of_int_loc_descriptor (-i) + 1;
	      if (s < r)
		return s;
	    }
	  return r;
	}
    }
}

/* Return loc description representing "address" of integer value.
   This can appear only as toplevel expression.  */

static dw_loc_descr_ref
address_of_int_loc_descriptor (int size, HOST_WIDE_INT i)
{
  int litsize;
  dw_loc_descr_ref loc_result = NULL;

  if (!(dwarf_version >= 4 || !dwarf_strict))
    return NULL;

  litsize = size_of_int_loc_descriptor (i);
  /* Determine if DW_OP_stack_value or DW_OP_implicit_value
     is more compact.  For DW_OP_stack_value we need:
     litsize + 1 (DW_OP_stack_value)
     and for DW_OP_implicit_value:
     1 (DW_OP_implicit_value) + 1 (length) + size.  */
  if ((int) DWARF2_ADDR_SIZE >= size && litsize + 1 <= 1 + 1 + size)
    {
      loc_result = int_loc_descriptor (i);
      add_loc_descr (&loc_result,
		     new_loc_descr (DW_OP_stack_value, 0, 0));
      return loc_result;
    }

  loc_result = new_loc_descr (DW_OP_implicit_value,
			      size, 0);
  loc_result->dw_loc_oprnd2.val_class = dw_val_class_const;
  loc_result->dw_loc_oprnd2.v.val_int = i;
  return loc_result;
}

/* Return a location descriptor that designates a base+offset location.  */

static dw_loc_descr_ref
based_loc_descr (rtx reg, poly_int64 offset,
		 enum var_init_status initialized)
{
  unsigned int regno;
  dw_loc_descr_ref result;
  dw_fde_ref fde = cfun->fde;

  /* We only use "frame base" when we're sure we're talking about the
     post-prologue local stack frame.  We do this by *not* running
     register elimination until this point, and recognizing the special
     argument pointer and soft frame pointer rtx's.  */
  if (reg == arg_pointer_rtx || reg == frame_pointer_rtx)
    {
      rtx elim = (ira_use_lra_p
		  ? lra_eliminate_regs (reg, VOIDmode, NULL_RTX)
		  : eliminate_regs (reg, VOIDmode, NULL_RTX));

      if (elim != reg)
	{
	  /* Allow hard frame pointer here even if frame pointer
	    isn't used since hard frame pointer is encoded with
	    DW_OP_fbreg which uses the DW_AT_frame_base attribute,
	    not hard frame pointer directly.  */
	  elim = strip_offset_and_add (elim, &offset);
	  gcc_assert (elim == hard_frame_pointer_rtx
		      || elim == stack_pointer_rtx);

	  /* If drap register is used to align stack, use frame
	     pointer + offset to access stack variables.  If stack
	     is aligned without drap, use stack pointer + offset to
	     access stack variables.  */
	  if (crtl->stack_realign_tried
	      && reg == frame_pointer_rtx)
	    {
	      int base_reg
		= DWARF_FRAME_REGNUM ((fde && fde->drap_reg != INVALID_REGNUM)
				      ? HARD_FRAME_POINTER_REGNUM
				      : REGNO (elim));
	      return new_reg_loc_descr (base_reg, offset);
	    }

	  gcc_assert (frame_pointer_fb_offset_valid);
	  offset += frame_pointer_fb_offset;
	  HOST_WIDE_INT const_offset;
	  if (offset.is_constant (&const_offset))
	    return new_loc_descr (DW_OP_fbreg, const_offset, 0);
	  else
	    {
	      dw_loc_descr_ref ret = new_loc_descr (DW_OP_fbreg, 0, 0);
	      loc_descr_plus_const (&ret, offset);
	      return ret;
	    }
	}
    }

  regno = REGNO (reg);
#ifdef LEAF_REG_REMAP
  if (crtl->uses_only_leaf_regs)
    {
      int leaf_reg = LEAF_REG_REMAP (regno);
      if (leaf_reg != -1)
	regno = (unsigned) leaf_reg;
    }
#endif
  regno = DWARF_FRAME_REGNUM (regno);

  HOST_WIDE_INT const_offset;
  if (!optimize && fde
      && (fde->drap_reg == regno || fde->vdrap_reg == regno)
      && offset.is_constant (&const_offset))
    {
      /* Use cfa+offset to represent the location of arguments passed
	 on the stack when drap is used to align stack.
	 Only do this when not optimizing, for optimized code var-tracking
	 is supposed to track where the arguments live and the register
	 used as vdrap or drap in some spot might be used for something
	 else in other part of the routine.  */
      return new_loc_descr (DW_OP_fbreg, const_offset, 0);
    }

  result = new_reg_loc_descr (regno, offset);

  if (initialized == VAR_INIT_STATUS_UNINITIALIZED)
    add_loc_descr (&result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));

  return result;
}

/* Return true if this RTL expression describes a base+offset calculation.  */

static inline int
is_based_loc (const_rtx rtl)
{
  return (GET_CODE (rtl) == PLUS
	  && ((REG_P (XEXP (rtl, 0))
	       && REGNO (XEXP (rtl, 0)) < FIRST_PSEUDO_REGISTER
	       && CONST_INT_P (XEXP (rtl, 1)))));
}

/* Try to handle TLS MEMs, for which mem_loc_descriptor on XEXP (mem, 0)
   failed.  */

static dw_loc_descr_ref
tls_mem_loc_descriptor (rtx mem)
{
  tree base;
  dw_loc_descr_ref loc_result;

  if (MEM_EXPR (mem) == NULL_TREE || !MEM_OFFSET_KNOWN_P (mem))
    return NULL;

  base = get_base_address (MEM_EXPR (mem));
  if (base == NULL
      || !VAR_P (base)
      || !DECL_THREAD_LOCAL_P (base))
    return NULL;

  loc_result = loc_descriptor_from_tree (MEM_EXPR (mem), 1, NULL);
  if (loc_result == NULL)
    return NULL;

  if (maybe_ne (MEM_OFFSET (mem), 0))
    loc_descr_plus_const (&loc_result, MEM_OFFSET (mem));

  return loc_result;
}

/* Output debug info about reason why we failed to expand expression as dwarf
   expression.  */

static void
expansion_failed (tree expr, rtx rtl, char const *reason)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "Failed to expand as dwarf: ");
      if (expr)
	print_generic_expr (dump_file, expr, dump_flags);
      if (rtl)
	{
	  fprintf (dump_file, "\n");
	  print_rtl (dump_file, rtl);
	}
      fprintf (dump_file, "\nReason: %s\n", reason);
    }
}

/* Helper function for const_ok_for_output.  */

static bool
const_ok_for_output_1 (rtx rtl)
{
  if (targetm.const_not_ok_for_debug_p (rtl))
    {
      if (GET_CODE (rtl) != UNSPEC)
	{
	  expansion_failed (NULL_TREE, rtl,
			    "Expression rejected for debug by the backend.\n");
	  return false;
	}

      /* If delegitimize_address couldn't do anything with the UNSPEC, and
	 the target hook doesn't explicitly allow it in debug info, assume
	 we can't express it in the debug info.  */
      /* Don't complain about TLS UNSPECs, those are just too hard to
	 delegitimize.  Note this could be a non-decl SYMBOL_REF such as
	 one in a constant pool entry, so testing SYMBOL_REF_TLS_MODEL
	 rather than DECL_THREAD_LOCAL_P is not just an optimization.  */
      if (flag_checking
	  && (XVECLEN (rtl, 0) == 0
	      || GET_CODE (XVECEXP (rtl, 0, 0)) != SYMBOL_REF
	      || SYMBOL_REF_TLS_MODEL (XVECEXP (rtl, 0, 0)) == TLS_MODEL_NONE))
	inform (current_function_decl
		? DECL_SOURCE_LOCATION (current_function_decl)
		: UNKNOWN_LOCATION,
#if NUM_UNSPEC_VALUES > 0
		"non-delegitimized UNSPEC %s (%d) found in variable location",
		((XINT (rtl, 1) >= 0 && XINT (rtl, 1) < NUM_UNSPEC_VALUES)
		 ? unspec_strings[XINT (rtl, 1)] : "unknown"),
#else
		"non-delegitimized UNSPEC %d found in variable location",
#endif
		XINT (rtl, 1));
      expansion_failed (NULL_TREE, rtl,
			"UNSPEC hasn't been delegitimized.\n");
      return false;
    }

  if (CONST_POLY_INT_P (rtl))
    return false;

  /* FIXME: Refer to PR60655. It is possible for simplification
     of rtl expressions in var tracking to produce such expressions.
     We should really identify / validate expressions
     enclosed in CONST that can be handled by assemblers on various
     targets and only handle legitimate cases here.  */
  switch (GET_CODE (rtl))
    {
    case SYMBOL_REF:
      break;
    case NOT:
    case NEG:
      return false;
    case PLUS:
      {
	/* Make sure SYMBOL_REFs/UNSPECs are at most in one of the
	   operands.  */
	subrtx_var_iterator::array_type array;
	bool first = false;
	FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 0), ALL)
	  if (SYMBOL_REF_P (*iter)
	      || LABEL_P (*iter)
	      || GET_CODE (*iter) == UNSPEC)
	    {
	      first = true;
	      break;
	    }
	if (!first)
	  return true;
	FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 1), ALL)
	  if (SYMBOL_REF_P (*iter)
	      || LABEL_P (*iter)
	      || GET_CODE (*iter) == UNSPEC)
	    return false;
	return true;
      }
    case MINUS:
      {
	/* Disallow negation of SYMBOL_REFs or UNSPECs when they
	   appear in the second operand of MINUS.  */
	subrtx_var_iterator::array_type array;
	FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 1), ALL)
	  if (SYMBOL_REF_P (*iter)
	      || LABEL_P (*iter)
	      || GET_CODE (*iter) == UNSPEC)
	    return false;
	return true;
      }
    default:
      return true;
    }

  if (CONSTANT_POOL_ADDRESS_P (rtl))
    {
      bool marked;
      get_pool_constant_mark (rtl, &marked);
      /* If all references to this pool constant were optimized away,
	 it was not output and thus we can't represent it.  */
      if (!marked)
	{
	  expansion_failed (NULL_TREE, rtl,
			    "Constant was removed from constant pool.\n");
	  return false;
	}
    }

  if (SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
    return false;

  /* Avoid references to external symbols in debug info, on several targets
     the linker might even refuse to link when linking a shared library,
     and in many other cases the relocations for .debug_info/.debug_loc are
     dropped, so the address becomes zero anyway.  Hidden symbols, guaranteed
     to be defined within the same shared library or executable are fine.  */
  if (SYMBOL_REF_EXTERNAL_P (rtl))
    {
      tree decl = SYMBOL_REF_DECL (rtl);

      if (decl == NULL || !targetm.binds_local_p (decl))
	{
	  expansion_failed (NULL_TREE, rtl,
			    "Symbol not defined in current TU.\n");
	  return false;
	}
    }

  return true;
}

/* Return true if constant RTL can be emitted in DW_OP_addr or
   DW_AT_const_value.  TLS SYMBOL_REFs, external SYMBOL_REFs or
   non-marked constant pool SYMBOL_REFs can't be referenced in it.  */

static bool
const_ok_for_output (rtx rtl)
{
  if (GET_CODE (rtl) == SYMBOL_REF)
    return const_ok_for_output_1 (rtl);

  if (GET_CODE (rtl) == CONST)
    {
      subrtx_var_iterator::array_type array;
      FOR_EACH_SUBRTX_VAR (iter, array, XEXP (rtl, 0), ALL)
	if (!const_ok_for_output_1 (*iter))
	  return false;
      return true;
    }

  return true;
}

/* Return a reference to DW_TAG_base_type corresponding to MODE and UNSIGNEDP
   if possible, NULL otherwise.  */

static dw_die_ref
base_type_for_mode (machine_mode mode, bool unsignedp)
{
  dw_die_ref type_die;
  tree type = lang_hooks.types.type_for_mode (mode, unsignedp);

  if (type == NULL)
    return NULL;
  switch (TREE_CODE (type))
    {
    case INTEGER_TYPE:
    case REAL_TYPE:
      break;
    default:
      return NULL;
    }
  type_die = lookup_type_die (type);
  if (!type_die)
    type_die = modified_type_die (type, TYPE_UNQUALIFIED, false,
				  comp_unit_die ());
  if (type_die == NULL || type_die->die_tag != DW_TAG_base_type)
    return NULL;
  return type_die;
}

/* For OP descriptor assumed to be in unsigned MODE, convert it to a unsigned
   type matching MODE, or, if MODE is narrower than or as wide as
   DWARF2_ADDR_SIZE, untyped.  Return NULL if the conversion is not
   possible.  */

static dw_loc_descr_ref
convert_descriptor_to_mode (scalar_int_mode mode, dw_loc_descr_ref op)
{
  machine_mode outer_mode = mode;
  dw_die_ref type_die;
  dw_loc_descr_ref cvt;

  if (GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE)
    {
      add_loc_descr (&op, new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0));
      return op;
    }
  type_die = base_type_for_mode (outer_mode, 1);
  if (type_die == NULL)
    return NULL;
  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
  add_loc_descr (&op, cvt);
  return op;
}

/* Return location descriptor for comparison OP with operands OP0 and OP1.  */

static dw_loc_descr_ref
compare_loc_descriptor (enum dwarf_location_atom op, dw_loc_descr_ref op0,
			dw_loc_descr_ref op1)
{
  dw_loc_descr_ref ret = op0;
  add_loc_descr (&ret, op1);
  add_loc_descr (&ret, new_loc_descr (op, 0, 0));
  if (STORE_FLAG_VALUE != 1)
    {
      add_loc_descr (&ret, int_loc_descriptor (STORE_FLAG_VALUE));
      add_loc_descr (&ret, new_loc_descr (DW_OP_mul, 0, 0));
    }
  return ret;
}

/* Subroutine of scompare_loc_descriptor for the case in which we're
   comparing two scalar integer operands OP0 and OP1 that have mode OP_MODE,
   and in which OP_MODE is bigger than DWARF2_ADDR_SIZE.  */

static dw_loc_descr_ref
scompare_loc_descriptor_wide (enum dwarf_location_atom op,
			      scalar_int_mode op_mode,
			      dw_loc_descr_ref op0, dw_loc_descr_ref op1)
{
  dw_die_ref type_die = base_type_for_mode (op_mode, 0);
  dw_loc_descr_ref cvt;

  if (type_die == NULL)
    return NULL;
  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
  add_loc_descr (&op0, cvt);
  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
  add_loc_descr (&op1, cvt);
  return compare_loc_descriptor (op, op0, op1);
}

/* Subroutine of scompare_loc_descriptor for the case in which we're
   comparing two scalar integer operands OP0 and OP1 that have mode OP_MODE,
   and in which OP_MODE is smaller than DWARF2_ADDR_SIZE.  */

static dw_loc_descr_ref
scompare_loc_descriptor_narrow (enum dwarf_location_atom op, rtx rtl,
				scalar_int_mode op_mode,
				dw_loc_descr_ref op0, dw_loc_descr_ref op1)
{
  int shift = (DWARF2_ADDR_SIZE - GET_MODE_SIZE (op_mode)) * BITS_PER_UNIT;
  /* For eq/ne, if the operands are known to be zero-extended,
     there is no need to do the fancy shifting up.  */
  if (op == DW_OP_eq || op == DW_OP_ne)
    {
      dw_loc_descr_ref last0, last1;
      for (last0 = op0; last0->dw_loc_next != NULL; last0 = last0->dw_loc_next)
	;
      for (last1 = op1; last1->dw_loc_next != NULL; last1 = last1->dw_loc_next)
	;
      /* deref_size zero extends, and for constants we can check
	 whether they are zero extended or not.  */
      if (((last0->dw_loc_opc == DW_OP_deref_size
	    && last0->dw_loc_oprnd1.v.val_int <= GET_MODE_SIZE (op_mode))
	   || (CONST_INT_P (XEXP (rtl, 0))
	       && (unsigned HOST_WIDE_INT) INTVAL (XEXP (rtl, 0))
		  == (INTVAL (XEXP (rtl, 0)) & GET_MODE_MASK (op_mode))))
	  && ((last1->dw_loc_opc == DW_OP_deref_size
	       && last1->dw_loc_oprnd1.v.val_int <= GET_MODE_SIZE (op_mode))
	      || (CONST_INT_P (XEXP (rtl, 1))
		  && (unsigned HOST_WIDE_INT) INTVAL (XEXP (rtl, 1))
		     == (INTVAL (XEXP (rtl, 1)) & GET_MODE_MASK (op_mode)))))
	return compare_loc_descriptor (op, op0, op1);

      /* EQ/NE comparison against constant in narrower type than
	 DWARF2_ADDR_SIZE can be performed either as
	 DW_OP_const1u <shift> DW_OP_shl DW_OP_const* <cst << shift>
	 DW_OP_{eq,ne}
	 or
	 DW_OP_const*u <mode_mask> DW_OP_and DW_OP_const* <cst & mode_mask>
	 DW_OP_{eq,ne}.  Pick whatever is shorter.  */
      if (CONST_INT_P (XEXP (rtl, 1))
	  && GET_MODE_BITSIZE (op_mode) < HOST_BITS_PER_WIDE_INT
	  && (size_of_int_loc_descriptor (shift) + 1
	      + size_of_int_loc_descriptor (UINTVAL (XEXP (rtl, 1)) << shift)
	      >= size_of_int_loc_descriptor (GET_MODE_MASK (op_mode)) + 1
		 + size_of_int_loc_descriptor (INTVAL (XEXP (rtl, 1))
					       & GET_MODE_MASK (op_mode))))
	{
	  add_loc_descr (&op0, int_loc_descriptor (GET_MODE_MASK (op_mode)));
	  add_loc_descr (&op0, new_loc_descr (DW_OP_and, 0, 0));
	  op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1))
				    & GET_MODE_MASK (op_mode));
	  return compare_loc_descriptor (op, op0, op1);
	}
    }
  add_loc_descr (&op0, int_loc_descriptor (shift));
  add_loc_descr (&op0, new_loc_descr (DW_OP_shl, 0, 0));
  if (CONST_INT_P (XEXP (rtl, 1)))
    op1 = int_loc_descriptor (UINTVAL (XEXP (rtl, 1)) << shift);
  else
    {
      add_loc_descr (&op1, int_loc_descriptor (shift));
      add_loc_descr (&op1, new_loc_descr (DW_OP_shl, 0, 0));
    }
  return compare_loc_descriptor (op, op0, op1);
}

/* Return location descriptor for signed comparison OP RTL.  */

static dw_loc_descr_ref
scompare_loc_descriptor (enum dwarf_location_atom op, rtx rtl,
			 machine_mode mem_mode)
{
  machine_mode op_mode = GET_MODE (XEXP (rtl, 0));
  dw_loc_descr_ref op0, op1;

  if (op_mode == VOIDmode)
    op_mode = GET_MODE (XEXP (rtl, 1));
  if (op_mode == VOIDmode)
    return NULL;

  scalar_int_mode int_op_mode;
  if (dwarf_strict
      && dwarf_version < 5
      && (!is_a <scalar_int_mode> (op_mode, &int_op_mode)
	  || GET_MODE_SIZE (int_op_mode) > DWARF2_ADDR_SIZE))
    return NULL;

  op0 = mem_loc_descriptor (XEXP (rtl, 0), op_mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  op1 = mem_loc_descriptor (XEXP (rtl, 1), op_mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);

  if (op0 == NULL || op1 == NULL)
    return NULL;

  if (is_a <scalar_int_mode> (op_mode, &int_op_mode))
    {
      if (GET_MODE_SIZE (int_op_mode) < DWARF2_ADDR_SIZE)
	return scompare_loc_descriptor_narrow (op, rtl, int_op_mode, op0, op1);

      if (GET_MODE_SIZE (int_op_mode) > DWARF2_ADDR_SIZE)
	return scompare_loc_descriptor_wide (op, int_op_mode, op0, op1);
    }
  return compare_loc_descriptor (op, op0, op1);
}

/* Return location descriptor for unsigned comparison OP RTL.  */

static dw_loc_descr_ref
ucompare_loc_descriptor (enum dwarf_location_atom op, rtx rtl,
			 machine_mode mem_mode)
{
  dw_loc_descr_ref op0, op1;

  machine_mode test_op_mode = GET_MODE (XEXP (rtl, 0));
  if (test_op_mode == VOIDmode)
    test_op_mode = GET_MODE (XEXP (rtl, 1));

  scalar_int_mode op_mode;
  if (!is_a <scalar_int_mode> (test_op_mode, &op_mode))
    return NULL;

  if (dwarf_strict
      && dwarf_version < 5
      && GET_MODE_SIZE (op_mode) > DWARF2_ADDR_SIZE)
    return NULL;

  op0 = mem_loc_descriptor (XEXP (rtl, 0), op_mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  op1 = mem_loc_descriptor (XEXP (rtl, 1), op_mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);

  if (op0 == NULL || op1 == NULL)
    return NULL;

  if (GET_MODE_SIZE (op_mode) < DWARF2_ADDR_SIZE)
    {
      HOST_WIDE_INT mask = GET_MODE_MASK (op_mode);
      dw_loc_descr_ref last0, last1;
      for (last0 = op0; last0->dw_loc_next != NULL; last0 = last0->dw_loc_next)
	;
      for (last1 = op1; last1->dw_loc_next != NULL; last1 = last1->dw_loc_next)
	;
      if (CONST_INT_P (XEXP (rtl, 0)))
	op0 = int_loc_descriptor (INTVAL (XEXP (rtl, 0)) & mask);
      /* deref_size zero extends, so no need to mask it again.  */
      else if (last0->dw_loc_opc != DW_OP_deref_size
	       || last0->dw_loc_oprnd1.v.val_int > GET_MODE_SIZE (op_mode))
	{
	  add_loc_descr (&op0, int_loc_descriptor (mask));
	  add_loc_descr (&op0, new_loc_descr (DW_OP_and, 0, 0));
	}
      if (CONST_INT_P (XEXP (rtl, 1)))
	op1 = int_loc_descriptor (INTVAL (XEXP (rtl, 1)) & mask);
      /* deref_size zero extends, so no need to mask it again.  */
      else if (last1->dw_loc_opc != DW_OP_deref_size
	       || last1->dw_loc_oprnd1.v.val_int > GET_MODE_SIZE (op_mode))
	{
	  add_loc_descr (&op1, int_loc_descriptor (mask));
	  add_loc_descr (&op1, new_loc_descr (DW_OP_and, 0, 0));
	}
    }
  else if (GET_MODE_SIZE (op_mode) == DWARF2_ADDR_SIZE)
    {
      HOST_WIDE_INT bias = 1;
      bias <<= (DWARF2_ADDR_SIZE * BITS_PER_UNIT - 1);
      add_loc_descr (&op0, new_loc_descr (DW_OP_plus_uconst, bias, 0));
      if (CONST_INT_P (XEXP (rtl, 1)))
	op1 = int_loc_descriptor ((unsigned HOST_WIDE_INT) bias
				  + INTVAL (XEXP (rtl, 1)));
      else
	add_loc_descr (&op1, new_loc_descr (DW_OP_plus_uconst,
					    bias, 0));
    }
  return compare_loc_descriptor (op, op0, op1);
}

/* Return location descriptor for {U,S}{MIN,MAX}.  */

static dw_loc_descr_ref
minmax_loc_descriptor (rtx rtl, machine_mode mode,
		       machine_mode mem_mode)
{
  enum dwarf_location_atom op;
  dw_loc_descr_ref op0, op1, ret;
  dw_loc_descr_ref bra_node, drop_node;

  scalar_int_mode int_mode;
  if (dwarf_strict
      && dwarf_version < 5
      && (!is_a <scalar_int_mode> (mode, &int_mode)
	  || GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE))
    return NULL;

  op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);

  if (op0 == NULL || op1 == NULL)
    return NULL;

  add_loc_descr (&op0, new_loc_descr (DW_OP_dup, 0, 0));
  add_loc_descr (&op1, new_loc_descr (DW_OP_swap, 0, 0));
  add_loc_descr (&op1, new_loc_descr (DW_OP_over, 0, 0));
  if (GET_CODE (rtl) == UMIN || GET_CODE (rtl) == UMAX)
    {
      /* Checked by the caller.  */
      int_mode = as_a <scalar_int_mode> (mode);
      if (GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
	{
	  HOST_WIDE_INT mask = GET_MODE_MASK (int_mode);
	  add_loc_descr (&op0, int_loc_descriptor (mask));
	  add_loc_descr (&op0, new_loc_descr (DW_OP_and, 0, 0));
	  add_loc_descr (&op1, int_loc_descriptor (mask));
	  add_loc_descr (&op1, new_loc_descr (DW_OP_and, 0, 0));
	}
      else if (GET_MODE_SIZE (int_mode) == DWARF2_ADDR_SIZE)
	{
	  HOST_WIDE_INT bias = 1;
	  bias <<= (DWARF2_ADDR_SIZE * BITS_PER_UNIT - 1);
	  add_loc_descr (&op0, new_loc_descr (DW_OP_plus_uconst, bias, 0));
	  add_loc_descr (&op1, new_loc_descr (DW_OP_plus_uconst, bias, 0));
	}
    }
  else if (is_a <scalar_int_mode> (mode, &int_mode)
	   && GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
    {
      int shift = (DWARF2_ADDR_SIZE - GET_MODE_SIZE (int_mode)) * BITS_PER_UNIT;
      add_loc_descr (&op0, int_loc_descriptor (shift));
      add_loc_descr (&op0, new_loc_descr (DW_OP_shl, 0, 0));
      add_loc_descr (&op1, int_loc_descriptor (shift));
      add_loc_descr (&op1, new_loc_descr (DW_OP_shl, 0, 0));
    }
  else if (is_a <scalar_int_mode> (mode, &int_mode)
	   && GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
    {
      dw_die_ref type_die = base_type_for_mode (int_mode, 0);
      dw_loc_descr_ref cvt;
      if (type_die == NULL)
	return NULL;
      cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
      add_loc_descr (&op0, cvt);
      cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
      add_loc_descr (&op1, cvt);
    }

  if (GET_CODE (rtl) == SMIN || GET_CODE (rtl) == UMIN)
    op = DW_OP_lt;
  else
    op = DW_OP_gt;
  ret = op0;
  add_loc_descr (&ret, op1);
  add_loc_descr (&ret, new_loc_descr (op, 0, 0));
  bra_node = new_loc_descr (DW_OP_bra, 0, 0);
  add_loc_descr (&ret, bra_node);
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  drop_node = new_loc_descr (DW_OP_drop, 0, 0);
  add_loc_descr (&ret, drop_node);
  bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
  bra_node->dw_loc_oprnd1.v.val_loc = drop_node;
  if ((GET_CODE (rtl) == SMIN || GET_CODE (rtl) == SMAX)
      && is_a <scalar_int_mode> (mode, &int_mode)
      && GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
    ret = convert_descriptor_to_mode (int_mode, ret);
  return ret;
}

/* Helper function for mem_loc_descriptor.  Perform OP binary op,
   but after converting arguments to type_die, afterwards
   convert back to unsigned.  */

static dw_loc_descr_ref
typed_binop (enum dwarf_location_atom op, rtx rtl, dw_die_ref type_die,
	     scalar_int_mode mode, machine_mode mem_mode)
{
  dw_loc_descr_ref cvt, op0, op1;

  if (type_die == NULL)
    return NULL;
  op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (op0 == NULL || op1 == NULL)
    return NULL;
  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
  add_loc_descr (&op0, cvt);
  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
  add_loc_descr (&op1, cvt);
  add_loc_descr (&op0, op1);
  add_loc_descr (&op0, new_loc_descr (op, 0, 0));
  return convert_descriptor_to_mode (mode, op0);
}

/* CLZ (where constV is CLZ_DEFINED_VALUE_AT_ZERO computed value,
   const0 is DW_OP_lit0 or corresponding typed constant,
   const1 is DW_OP_lit1 or corresponding typed constant
   and constMSB is constant with just the MSB bit set
   for the mode):
       DW_OP_dup DW_OP_bra <L1> DW_OP_drop constV DW_OP_skip <L4>
   L1: const0 DW_OP_swap
   L2: DW_OP_dup constMSB DW_OP_and DW_OP_bra <L3> const1 DW_OP_shl
       DW_OP_swap DW_OP_plus_uconst <1> DW_OP_swap DW_OP_skip <L2>
   L3: DW_OP_drop
   L4: DW_OP_nop

   CTZ is similar:
       DW_OP_dup DW_OP_bra <L1> DW_OP_drop constV DW_OP_skip <L4>
   L1: const0 DW_OP_swap
   L2: DW_OP_dup const1 DW_OP_and DW_OP_bra <L3> const1 DW_OP_shr
       DW_OP_swap DW_OP_plus_uconst <1> DW_OP_swap DW_OP_skip <L2>
   L3: DW_OP_drop
   L4: DW_OP_nop

   FFS is similar:
       DW_OP_dup DW_OP_bra <L1> DW_OP_drop const0 DW_OP_skip <L4>
   L1: const1 DW_OP_swap
   L2: DW_OP_dup const1 DW_OP_and DW_OP_bra <L3> const1 DW_OP_shr
       DW_OP_swap DW_OP_plus_uconst <1> DW_OP_swap DW_OP_skip <L2>
   L3: DW_OP_drop
   L4: DW_OP_nop  */

static dw_loc_descr_ref
clz_loc_descriptor (rtx rtl, scalar_int_mode mode,
		    machine_mode mem_mode)
{
  dw_loc_descr_ref op0, ret, tmp;
  HOST_WIDE_INT valv;
  dw_loc_descr_ref l1jump, l1label;
  dw_loc_descr_ref l2jump, l2label;
  dw_loc_descr_ref l3jump, l3label;
  dw_loc_descr_ref l4jump, l4label;
  rtx msb;

  if (GET_MODE (XEXP (rtl, 0)) != mode)
    return NULL;

  op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (op0 == NULL)
    return NULL;
  ret = op0;
  if (GET_CODE (rtl) == CLZ)
    {
      if (!CLZ_DEFINED_VALUE_AT_ZERO (mode, valv))
	valv = GET_MODE_BITSIZE (mode);
    }
  else if (GET_CODE (rtl) == FFS)
    valv = 0;
  else if (!CTZ_DEFINED_VALUE_AT_ZERO (mode, valv))
    valv = GET_MODE_BITSIZE (mode);
  add_loc_descr (&ret, new_loc_descr (DW_OP_dup, 0, 0));
  l1jump = new_loc_descr (DW_OP_bra, 0, 0);
  add_loc_descr (&ret, l1jump);
  add_loc_descr (&ret, new_loc_descr (DW_OP_drop, 0, 0));
  tmp = mem_loc_descriptor (GEN_INT (valv), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (tmp == NULL)
    return NULL;
  add_loc_descr (&ret, tmp);
  l4jump = new_loc_descr (DW_OP_skip, 0, 0);
  add_loc_descr (&ret, l4jump);
  l1label = mem_loc_descriptor (GET_CODE (rtl) == FFS
				? const1_rtx : const0_rtx,
				mode, mem_mode,
				VAR_INIT_STATUS_INITIALIZED);
  if (l1label == NULL)
    return NULL;
  add_loc_descr (&ret, l1label);
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  l2label = new_loc_descr (DW_OP_dup, 0, 0);
  add_loc_descr (&ret, l2label);
  if (GET_CODE (rtl) != CLZ)
    msb = const1_rtx;
  else if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
    msb = GEN_INT (HOST_WIDE_INT_1U
		   << (GET_MODE_BITSIZE (mode) - 1));
  else
    msb = immed_wide_int_const
      (wi::set_bit_in_zero (GET_MODE_PRECISION (mode) - 1,
			    GET_MODE_PRECISION (mode)), mode);
  if (GET_CODE (msb) == CONST_INT && INTVAL (msb) < 0)
    tmp = new_loc_descr (HOST_BITS_PER_WIDE_INT == 32
			 ? DW_OP_const4u : HOST_BITS_PER_WIDE_INT == 64
			 ? DW_OP_const8u : DW_OP_constu, INTVAL (msb), 0);
  else
    tmp = mem_loc_descriptor (msb, mode, mem_mode,
			      VAR_INIT_STATUS_INITIALIZED);
  if (tmp == NULL)
    return NULL;
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (DW_OP_and, 0, 0));
  l3jump = new_loc_descr (DW_OP_bra, 0, 0);
  add_loc_descr (&ret, l3jump);
  tmp = mem_loc_descriptor (const1_rtx, mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (tmp == NULL)
    return NULL;
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (GET_CODE (rtl) == CLZ
				      ? DW_OP_shl : DW_OP_shr, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_plus_uconst, 1, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  l2jump = new_loc_descr (DW_OP_skip, 0, 0);
  add_loc_descr (&ret, l2jump);
  l3label = new_loc_descr (DW_OP_drop, 0, 0);
  add_loc_descr (&ret, l3label);
  l4label = new_loc_descr (DW_OP_nop, 0, 0);
  add_loc_descr (&ret, l4label);
  l1jump->dw_loc_oprnd1.val_class = dw_val_class_loc;
  l1jump->dw_loc_oprnd1.v.val_loc = l1label;
  l2jump->dw_loc_oprnd1.val_class = dw_val_class_loc;
  l2jump->dw_loc_oprnd1.v.val_loc = l2label;
  l3jump->dw_loc_oprnd1.val_class = dw_val_class_loc;
  l3jump->dw_loc_oprnd1.v.val_loc = l3label;
  l4jump->dw_loc_oprnd1.val_class = dw_val_class_loc;
  l4jump->dw_loc_oprnd1.v.val_loc = l4label;
  return ret;
}

/* POPCOUNT (const0 is DW_OP_lit0 or corresponding typed constant,
   const1 is DW_OP_lit1 or corresponding typed constant):
       const0 DW_OP_swap
   L1: DW_OP_dup DW_OP_bra <L2> DW_OP_dup DW_OP_rot const1 DW_OP_and
       DW_OP_plus DW_OP_swap const1 DW_OP_shr DW_OP_skip <L1>
   L2: DW_OP_drop

   PARITY is similar:
   L1: DW_OP_dup DW_OP_bra <L2> DW_OP_dup DW_OP_rot const1 DW_OP_and
       DW_OP_xor DW_OP_swap const1 DW_OP_shr DW_OP_skip <L1>
   L2: DW_OP_drop  */

static dw_loc_descr_ref
popcount_loc_descriptor (rtx rtl, scalar_int_mode mode,
			 machine_mode mem_mode)
{
  dw_loc_descr_ref op0, ret, tmp;
  dw_loc_descr_ref l1jump, l1label;
  dw_loc_descr_ref l2jump, l2label;

  if (GET_MODE (XEXP (rtl, 0)) != mode)
    return NULL;

  op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (op0 == NULL)
    return NULL;
  ret = op0;
  tmp = mem_loc_descriptor (const0_rtx, mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (tmp == NULL)
    return NULL;
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  l1label = new_loc_descr (DW_OP_dup, 0, 0);
  add_loc_descr (&ret, l1label);
  l2jump = new_loc_descr (DW_OP_bra, 0, 0);
  add_loc_descr (&ret, l2jump);
  add_loc_descr (&ret, new_loc_descr (DW_OP_dup, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_rot, 0, 0));
  tmp = mem_loc_descriptor (const1_rtx, mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (tmp == NULL)
    return NULL;
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (DW_OP_and, 0, 0));
  add_loc_descr (&ret, new_loc_descr (GET_CODE (rtl) == POPCOUNT
				      ? DW_OP_plus : DW_OP_xor, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  tmp = mem_loc_descriptor (const1_rtx, mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (DW_OP_shr, 0, 0));
  l1jump = new_loc_descr (DW_OP_skip, 0, 0);
  add_loc_descr (&ret, l1jump);
  l2label = new_loc_descr (DW_OP_drop, 0, 0);
  add_loc_descr (&ret, l2label);
  l1jump->dw_loc_oprnd1.val_class = dw_val_class_loc;
  l1jump->dw_loc_oprnd1.v.val_loc = l1label;
  l2jump->dw_loc_oprnd1.val_class = dw_val_class_loc;
  l2jump->dw_loc_oprnd1.v.val_loc = l2label;
  return ret;
}

/* BSWAP (constS is initial shift count, either 56 or 24):
       constS const0
   L1: DW_OP_pick <2> constS DW_OP_pick <3> DW_OP_minus DW_OP_shr
       const255 DW_OP_and DW_OP_pick <2> DW_OP_shl DW_OP_or
       DW_OP_swap DW_OP_dup const0 DW_OP_eq DW_OP_bra <L2> const8
       DW_OP_minus DW_OP_swap DW_OP_skip <L1>
   L2: DW_OP_drop DW_OP_swap DW_OP_drop  */

static dw_loc_descr_ref
bswap_loc_descriptor (rtx rtl, scalar_int_mode mode,
		      machine_mode mem_mode)
{
  dw_loc_descr_ref op0, ret, tmp;
  dw_loc_descr_ref l1jump, l1label;
  dw_loc_descr_ref l2jump, l2label;

  if (BITS_PER_UNIT != 8
      || (GET_MODE_BITSIZE (mode) != 32
	  && GET_MODE_BITSIZE (mode) != 64))
    return NULL;

  op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (op0 == NULL)
    return NULL;

  ret = op0;
  tmp = mem_loc_descriptor (GEN_INT (GET_MODE_BITSIZE (mode) - 8),
			    mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (tmp == NULL)
    return NULL;
  add_loc_descr (&ret, tmp);
  tmp = mem_loc_descriptor (const0_rtx, mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (tmp == NULL)
    return NULL;
  add_loc_descr (&ret, tmp);
  l1label = new_loc_descr (DW_OP_pick, 2, 0);
  add_loc_descr (&ret, l1label);
  tmp = mem_loc_descriptor (GEN_INT (GET_MODE_BITSIZE (mode) - 8),
			    mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (DW_OP_pick, 3, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_minus, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_shr, 0, 0));
  tmp = mem_loc_descriptor (GEN_INT (255), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (tmp == NULL)
    return NULL;
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (DW_OP_and, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_pick, 2, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_shl, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_or, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_dup, 0, 0));
  tmp = mem_loc_descriptor (const0_rtx, mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (DW_OP_eq, 0, 0));
  l2jump = new_loc_descr (DW_OP_bra, 0, 0);
  add_loc_descr (&ret, l2jump);
  tmp = mem_loc_descriptor (GEN_INT (8), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  add_loc_descr (&ret, tmp);
  add_loc_descr (&ret, new_loc_descr (DW_OP_minus, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  l1jump = new_loc_descr (DW_OP_skip, 0, 0);
  add_loc_descr (&ret, l1jump);
  l2label = new_loc_descr (DW_OP_drop, 0, 0);
  add_loc_descr (&ret, l2label);
  add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_drop, 0, 0));
  l1jump->dw_loc_oprnd1.val_class = dw_val_class_loc;
  l1jump->dw_loc_oprnd1.v.val_loc = l1label;
  l2jump->dw_loc_oprnd1.val_class = dw_val_class_loc;
  l2jump->dw_loc_oprnd1.v.val_loc = l2label;
  return ret;
}

/* ROTATE (constMASK is mode mask, BITSIZE is bitsize of mode):
   DW_OP_over DW_OP_over DW_OP_shl [ constMASK DW_OP_and ] DW_OP_rot
   [ DW_OP_swap constMASK DW_OP_and DW_OP_swap ] DW_OP_neg
   DW_OP_plus_uconst <BITSIZE> DW_OP_shr DW_OP_or

   ROTATERT is similar:
   DW_OP_over DW_OP_over DW_OP_neg DW_OP_plus_uconst <BITSIZE>
   DW_OP_shl [ constMASK DW_OP_and ] DW_OP_rot
   [ DW_OP_swap constMASK DW_OP_and DW_OP_swap ] DW_OP_shr DW_OP_or  */

static dw_loc_descr_ref
rotate_loc_descriptor (rtx rtl, scalar_int_mode mode,
		       machine_mode mem_mode)
{
  rtx rtlop1 = XEXP (rtl, 1);
  dw_loc_descr_ref op0, op1, ret, mask[2] = { NULL, NULL };
  int i;

  if (is_narrower_int_mode (GET_MODE (rtlop1), mode))
    rtlop1 = gen_rtx_ZERO_EXTEND (mode, rtlop1);
  op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  op1 = mem_loc_descriptor (rtlop1, mode, mem_mode,
			    VAR_INIT_STATUS_INITIALIZED);
  if (op0 == NULL || op1 == NULL)
    return NULL;
  if (GET_MODE_SIZE (mode) < DWARF2_ADDR_SIZE)
    for (i = 0; i < 2; i++)
      {
	if (GET_MODE_BITSIZE (mode) < HOST_BITS_PER_WIDE_INT)
	  mask[i] = mem_loc_descriptor (GEN_INT (GET_MODE_MASK (mode)),
					mode, mem_mode,
					VAR_INIT_STATUS_INITIALIZED);
	else if (GET_MODE_BITSIZE (mode) == HOST_BITS_PER_WIDE_INT)
	  mask[i] = new_loc_descr (HOST_BITS_PER_WIDE_INT == 32
				   ? DW_OP_const4u
				   : HOST_BITS_PER_WIDE_INT == 64
				   ? DW_OP_const8u : DW_OP_constu,
				   GET_MODE_MASK (mode), 0);
	else
	  mask[i] = NULL;
	if (mask[i] == NULL)
	  return NULL;
	add_loc_descr (&mask[i], new_loc_descr (DW_OP_and, 0, 0));
      }
  ret = op0;
  add_loc_descr (&ret, op1);
  add_loc_descr (&ret, new_loc_descr (DW_OP_over, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_over, 0, 0));
  if (GET_CODE (rtl) == ROTATERT)
    {
      add_loc_descr (&ret, new_loc_descr (DW_OP_neg, 0, 0));
      add_loc_descr (&ret, new_loc_descr (DW_OP_plus_uconst,
					  GET_MODE_BITSIZE (mode), 0));
    }
  add_loc_descr (&ret, new_loc_descr (DW_OP_shl, 0, 0));
  if (mask[0] != NULL)
    add_loc_descr (&ret, mask[0]);
  add_loc_descr (&ret, new_loc_descr (DW_OP_rot, 0, 0));
  if (mask[1] != NULL)
    {
      add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
      add_loc_descr (&ret, mask[1]);
      add_loc_descr (&ret, new_loc_descr (DW_OP_swap, 0, 0));
    }
  if (GET_CODE (rtl) == ROTATE)
    {
      add_loc_descr (&ret, new_loc_descr (DW_OP_neg, 0, 0));
      add_loc_descr (&ret, new_loc_descr (DW_OP_plus_uconst,
					  GET_MODE_BITSIZE (mode), 0));
    }
  add_loc_descr (&ret, new_loc_descr (DW_OP_shr, 0, 0));
  add_loc_descr (&ret, new_loc_descr (DW_OP_or, 0, 0));
  return ret;
}

/* Helper function for mem_loc_descriptor.  Return DW_OP_GNU_parameter_ref
   for DEBUG_PARAMETER_REF RTL.  */

static dw_loc_descr_ref
parameter_ref_descriptor (rtx rtl)
{
  dw_loc_descr_ref ret;
  dw_die_ref ref;

  if (dwarf_strict)
    return NULL;
  gcc_assert (TREE_CODE (DEBUG_PARAMETER_REF_DECL (rtl)) == PARM_DECL);
  /* With LTO during LTRANS we get the late DIE that refers to the early
     DIE, thus we add another indirection here.  This seems to confuse
     gdb enough to make gcc.dg/guality/pr68860-1.c FAIL with LTO.  */
  ref = lookup_decl_die (DEBUG_PARAMETER_REF_DECL (rtl));
  ret = new_loc_descr (DW_OP_GNU_parameter_ref, 0, 0);
  if (ref)
    {
      ret->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
      ret->dw_loc_oprnd1.v.val_die_ref.die = ref;
      ret->dw_loc_oprnd1.v.val_die_ref.external = 0;
    }
  else
    {
      ret->dw_loc_oprnd1.val_class = dw_val_class_decl_ref;
      ret->dw_loc_oprnd1.v.val_decl_ref = DEBUG_PARAMETER_REF_DECL (rtl);
    }
  return ret;
}

/* The following routine converts the RTL for a variable or parameter
   (resident in memory) into an equivalent Dwarf representation of a
   mechanism for getting the address of that same variable onto the top of a
   hypothetical "address evaluation" stack.

   When creating memory location descriptors, we are effectively transforming
   the RTL for a memory-resident object into its Dwarf postfix expression
   equivalent.  This routine recursively descends an RTL tree, turning
   it into Dwarf postfix code as it goes.

   MODE is the mode that should be assumed for the rtl if it is VOIDmode.

   MEM_MODE is the mode of the memory reference, needed to handle some
   autoincrement addressing modes.

   Return 0 if we can't represent the location.  */

dw_loc_descr_ref
mem_loc_descriptor (rtx rtl, machine_mode mode,
		    machine_mode mem_mode,
		    enum var_init_status initialized)
{
  dw_loc_descr_ref mem_loc_result = NULL;
  enum dwarf_location_atom op;
  dw_loc_descr_ref op0, op1;
  rtx inner = NULL_RTX;
  poly_int64 offset;

  if (mode == VOIDmode)
    mode = GET_MODE (rtl);

  /* Note that for a dynamically sized array, the location we will generate a
     description of here will be the lowest numbered location which is
     actually within the array.  That's *not* necessarily the same as the
     zeroth element of the array.  */

  rtl = targetm.delegitimize_address (rtl);

  if (mode != GET_MODE (rtl) && GET_MODE (rtl) != VOIDmode)
    return NULL;

  scalar_int_mode int_mode = BImode, inner_mode, op1_mode;
  switch (GET_CODE (rtl))
    {
    case POST_INC:
    case POST_DEC:
    case POST_MODIFY:
      return mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode, initialized);

    case SUBREG:
      /* The case of a subreg may arise when we have a local (register)
	 variable or a formal (register) parameter which doesn't quite fill
	 up an entire register.  For now, just assume that it is
	 legitimate to make the Dwarf info refer to the whole register which
	 contains the given subreg.  */
      if (!subreg_lowpart_p (rtl))
	break;
      inner = SUBREG_REG (rtl);
      /* FALLTHRU */
    case TRUNCATE:
      if (inner == NULL_RTX)
        inner = XEXP (rtl, 0);
      if (is_a <scalar_int_mode> (mode, &int_mode)
	  && is_a <scalar_int_mode> (GET_MODE (inner), &inner_mode)
	  && (GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE
#ifdef POINTERS_EXTEND_UNSIGNED
	      || (int_mode == Pmode && mem_mode != VOIDmode)
#endif
	     )
	  && GET_MODE_SIZE (inner_mode) <= DWARF2_ADDR_SIZE)
	{
	  mem_loc_result = mem_loc_descriptor (inner,
					       inner_mode,
					       mem_mode, initialized);
	  break;
	}
      if (dwarf_strict && dwarf_version < 5)
	break;
      if (is_a <scalar_int_mode> (mode, &int_mode)
	  && is_a <scalar_int_mode> (GET_MODE (inner), &inner_mode)
	  ? GET_MODE_SIZE (int_mode) <= GET_MODE_SIZE (inner_mode)
	  : known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (GET_MODE (inner))))
	{
	  dw_die_ref type_die;
	  dw_loc_descr_ref cvt;

	  mem_loc_result = mem_loc_descriptor (inner,
					       GET_MODE (inner),
					       mem_mode, initialized);
	  if (mem_loc_result == NULL)
	    break;
	  type_die = base_type_for_mode (mode, SCALAR_INT_MODE_P (mode));
	  if (type_die == NULL)
	    {
	      mem_loc_result = NULL;
	      break;
	    }
	  if (maybe_ne (GET_MODE_SIZE (mode), GET_MODE_SIZE (GET_MODE (inner))))
	    cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
	  else
	    cvt = new_loc_descr (dwarf_OP (DW_OP_reinterpret), 0, 0);
	  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  add_loc_descr (&mem_loc_result, cvt);
	  if (is_a <scalar_int_mode> (mode, &int_mode)
	      && GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE)
	    {
	      /* Convert it to untyped afterwards.  */
	      cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
	      add_loc_descr (&mem_loc_result, cvt);
	    }
	}
      break;

    case REG:
      if (!is_a <scalar_int_mode> (mode, &int_mode)
	  || (GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE
	      && rtl != arg_pointer_rtx
	      && rtl != frame_pointer_rtx
#ifdef POINTERS_EXTEND_UNSIGNED
	      && (int_mode != Pmode || mem_mode == VOIDmode)
#endif
	      ))
	{
	  dw_die_ref type_die;
	  unsigned int dbx_regnum;

	  if (dwarf_strict && dwarf_version < 5)
	    break;
	  if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
	    break;
	  type_die = base_type_for_mode (mode, SCALAR_INT_MODE_P (mode));
	  if (type_die == NULL)
	    break;

	  dbx_regnum = dbx_reg_number (rtl);
	  if (dbx_regnum == IGNORED_DWARF_REGNUM)
	    break;
	  mem_loc_result = new_loc_descr (dwarf_OP (DW_OP_regval_type),
					  dbx_regnum, 0);
	  mem_loc_result->dw_loc_oprnd2.val_class = dw_val_class_die_ref;
	  mem_loc_result->dw_loc_oprnd2.v.val_die_ref.die = type_die;
	  mem_loc_result->dw_loc_oprnd2.v.val_die_ref.external = 0;
	  break;
	}
      /* Whenever a register number forms a part of the description of the
	 method for calculating the (dynamic) address of a memory resident
	 object, DWARF rules require the register number be referred to as
	 a "base register".  This distinction is not based in any way upon
	 what category of register the hardware believes the given register
	 belongs to.  This is strictly DWARF terminology we're dealing with
	 here. Note that in cases where the location of a memory-resident
	 data object could be expressed as: OP_ADD (OP_BASEREG (basereg),
	 OP_CONST (0)) the actual DWARF location descriptor that we generate
	 may just be OP_BASEREG (basereg).  This may look deceptively like
	 the object in question was allocated to a register (rather than in
	 memory) so DWARF consumers need to be aware of the subtle
	 distinction between OP_REG and OP_BASEREG.  */
      if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
	mem_loc_result = based_loc_descr (rtl, 0, VAR_INIT_STATUS_INITIALIZED);
      else if (stack_realign_drap
	       && crtl->drap_reg
	       && crtl->args.internal_arg_pointer == rtl
	       && REGNO (crtl->drap_reg) < FIRST_PSEUDO_REGISTER)
	{
	  /* If RTL is internal_arg_pointer, which has been optimized
	     out, use DRAP instead.  */
	  mem_loc_result = based_loc_descr (crtl->drap_reg, 0,
					    VAR_INIT_STATUS_INITIALIZED);
	}
      break;

    case SIGN_EXTEND:
    case ZERO_EXTEND:
      if (!is_a <scalar_int_mode> (mode, &int_mode)
	  || !is_a <scalar_int_mode> (GET_MODE (XEXP (rtl, 0)), &inner_mode))
	break;
      op0 = mem_loc_descriptor (XEXP (rtl, 0), inner_mode,
				mem_mode, VAR_INIT_STATUS_INITIALIZED);
      if (op0 == 0)
	break;
      else if (GET_CODE (rtl) == ZERO_EXTEND
	       && GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE
	       && GET_MODE_BITSIZE (inner_mode) < HOST_BITS_PER_WIDE_INT
	       /* If DW_OP_const{1,2,4}u won't be used, it is shorter
		  to expand zero extend as two shifts instead of
		  masking.  */
	       && GET_MODE_SIZE (inner_mode) <= 4)
	{
	  mem_loc_result = op0;
	  add_loc_descr (&mem_loc_result,
			 int_loc_descriptor (GET_MODE_MASK (inner_mode)));
	  add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_and, 0, 0));
	}
      else if (GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE)
	{
	  int shift = DWARF2_ADDR_SIZE - GET_MODE_SIZE (inner_mode);
	  shift *= BITS_PER_UNIT;
	  if (GET_CODE (rtl) == SIGN_EXTEND)
	    op = DW_OP_shra;
	  else
	    op = DW_OP_shr;
	  mem_loc_result = op0;
	  add_loc_descr (&mem_loc_result, int_loc_descriptor (shift));
	  add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_shl, 0, 0));
	  add_loc_descr (&mem_loc_result, int_loc_descriptor (shift));
	  add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
	}
      else if (!dwarf_strict || dwarf_version >= 5)
	{
	  dw_die_ref type_die1, type_die2;
	  dw_loc_descr_ref cvt;

	  type_die1 = base_type_for_mode (inner_mode,
					  GET_CODE (rtl) == ZERO_EXTEND);
	  if (type_die1 == NULL)
	    break;
	  type_die2 = base_type_for_mode (int_mode, 1);
	  if (type_die2 == NULL)
	    break;
	  mem_loc_result = op0;
	  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
	  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die1;
	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  add_loc_descr (&mem_loc_result, cvt);
	  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
	  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die2;
	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  add_loc_descr (&mem_loc_result, cvt);
	}
      break;

    case MEM:
      {
	rtx new_rtl = avoid_constant_pool_reference (rtl);
	if (new_rtl != rtl)
	  {
	    mem_loc_result = mem_loc_descriptor (new_rtl, mode, mem_mode,
						 initialized);
	    if (mem_loc_result != NULL)
	      return mem_loc_result;
	  }
      }
      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0),
					   get_address_mode (rtl), mode,
					   VAR_INIT_STATUS_INITIALIZED);
      if (mem_loc_result == NULL)
	mem_loc_result = tls_mem_loc_descriptor (rtl);
      if (mem_loc_result != NULL)
	{
	  if (!is_a <scalar_int_mode> (mode, &int_mode)
	      || GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
	    {
	      dw_die_ref type_die;
	      dw_loc_descr_ref deref;
	      HOST_WIDE_INT size;

	      if (dwarf_strict && dwarf_version < 5)
		return NULL;
	      if (!GET_MODE_SIZE (mode).is_constant (&size))
		return NULL;
	      type_die
		= base_type_for_mode (mode, SCALAR_INT_MODE_P (mode));
	      if (type_die == NULL)
		return NULL;
	      deref = new_loc_descr (dwarf_OP (DW_OP_deref_type), size, 0);
	      deref->dw_loc_oprnd2.val_class = dw_val_class_die_ref;
	      deref->dw_loc_oprnd2.v.val_die_ref.die = type_die;
	      deref->dw_loc_oprnd2.v.val_die_ref.external = 0;
	      add_loc_descr (&mem_loc_result, deref);
	    }
	  else if (GET_MODE_SIZE (int_mode) == DWARF2_ADDR_SIZE)
	    add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
	  else
	    add_loc_descr (&mem_loc_result,
			   new_loc_descr (DW_OP_deref_size,
					  GET_MODE_SIZE (int_mode), 0));
	}
      break;

    case LO_SUM:
      return mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode, initialized);

    case LABEL_REF:
      /* Some ports can transform a symbol ref into a label ref, because
	 the symbol ref is too far away and has to be dumped into a constant
	 pool.  */
    case CONST:
    case SYMBOL_REF:
    case UNSPEC:
      if (!is_a <scalar_int_mode> (mode, &int_mode)
	  || (GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE
#ifdef POINTERS_EXTEND_UNSIGNED
	      && (int_mode != Pmode || mem_mode == VOIDmode)
#endif
	      ))
	break;

      if (GET_CODE (rtl) == UNSPEC)
	{
	  /* If delegitimize_address couldn't do anything with the UNSPEC, we
	     can't express it in the debug info.  This can happen e.g. with some
	     TLS UNSPECs.  Allow UNSPECs formerly from CONST that the backend
	     approves.  */
	  bool not_ok = false;
	  subrtx_var_iterator::array_type array;
	  FOR_EACH_SUBRTX_VAR (iter, array, rtl, ALL)
	    if (*iter != rtl && !CONSTANT_P (*iter))
	      {
		not_ok = true;
		break;
	      }

	  if (not_ok)
	    break;

	  FOR_EACH_SUBRTX_VAR (iter, array, rtl, ALL)
	    if (!const_ok_for_output_1 (*iter))
	      {
		not_ok = true;
		break;
	      }

	  if (not_ok)
	    break;

	  rtl = gen_rtx_CONST (GET_MODE (rtl), rtl);
	  goto symref;
	}

      if (GET_CODE (rtl) == SYMBOL_REF
	  && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
	{
	  dw_loc_descr_ref temp;

	  /* If this is not defined, we have no way to emit the data.  */
	  if (!targetm.have_tls || !targetm.asm_out.output_dwarf_dtprel)
	    break;

          temp = new_addr_loc_descr (rtl, dtprel_true);

	  /* We check for DWARF 5 here because gdb did not implement
	     DW_OP_form_tls_address until after 7.12.  */
	  mem_loc_result = new_loc_descr ((dwarf_version >= 5
					   ? DW_OP_form_tls_address
					   : DW_OP_GNU_push_tls_address),
					  0, 0);
	  add_loc_descr (&mem_loc_result, temp);

	  break;
	}

      if (!const_ok_for_output (rtl))
	{
	  if (GET_CODE (rtl) == CONST)
	    switch (GET_CODE (XEXP (rtl, 0)))
	      {
	      case NOT:
		op = DW_OP_not;
		goto try_const_unop;
	      case NEG:
		op = DW_OP_neg;
		goto try_const_unop;
	      try_const_unop:
		rtx arg;
		arg = XEXP (XEXP (rtl, 0), 0);
		if (!CONSTANT_P (arg))
		  arg = gen_rtx_CONST (int_mode, arg);
		op0 = mem_loc_descriptor (arg, int_mode, mem_mode,
					  initialized);
		if (op0)
		  {
		    mem_loc_result = op0;
		    add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
		  }
		break;
	      default:
		mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), int_mode,
						     mem_mode, initialized);
		break;
	      }
	  break;
	}

    symref:
      mem_loc_result = new_addr_loc_descr (rtl, dtprel_false);
      vec_safe_push (used_rtx_array, rtl);
      break;

    case CONCAT:
    case CONCATN:
    case VAR_LOCATION:
    case DEBUG_IMPLICIT_PTR:
      expansion_failed (NULL_TREE, rtl,
			"CONCAT/CONCATN/VAR_LOCATION is handled only by loc_descriptor");
      return 0;

    case ENTRY_VALUE:
      if (dwarf_strict && dwarf_version < 5)
	return NULL;
      if (REG_P (ENTRY_VALUE_EXP (rtl)))
	{
	  if (!is_a <scalar_int_mode> (mode, &int_mode)
	      || GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
	    op0 = mem_loc_descriptor (ENTRY_VALUE_EXP (rtl), mode,
				      VOIDmode, VAR_INIT_STATUS_INITIALIZED);
	  else
	    {
              unsigned int dbx_regnum = dbx_reg_number (ENTRY_VALUE_EXP (rtl));
	      if (dbx_regnum == IGNORED_DWARF_REGNUM)
		return NULL;
	      op0 = one_reg_loc_descriptor (dbx_regnum,
					    VAR_INIT_STATUS_INITIALIZED);
	    }
	}
      else if (MEM_P (ENTRY_VALUE_EXP (rtl))
	       && REG_P (XEXP (ENTRY_VALUE_EXP (rtl), 0)))
	{
	  op0 = mem_loc_descriptor (ENTRY_VALUE_EXP (rtl), mode,
				    VOIDmode, VAR_INIT_STATUS_INITIALIZED);
	  if (op0 && op0->dw_loc_opc == DW_OP_fbreg)
	    return NULL;
	}
      else
	gcc_unreachable ();
      if (op0 == NULL)
	return NULL;
      mem_loc_result = new_loc_descr (dwarf_OP (DW_OP_entry_value), 0, 0);
      mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_loc;
      mem_loc_result->dw_loc_oprnd1.v.val_loc = op0;
      break;

    case DEBUG_PARAMETER_REF:
      mem_loc_result = parameter_ref_descriptor (rtl);
      break;

    case PRE_MODIFY:
      /* Extract the PLUS expression nested inside and fall into
	 PLUS code below.  */
      rtl = XEXP (rtl, 1);
      goto plus;

    case PRE_INC:
    case PRE_DEC:
      /* Turn these into a PLUS expression and fall into the PLUS code
	 below.  */
      rtl = gen_rtx_PLUS (mode, XEXP (rtl, 0),
			  gen_int_mode (GET_CODE (rtl) == PRE_INC
					? GET_MODE_UNIT_SIZE (mem_mode)
					: -GET_MODE_UNIT_SIZE (mem_mode),
					mode));

      /* fall through */

    case PLUS:
    plus:
      if (is_based_loc (rtl)
	  && is_a <scalar_int_mode> (mode, &int_mode)
	  && (GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE
	      || XEXP (rtl, 0) == arg_pointer_rtx
	      || XEXP (rtl, 0) == frame_pointer_rtx))
	mem_loc_result = based_loc_descr (XEXP (rtl, 0),
					  INTVAL (XEXP (rtl, 1)),
					  VAR_INIT_STATUS_INITIALIZED);
      else
	{
	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
					       VAR_INIT_STATUS_INITIALIZED);
	  if (mem_loc_result == 0)
	    break;

	  if (CONST_INT_P (XEXP (rtl, 1))
	      && (GET_MODE_SIZE (as_a <scalar_int_mode> (mode))
		  <= DWARF2_ADDR_SIZE))
	    loc_descr_plus_const (&mem_loc_result, INTVAL (XEXP (rtl, 1)));
	  else
	    {
	      op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
					VAR_INIT_STATUS_INITIALIZED);
	      if (op1 == 0)
		return NULL;
	      add_loc_descr (&mem_loc_result, op1);
	      add_loc_descr (&mem_loc_result,
			     new_loc_descr (DW_OP_plus, 0, 0));
	    }
	}
      break;

    /* If a pseudo-reg is optimized away, it is possible for it to
       be replaced with a MEM containing a multiply or shift.  */
    case MINUS:
      op = DW_OP_minus;
      goto do_binop;

    case MULT:
      op = DW_OP_mul;
      goto do_binop;

    case DIV:
      if ((!dwarf_strict || dwarf_version >= 5)
	  && is_a <scalar_int_mode> (mode, &int_mode)
	  && GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
	{
	  mem_loc_result = typed_binop (DW_OP_div, rtl,
					base_type_for_mode (mode, 0),
					int_mode, mem_mode);
	  break;
	}
      op = DW_OP_div;
      goto do_binop;

    case UMOD:
      op = DW_OP_mod;
      goto do_binop;

    case ASHIFT:
      op = DW_OP_shl;
      goto do_shift;

    case ASHIFTRT:
      op = DW_OP_shra;
      goto do_shift;

    case LSHIFTRT:
      op = DW_OP_shr;
      goto do_shift;

    do_shift:
      if (!is_a <scalar_int_mode> (mode, &int_mode))
	break;
      op0 = mem_loc_descriptor (XEXP (rtl, 0), int_mode, mem_mode,
				VAR_INIT_STATUS_INITIALIZED);
      {
	rtx rtlop1 = XEXP (rtl, 1);
	if (is_a <scalar_int_mode> (GET_MODE (rtlop1), &op1_mode)
	    && GET_MODE_BITSIZE (op1_mode) < GET_MODE_BITSIZE (int_mode))
	  rtlop1 = gen_rtx_ZERO_EXTEND (int_mode, rtlop1);
	op1 = mem_loc_descriptor (rtlop1, int_mode, mem_mode,
				  VAR_INIT_STATUS_INITIALIZED);
      }

      if (op0 == 0 || op1 == 0)
	break;

      mem_loc_result = op0;
      add_loc_descr (&mem_loc_result, op1);
      add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
      break;

    case AND:
      op = DW_OP_and;
      goto do_binop;

    case IOR:
      op = DW_OP_or;
      goto do_binop;

    case XOR:
      op = DW_OP_xor;
      goto do_binop;

    do_binop:
      op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
				VAR_INIT_STATUS_INITIALIZED);
      op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
				VAR_INIT_STATUS_INITIALIZED);

      if (op0 == 0 || op1 == 0)
	break;

      mem_loc_result = op0;
      add_loc_descr (&mem_loc_result, op1);
      add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
      break;

    case MOD:
      if ((!dwarf_strict || dwarf_version >= 5)
	  && is_a <scalar_int_mode> (mode, &int_mode)
	  && GET_MODE_SIZE (int_mode) > DWARF2_ADDR_SIZE)
	{
	  mem_loc_result = typed_binop (DW_OP_mod, rtl,
					base_type_for_mode (mode, 0),
					int_mode, mem_mode);
	  break;
	}

      op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
				VAR_INIT_STATUS_INITIALIZED);
      op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
				VAR_INIT_STATUS_INITIALIZED);

      if (op0 == 0 || op1 == 0)
	break;

      mem_loc_result = op0;
      add_loc_descr (&mem_loc_result, op1);
      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_over, 0, 0));
      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_over, 0, 0));
      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_div, 0, 0));
      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_mul, 0, 0));
      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_minus, 0, 0));
      break;

    case UDIV:
      if ((!dwarf_strict || dwarf_version >= 5)
	  && is_a <scalar_int_mode> (mode, &int_mode))
	{
	  /* We can use a signed divide if the sign bit is not set.  */
	  if (GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
	    {
	      op = DW_OP_div;
	      goto do_binop;
	    }

	  mem_loc_result = typed_binop (DW_OP_div, rtl,
					base_type_for_mode (int_mode, 1),
					int_mode, mem_mode);
	}
      break;

    case NOT:
      op = DW_OP_not;
      goto do_unop;

    case ABS:
      op = DW_OP_abs;
      goto do_unop;

    case NEG:
      op = DW_OP_neg;
      goto do_unop;

    do_unop:
      op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode,
				VAR_INIT_STATUS_INITIALIZED);

      if (op0 == 0)
	break;

      mem_loc_result = op0;
      add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
      break;

    case CONST_INT:
      if (!is_a <scalar_int_mode> (mode, &int_mode)
	  || GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE
#ifdef POINTERS_EXTEND_UNSIGNED
	  || (int_mode == Pmode
	      && mem_mode != VOIDmode
	      && trunc_int_for_mode (INTVAL (rtl), ptr_mode) == INTVAL (rtl))
#endif
	  )
	{
	  mem_loc_result = int_loc_descriptor (INTVAL (rtl));
	  break;
	}
      if ((!dwarf_strict || dwarf_version >= 5)
	  && (GET_MODE_BITSIZE (int_mode) == HOST_BITS_PER_WIDE_INT
	      || GET_MODE_BITSIZE (int_mode) == HOST_BITS_PER_DOUBLE_INT))
	{
	  dw_die_ref type_die = base_type_for_mode (int_mode, 1);
	  scalar_int_mode amode;
	  if (type_die == NULL)
	    return NULL;
	  if (INTVAL (rtl) >= 0
	      && (int_mode_for_size (DWARF2_ADDR_SIZE * BITS_PER_UNIT, 0)
		  .exists (&amode))
	      && trunc_int_for_mode (INTVAL (rtl), amode) == INTVAL (rtl)
	      /* const DW_OP_convert <XXX> vs.
		 DW_OP_const_type <XXX, 1, const>.  */
	      && size_of_int_loc_descriptor (INTVAL (rtl)) + 1 + 1
		 < (unsigned long) 1 + 1 + 1 + GET_MODE_SIZE (int_mode))
	    {
	      mem_loc_result = int_loc_descriptor (INTVAL (rtl));
	      op0 = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
	      op0->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	      op0->dw_loc_oprnd1.v.val_die_ref.die = type_die;
	      op0->dw_loc_oprnd1.v.val_die_ref.external = 0;
	      add_loc_descr (&mem_loc_result, op0);
	      return mem_loc_result;
	    }
	  mem_loc_result = new_loc_descr (dwarf_OP (DW_OP_const_type), 0,
					  INTVAL (rtl));
	  mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  mem_loc_result->dw_loc_oprnd1.v.val_die_ref.die = type_die;
	  mem_loc_result->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  if (GET_MODE_BITSIZE (int_mode) == HOST_BITS_PER_WIDE_INT)
	    mem_loc_result->dw_loc_oprnd2.val_class = dw_val_class_const;
	  else
	    {
	      mem_loc_result->dw_loc_oprnd2.val_class
		= dw_val_class_const_double;
	      mem_loc_result->dw_loc_oprnd2.v.val_double
		= double_int::from_shwi (INTVAL (rtl));
	    }
	}
      break;

    case CONST_DOUBLE:
      if (!dwarf_strict || dwarf_version >= 5)
	{
	  dw_die_ref type_die;

	  /* Note that if TARGET_SUPPORTS_WIDE_INT == 0, a
	     CONST_DOUBLE rtx could represent either a large integer
	     or a floating-point constant.  If TARGET_SUPPORTS_WIDE_INT != 0,
	     the value is always a floating point constant.

	     When it is an integer, a CONST_DOUBLE is used whenever
	     the constant requires 2 HWIs to be adequately represented.
	     We output CONST_DOUBLEs as blocks.  */
	  if (mode == VOIDmode
	      || (GET_MODE (rtl) == VOIDmode
		  && maybe_ne (GET_MODE_BITSIZE (mode),
			       HOST_BITS_PER_DOUBLE_INT)))
	    break;
	  type_die = base_type_for_mode (mode, SCALAR_INT_MODE_P (mode));
	  if (type_die == NULL)
	    return NULL;
	  mem_loc_result = new_loc_descr (dwarf_OP (DW_OP_const_type), 0, 0);
	  mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  mem_loc_result->dw_loc_oprnd1.v.val_die_ref.die = type_die;
	  mem_loc_result->dw_loc_oprnd1.v.val_die_ref.external = 0;
#if TARGET_SUPPORTS_WIDE_INT == 0
	  if (!SCALAR_FLOAT_MODE_P (mode))
	    {
	      mem_loc_result->dw_loc_oprnd2.val_class
		= dw_val_class_const_double;
	      mem_loc_result->dw_loc_oprnd2.v.val_double
		= rtx_to_double_int (rtl);
	    }
	  else
#endif
	    {
	      scalar_float_mode float_mode = as_a <scalar_float_mode> (mode);
	      unsigned int length = GET_MODE_SIZE (float_mode);
	      unsigned char *array = ggc_vec_alloc<unsigned char> (length);
	      unsigned int elt_size = insert_float (rtl, array);

	      mem_loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec;
	      mem_loc_result->dw_loc_oprnd2.v.val_vec.length
		= length / elt_size;
	      mem_loc_result->dw_loc_oprnd2.v.val_vec.elt_size = elt_size;
	      mem_loc_result->dw_loc_oprnd2.v.val_vec.array = array;
	    }
	}
      break;

    case CONST_WIDE_INT:
      if (!dwarf_strict || dwarf_version >= 5)
	{
	  dw_die_ref type_die;

	  type_die = base_type_for_mode (mode, SCALAR_INT_MODE_P (mode));
	  if (type_die == NULL)
	    return NULL;
	  mem_loc_result = new_loc_descr (dwarf_OP (DW_OP_const_type), 0, 0);
	  mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  mem_loc_result->dw_loc_oprnd1.v.val_die_ref.die = type_die;
	  mem_loc_result->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  mem_loc_result->dw_loc_oprnd2.val_class
	    = dw_val_class_wide_int;
	  mem_loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc<wide_int> ();
	  *mem_loc_result->dw_loc_oprnd2.v.val_wide = rtx_mode_t (rtl, mode);
	}
      break;

    case CONST_POLY_INT:
      mem_loc_result = int_loc_descriptor (rtx_to_poly_int64 (rtl));
      break;

    case EQ:
      mem_loc_result = scompare_loc_descriptor (DW_OP_eq, rtl, mem_mode);
      break;

    case GE:
      mem_loc_result = scompare_loc_descriptor (DW_OP_ge, rtl, mem_mode);
      break;

    case GT:
      mem_loc_result = scompare_loc_descriptor (DW_OP_gt, rtl, mem_mode);
      break;

    case LE:
      mem_loc_result = scompare_loc_descriptor (DW_OP_le, rtl, mem_mode);
      break;

    case LT:
      mem_loc_result = scompare_loc_descriptor (DW_OP_lt, rtl, mem_mode);
      break;

    case NE:
      mem_loc_result = scompare_loc_descriptor (DW_OP_ne, rtl, mem_mode);
      break;

    case GEU:
      mem_loc_result = ucompare_loc_descriptor (DW_OP_ge, rtl, mem_mode);
      break;

    case GTU:
      mem_loc_result = ucompare_loc_descriptor (DW_OP_gt, rtl, mem_mode);
      break;

    case LEU:
      mem_loc_result = ucompare_loc_descriptor (DW_OP_le, rtl, mem_mode);
      break;

    case LTU:
      mem_loc_result = ucompare_loc_descriptor (DW_OP_lt, rtl, mem_mode);
      break;

    case UMIN:
    case UMAX:
      if (!SCALAR_INT_MODE_P (mode))
	break;
      /* FALLTHRU */
    case SMIN:
    case SMAX:
      mem_loc_result = minmax_loc_descriptor (rtl, mode, mem_mode);
      break;

    case ZERO_EXTRACT:
    case SIGN_EXTRACT:
      if (CONST_INT_P (XEXP (rtl, 1))
	  && CONST_INT_P (XEXP (rtl, 2))
	  && is_a <scalar_int_mode> (mode, &int_mode)
	  && is_a <scalar_int_mode> (GET_MODE (XEXP (rtl, 0)), &inner_mode)
	  && GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE
	  && GET_MODE_SIZE (inner_mode) <= DWARF2_ADDR_SIZE
	  && ((unsigned) INTVAL (XEXP (rtl, 1))
	      + (unsigned) INTVAL (XEXP (rtl, 2))
	      <= GET_MODE_BITSIZE (int_mode)))
	{
	  int shift, size;
	  op0 = mem_loc_descriptor (XEXP (rtl, 0), inner_mode,
				    mem_mode, VAR_INIT_STATUS_INITIALIZED);
	  if (op0 == 0)
	    break;
	  if (GET_CODE (rtl) == SIGN_EXTRACT)
	    op = DW_OP_shra;
	  else
	    op = DW_OP_shr;
	  mem_loc_result = op0;
	  size = INTVAL (XEXP (rtl, 1));
	  shift = INTVAL (XEXP (rtl, 2));
	  if (BITS_BIG_ENDIAN)
	    shift = GET_MODE_BITSIZE (inner_mode) - shift - size;
	  if (shift + size != (int) DWARF2_ADDR_SIZE)
	    {
	      add_loc_descr (&mem_loc_result,
			     int_loc_descriptor (DWARF2_ADDR_SIZE
						 - shift - size));
	      add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_shl, 0, 0));
	    }
	  if (size != (int) DWARF2_ADDR_SIZE)
	    {
	      add_loc_descr (&mem_loc_result,
			     int_loc_descriptor (DWARF2_ADDR_SIZE - size));
	      add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
	    }
	}
      break;

    case IF_THEN_ELSE:
      {
	dw_loc_descr_ref op2, bra_node, drop_node;
	op0 = mem_loc_descriptor (XEXP (rtl, 0),
				  GET_MODE (XEXP (rtl, 0)) == VOIDmode
				  ? word_mode : GET_MODE (XEXP (rtl, 0)),
				  mem_mode, VAR_INIT_STATUS_INITIALIZED);
	op1 = mem_loc_descriptor (XEXP (rtl, 1), mode, mem_mode,
				  VAR_INIT_STATUS_INITIALIZED);
	op2 = mem_loc_descriptor (XEXP (rtl, 2), mode, mem_mode,
				  VAR_INIT_STATUS_INITIALIZED);
	if (op0 == NULL || op1 == NULL || op2 == NULL)
	  break;

	mem_loc_result = op1;
	add_loc_descr (&mem_loc_result, op2);
	add_loc_descr (&mem_loc_result, op0);
	bra_node = new_loc_descr (DW_OP_bra, 0, 0);
	add_loc_descr (&mem_loc_result, bra_node);
	add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_swap, 0, 0));
	drop_node = new_loc_descr (DW_OP_drop, 0, 0);
	add_loc_descr (&mem_loc_result, drop_node);
	bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
	bra_node->dw_loc_oprnd1.v.val_loc = drop_node;
      }
      break;

    case FLOAT_EXTEND:
    case FLOAT_TRUNCATE:
    case FLOAT:
    case UNSIGNED_FLOAT:
    case FIX:
    case UNSIGNED_FIX:
      if (!dwarf_strict || dwarf_version >= 5)
	{
	  dw_die_ref type_die;
	  dw_loc_descr_ref cvt;

	  op0 = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (XEXP (rtl, 0)),
				    mem_mode, VAR_INIT_STATUS_INITIALIZED);
	  if (op0 == NULL)
	    break;
	  if (is_a <scalar_int_mode> (GET_MODE (XEXP (rtl, 0)), &int_mode)
	      && (GET_CODE (rtl) == FLOAT
		  || GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE))
	    {
	      type_die = base_type_for_mode (int_mode,
					     GET_CODE (rtl) == UNSIGNED_FLOAT);
	      if (type_die == NULL)
		break;
	      cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
	      cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	      cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
	      cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
	      add_loc_descr (&op0, cvt);
	    }
	  type_die = base_type_for_mode (mode, GET_CODE (rtl) == UNSIGNED_FIX);
	  if (type_die == NULL)
	    break;
	  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
	  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
	  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  add_loc_descr (&op0, cvt);
	  if (is_a <scalar_int_mode> (mode, &int_mode)
	      && (GET_CODE (rtl) == FIX
		  || GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE))
	    {
	      op0 = convert_descriptor_to_mode (int_mode, op0);
	      if (op0 == NULL)
		break;
	    }
	  mem_loc_result = op0;
	}
      break;

    case CLZ:
    case CTZ:
    case FFS:
      if (is_a <scalar_int_mode> (mode, &int_mode))
	mem_loc_result = clz_loc_descriptor (rtl, int_mode, mem_mode);
      break;

    case POPCOUNT:
    case PARITY:
      if (is_a <scalar_int_mode> (mode, &int_mode))
	mem_loc_result = popcount_loc_descriptor (rtl, int_mode, mem_mode);
      break;

    case BSWAP:
      if (is_a <scalar_int_mode> (mode, &int_mode))
	mem_loc_result = bswap_loc_descriptor (rtl, int_mode, mem_mode);
      break;

    case ROTATE:
    case ROTATERT:
      if (is_a <scalar_int_mode> (mode, &int_mode))
	mem_loc_result = rotate_loc_descriptor (rtl, int_mode, mem_mode);
      break;

    case COMPARE:
      /* In theory, we could implement the above.  */
      /* DWARF cannot represent the unsigned compare operations
	 natively.  */
    case SS_MULT:
    case US_MULT:
    case SS_DIV:
    case US_DIV:
    case SS_PLUS:
    case US_PLUS:
    case SS_MINUS:
    case US_MINUS:
    case SS_NEG:
    case US_NEG:
    case SS_ABS:
    case SS_ASHIFT:
    case US_ASHIFT:
    case SS_TRUNCATE:
    case US_TRUNCATE:
    case UNORDERED:
    case ORDERED:
    case UNEQ:
    case UNGE:
    case UNGT:
    case UNLE:
    case UNLT:
    case LTGT:
    case FRACT_CONVERT:
    case UNSIGNED_FRACT_CONVERT:
    case SAT_FRACT:
    case UNSIGNED_SAT_FRACT:
    case SQRT:
    case ASM_OPERANDS:
    case VEC_MERGE:
    case VEC_SELECT:
    case VEC_CONCAT:
    case VEC_DUPLICATE:
    case VEC_SERIES:
    case HIGH:
    case FMA:
    case STRICT_LOW_PART:
    case CONST_VECTOR:
    case CONST_FIXED:
    case CLRSB:
    case CLOBBER:
    case SMUL_HIGHPART:
    case UMUL_HIGHPART:
      break;

    case CONST_STRING:
      resolve_one_addr (&rtl);
      goto symref;

    /* RTL sequences inside PARALLEL record a series of DWARF operations for
       the expression.  An UNSPEC rtx represents a raw DWARF operation,
       new_loc_descr is called for it to build the operation directly.
       Otherwise mem_loc_descriptor is called recursively.  */
    case PARALLEL:
      {
	int index = 0;
	dw_loc_descr_ref exp_result = NULL;

	for (; index < XVECLEN (rtl, 0); index++)
	  {
	    rtx elem = XVECEXP (rtl, 0, index);
	    if (GET_CODE (elem) == UNSPEC)
	      {
		/* Each DWARF operation UNSPEC contain two operands, if
		   one operand is not used for the operation, const0_rtx is
		   passed.  */
		gcc_assert (XVECLEN (elem, 0) == 2);

		HOST_WIDE_INT dw_op = XINT (elem, 1);
		HOST_WIDE_INT oprnd1 = INTVAL (XVECEXP (elem, 0, 0));
		HOST_WIDE_INT oprnd2 = INTVAL (XVECEXP (elem, 0, 1));
		exp_result
		  = new_loc_descr ((enum dwarf_location_atom) dw_op, oprnd1,
				   oprnd2);
	      }
	    else
	      exp_result
		= mem_loc_descriptor (elem, mode, mem_mode,
				      VAR_INIT_STATUS_INITIALIZED);

	    if (!mem_loc_result)
	      mem_loc_result = exp_result;
	    else
	      add_loc_descr (&mem_loc_result, exp_result);
	  }

	break;
      }

    default:
      if (flag_checking)
	{
	  print_rtl (stderr, rtl);
	  gcc_unreachable ();
	}
      break;
    }

  if (mem_loc_result && initialized == VAR_INIT_STATUS_UNINITIALIZED)
    add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));

  return mem_loc_result;
}

/* Return a descriptor that describes the concatenation of two locations.
   This is typically a complex variable.  */

static dw_loc_descr_ref
concat_loc_descriptor (rtx x0, rtx x1, enum var_init_status initialized)
{
  /* At present we only track constant-sized pieces.  */
  unsigned int size0, size1;
  if (!GET_MODE_SIZE (GET_MODE (x0)).is_constant (&size0)
      || !GET_MODE_SIZE (GET_MODE (x1)).is_constant (&size1))
    return 0;

  dw_loc_descr_ref cc_loc_result = NULL;
  dw_loc_descr_ref x0_ref
    = loc_descriptor (x0, VOIDmode, VAR_INIT_STATUS_INITIALIZED);
  dw_loc_descr_ref x1_ref
    = loc_descriptor (x1, VOIDmode, VAR_INIT_STATUS_INITIALIZED);

  if (x0_ref == 0 || x1_ref == 0)
    return 0;

  cc_loc_result = x0_ref;
  add_loc_descr_op_piece (&cc_loc_result, size0);

  add_loc_descr (&cc_loc_result, x1_ref);
  add_loc_descr_op_piece (&cc_loc_result, size1);

  if (initialized == VAR_INIT_STATUS_UNINITIALIZED)
    add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));

  return cc_loc_result;
}

/* Return a descriptor that describes the concatenation of N
   locations.  */

static dw_loc_descr_ref
concatn_loc_descriptor (rtx concatn, enum var_init_status initialized)
{
  unsigned int i;
  dw_loc_descr_ref cc_loc_result = NULL;
  unsigned int n = XVECLEN (concatn, 0);
  unsigned int size;

  for (i = 0; i < n; ++i)
    {
      dw_loc_descr_ref ref;
      rtx x = XVECEXP (concatn, 0, i);

      /* At present we only track constant-sized pieces.  */
      if (!GET_MODE_SIZE (GET_MODE (x)).is_constant (&size))
	return NULL;

      ref = loc_descriptor (x, VOIDmode, VAR_INIT_STATUS_INITIALIZED);
      if (ref == NULL)
	return NULL;

      add_loc_descr (&cc_loc_result, ref);
      add_loc_descr_op_piece (&cc_loc_result, size);
    }

  if (cc_loc_result && initialized == VAR_INIT_STATUS_UNINITIALIZED)
    add_loc_descr (&cc_loc_result, new_loc_descr (DW_OP_GNU_uninit, 0, 0));

  return cc_loc_result;
}

/* Helper function for loc_descriptor.  Return DW_OP_implicit_pointer
   for DEBUG_IMPLICIT_PTR RTL.  */

static dw_loc_descr_ref
implicit_ptr_descriptor (rtx rtl, HOST_WIDE_INT offset)
{
  dw_loc_descr_ref ret;
  dw_die_ref ref;

  if (dwarf_strict && dwarf_version < 5)
    return NULL;
  gcc_assert (TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == VAR_DECL
	      || TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == PARM_DECL
	      || TREE_CODE (DEBUG_IMPLICIT_PTR_DECL (rtl)) == RESULT_DECL);
  ref = lookup_decl_die (DEBUG_IMPLICIT_PTR_DECL (rtl));
  ret = new_loc_descr (dwarf_OP (DW_OP_implicit_pointer), 0, offset);
  ret->dw_loc_oprnd2.val_class = dw_val_class_const;
  if (ref)
    {
      ret->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
      ret->dw_loc_oprnd1.v.val_die_ref.die = ref;
      ret->dw_loc_oprnd1.v.val_die_ref.external = 0;
    }
  else
    {
      ret->dw_loc_oprnd1.val_class = dw_val_class_decl_ref;
      ret->dw_loc_oprnd1.v.val_decl_ref = DEBUG_IMPLICIT_PTR_DECL (rtl);
    }
  return ret;
}

/* Output a proper Dwarf location descriptor for a variable or parameter
   which is either allocated in a register or in a memory location.  For a
   register, we just generate an OP_REG and the register number.  For a
   memory location we provide a Dwarf postfix expression describing how to
   generate the (dynamic) address of the object onto the address stack.

   MODE is mode of the decl if this loc_descriptor is going to be used in
   .debug_loc section where DW_OP_stack_value and DW_OP_implicit_value are
   allowed, VOIDmode otherwise.

   If we don't know how to describe it, return 0.  */

static dw_loc_descr_ref
loc_descriptor (rtx rtl, machine_mode mode,
		enum var_init_status initialized)
{
  dw_loc_descr_ref loc_result = NULL;
  scalar_int_mode int_mode;

  switch (GET_CODE (rtl))
    {
    case SUBREG:
      /* The case of a subreg may arise when we have a local (register)
	 variable or a formal (register) parameter which doesn't quite fill
	 up an entire register.  For now, just assume that it is
	 legitimate to make the Dwarf info refer to the whole register which
	 contains the given subreg.  */
      if (REG_P (SUBREG_REG (rtl)) && subreg_lowpart_p (rtl))
	loc_result = loc_descriptor (SUBREG_REG (rtl),
				     GET_MODE (SUBREG_REG (rtl)), initialized);
      else
	goto do_default;
      break;

    case REG:
      loc_result = reg_loc_descriptor (rtl, initialized);
      break;

    case MEM:
      loc_result = mem_loc_descriptor (XEXP (rtl, 0), get_address_mode (rtl),
				       GET_MODE (rtl), initialized);
      if (loc_result == NULL)
	loc_result = tls_mem_loc_descriptor (rtl);
      if (loc_result == NULL)
	{
	  rtx new_rtl = avoid_constant_pool_reference (rtl);
	  if (new_rtl != rtl)
	    loc_result = loc_descriptor (new_rtl, mode, initialized);
	}
      break;

    case CONCAT:
      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1),
					  initialized);
      break;

    case CONCATN:
      loc_result = concatn_loc_descriptor (rtl, initialized);
      break;

    case VAR_LOCATION:
      /* Single part.  */
      if (GET_CODE (PAT_VAR_LOCATION_LOC (rtl)) != PARALLEL)
	{
	  rtx loc = PAT_VAR_LOCATION_LOC (rtl);
	  if (GET_CODE (loc) == EXPR_LIST)
	    loc = XEXP (loc, 0);
	  loc_result = loc_descriptor (loc, mode, initialized);
	  break;
	}

      rtl = XEXP (rtl, 1);
      /* FALLTHRU */

    case PARALLEL:
      {
	rtvec par_elems = XVEC (rtl, 0);
	int num_elem = GET_NUM_ELEM (par_elems);
	machine_mode mode;
	int i, size;

	/* Create the first one, so we have something to add to.  */
	loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
				     VOIDmode, initialized);
	if (loc_result == NULL)
	  return NULL;
	mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
	/* At present we only track constant-sized pieces.  */
	if (!GET_MODE_SIZE (mode).is_constant (&size))
	  return NULL;
	add_loc_descr_op_piece (&loc_result, size);
	for (i = 1; i < num_elem; i++)
	  {
	    dw_loc_descr_ref temp;

	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0),
				   VOIDmode, initialized);
	    if (temp == NULL)
	      return NULL;
	    add_loc_descr (&loc_result, temp);
	    mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
	    /* At present we only track constant-sized pieces.  */
	    if (!GET_MODE_SIZE (mode).is_constant (&size))
	      return NULL;
	    add_loc_descr_op_piece (&loc_result, size);
	  }
      }
      break;

    case CONST_INT:
      if (mode != VOIDmode && mode != BLKmode)
	{
	  int_mode = as_a <scalar_int_mode> (mode);
	  loc_result = address_of_int_loc_descriptor (GET_MODE_SIZE (int_mode),
						      INTVAL (rtl));
	}
      break;

    case CONST_DOUBLE:
      if (mode == VOIDmode)
	mode = GET_MODE (rtl);

      if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
	{
	  gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl));

	  /* Note that a CONST_DOUBLE rtx could represent either an integer
	     or a floating-point constant.  A CONST_DOUBLE is used whenever
	     the constant requires more than one word in order to be
	     adequately represented.  We output CONST_DOUBLEs as blocks.  */
	  scalar_mode smode = as_a <scalar_mode> (mode);
	  loc_result = new_loc_descr (DW_OP_implicit_value,
				      GET_MODE_SIZE (smode), 0);
#if TARGET_SUPPORTS_WIDE_INT == 0
	  if (!SCALAR_FLOAT_MODE_P (smode))
	    {
	      loc_result->dw_loc_oprnd2.val_class = dw_val_class_const_double;
	      loc_result->dw_loc_oprnd2.v.val_double
	        = rtx_to_double_int (rtl);
	    }
	  else
#endif
	    {
	      unsigned int length = GET_MODE_SIZE (smode);
	      unsigned char *array = ggc_vec_alloc<unsigned char> (length);
	      unsigned int elt_size = insert_float (rtl, array);

	      loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec;
	      loc_result->dw_loc_oprnd2.v.val_vec.length = length / elt_size;
	      loc_result->dw_loc_oprnd2.v.val_vec.elt_size = elt_size;
	      loc_result->dw_loc_oprnd2.v.val_vec.array = array;
	    }
	}
      break;

    case CONST_WIDE_INT:
      if (mode == VOIDmode)
	mode = GET_MODE (rtl);

      if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
	{
	  int_mode = as_a <scalar_int_mode> (mode);
	  loc_result = new_loc_descr (DW_OP_implicit_value,
				      GET_MODE_SIZE (int_mode), 0);
	  loc_result->dw_loc_oprnd2.val_class = dw_val_class_wide_int;
	  loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc<wide_int> ();
	  *loc_result->dw_loc_oprnd2.v.val_wide = rtx_mode_t (rtl, int_mode);
	}
      break;

    case CONST_VECTOR:
      if (mode == VOIDmode)
	mode = GET_MODE (rtl);

      if (mode != VOIDmode
	  /* The combination of a length and byte elt_size doesn't extend
	     naturally to boolean vectors, where several elements are packed
	     into the same byte.  */
	  && GET_MODE_CLASS (mode) != MODE_VECTOR_BOOL
	  && (dwarf_version >= 4 || !dwarf_strict))
	{
	  unsigned int length;
	  if (!CONST_VECTOR_NUNITS (rtl).is_constant (&length))
	    return NULL;

	  unsigned int elt_size = GET_MODE_UNIT_SIZE (GET_MODE (rtl));
	  unsigned char *array
	    = ggc_vec_alloc<unsigned char> (length * elt_size);
	  unsigned int i;
	  unsigned char *p;
	  machine_mode imode = GET_MODE_INNER (mode);

	  gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl));
	  switch (GET_MODE_CLASS (mode))
	    {
	    case MODE_VECTOR_INT:
	      for (i = 0, p = array; i < length; i++, p += elt_size)
		{
		  rtx elt = CONST_VECTOR_ELT (rtl, i);
		  insert_wide_int (rtx_mode_t (elt, imode), p, elt_size);
		}
	      break;

	    case MODE_VECTOR_FLOAT:
	      for (i = 0, p = array; i < length; i++, p += elt_size)
		{
		  rtx elt = CONST_VECTOR_ELT (rtl, i);
		  insert_float (elt, p);
		}
	      break;

	    default:
	      gcc_unreachable ();
	    }

	  loc_result = new_loc_descr (DW_OP_implicit_value,
				      length * elt_size, 0);
	  loc_result->dw_loc_oprnd2.val_class = dw_val_class_vec;
	  loc_result->dw_loc_oprnd2.v.val_vec.length = length;
	  loc_result->dw_loc_oprnd2.v.val_vec.elt_size = elt_size;
	  loc_result->dw_loc_oprnd2.v.val_vec.array = array;
	}
      break;

    case CONST:
      if (mode == VOIDmode
	  || CONST_SCALAR_INT_P (XEXP (rtl, 0))
	  || CONST_DOUBLE_AS_FLOAT_P (XEXP (rtl, 0))
	  || GET_CODE (XEXP (rtl, 0)) == CONST_VECTOR)
	{
	  loc_result = loc_descriptor (XEXP (rtl, 0), mode, initialized);
	  break;
	}
      /* FALLTHROUGH */
    case SYMBOL_REF:
      if (!const_ok_for_output (rtl))
	break;
      /* FALLTHROUGH */
    case LABEL_REF:
      if (is_a <scalar_int_mode> (mode, &int_mode)
	  && GET_MODE_SIZE (int_mode) == DWARF2_ADDR_SIZE
	  && (dwarf_version >= 4 || !dwarf_strict))
	{
         loc_result = new_addr_loc_descr (rtl, dtprel_false);
	  add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
	  vec_safe_push (used_rtx_array, rtl);
	}
      break;

    case DEBUG_IMPLICIT_PTR:
      loc_result = implicit_ptr_descriptor (rtl, 0);
      break;

    case PLUS:
      if (GET_CODE (XEXP (rtl, 0)) == DEBUG_IMPLICIT_PTR
	  && CONST_INT_P (XEXP (rtl, 1)))
	{
	  loc_result
	    = implicit_ptr_descriptor (XEXP (rtl, 0), INTVAL (XEXP (rtl, 1)));
	  break;
	}
      /* FALLTHRU */
    do_default:
    default:
      if ((is_a <scalar_int_mode> (mode, &int_mode)
	   && GET_MODE (rtl) == int_mode
	   && GET_MODE_SIZE (int_mode) <= DWARF2_ADDR_SIZE
	   && dwarf_version >= 4)
	  || (!dwarf_strict && mode != VOIDmode && mode != BLKmode))
	{
	  /* Value expression.  */
	  loc_result = mem_loc_descriptor (rtl, mode, VOIDmode, initialized);
	  if (loc_result)
	    add_loc_descr (&loc_result,
			   new_loc_descr (DW_OP_stack_value, 0, 0));
	}
      break;
    }

  return loc_result;
}

/* We need to figure out what section we should use as the base for the
   address ranges where a given location is valid.
   1. If this particular DECL has a section associated with it, use that.
   2. If this function has a section associated with it, use that.
   3. Otherwise, use the text section.
   XXX: If you split a variable across multiple sections, we won't notice.  */

static const char *
secname_for_decl (const_tree decl)
{
  const char *secname;

  if (VAR_OR_FUNCTION_DECL_P (decl)
      && (DECL_EXTERNAL (decl) || TREE_PUBLIC (decl) || TREE_STATIC (decl))
      && DECL_SECTION_NAME (decl))
    secname = DECL_SECTION_NAME (decl);
  else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
    {
      if (in_cold_section_p)
	{
	  section *sec = current_function_section ();
	  if (sec->common.flags & SECTION_NAMED)
	    return sec->named.name;
	}
      secname = DECL_SECTION_NAME (current_function_decl);
    }
  else if (cfun && in_cold_section_p)
    secname = crtl->subsections.cold_section_label;
  else
    secname = text_section_label;

  return secname;
}

/* Return true when DECL_BY_REFERENCE is defined and set for DECL.  */

static bool
decl_by_reference_p (tree decl)
{
  return ((TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL
  	   || VAR_P (decl))
	  && DECL_BY_REFERENCE (decl));
}

/* Helper function for dw_loc_list.  Compute proper Dwarf location descriptor
   for VARLOC.  */

static dw_loc_descr_ref
dw_loc_list_1 (tree loc, rtx varloc, int want_address,
	       enum var_init_status initialized)
{
  int have_address = 0;
  dw_loc_descr_ref descr;
  machine_mode mode;

  if (want_address != 2)
    {
      gcc_assert (GET_CODE (varloc) == VAR_LOCATION);
      /* Single part.  */
      if (GET_CODE (PAT_VAR_LOCATION_LOC (varloc)) != PARALLEL)
	{
	  varloc = PAT_VAR_LOCATION_LOC (varloc);
	  if (GET_CODE (varloc) == EXPR_LIST)
	    varloc = XEXP (varloc, 0);
	  mode = GET_MODE (varloc);
	  if (MEM_P (varloc))
	    {
	      rtx addr = XEXP (varloc, 0);
	      descr = mem_loc_descriptor (addr, get_address_mode (varloc),
					  mode, initialized);
	      if (descr)
		have_address = 1;
	      else
		{
		  rtx x = avoid_constant_pool_reference (varloc);
		  if (x != varloc)
		    descr = mem_loc_descriptor (x, mode, VOIDmode,
						initialized);
		}
	    }
	  else
	    descr = mem_loc_descriptor (varloc, mode, VOIDmode, initialized);
	}
      else
	return 0;
    }
  else
    {
      if (GET_CODE (varloc) == VAR_LOCATION)
	mode = DECL_MODE (PAT_VAR_LOCATION_DECL (varloc));
      else
	mode = DECL_MODE (loc);
      descr = loc_descriptor (varloc, mode, initialized);
      have_address = 1;
    }

  if (!descr)
    return 0;

  if (want_address == 2 && !have_address
      && (dwarf_version >= 4 || !dwarf_strict))
    {
      if (int_size_in_bytes (TREE_TYPE (loc)) > DWARF2_ADDR_SIZE)
	{
	  expansion_failed (loc, NULL_RTX,
			    "DWARF address size mismatch");
	  return 0;
	}
      add_loc_descr (&descr, new_loc_descr (DW_OP_stack_value, 0, 0));
      have_address = 1;
    }
  /* Show if we can't fill the request for an address.  */
  if (want_address && !have_address)
    {
      expansion_failed (loc, NULL_RTX,
			"Want address and only have value");
      return 0;
    }

  /* If we've got an address and don't want one, dereference.  */
  if (!want_address && have_address)
    {
      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (loc));
      enum dwarf_location_atom op;

      if (size > DWARF2_ADDR_SIZE || size == -1)
	{
	  expansion_failed (loc, NULL_RTX,
			    "DWARF address size mismatch");
	  return 0;
	}
      else if (size == DWARF2_ADDR_SIZE)
	op = DW_OP_deref;
      else
	op = DW_OP_deref_size;

      add_loc_descr (&descr, new_loc_descr (op, size, 0));
    }

  return descr;
}

/* Create a DW_OP_piece or DW_OP_bit_piece for bitsize, or return NULL
   if it is not possible.  */

static dw_loc_descr_ref
new_loc_descr_op_bit_piece (HOST_WIDE_INT bitsize, HOST_WIDE_INT offset)
{
  if ((bitsize % BITS_PER_UNIT) == 0 && offset == 0)
    return new_loc_descr (DW_OP_piece, bitsize / BITS_PER_UNIT, 0);
  else if (dwarf_version >= 3 || !dwarf_strict)
    return new_loc_descr (DW_OP_bit_piece, bitsize, offset);
  else
    return NULL;
}

/* Helper function for dw_loc_list.  Compute proper Dwarf location descriptor
   for VAR_LOC_NOTE for variable DECL that has been optimized by SRA.  */

static dw_loc_descr_ref
dw_sra_loc_expr (tree decl, rtx loc)
{
  rtx p;
  unsigned HOST_WIDE_INT padsize = 0;
  dw_loc_descr_ref descr, *descr_tail;
  unsigned HOST_WIDE_INT decl_size;
  rtx varloc;
  enum var_init_status initialized;

  if (DECL_SIZE (decl) == NULL
      || !tree_fits_uhwi_p (DECL_SIZE (decl)))
    return NULL;

  decl_size = tree_to_uhwi (DECL_SIZE (decl));
  descr = NULL;
  descr_tail = &descr;

  for (p = loc; p; p = XEXP (p, 1))
    {
      unsigned HOST_WIDE_INT bitsize = decl_piece_bitsize (p);
      rtx loc_note = *decl_piece_varloc_ptr (p);
      dw_loc_descr_ref cur_descr;
      dw_loc_descr_ref *tail, last = NULL;
      unsigned HOST_WIDE_INT opsize = 0;

      if (loc_note == NULL_RTX
	  || NOTE_VAR_LOCATION_LOC (loc_note) == NULL_RTX)
	{
	  padsize += bitsize;
	  continue;
	}
      initialized = NOTE_VAR_LOCATION_STATUS (loc_note);
      varloc = NOTE_VAR_LOCATION (loc_note);
      cur_descr = dw_loc_list_1 (decl, varloc, 2, initialized);
      if (cur_descr == NULL)
	{
	  padsize += bitsize;
	  continue;
	}

      /* Check that cur_descr either doesn't use
	 DW_OP_*piece operations, or their sum is equal
	 to bitsize.  Otherwise we can't embed it.  */
      for (tail = &cur_descr; *tail != NULL;
	   tail = &(*tail)->dw_loc_next)
	if ((*tail)->dw_loc_opc == DW_OP_piece)
	  {
	    opsize += (*tail)->dw_loc_oprnd1.v.val_unsigned
		      * BITS_PER_UNIT;
	    last = *tail;
	  }
	else if ((*tail)->dw_loc_opc == DW_OP_bit_piece)
	  {
	    opsize += (*tail)->dw_loc_oprnd1.v.val_unsigned;
	    last = *tail;
	  }

      if (last != NULL && opsize != bitsize)
	{
	  padsize += bitsize;
	  /* Discard the current piece of the descriptor and release any
	     addr_table entries it uses.  */
	  remove_loc_list_addr_table_entries (cur_descr);
	  continue;
	}

      /* If there is a hole, add DW_OP_*piece after empty DWARF
	 expression, which means that those bits are optimized out.  */
      if (padsize)
	{
	  if (padsize > decl_size)
	    {
	      remove_loc_list_addr_table_entries (cur_descr);
	      goto discard_descr;
	    }
	  decl_size -= padsize;
	  *descr_tail = new_loc_descr_op_bit_piece (padsize, 0);
	  if (*descr_tail == NULL)
	    {
	      remove_loc_list_addr_table_entries (cur_descr);
	      goto discard_descr;
	    }
	  descr_tail = &(*descr_tail)->dw_loc_next;
	  padsize = 0;
	}
      *descr_tail = cur_descr;
      descr_tail = tail;
      if (bitsize > decl_size)
	goto discard_descr;
      decl_size -= bitsize;
      if (last == NULL)
	{
	  HOST_WIDE_INT offset = 0;
	  if (GET_CODE (varloc) == VAR_LOCATION
	      && GET_CODE (PAT_VAR_LOCATION_LOC (varloc)) != PARALLEL)
	    {
	      varloc = PAT_VAR_LOCATION_LOC (varloc);
	      if (GET_CODE (varloc) == EXPR_LIST)
		varloc = XEXP (varloc, 0);
	    }
	  do 
	    {
	      if (GET_CODE (varloc) == CONST
		  || GET_CODE (varloc) == SIGN_EXTEND
		  || GET_CODE (varloc) == ZERO_EXTEND)
		varloc = XEXP (varloc, 0);
	      else if (GET_CODE (varloc) == SUBREG)
		varloc = SUBREG_REG (varloc);
	      else
		break;
	    }
	  while (1);
	  /* DW_OP_bit_size offset should be zero for register
	     or implicit location descriptions and empty location
	     descriptions, but for memory addresses needs big endian
	     adjustment.  */
	  if (MEM_P (varloc))
	    {
	      unsigned HOST_WIDE_INT memsize;
	      if (!poly_uint64 (MEM_SIZE (varloc)).is_constant (&memsize))
		goto discard_descr;
	      memsize *= BITS_PER_UNIT;
	      if (memsize != bitsize)
		{
		  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
		      && (memsize > BITS_PER_WORD || bitsize > BITS_PER_WORD))
		    goto discard_descr;
		  if (memsize < bitsize)
		    goto discard_descr;
		  if (BITS_BIG_ENDIAN)
		    offset = memsize - bitsize;
		}
	    }

	  *descr_tail = new_loc_descr_op_bit_piece (bitsize, offset);
	  if (*descr_tail == NULL)
	    goto discard_descr;
	  descr_tail = &(*descr_tail)->dw_loc_next;
	}
    }

  /* If there were any non-empty expressions, add padding till the end of
     the decl.  */
  if (descr != NULL && decl_size != 0)
    {
      *descr_tail = new_loc_descr_op_bit_piece (decl_size, 0);
      if (*descr_tail == NULL)
	goto discard_descr;
    }
  return descr;

discard_descr:
  /* Discard the descriptor and release any addr_table entries it uses.  */
  remove_loc_list_addr_table_entries (descr);
  return NULL;
}

/* Return the dwarf representation of the location list LOC_LIST of
   DECL.  WANT_ADDRESS has the same meaning as in loc_list_from_tree
   function.  */

static dw_loc_list_ref
dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
{
  const char *endname, *secname;
  var_loc_view endview;
  rtx varloc;
  enum var_init_status initialized;
  struct var_loc_node *node;
  dw_loc_descr_ref descr;
  char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
  dw_loc_list_ref list = NULL;
  dw_loc_list_ref *listp = &list;

  /* Now that we know what section we are using for a base,
     actually construct the list of locations.
     The first location information is what is passed to the
     function that creates the location list, and the remaining
     locations just get added on to that list.
     Note that we only know the start address for a location
     (IE location changes), so to build the range, we use
     the range [current location start, next location start].
     This means we have to special case the last node, and generate
     a range of [last location start, end of function label].  */

  if (cfun && crtl->has_bb_partition)
    {
      bool save_in_cold_section_p = in_cold_section_p;
      in_cold_section_p = first_function_block_is_cold;
      if (loc_list->last_before_switch == NULL)
	in_cold_section_p = !in_cold_section_p;
      secname = secname_for_decl (decl);
      in_cold_section_p = save_in_cold_section_p;
    }
  else
    secname = secname_for_decl (decl);

  for (node = loc_list->first; node; node = node->next)
    {
      bool range_across_switch = false;
      if (GET_CODE (node->loc) == EXPR_LIST
	  || NOTE_VAR_LOCATION_LOC (node->loc) != NULL_RTX)
	{
	  if (GET_CODE (node->loc) == EXPR_LIST)
	    {
	      descr = NULL;
	      /* This requires DW_OP_{,bit_}piece, which is not usable
		 inside DWARF expressions.  */
	      if (want_address == 2)
		descr = dw_sra_loc_expr (decl, node->loc);
	    }
	  else
	    {
	      initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
	      varloc = NOTE_VAR_LOCATION (node->loc);
	      descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
	    }
	  if (descr)
	    {
	      /* If section switch happens in between node->label
		 and node->next->label (or end of function) and
		 we can't emit it as a single entry list,
		 emit two ranges, first one ending at the end
		 of first partition and second one starting at the
		 beginning of second partition.  */
	      if (node == loc_list->last_before_switch
		  && (node != loc_list->first || loc_list->first->next
		      /* If we are to emit a view number, we will emit
			 a loclist rather than a single location
			 expression for the entire function (see
			 loc_list_has_views), so we have to split the
			 range that straddles across partitions.  */
		      || !ZERO_VIEW_P (node->view))
		  && current_function_decl)
		{
		  endname = cfun->fde->dw_fde_end;
		  endview = 0;
		  range_across_switch = true;
		}
	      /* The variable has a location between NODE->LABEL and
		 NODE->NEXT->LABEL.  */
	      else if (node->next)
		endname = node->next->label, endview = node->next->view;
	      /* If the variable has a location at the last label
		 it keeps its location until the end of function.  */
	      else if (!current_function_decl)
		endname = text_end_label, endview = 0;
	      else
		{
		  ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
					       current_function_funcdef_no);
		  endname = ggc_strdup (label_id);
		  endview = 0;
		}

	      *listp = new_loc_list (descr, node->label, node->view,
				     endname, endview, secname);
	      if (TREE_CODE (decl) == PARM_DECL
		  && node == loc_list->first
		  && NOTE_P (node->loc)
		  && strcmp (node->label, endname) == 0)
		(*listp)->force = true;
	      listp = &(*listp)->dw_loc_next;
	    }
	}

      if (cfun
	  && crtl->has_bb_partition
	  && node == loc_list->last_before_switch)
	{
	  bool save_in_cold_section_p = in_cold_section_p;
	  in_cold_section_p = !first_function_block_is_cold;
	  secname = secname_for_decl (decl);
	  in_cold_section_p = save_in_cold_section_p;
	}

      if (range_across_switch)
	{
	  if (GET_CODE (node->loc) == EXPR_LIST)
	    descr = dw_sra_loc_expr (decl, node->loc);
	  else
	    {
	      initialized = NOTE_VAR_LOCATION_STATUS (node->loc);
	      varloc = NOTE_VAR_LOCATION (node->loc);
	      descr = dw_loc_list_1 (decl, varloc, want_address,
				     initialized);
	    }
	  gcc_assert (descr);
	  /* The variable has a location between NODE->LABEL and
	     NODE->NEXT->LABEL.  */
	  if (node->next)
	    endname = node->next->label, endview = node->next->view;
	  else
	    endname = cfun->fde->dw_fde_second_end, endview = 0;
	  *listp = new_loc_list (descr, cfun->fde->dw_fde_second_begin, 0,
				 endname, endview, secname);
	  listp = &(*listp)->dw_loc_next;
	}
    }

  /* Try to avoid the overhead of a location list emitting a location
     expression instead, but only if we didn't have more than one
     location entry in the first place.  If some entries were not
     representable, we don't want to pretend a single entry that was
     applies to the entire scope in which the variable is
     available.  */
  if (list && loc_list->first->next)
    gen_llsym (list);
  else
    maybe_gen_llsym (list);

  return list;
}

/* Return if the loc_list has only single element and thus can be represented
   as location description.   */

static bool
single_element_loc_list_p (dw_loc_list_ref list)
{
  gcc_assert (!list->dw_loc_next || list->ll_symbol);
  return !list->ll_symbol;
}

/* Duplicate a single element of location list.  */

static inline dw_loc_descr_ref
copy_loc_descr (dw_loc_descr_ref ref)
{
  dw_loc_descr_ref copy = ggc_alloc<dw_loc_descr_node> ();
  memcpy (copy, ref, sizeof (dw_loc_descr_node));
  return copy;
}

/* To each location in list LIST append loc descr REF.  */

static void
add_loc_descr_to_each (dw_loc_list_ref list, dw_loc_descr_ref ref)
{
  dw_loc_descr_ref copy;
  add_loc_descr (&list->expr, ref);
  list = list->dw_loc_next;
  while (list)
    {
      copy = copy_loc_descr (ref);
      add_loc_descr (&list->expr, copy);
      while (copy->dw_loc_next)
	copy = copy->dw_loc_next = copy_loc_descr (copy->dw_loc_next);
      list = list->dw_loc_next;
    }
}

/* To each location in list LIST prepend loc descr REF.  */

static void
prepend_loc_descr_to_each (dw_loc_list_ref list, dw_loc_descr_ref ref)
{
  dw_loc_descr_ref copy;
  dw_loc_descr_ref ref_end = list->expr;
  add_loc_descr (&ref, list->expr);
  list->expr = ref;
  list = list->dw_loc_next;
  while (list)
    {
      dw_loc_descr_ref end = list->expr;
      list->expr = copy = copy_loc_descr (ref);
      while (copy->dw_loc_next != ref_end)
	copy = copy->dw_loc_next = copy_loc_descr (copy->dw_loc_next);
      copy->dw_loc_next = end;
      list = list->dw_loc_next;
    }
}

/* Given two lists RET and LIST
   produce location list that is result of adding expression in LIST
   to expression in RET on each position in program.
   Might be destructive on both RET and LIST.

   TODO: We handle only simple cases of RET or LIST having at most one
   element.  General case would involve sorting the lists in program order
   and merging them that will need some additional work.
   Adding that will improve quality of debug info especially for SRA-ed
   structures.  */

static void
add_loc_list (dw_loc_list_ref *ret, dw_loc_list_ref list)
{
  if (!list)
    return;
  if (!*ret)
    {
      *ret = list;
      return;
    }
  if (!list->dw_loc_next)
    {
      add_loc_descr_to_each (*ret, list->expr);
      return;
    }
  if (!(*ret)->dw_loc_next)
    {
      prepend_loc_descr_to_each (list, (*ret)->expr);
      *ret = list;
      return;
    }
  expansion_failed (NULL_TREE, NULL_RTX,
		    "Don't know how to merge two non-trivial"
		    " location lists.\n");
  *ret = NULL;
  return;
}

/* LOC is constant expression.  Try a luck, look it up in constant
   pool and return its loc_descr of its address.  */

static dw_loc_descr_ref
cst_pool_loc_descr (tree loc)
{
  /* Get an RTL for this, if something has been emitted.  */
  rtx rtl = lookup_constant_def (loc);

  if (!rtl || !MEM_P (rtl))
    {
      gcc_assert (!rtl);
      return 0;
    }
  gcc_assert (GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF);

  /* TODO: We might get more coverage if we was actually delaying expansion
     of all expressions till end of compilation when constant pools are fully
     populated.  */
  if (!TREE_ASM_WRITTEN (SYMBOL_REF_DECL (XEXP (rtl, 0))))
    {
      expansion_failed (loc, NULL_RTX,
			"CST value in contant pool but not marked.");
      return 0;
    }
  return mem_loc_descriptor (XEXP (rtl, 0), get_address_mode (rtl),
			     GET_MODE (rtl), VAR_INIT_STATUS_INITIALIZED);
}

/* Return dw_loc_list representing address of addr_expr LOC
   by looking for inner INDIRECT_REF expression and turning
   it into simple arithmetics.

   See loc_list_from_tree for the meaning of CONTEXT.  */

static dw_loc_list_ref
loc_list_for_address_of_addr_expr_of_indirect_ref (tree loc, bool toplev,
						   loc_descr_context *context)
{
  tree obj, offset;
  poly_int64 bitsize, bitpos, bytepos;
  machine_mode mode;
  int unsignedp, reversep, volatilep = 0;
  dw_loc_list_ref list_ret = NULL, list_ret1 = NULL;

  obj = get_inner_reference (TREE_OPERAND (loc, 0),
			     &bitsize, &bitpos, &offset, &mode,
			     &unsignedp, &reversep, &volatilep);
  STRIP_NOPS (obj);
  if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos))
    {
      expansion_failed (loc, NULL_RTX, "bitfield access");
      return 0;
    }
  if (!INDIRECT_REF_P (obj))
    {
      expansion_failed (obj,
			NULL_RTX, "no indirect ref in inner refrence");
      return 0;
    }
  if (!offset && known_eq (bitpos, 0))
    list_ret = loc_list_from_tree (TREE_OPERAND (obj, 0), toplev ? 2 : 1,
				   context);
  else if (toplev
	   && int_size_in_bytes (TREE_TYPE (loc)) <= DWARF2_ADDR_SIZE
	   && (dwarf_version >= 4 || !dwarf_strict))
    {
      list_ret = loc_list_from_tree (TREE_OPERAND (obj, 0), 0, context);
      if (!list_ret)
	return 0;
      if (offset)
	{
	  /* Variable offset.  */
	  list_ret1 = loc_list_from_tree (offset, 0, context);
	  if (list_ret1 == 0)
	    return 0;
	  add_loc_list (&list_ret, list_ret1);
	  if (!list_ret)
	    return 0;
	  add_loc_descr_to_each (list_ret,
				 new_loc_descr (DW_OP_plus, 0, 0));
	}
      HOST_WIDE_INT value;
      if (bytepos.is_constant (&value) && value > 0)
	add_loc_descr_to_each (list_ret,
			       new_loc_descr (DW_OP_plus_uconst, value, 0));
      else if (maybe_ne (bytepos, 0))
	loc_list_plus_const (list_ret, bytepos);
      add_loc_descr_to_each (list_ret,
			     new_loc_descr (DW_OP_stack_value, 0, 0));
    }
  return list_ret;
}

/* Set LOC to the next operation that is not a DW_OP_nop operation. In the case
   all operations from LOC are nops, move to the last one.  Insert in NOPS all
   operations that are skipped.  */

static void
loc_descr_to_next_no_nop (dw_loc_descr_ref &loc,
			  hash_set<dw_loc_descr_ref> &nops)
{
  while (loc->dw_loc_next != NULL && loc->dw_loc_opc == DW_OP_nop)
    {
      nops.add (loc);
      loc = loc->dw_loc_next;
    }
}

/* Helper for loc_descr_without_nops: free the location description operation
   P.  */

bool
free_loc_descr (const dw_loc_descr_ref &loc, void *data ATTRIBUTE_UNUSED)
{
  ggc_free (loc);
  return true;
}

/* Remove all DW_OP_nop operations from LOC except, if it exists, the one that
   finishes LOC.  */

static void
loc_descr_without_nops (dw_loc_descr_ref &loc)
{
  if (loc->dw_loc_opc == DW_OP_nop && loc->dw_loc_next == NULL)
    return;

  /* Set of all DW_OP_nop operations we remove.  */
  hash_set<dw_loc_descr_ref> nops;

  /* First, strip all prefix NOP operations in order to keep the head of the
     operations list.  */
  loc_descr_to_next_no_nop (loc, nops);

  for (dw_loc_descr_ref cur = loc; cur != NULL;)
    {
      /* For control flow operations: strip "prefix" nops in destination
	 labels.  */
      if (cur->dw_loc_oprnd1.val_class == dw_val_class_loc)
	loc_descr_to_next_no_nop (cur->dw_loc_oprnd1.v.val_loc, nops);
      if (cur->dw_loc_oprnd2.val_class == dw_val_class_loc)
	loc_descr_to_next_no_nop (cur->dw_loc_oprnd2.v.val_loc, nops);

      /* Do the same for the operations that follow, then move to the next
	 iteration.  */
      if (cur->dw_loc_next != NULL)
	loc_descr_to_next_no_nop (cur->dw_loc_next, nops);
      cur = cur->dw_loc_next;
    }

  nops.traverse<void *, free_loc_descr> (NULL);
}


struct dwarf_procedure_info;

/* Helper structure for location descriptions generation.  */
struct loc_descr_context
{
  /* The type that is implicitly referenced by DW_OP_push_object_address, or
     NULL_TREE if DW_OP_push_object_address in invalid for this location
     description.  This is used when processing PLACEHOLDER_EXPR nodes.  */
  tree context_type;
  /* The ..._DECL node that should be translated as a
     DW_OP_push_object_address operation.  */
  tree base_decl;
  /* Information about the DWARF procedure we are currently generating. NULL if
     we are not generating a DWARF procedure.  */
  struct dwarf_procedure_info *dpi;
  /* True if integral PLACEHOLDER_EXPR stands for the first argument passed
     by consumer.  Used for DW_TAG_generic_subrange attributes.  */
  bool placeholder_arg;
  /* True if PLACEHOLDER_EXPR has been seen.  */
  bool placeholder_seen;
  /* True if strict preservation of signedness has been requested.  */
  bool strict_signedness;
};

/* DWARF procedures generation

   DWARF expressions (aka. location descriptions) are used to encode variable
   things such as sizes or offsets.  Such computations can have redundant parts
   that can be factorized in order to reduce the size of the output debug
   information.  This is the whole point of DWARF procedures.

   Thanks to stor-layout.c, size and offset expressions in GENERIC trees are
   already factorized into functions ("size functions") in order to handle very
   big and complex types.  Such functions are quite simple: they have integral
   arguments, they return an integral result and their body contains only a
   return statement with arithmetic expressions.  This is the only kind of
   function we are interested in translating into DWARF procedures, here.

   DWARF expressions and DWARF procedure are executed using a stack, so we have
   to define some calling convention for them to interact.  Let's say that:

   - Before calling a DWARF procedure, DWARF expressions must push on the stack
     all arguments in reverse order (right-to-left) so that when the DWARF
     procedure execution starts, the first argument is the top of the stack.

   - Then, when returning, the DWARF procedure must have consumed all arguments
     on the stack, must have pushed the result and touched nothing else.

   - Each integral argument and the result are integral types can be hold in a
     single stack slot.

   - We call "frame offset" the number of stack slots that are "under DWARF
     procedure control": it includes the arguments slots, the temporaries and
     the result slot. Thus, it is equal to the number of arguments when the
     procedure execution starts and must be equal to one (the result) when it
     returns.  */

/* Helper structure used when generating operations for a DWARF procedure.  */
struct dwarf_procedure_info
{
  /* The FUNCTION_DECL node corresponding to the DWARF procedure that is
     currently translated.  */
  tree fndecl;
  /* The number of arguments FNDECL takes.  */
  unsigned args_count;
};

/* Return a pointer to a newly created DIE node for a DWARF procedure.  Add
   LOCATION as its DW_AT_location attribute.  If FNDECL is not NULL_TREE,
   equate it to this DIE.  */

static dw_die_ref
new_dwarf_proc_die (dw_loc_descr_ref location, tree fndecl,
		    dw_die_ref parent_die)
{
  dw_die_ref dwarf_proc_die;

  if ((dwarf_version < 3 && dwarf_strict)
      || location == NULL)
    return NULL;

  dwarf_proc_die = new_die (DW_TAG_dwarf_procedure, parent_die, fndecl);
  if (fndecl)
    equate_decl_number_to_die (fndecl, dwarf_proc_die);
  add_AT_loc (dwarf_proc_die, DW_AT_location, location);
  return dwarf_proc_die;
}

/* Return whether TYPE is a supported type as a DWARF procedure argument
   type or return type (we handle only scalar types and pointer types that
   aren't wider than the DWARF expression evaluation stack).  */

static bool
is_handled_procedure_type (tree type)
{
  return ((INTEGRAL_TYPE_P (type)
	   || TREE_CODE (type) == OFFSET_TYPE
	   || TREE_CODE (type) == POINTER_TYPE)
	  && int_size_in_bytes (type) <= DWARF2_ADDR_SIZE);
}

/* Helper for resolve_args_picking: do the same but stop when coming across
   visited nodes.  For each node we visit, register in FRAME_OFFSETS the frame
   offset *before* evaluating the corresponding operation.  */

static bool
resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
			struct dwarf_procedure_info *dpi,
			hash_map<dw_loc_descr_ref, unsigned> &frame_offsets)
{
  /* The "frame_offset" identifier is already used to name a macro... */
  unsigned frame_offset_ = initial_frame_offset;
  dw_loc_descr_ref l;

  for (l = loc; l != NULL;)
    {
      bool existed;
      unsigned &l_frame_offset = frame_offsets.get_or_insert (l, &existed);

      /* If we already met this node, there is nothing to compute anymore.  */
      if (existed)
	{
	  /* Make sure that the stack size is consistent wherever the execution
	     flow comes from.  */
	  gcc_assert ((unsigned) l_frame_offset == frame_offset_);
	  break;
	}
      l_frame_offset = frame_offset_;

      /* If needed, relocate the picking offset with respect to the frame
	 offset. */
      if (l->frame_offset_rel)
	{
	  unsigned HOST_WIDE_INT off;
	  switch (l->dw_loc_opc)
	    {
	    case DW_OP_pick:
	      off = l->dw_loc_oprnd1.v.val_unsigned;
	      break;
	    case DW_OP_dup:
	      off = 0;
	      break;
	    case DW_OP_over:
	      off = 1;
	      break;
	    default:
	      gcc_unreachable ();
	    }
	  /* frame_offset_ is the size of the current stack frame, including
	     incoming arguments. Besides, the arguments are pushed
	     right-to-left.  Thus, in order to access the Nth argument from
	     this operation node, the picking has to skip temporaries *plus*
	     one stack slot per argument (0 for the first one, 1 for the second
	     one, etc.).

	     The targetted argument number (N) is already set as the operand,
	     and the number of temporaries can be computed with:
	       frame_offsets_ - dpi->args_count */
	  off += frame_offset_ - dpi->args_count;

	  /* DW_OP_pick handles only offsets from 0 to 255 (inclusive)...  */
	  if (off > 255)
	    return false;

	  if (off == 0)
	    {
	      l->dw_loc_opc = DW_OP_dup;
	      l->dw_loc_oprnd1.v.val_unsigned = 0;
	    }
	  else if (off == 1)
	    {
	      l->dw_loc_opc = DW_OP_over;
	      l->dw_loc_oprnd1.v.val_unsigned = 0;
	    }
	  else
	    {
	      l->dw_loc_opc = DW_OP_pick;
	      l->dw_loc_oprnd1.v.val_unsigned = off;
	    }
	}

      /* Update frame_offset according to the effect the current operation has
	 on the stack.  */
      switch (l->dw_loc_opc)
	{
	case DW_OP_deref:
	case DW_OP_swap:
	case DW_OP_rot:
	case DW_OP_abs:
	case DW_OP_neg:
	case DW_OP_not:
	case DW_OP_plus_uconst:
	case DW_OP_skip:
	case DW_OP_reg0:
	case DW_OP_reg1:
	case DW_OP_reg2:
	case DW_OP_reg3:
	case DW_OP_reg4:
	case DW_OP_reg5:
	case DW_OP_reg6:
	case DW_OP_reg7:
	case DW_OP_reg8:
	case DW_OP_reg9:
	case DW_OP_reg10:
	case DW_OP_reg11:
	case DW_OP_reg12:
	case DW_OP_reg13:
	case DW_OP_reg14:
	case DW_OP_reg15:
	case DW_OP_reg16:
	case DW_OP_reg17:
	case DW_OP_reg18:
	case DW_OP_reg19:
	case DW_OP_reg20:
	case DW_OP_reg21:
	case DW_OP_reg22:
	case DW_OP_reg23:
	case DW_OP_reg24:
	case DW_OP_reg25:
	case DW_OP_reg26:
	case DW_OP_reg27:
	case DW_OP_reg28:
	case DW_OP_reg29:
	case DW_OP_reg30:
	case DW_OP_reg31:
	case DW_OP_bregx:
	case DW_OP_piece:
	case DW_OP_deref_size:
	case DW_OP_nop:
	case DW_OP_bit_piece:
	case DW_OP_implicit_value:
	case DW_OP_stack_value:
	case DW_OP_deref_type:
	case DW_OP_convert:
	case DW_OP_reinterpret:
	case DW_OP_GNU_deref_type:
	case DW_OP_GNU_convert:
	case DW_OP_GNU_reinterpret:
	  break;

	case DW_OP_addr:
	case DW_OP_const1u:
	case DW_OP_const1s:
	case DW_OP_const2u:
	case DW_OP_const2s:
	case DW_OP_const4u:
	case DW_OP_const4s:
	case DW_OP_const8u:
	case DW_OP_const8s:
	case DW_OP_constu:
	case DW_OP_consts:
	case DW_OP_dup:
	case DW_OP_over:
	case DW_OP_pick:
	case DW_OP_lit0:
	case DW_OP_lit1:
	case DW_OP_lit2:
	case DW_OP_lit3:
	case DW_OP_lit4:
	case DW_OP_lit5:
	case DW_OP_lit6:
	case DW_OP_lit7:
	case DW_OP_lit8:
	case DW_OP_lit9:
	case DW_OP_lit10:
	case DW_OP_lit11:
	case DW_OP_lit12:
	case DW_OP_lit13:
	case DW_OP_lit14:
	case DW_OP_lit15:
	case DW_OP_lit16:
	case DW_OP_lit17:
	case DW_OP_lit18:
	case DW_OP_lit19:
	case DW_OP_lit20:
	case DW_OP_lit21:
	case DW_OP_lit22:
	case DW_OP_lit23:
	case DW_OP_lit24:
	case DW_OP_lit25:
	case DW_OP_lit26:
	case DW_OP_lit27:
	case DW_OP_lit28:
	case DW_OP_lit29:
	case DW_OP_lit30:
	case DW_OP_lit31:
	case DW_OP_breg0:
	case DW_OP_breg1:
	case DW_OP_breg2:
	case DW_OP_breg3:
	case DW_OP_breg4:
	case DW_OP_breg5:
	case DW_OP_breg6:
	case DW_OP_breg7:
	case DW_OP_breg8:
	case DW_OP_breg9:
	case DW_OP_breg10:
	case DW_OP_breg11:
	case DW_OP_breg12:
	case DW_OP_breg13:
	case DW_OP_breg14:
	case DW_OP_breg15:
	case DW_OP_breg16:
	case DW_OP_breg17:
	case DW_OP_breg18:
	case DW_OP_breg19:
	case DW_OP_breg20:
	case DW_OP_breg21:
	case DW_OP_breg22:
	case DW_OP_breg23:
	case DW_OP_breg24:
	case DW_OP_breg25:
	case DW_OP_breg26:
	case DW_OP_breg27:
	case DW_OP_breg28:
	case DW_OP_breg29:
	case DW_OP_breg30:
	case DW_OP_breg31:
	case DW_OP_fbreg:
	case DW_OP_push_object_address:
	case DW_OP_call_frame_cfa:
	case DW_OP_GNU_variable_value:
	case DW_OP_GNU_addr_index:
	case DW_OP_GNU_const_index:
	  ++frame_offset_;
	  break;

	case DW_OP_drop:
	case DW_OP_xderef:
	case DW_OP_and:
	case DW_OP_div:
	case DW_OP_minus:
	case DW_OP_mod:
	case DW_OP_mul:
	case DW_OP_or:
	case DW_OP_plus:
	case DW_OP_shl:
	case DW_OP_shr:
	case DW_OP_shra:
	case DW_OP_xor:
	case DW_OP_bra:
	case DW_OP_eq:
	case DW_OP_ge:
	case DW_OP_gt:
	case DW_OP_le:
	case DW_OP_lt:
	case DW_OP_ne:
	case DW_OP_regx:
	case DW_OP_xderef_size:
	  --frame_offset_;
	  break;

	case DW_OP_call2:
	case DW_OP_call4:
	case DW_OP_call_ref:
	  {
	    dw_die_ref dwarf_proc = l->dw_loc_oprnd1.v.val_die_ref.die;
	    int *stack_usage = dwarf_proc_stack_usage_map->get (dwarf_proc);

	    if (stack_usage == NULL)
	      return false;
	    frame_offset_ += *stack_usage;
	    break;
	  }

	case DW_OP_implicit_pointer:
	case DW_OP_entry_value:
	case DW_OP_const_type:
	case DW_OP_regval_type:
	case DW_OP_form_tls_address:
	case DW_OP_GNU_push_tls_address:
	case DW_OP_GNU_uninit:
	case DW_OP_GNU_encoded_addr:
	case DW_OP_GNU_implicit_pointer:
	case DW_OP_GNU_entry_value:
	case DW_OP_GNU_const_type:
	case DW_OP_GNU_regval_type:
	case DW_OP_GNU_parameter_ref:
	  /* loc_list_from_tree will probably not output these operations for
	     size functions, so assume they will not appear here.  */
	  /* Fall through...  */

	default:
	  gcc_unreachable ();
	}

      /* Now, follow the control flow (except subroutine calls).  */
      switch (l->dw_loc_opc)
	{
	case DW_OP_bra:
	  if (!resolve_args_picking_1 (l->dw_loc_next, frame_offset_, dpi,
				       frame_offsets))
	    return false;
	  /* Fall through. */

	case DW_OP_skip:
	  l = l->dw_loc_oprnd1.v.val_loc;
	  break;

	case DW_OP_stack_value:
	  return true;

	default:
	  l = l->dw_loc_next;
	  break;
	}
    }

  return true;
}

/* Make a DFS over operations reachable through LOC (i.e. follow branch
   operations) in order to resolve the operand of DW_OP_pick operations that
   target DWARF procedure arguments (DPI).  INITIAL_FRAME_OFFSET is the frame
   offset *before* LOC is executed.  Return if all relocations were
   successful.  */

static bool
resolve_args_picking (dw_loc_descr_ref loc, unsigned initial_frame_offset,
		      struct dwarf_procedure_info *dpi)
{
  /* Associate to all visited operations the frame offset *before* evaluating
     this operation.  */
  hash_map<dw_loc_descr_ref, unsigned> frame_offsets;

  return
    resolve_args_picking_1 (loc, initial_frame_offset, dpi, frame_offsets);
}

/* Try to generate a DWARF procedure that computes the same result as FNDECL.
   Return NULL if it is not possible.  */

static dw_die_ref
function_to_dwarf_procedure (tree fndecl)
{
  struct dwarf_procedure_info dpi;
  struct loc_descr_context ctx = {
    NULL_TREE,	/* context_type */
    NULL_TREE,	/* base_decl */
    &dpi,	/* dpi */
    false,      /* placeholder_arg */
    false,      /* placeholder_seen */
    true	/* strict_signedness */
  };
  dw_die_ref dwarf_proc_die;
  tree tree_body = DECL_SAVED_TREE (fndecl);
  dw_loc_descr_ref loc_body, epilogue;

  tree cursor;
  unsigned i;

  /* Do not generate multiple DWARF procedures for the same function
     declaration.  */
  dwarf_proc_die = lookup_decl_die (fndecl);
  if (dwarf_proc_die != NULL)
    return dwarf_proc_die;

  /* DWARF procedures are available starting with the DWARFv3 standard.  */
  if (dwarf_version < 3 && dwarf_strict)
    return NULL;

  /* We handle only functions for which we still have a body, that return a
     supported type and that takes arguments with supported types.  Note that
     there is no point translating functions that return nothing.  */
  if (tree_body == NULL_TREE
      || DECL_RESULT (fndecl) == NULL_TREE
      || !is_handled_procedure_type (TREE_TYPE (DECL_RESULT (fndecl))))
    return NULL;

  for (cursor = DECL_ARGUMENTS (fndecl);
       cursor != NULL_TREE;
       cursor = TREE_CHAIN (cursor))
    if (!is_handled_procedure_type (TREE_TYPE (cursor)))
      return NULL;

  /* Match only "expr" in: RETURN_EXPR (MODIFY_EXPR (RESULT_DECL, expr)).  */
  if (TREE_CODE (tree_body) != RETURN_EXPR)
    return NULL;
  tree_body = TREE_OPERAND (tree_body, 0);
  if (TREE_CODE (tree_body) != MODIFY_EXPR
      || TREE_OPERAND (tree_body, 0) != DECL_RESULT (fndecl))
    return NULL;
  tree_body = TREE_OPERAND (tree_body, 1);

  /* Try to translate the body expression itself.  Note that this will probably
     cause an infinite recursion if its call graph has a cycle.  This is very
     unlikely for size functions, however, so don't bother with such things at
     the moment.  */
  dpi.fndecl = fndecl;
  dpi.args_count = list_length (DECL_ARGUMENTS (fndecl));
  loc_body = loc_descriptor_from_tree (tree_body, 0, &ctx);
  if (!loc_body)
    return NULL;

  /* After evaluating all operands in "loc_body", we should still have on the
     stack all arguments plus the desired function result (top of the stack).
     Generate code in order to keep only the result in our stack frame.  */
  epilogue = NULL;
  for (i = 0; i < dpi.args_count; ++i)
    {
      dw_loc_descr_ref op_couple = new_loc_descr (DW_OP_swap, 0, 0);
      op_couple->dw_loc_next = new_loc_descr (DW_OP_drop, 0, 0);
      op_couple->dw_loc_next->dw_loc_next = epilogue;
      epilogue = op_couple;
    }
  add_loc_descr (&loc_body, epilogue);
  if (!resolve_args_picking (loc_body, dpi.args_count, &dpi))
    return NULL;

  /* Trailing nops from loc_descriptor_from_tree (if any) cannot be removed
     because they are considered useful.  Now there is an epilogue, they are
     not anymore, so give it another try.   */
  loc_descr_without_nops (loc_body);

  /* fndecl may be used both as a regular DW_TAG_subprogram DIE and as
     a DW_TAG_dwarf_procedure, so we may have a conflict, here.  It's unlikely,
     though, given that size functions do not come from source, so they should
     not have a dedicated DW_TAG_subprogram DIE.  */
  dwarf_proc_die
    = new_dwarf_proc_die (loc_body, fndecl,
			  get_context_die (DECL_CONTEXT (fndecl)));

  /* The called DWARF procedure consumes one stack slot per argument and
     returns one stack slot.  */
  dwarf_proc_stack_usage_map->put (dwarf_proc_die, 1 - dpi.args_count);

  return dwarf_proc_die;
}

/* Helper function for loc_list_from_tree.  Perform OP binary op,
   but after converting arguments to type_die, afterwards convert
   back to unsigned.  */

static dw_loc_list_ref
typed_binop_from_tree (enum dwarf_location_atom op, tree loc,
		       dw_die_ref type_die, scalar_int_mode mode,
		       struct loc_descr_context *context)
{
  dw_loc_list_ref op0, op1;
  dw_loc_descr_ref cvt, binop;

  if (type_die == NULL)
    return NULL;

  op0 = loc_list_from_tree (TREE_OPERAND (loc, 0), 0, context);
  op1 = loc_list_from_tree (TREE_OPERAND (loc, 1), 0, context);
  if (op0 == NULL || op1 == NULL)
    return NULL;

  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
  add_loc_descr_to_each (op0, cvt);

  cvt = new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0);
  cvt->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
  cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die;
  cvt->dw_loc_oprnd1.v.val_die_ref.external = 0;
  add_loc_descr_to_each (op1, cvt);

  add_loc_list (&op0, op1);
  if (op0 == NULL)
    return NULL;

  binop = new_loc_descr (op, 0, 0);
  convert_descriptor_to_mode (mode, binop);
  add_loc_descr_to_each (op0, binop);

  return op0;
}

/* Generate Dwarf location list representing LOC.
   If WANT_ADDRESS is false, expression computing LOC will be computed
   If WANT_ADDRESS is 1, expression computing address of LOC will be returned
   if WANT_ADDRESS is 2, expression computing address useable in location
     will be returned (i.e. DW_OP_reg can be used
     to refer to register values).

   CONTEXT provides information to customize the location descriptions
   generation.  Its context_type field specifies what type is implicitly
   referenced by DW_OP_push_object_address.  If it is NULL_TREE, this operation
   will not be generated.

   Its DPI field determines whether we are generating a DWARF expression for a
   DWARF procedure, so PARM_DECL references are processed specifically.

   If CONTEXT is NULL, the behavior is the same as if context_type, base_decl
   and dpi fields were null.  */

static dw_loc_list_ref
loc_list_from_tree_1 (tree loc, int want_address,
		      struct loc_descr_context *context)
{
  dw_loc_descr_ref ret = NULL, ret1 = NULL;
  dw_loc_list_ref list_ret = NULL, list_ret1 = NULL;
  int have_address = 0;
  enum dwarf_location_atom op;

  /* ??? Most of the time we do not take proper care for sign/zero
     extending the values properly.  Hopefully this won't be a real
     problem...  */

  if (context != NULL
      && context->base_decl == loc
      && want_address == 0)
    {
      if (dwarf_version >= 3 || !dwarf_strict)
	return new_loc_list (new_loc_descr (DW_OP_push_object_address, 0, 0),
			     NULL, 0, NULL, 0, NULL);
      else
	return NULL;
    }

  switch (TREE_CODE (loc))
    {
    case ERROR_MARK:
      expansion_failed (loc, NULL_RTX, "ERROR_MARK");
      return 0;

    case PLACEHOLDER_EXPR:
      /* This case involves extracting fields from an object to determine the
	 position of other fields. It is supposed to appear only as the first
	 operand of COMPONENT_REF nodes and to reference precisely the type
	 that the context allows or its enclosing type.  */
      if (context != NULL
	  && (TREE_TYPE (loc) == context->context_type
	      || TREE_TYPE (loc) == TYPE_CONTEXT (context->context_type))
	  && want_address >= 1)
	{
	  if (dwarf_version >= 3 || !dwarf_strict)
	    {
	      ret = new_loc_descr (DW_OP_push_object_address, 0, 0);
	      have_address = 1;
	      break;
	    }
	  else
	    return NULL;
	}
      /* For DW_TAG_generic_subrange attributes, PLACEHOLDER_EXPR stands for
	 the single argument passed by consumer.  */
      else if (context != NULL
	       && context->placeholder_arg
	       && INTEGRAL_TYPE_P (TREE_TYPE (loc))
	       && want_address == 0)
	{
	  ret = new_loc_descr (DW_OP_pick, 0, 0);
	  ret->frame_offset_rel = 1;
	  context->placeholder_seen = true;
	  break;
	}
      else
	expansion_failed (loc, NULL_RTX,
			  "PLACEHOLDER_EXPR for an unexpected type");
      break;

    case CALL_EXPR:
	{
	  tree callee = get_callee_fndecl (loc);
	  dw_die_ref dwarf_proc;

	  if (callee
	      && is_handled_procedure_type (TREE_TYPE (TREE_TYPE (callee)))
	      && (dwarf_proc = function_to_dwarf_procedure (callee)))
	    {
	      /* DWARF procedures are used for size functions, which are built
		 when size expressions contain conditional constructs, so we
		 request strict preservation of signedness for comparisons.  */
	      bool old_strict_signedness;
	      if (context)
		{
		  old_strict_signedness = context->strict_signedness;
		  context->strict_signedness = true;
		}

	      /* Evaluate arguments right-to-left so that the first argument
		 will be the top-most one on the stack.  */
	      for (int i = call_expr_nargs (loc) - 1; i >= 0; --i)
		{
		  tree arg = CALL_EXPR_ARG (loc, i);
		  ret1 = loc_descriptor_from_tree (arg, 0, context);
		  if (!ret1)
		    {
		      expansion_failed (arg, NULL_RTX, "CALL_EXPR argument");
		      return NULL;
		    }
		  add_loc_descr (&ret, ret1);
		}

	      ret1 = new_loc_descr (DW_OP_call4, 0, 0);
	      ret1->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	      ret1->dw_loc_oprnd1.v.val_die_ref.die = dwarf_proc;
	      ret1->dw_loc_oprnd1.v.val_die_ref.external = 0;
	      add_loc_descr (&ret, ret1);
	      if (context)
		context->strict_signedness = old_strict_signedness;
	    }
	  else
	    expansion_failed (loc, NULL_RTX, "CALL_EXPR target");
	  break;
	}

    case PREINCREMENT_EXPR:
    case PREDECREMENT_EXPR:
    case POSTINCREMENT_EXPR:
    case POSTDECREMENT_EXPR:
      expansion_failed (loc, NULL_RTX, "PRE/POST INDCREMENT/DECREMENT");
      /* There are no opcodes for these operations.  */
      return 0;

    case ADDR_EXPR:
      /* If we already want an address, see if there is INDIRECT_REF inside
         e.g. for &this->field.  */
      if (want_address)
	{
	  list_ret = loc_list_for_address_of_addr_expr_of_indirect_ref
		       (loc, want_address == 2, context);
	  if (list_ret)
	    have_address = 1;
	  else if (decl_address_ip_invariant_p (TREE_OPERAND (loc, 0))
	  	   && (ret = cst_pool_loc_descr (loc)))
	    have_address = 1;
	}
        /* Otherwise, process the argument and look for the address.  */
      if (!list_ret && !ret)
        list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 1, context);
      else
	{
	  if (want_address)
	    expansion_failed (loc, NULL_RTX, "need address of ADDR_EXPR");
	  return NULL;
	}
      break;

    case VAR_DECL:
      if (DECL_THREAD_LOCAL_P (loc))
	{
	  rtx rtl;
         enum dwarf_location_atom tls_op;
         enum dtprel_bool dtprel = dtprel_false;

	  if (targetm.have_tls)
	    {
	      /* If this is not defined, we have no way to emit the
		 data.  */
	      if (!targetm.asm_out.output_dwarf_dtprel)
		return 0;

	       /* The way DW_OP_GNU_push_tls_address is specified, we
	     	  can only look up addresses of objects in the current
	     	  module.  We used DW_OP_addr as first op, but that's
		  wrong, because DW_OP_addr is relocated by the debug
		  info consumer, while DW_OP_GNU_push_tls_address
		  operand shouldn't be.  */
	      if (DECL_EXTERNAL (loc) && !targetm.binds_local_p (loc))
		return 0;
	      dtprel = dtprel_true;
	      /* We check for DWARF 5 here because gdb did not implement
		 DW_OP_form_tls_address until after 7.12.  */
	      tls_op = (dwarf_version >= 5 ? DW_OP_form_tls_address
			: DW_OP_GNU_push_tls_address);
	    }
	  else
	    {
	      if (!targetm.emutls.debug_form_tls_address
		  || !(dwarf_version >= 3 || !dwarf_strict))
		return 0;
	      /* We stuffed the control variable into the DECL_VALUE_EXPR
		 to signal (via DECL_HAS_VALUE_EXPR_P) that the decl should
		 no longer appear in gimple code.  We used the control
		 variable in specific so that we could pick it up here.  */
	      loc = DECL_VALUE_EXPR (loc);
              tls_op = DW_OP_form_tls_address;
	    }

	  rtl = rtl_for_decl_location (loc);
	  if (rtl == NULL_RTX)
	    return 0;

	  if (!MEM_P (rtl))
	    return 0;
	  rtl = XEXP (rtl, 0);
	  if (! CONSTANT_P (rtl))
	    return 0;

          ret = new_addr_loc_descr (rtl, dtprel);
          ret1 = new_loc_descr (tls_op, 0, 0);
	  add_loc_descr (&ret, ret1);

	  have_address = 1;
	  break;
	}
      /* FALLTHRU */

    case PARM_DECL:
      if (context != NULL && context->dpi != NULL
	  && DECL_CONTEXT (loc) == context->dpi->fndecl)
	{
	  /* We are generating code for a DWARF procedure and we want to access
	     one of its arguments: find the appropriate argument offset and let
	     the resolve_args_picking pass compute the offset that complies
	     with the stack frame size.  */
	  unsigned i = 0;
	  tree cursor;

	  for (cursor = DECL_ARGUMENTS (context->dpi->fndecl);
	       cursor != NULL_TREE && cursor != loc;
	       cursor = TREE_CHAIN (cursor), ++i)
	    ;
	  /* If we are translating a DWARF procedure, all referenced parameters
	     must belong to the current function.  */
	  gcc_assert (cursor != NULL_TREE);

	  ret = new_loc_descr (DW_OP_pick, i, 0);
	  ret->frame_offset_rel = 1;
	  break;
	}
      /* FALLTHRU */

    case RESULT_DECL:
      if (DECL_HAS_VALUE_EXPR_P (loc))
	{
	  tree value_expr = DECL_VALUE_EXPR (loc);

	  /* Non-local frame structures are DECL_IGNORED_P variables so we need
	     to wait until they get an RTX in order to reference them.  */
	  if (early_dwarf
	      && TREE_CODE (value_expr) == COMPONENT_REF
	      && VAR_P (TREE_OPERAND (value_expr, 0))
	      && DECL_NONLOCAL_FRAME (TREE_OPERAND (value_expr, 0)))
	    ;
	  else
	    return loc_list_from_tree_1 (value_expr, want_address, context);
	}

      /* FALLTHRU */

    case FUNCTION_DECL:
      {
	rtx rtl;
	var_loc_list *loc_list = lookup_decl_loc (loc);

	if (loc_list && loc_list->first)
	  {
	    list_ret = dw_loc_list (loc_list, loc, want_address);
	    have_address = want_address != 0;
	    break;
	  }
	rtl = rtl_for_decl_location (loc);
	if (rtl == NULL_RTX)
	  {
	    if (TREE_CODE (loc) != FUNCTION_DECL
		&& early_dwarf
		&& want_address != 1
		&& ! DECL_IGNORED_P (loc)
		&& (INTEGRAL_TYPE_P (TREE_TYPE (loc))
		    || POINTER_TYPE_P (TREE_TYPE (loc)))
		&& (GET_MODE_SIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (loc)))
		    <= DWARF2_ADDR_SIZE))
	      {
		dw_die_ref ref = lookup_decl_die (loc);
		if (ref)
		  {
		    ret = new_loc_descr (DW_OP_GNU_variable_value, 0, 0);
		    ret->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
		    ret->dw_loc_oprnd1.v.val_die_ref.die = ref;
		    ret->dw_loc_oprnd1.v.val_die_ref.external = 0;
		  }
		else if (current_function_decl
			 && DECL_CONTEXT (loc) == current_function_decl)
		  {
		    ret = new_loc_descr (DW_OP_GNU_variable_value, 0, 0);
		    ret->dw_loc_oprnd1.val_class = dw_val_class_decl_ref;
		    ret->dw_loc_oprnd1.v.val_decl_ref = loc;
		  }
		break;
	      }
	    expansion_failed (loc, NULL_RTX, "DECL has no RTL");
	    return 0;
	  }
	else if (CONST_INT_P (rtl))
	  {
	    HOST_WIDE_INT val = INTVAL (rtl);
	    if (TYPE_UNSIGNED (TREE_TYPE (loc)))
	      val &= GET_MODE_MASK (DECL_MODE (loc));
	    ret = int_loc_descriptor (val);
	  }
	else if (GET_CODE (rtl) == CONST_STRING)
	  {
	    expansion_failed (loc, NULL_RTX, "CONST_STRING");
	    return 0;
	  }
	else if (CONSTANT_P (rtl) && const_ok_for_output (rtl))
          ret = new_addr_loc_descr (rtl, dtprel_false);
	else
	  {
	    machine_mode mode, mem_mode;

	    /* Certain constructs can only be represented at top-level.  */
	    if (want_address == 2)
	      {
		ret = loc_descriptor (rtl, VOIDmode,
				      VAR_INIT_STATUS_INITIALIZED);
		have_address = 1;
	      }
	    else
	      {
		mode = GET_MODE (rtl);
		mem_mode = VOIDmode;
		if (MEM_P (rtl))
		  {
		    mem_mode = mode;
		    mode = get_address_mode (rtl);
		    rtl = XEXP (rtl, 0);
		    have_address = 1;
		  }
		ret = mem_loc_descriptor (rtl, mode, mem_mode,
					  VAR_INIT_STATUS_INITIALIZED);
	      }
	    if (!ret)
	      expansion_failed (loc, rtl,
				"failed to produce loc descriptor for rtl");
	  }
      }
      break;

    case MEM_REF:
      if (!integer_zerop (TREE_OPERAND (loc, 1)))
	{
	  have_address = 1;
	  goto do_plus;
	}
      /* Fallthru.  */
    case INDIRECT_REF:
      list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
      have_address = 1;
      break;

    case TARGET_MEM_REF:
    case SSA_NAME:
    case DEBUG_EXPR_DECL:
      return NULL;

    case COMPOUND_EXPR:
      return loc_list_from_tree_1 (TREE_OPERAND (loc, 1), want_address,
				   context);

    CASE_CONVERT:
    case VIEW_CONVERT_EXPR:
    case SAVE_EXPR:
    case MODIFY_EXPR:
    case NON_LVALUE_EXPR:
      return loc_list_from_tree_1 (TREE_OPERAND (loc, 0), want_address,
				   context);

    case COMPONENT_REF:
    case BIT_FIELD_REF:
    case ARRAY_REF:
    case ARRAY_RANGE_REF:
    case REALPART_EXPR:
    case IMAGPART_EXPR:
      {
	tree obj, offset;
	poly_int64 bitsize, bitpos, bytepos;
	machine_mode mode;
	int unsignedp, reversep, volatilep = 0;

	obj = get_inner_reference (loc, &bitsize, &bitpos, &offset, &mode,
				   &unsignedp, &reversep, &volatilep);

	gcc_assert (obj != loc);

	list_ret = loc_list_from_tree_1 (obj,
					 want_address == 2
					 && known_eq (bitpos, 0)
					 && !offset ? 2 : 1,
					 context);
	/* TODO: We can extract value of the small expression via shifting even
	   for nonzero bitpos.  */
	if (list_ret == 0)
	  return 0;
	if (!multiple_p (bitpos, BITS_PER_UNIT, &bytepos)
	    || !multiple_p (bitsize, BITS_PER_UNIT))
	  {
	    expansion_failed (loc, NULL_RTX,
			      "bitfield access");
	    return 0;
	  }

	if (offset != NULL_TREE)
	  {
	    /* Variable offset.  */
	    list_ret1 = loc_list_from_tree_1 (offset, 0, context);
	    if (list_ret1 == 0)
	      return 0;
	    add_loc_list (&list_ret, list_ret1);
	    if (!list_ret)
	      return 0;
	    add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_plus, 0, 0));
	  }

	HOST_WIDE_INT value;
	if (bytepos.is_constant (&value) && value > 0)
	  add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_plus_uconst,
							  value, 0));
	else if (maybe_ne (bytepos, 0))
	  loc_list_plus_const (list_ret, bytepos);

	have_address = 1;
	break;
      }

    case INTEGER_CST:
      if ((want_address || !tree_fits_shwi_p (loc))
	  && (ret = cst_pool_loc_descr (loc)))
	have_address = 1;
      else if (want_address == 2
	       && tree_fits_shwi_p (loc)
	       && (ret = address_of_int_loc_descriptor
	       		   (int_size_in_bytes (TREE_TYPE (loc)),
	       		    tree_to_shwi (loc))))
	have_address = 1;
      else if (tree_fits_shwi_p (loc))
	ret = int_loc_descriptor (tree_to_shwi (loc));
      else if (tree_fits_uhwi_p (loc))
	ret = uint_loc_descriptor (tree_to_uhwi (loc));
      else
	{
	  expansion_failed (loc, NULL_RTX,
			    "Integer operand is not host integer");
	  return 0;
	}
      break;

    case POLY_INT_CST:
      {
	if (want_address)
	  {
	    expansion_failed (loc, NULL_RTX,
			      "constant address with a runtime component");
	    return 0;
	  }
	poly_int64 value;
	if (!poly_int_tree_p (loc, &value))
	  {
	    expansion_failed (loc, NULL_RTX, "constant too big");
	    return 0;
	  }
	ret = int_loc_descriptor (value);
      }
      break;

    case CONSTRUCTOR:
    case REAL_CST:
    case STRING_CST:
    case COMPLEX_CST:
      if ((ret = cst_pool_loc_descr (loc)))
	have_address = 1;
      else if (TREE_CODE (loc) == CONSTRUCTOR)
	{
	  tree type = TREE_TYPE (loc);
	  unsigned HOST_WIDE_INT size = int_size_in_bytes (type);
	  unsigned HOST_WIDE_INT offset = 0;
	  unsigned HOST_WIDE_INT cnt;
	  constructor_elt *ce;

	  if (TREE_CODE (type) == RECORD_TYPE)
	    {
	      /* This is very limited, but it's enough to output
		 pointers to member functions, as long as the
		 referenced function is defined in the current
		 translation unit.  */
	      FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (loc), cnt, ce)
		{
		  tree val = ce->value;

		  tree field = ce->index;

		  if (val)
		    STRIP_NOPS (val);

		  if (!field || DECL_BIT_FIELD (field))
		    {
		      expansion_failed (loc, NULL_RTX,
					"bitfield in record type constructor");
		      size = offset = (unsigned HOST_WIDE_INT)-1;
		      ret = NULL;
		      break;
		    }

		  HOST_WIDE_INT fieldsize = tree_to_shwi (DECL_SIZE_UNIT (field));
		  unsigned HOST_WIDE_INT pos = int_byte_position (field);
		  gcc_assert (pos + fieldsize <= size);
		  if (pos < offset)
		    {
		      expansion_failed (loc, NULL_RTX,
					"out-of-order fields in record constructor");
		      size = offset = (unsigned HOST_WIDE_INT)-1;
		      ret = NULL;
		      break;
		    }
		  if (pos > offset)
		    {
		      ret1 = new_loc_descr (DW_OP_piece, pos - offset, 0);
		      add_loc_descr (&ret, ret1);
		      offset = pos;
		    }
		  if (val && fieldsize != 0)
		    {
		      ret1 = loc_descriptor_from_tree (val, want_address, context);
		      if (!ret1)
			{
			  expansion_failed (loc, NULL_RTX,
					    "unsupported expression in field");
			  size = offset = (unsigned HOST_WIDE_INT)-1;
			  ret = NULL;
			  break;
			}
		      add_loc_descr (&ret, ret1);
		    }
		  if (fieldsize)
		    {
		      ret1 = new_loc_descr (DW_OP_piece, fieldsize, 0);
		      add_loc_descr (&ret, ret1);
		      offset = pos + fieldsize;
		    }
		}

	      if (offset != size)
		{
		  ret1 = new_loc_descr (DW_OP_piece, size - offset, 0);
		  add_loc_descr (&ret, ret1);
		  offset = size;
		}

	      have_address = !!want_address;
	    }
	  else
	    expansion_failed (loc, NULL_RTX,
			      "constructor of non-record type");
	}
      else
      /* We can construct small constants here using int_loc_descriptor.  */
	expansion_failed (loc, NULL_RTX,
			  "constructor or constant not in constant pool");
      break;

    case TRUTH_AND_EXPR:
    case TRUTH_ANDIF_EXPR:
    case BIT_AND_EXPR:
      op = DW_OP_and;
      goto do_binop;

    case TRUTH_XOR_EXPR:
    case BIT_XOR_EXPR:
      op = DW_OP_xor;
      goto do_binop;

    case TRUTH_OR_EXPR:
    case TRUTH_ORIF_EXPR:
    case BIT_IOR_EXPR:
      op = DW_OP_or;
      goto do_binop;

    case EXACT_DIV_EXPR:
    case FLOOR_DIV_EXPR:
    case TRUNC_DIV_EXPR:
      /* Turn a divide by a power of 2 into a shift when possible.  */
      if (TYPE_UNSIGNED (TREE_TYPE (loc))
	  && tree_fits_uhwi_p (TREE_OPERAND (loc, 1)))
	{
	  const int log2 = exact_log2 (tree_to_uhwi (TREE_OPERAND (loc, 1)));
	  if (log2 > 0)
	    {
	      list_ret
		= loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
	      if (list_ret == 0)
		return 0;

	      add_loc_descr_to_each (list_ret, uint_loc_descriptor (log2));
	      add_loc_descr_to_each (list_ret,
				     new_loc_descr (DW_OP_shr, 0, 0));
	      break;
	    }
	}

      /* fall through */

    case CEIL_DIV_EXPR:
    case ROUND_DIV_EXPR:
      if (TYPE_UNSIGNED (TREE_TYPE (loc)))
	{
	  enum machine_mode mode = TYPE_MODE (TREE_TYPE (loc));
	  scalar_int_mode int_mode;

	  if ((dwarf_strict && dwarf_version < 5)
	      || !is_a <scalar_int_mode> (mode, &int_mode))
	    return 0;

	  /* We can use a signed divide if the sign bit is not set.  */
	  if (GET_MODE_SIZE (int_mode) < DWARF2_ADDR_SIZE)
	    {
	      op = DW_OP_div;
	      goto do_binop;
	    }

	  list_ret = typed_binop_from_tree (DW_OP_div, loc,
					    base_type_for_mode (int_mode, 1),
					    int_mode, context);
	  break;
	}
      op = DW_OP_div;
      goto do_binop;

    case MINUS_EXPR:
      op = DW_OP_minus;
      goto do_binop;

    case FLOOR_MOD_EXPR:
    case CEIL_MOD_EXPR:
    case ROUND_MOD_EXPR:
    case TRUNC_MOD_EXPR:
      if (TYPE_UNSIGNED (TREE_TYPE (loc)))
	{
	  op = DW_OP_mod;
	  goto do_binop;
	}
      list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
      list_ret1 = loc_list_from_tree_1 (TREE_OPERAND (loc, 1), 0, context);
      if (list_ret == 0 || list_ret1 == 0)
	return 0;

      add_loc_list (&list_ret, list_ret1);
      if (list_ret == 0)
	return 0;
      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_over, 0, 0));
      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_over, 0, 0));
      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_div, 0, 0));
      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_mul, 0, 0));
      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_minus, 0, 0));
      break;

    case MULT_EXPR:
      op = DW_OP_mul;
      goto do_binop;

    case LSHIFT_EXPR:
      op = DW_OP_shl;
      goto do_binop;

    case RSHIFT_EXPR:
      op = (TYPE_UNSIGNED (TREE_TYPE (loc)) ? DW_OP_shr : DW_OP_shra);
      goto do_binop;

    case POINTER_PLUS_EXPR:
    case PLUS_EXPR:
    do_plus:
      if (tree_fits_shwi_p (TREE_OPERAND (loc, 1)))
	{
	  /* Big unsigned numbers can fit in HOST_WIDE_INT but it may be
	     smarter to encode their opposite.  The DW_OP_plus_uconst operation
	     takes 1 + X bytes, X being the size of the ULEB128 addend.  On the
	     other hand, a "<push literal>; DW_OP_minus" pattern takes 1 + Y
	     bytes, Y being the size of the operation that pushes the opposite
	     of the addend.  So let's choose the smallest representation.  */
	  const tree tree_addend = TREE_OPERAND (loc, 1);
	  offset_int wi_addend;
	  HOST_WIDE_INT shwi_addend;
	  dw_loc_descr_ref loc_naddend;

	  list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
	  if (list_ret == 0)
	    return 0;

	  /* Try to get the literal to push.  It is the opposite of the addend,
	     so as we rely on wrapping during DWARF evaluation, first decode
	     the literal as a "DWARF-sized" signed number.  */
	  wi_addend = wi::to_offset (tree_addend);
	  wi_addend = wi::sext (wi_addend, DWARF2_ADDR_SIZE * 8);
	  shwi_addend = wi_addend.to_shwi ();
	  loc_naddend = (shwi_addend != INTTYPE_MINIMUM (HOST_WIDE_INT))
			? int_loc_descriptor (-shwi_addend)
			: NULL;

	  if (loc_naddend != NULL
	      && ((unsigned) size_of_uleb128 (shwi_addend)
	          > size_of_loc_descr (loc_naddend)))
	    {
	      add_loc_descr_to_each (list_ret, loc_naddend);
	      add_loc_descr_to_each (list_ret,
				     new_loc_descr (DW_OP_minus, 0, 0));
	    }
	  else
	    {
	      for (dw_loc_descr_ref loc_cur = loc_naddend; loc_cur != NULL; )
		{
		  loc_naddend = loc_cur;
		  loc_cur = loc_cur->dw_loc_next;
		  ggc_free (loc_naddend);
		}
	      loc_list_plus_const (list_ret, wi_addend.to_shwi ());
	    }
	  break;
	}

      op = DW_OP_plus;
      goto do_binop;

    case LE_EXPR:
      op = DW_OP_le;
      goto do_comp_binop;

    case GE_EXPR:
      op = DW_OP_ge;
      goto do_comp_binop;

    case LT_EXPR:
      op = DW_OP_lt;
      goto do_comp_binop;

    case GT_EXPR:
      op = DW_OP_gt;
      goto do_comp_binop;

    do_comp_binop:
      if (TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (loc, 0))))
	{
	  list_ret = loc_list_from_tree (TREE_OPERAND (loc, 0), 0, context);
	  list_ret1 = loc_list_from_tree (TREE_OPERAND (loc, 1), 0, context);
	  list_ret = loc_list_from_uint_comparison (list_ret, list_ret1,
						    TREE_CODE (loc));
	  break;
	}
      else
	goto do_binop;

    case EQ_EXPR:
      op = DW_OP_eq;
      goto do_binop;

    case NE_EXPR:
      op = DW_OP_ne;
      goto do_binop;

    do_binop:
      list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
      list_ret1 = loc_list_from_tree_1 (TREE_OPERAND (loc, 1), 0, context);
      if (list_ret == 0 || list_ret1 == 0)
	return 0;

      add_loc_list (&list_ret, list_ret1);
      if (list_ret == 0)
	return 0;
      add_loc_descr_to_each (list_ret, new_loc_descr (op, 0, 0));
      break;

    case TRUTH_NOT_EXPR:
    case BIT_NOT_EXPR:
      op = DW_OP_not;
      goto do_unop;

    case ABS_EXPR:
      op = DW_OP_abs;
      goto do_unop;

    case NEGATE_EXPR:
      op = DW_OP_neg;
      goto do_unop;

    do_unop:
      list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
      if (list_ret == 0)
	return 0;

      add_loc_descr_to_each (list_ret, new_loc_descr (op, 0, 0));
      break;

    case MIN_EXPR:
    case MAX_EXPR:
      {
	const enum tree_code code =
	  TREE_CODE (loc) == MIN_EXPR ? GT_EXPR : LT_EXPR;

	loc = build3 (COND_EXPR, TREE_TYPE (loc),
		      build2 (code, integer_type_node,
			      TREE_OPERAND (loc, 0), TREE_OPERAND (loc, 1)),
		      TREE_OPERAND (loc, 1), TREE_OPERAND (loc, 0));
      }

      /* fall through */

    case COND_EXPR:
      {
	dw_loc_descr_ref lhs
	  = loc_descriptor_from_tree (TREE_OPERAND (loc, 1), 0, context);
	dw_loc_list_ref rhs
	  = loc_list_from_tree_1 (TREE_OPERAND (loc, 2), 0, context);
	dw_loc_descr_ref bra_node, jump_node, tmp;

	/* DW_OP_bra is branch-on-nonzero so avoid doing useless work.  */
	if (TREE_CODE (TREE_OPERAND (loc, 0)) == NE_EXPR
	    && integer_zerop (TREE_OPERAND (TREE_OPERAND (loc, 0), 1)))
	  list_ret
	    = loc_list_from_tree_1 (TREE_OPERAND (TREE_OPERAND (loc, 0), 0),
				    0, context);
	else
	  list_ret = loc_list_from_tree_1 (TREE_OPERAND (loc, 0), 0, context);
	if (list_ret == 0 || lhs == 0 || rhs == 0)
	  return 0;

	bra_node = new_loc_descr (DW_OP_bra, 0, 0);
	add_loc_descr_to_each (list_ret, bra_node);

	add_loc_list (&list_ret, rhs);
	jump_node = new_loc_descr (DW_OP_skip, 0, 0);
	add_loc_descr_to_each (list_ret, jump_node);

	add_loc_descr_to_each (list_ret, lhs);
	bra_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
	bra_node->dw_loc_oprnd1.v.val_loc = lhs;

	/* ??? Need a node to point the skip at.  Use a nop.  */
	tmp = new_loc_descr (DW_OP_nop, 0, 0);
	add_loc_descr_to_each (list_ret, tmp);
	jump_node->dw_loc_oprnd1.val_class = dw_val_class_loc;
	jump_node->dw_loc_oprnd1.v.val_loc = tmp;
      }
      break;

    case FIX_TRUNC_EXPR:
      return 0;

    case COMPOUND_LITERAL_EXPR:
      return loc_list_from_tree_1 (COMPOUND_LITERAL_EXPR_DECL (loc),
				   0, context);

    default:
      /* Leave front-end specific codes as simply unknown.  This comes
	 up, for instance, with the C STMT_EXPR.  */
      if ((unsigned int) TREE_CODE (loc)
	  >= (unsigned int) LAST_AND_UNUSED_TREE_CODE)
	{
	  expansion_failed (loc, NULL_RTX,
			    "language specific tree node");
	  return 0;
	}

      /* Otherwise this is a generic code; we should just lists all of
	 these explicitly.  We forgot one.  */
      if (flag_checking)
	gcc_unreachable ();

      /* In a release build, we want to degrade gracefully: better to
	 generate incomplete debugging information than to crash.  */
      return NULL;
    }

  if (!ret && !list_ret)
    return 0;

  if (want_address == 2 && !have_address
      && (dwarf_version >= 4 || !dwarf_strict))
    {
      if (int_size_in_bytes (TREE_TYPE (loc)) > DWARF2_ADDR_SIZE)
	{
	  expansion_failed (loc, NULL_RTX,
			    "DWARF address size mismatch");
	  return 0;
	}
      if (ret)
	add_loc_descr (&ret, new_loc_descr (DW_OP_stack_value, 0, 0));
      else
	add_loc_descr_to_each (list_ret,
			       new_loc_descr (DW_OP_stack_value, 0, 0));
      have_address = 1;
    }
  /* Show if we can't fill the request for an address.  */
  if (want_address && !have_address)
    {
      expansion_failed (loc, NULL_RTX,
			"Want address and only have value");
      return 0;
    }

  gcc_assert (!ret || !list_ret);

  /* If we've got an address and don't want one, dereference.  */
  if (!want_address && have_address)
    {
      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (loc));
      enum machine_mode mode = TYPE_MODE (TREE_TYPE (loc));
      scalar_int_mode int_mode;
      dw_die_ref type_die;
      dw_loc_descr_ref deref;

      /* If the size is greater than DWARF2_ADDR_SIZE, bail out.  */
      if (size > DWARF2_ADDR_SIZE || size == -1)
	{
	  expansion_failed (loc, NULL_RTX,
			    "DWARF address size mismatch");
	  return 0;
	}

      /* If it is equal to DWARF2_ADDR_SIZE, extension does not matter.  */
      else if (size == DWARF2_ADDR_SIZE)
	deref = new_loc_descr (DW_OP_deref, size, 0);

      /* If it is lower than DWARF2_ADDR_SIZE, DW_OP_deref_size will zero-
	 extend the value, which is really OK for unsigned types only.  */
      else if (!(context && context->strict_signedness)
	       || TYPE_UNSIGNED (TREE_TYPE (loc))
	       || (dwarf_strict && dwarf_version < 5)
	       || !is_a <scalar_int_mode> (mode, &int_mode)
	       || !(type_die = base_type_for_mode (mode, false)))
	deref = new_loc_descr (DW_OP_deref_size, size, 0);

      /* Use DW_OP_deref_type for signed integral types if possible, but
	 convert back to the generic type to avoid type mismatches later.  */
      else
	{
	  deref = new_loc_descr (dwarf_OP (DW_OP_deref_type), size, 0);
	  deref->dw_loc_oprnd2.val_class = dw_val_class_die_ref;
	  deref->dw_loc_oprnd2.v.val_die_ref.die = type_die;
	  deref->dw_loc_oprnd2.v.val_die_ref.external = 0;
	  add_loc_descr (&deref,
			 new_loc_descr (dwarf_OP (DW_OP_convert), 0, 0));
	}

      if (ret)
	add_loc_descr (&ret, deref);
      else
	add_loc_descr_to_each (list_ret, deref);
    }

  if (ret)
    list_ret = new_loc_list (ret, NULL, 0, NULL, 0, NULL);

  return list_ret;
}

/* Likewise, but strip useless DW_OP_nop operations in the resulting
   expressions.  */

static dw_loc_list_ref
loc_list_from_tree (tree loc, int want_address,
		    struct loc_descr_context *context)
{
  dw_loc_list_ref result = loc_list_from_tree_1 (loc, want_address, context);

  for (dw_loc_list_ref loc_cur = result;
       loc_cur != NULL; loc_cur = loc_cur->dw_loc_next)
    loc_descr_without_nops (loc_cur->expr);
  return result;
}

/* Same as above but return only single location expression.  */
static dw_loc_descr_ref
loc_descriptor_from_tree (tree loc, int want_address,
			  struct loc_descr_context *context)
{
  dw_loc_list_ref ret = loc_list_from_tree (loc, want_address, context);
  if (!ret)
    return NULL;
  if (ret->dw_loc_next)
    {
      expansion_failed (loc, NULL_RTX,
			"Location list where only loc descriptor needed");
      return NULL;
    }
  return ret->expr;
}

/* Given a pointer to what is assumed to be a FIELD_DECL node, return a
   pointer to the declared type for the relevant field variable, or return
   `integer_type_node' if the given node turns out to be an
   ERROR_MARK node.  */

static inline tree
field_type (const_tree decl)
{
  tree type;

  if (TREE_CODE (decl) == ERROR_MARK)
    return integer_type_node;

  type = DECL_BIT_FIELD_TYPE (decl);
  if (type == NULL_TREE)
    type = TREE_TYPE (decl);

  return type;
}

/* Given a pointer to a tree node, return the alignment in bits for
   it, or else return BITS_PER_WORD if the node actually turns out to
   be an ERROR_MARK node.  */

static inline unsigned
simple_type_align_in_bits (const_tree type)
{
  return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD;
}

static inline unsigned
simple_decl_align_in_bits (const_tree decl)
{
  return (TREE_CODE (decl) != ERROR_MARK) ? DECL_ALIGN (decl) : BITS_PER_WORD;
}

/* Return the result of rounding T up to ALIGN.  */

static inline offset_int
round_up_to_align (const offset_int &t, unsigned int align)
{
  return wi::udiv_trunc (t + align - 1, align) * align;
}

/* Helper structure for RECORD_TYPE processing.  */
struct vlr_context
{
  /* Root RECORD_TYPE.  It is needed to generate data member location
     descriptions in variable-length records (VLR), but also to cope with
     variants, which are composed of nested structures multiplexed with
     QUAL_UNION_TYPE nodes.  Each time such a structure is passed to a
     function processing a FIELD_DECL, it is required to be non null.  */
  tree struct_type;

  /* When generating a variant part in a RECORD_TYPE (i.e. a nested
     QUAL_UNION_TYPE), this holds an expression that computes the offset for
     this variant part as part of the root record (in storage units).  For
     regular records, it must be NULL_TREE.  */
  tree variant_part_offset;
};

/* Given a pointer to a FIELD_DECL, compute the byte offset of the lowest
   addressed byte of the "containing object" for the given FIELD_DECL. If
   possible, return a native constant through CST_OFFSET (in which case NULL is
   returned); otherwise return a DWARF expression that computes the offset.

   Set *CST_OFFSET to 0 and return NULL if we are unable to determine what
   that offset is, either because the argument turns out to be a pointer to an
   ERROR_MARK node, or because the offset expression is too complex for us.

   CTX is required: see the comment for VLR_CONTEXT.  */

static dw_loc_descr_ref
field_byte_offset (const_tree decl, struct vlr_context *ctx,
		   HOST_WIDE_INT *cst_offset)
{
  tree tree_result;
  dw_loc_list_ref loc_result;

  *cst_offset = 0;

  if (TREE_CODE (decl) == ERROR_MARK)
    return NULL;
  else
    gcc_assert (TREE_CODE (decl) == FIELD_DECL);

  /* We cannot handle variable bit offsets at the moment, so abort if it's the
     case.  */
  if (TREE_CODE (DECL_FIELD_BIT_OFFSET (decl)) != INTEGER_CST)
    return NULL;

  /* We used to handle only constant offsets in all cases.  Now, we handle
     properly dynamic byte offsets only when PCC bitfield type doesn't
     matter.  */
  if (PCC_BITFIELD_TYPE_MATTERS
      && TREE_CODE (DECL_FIELD_OFFSET (decl)) == INTEGER_CST)
    {
      offset_int object_offset_in_bits;
      offset_int object_offset_in_bytes;
      offset_int bitpos_int;
      tree type;
      tree field_size_tree;
      offset_int deepest_bitpos;
      offset_int field_size_in_bits;
      unsigned int type_align_in_bits;
      unsigned int decl_align_in_bits;
      offset_int type_size_in_bits;

      bitpos_int = wi::to_offset (bit_position (decl));
      type = field_type (decl);
      type_size_in_bits = offset_int_type_size_in_bits (type);
      type_align_in_bits = simple_type_align_in_bits (type);

      field_size_tree = DECL_SIZE (decl);

      /* The size could be unspecified if there was an error, or for
	 a flexible array member.  */
      if (!field_size_tree)
	field_size_tree = bitsize_zero_node;

      /* If the size of the field is not constant, use the type size.  */
      if (TREE_CODE (field_size_tree) == INTEGER_CST)
	field_size_in_bits = wi::to_offset (field_size_tree);
      else
	field_size_in_bits = type_size_in_bits;

      decl_align_in_bits = simple_decl_align_in_bits (decl);

      /* The GCC front-end doesn't make any attempt to keep track of the
	 starting bit offset (relative to the start of the containing
	 structure type) of the hypothetical "containing object" for a
	 bit-field.  Thus, when computing the byte offset value for the
	 start of the "containing object" of a bit-field, we must deduce
	 this information on our own. This can be rather tricky to do in
	 some cases.  For example, handling the following structure type
	 definition when compiling for an i386/i486 target (which only
	 aligns long long's to 32-bit boundaries) can be very tricky:

	 struct S { int field1; long long field2:31; };

	 Fortunately, there is a simple rule-of-thumb which can be used
	 in such cases.  When compiling for an i386/i486, GCC will
	 allocate 8 bytes for the structure shown above.  It decides to
	 do this based upon one simple rule for bit-field allocation.
	 GCC allocates each "containing object" for each bit-field at
	 the first (i.e. lowest addressed) legitimate alignment boundary
	 (based upon the required minimum alignment for the declared
	 type of the field) which it can possibly use, subject to the
	 condition that there is still enough available space remaining
	 in the containing object (when allocated at the selected point)
	 to fully accommodate all of the bits of the bit-field itself.

	 This simple rule makes it obvious why GCC allocates 8 bytes for
	 each object of the structure type shown above.  When looking
	 for a place to allocate the "containing object" for `field2',
	 the compiler simply tries to allocate a 64-bit "containing
	 object" at each successive 32-bit boundary (starting at zero)
	 until it finds a place to allocate that 64- bit field such that
	 at least 31 contiguous (and previously unallocated) bits remain
	 within that selected 64 bit field.  (As it turns out, for the
	 example above, the compiler finds it is OK to allocate the
	 "containing object" 64-bit field at bit-offset zero within the
	 structure type.)

	 Here we attempt to work backwards from the limited set of facts
	 we're given, and we try to deduce from those facts, where GCC
	 must have believed that the containing object started (within
	 the structure type). The value we deduce is then used (by the
	 callers of this routine) to generate DW_AT_location and
	 DW_AT_bit_offset attributes for fields (both bit-fields and, in
	 the case of DW_AT_location, regular fields as well).  */

      /* Figure out the bit-distance from the start of the structure to
	 the "deepest" bit of the bit-field.  */
      deepest_bitpos = bitpos_int + field_size_in_bits;

      /* This is the tricky part.  Use some fancy footwork to deduce
	 where the lowest addressed bit of the containing object must
	 be.  */
      object_offset_in_bits = deepest_bitpos - type_size_in_bits;

      /* Round up to type_align by default.  This works best for
	 bitfields.  */
      object_offset_in_bits
	= round_up_to_align (object_offset_in_bits, type_align_in_bits);

      if (wi::gtu_p (object_offset_in_bits, bitpos_int))
	{
	  object_offset_in_bits = deepest_bitpos - type_size_in_bits;

	  /* Round up to decl_align instead.  */
	  object_offset_in_bits
	    = round_up_to_align (object_offset_in_bits, decl_align_in_bits);
	}

      object_offset_in_bytes
	= wi::lrshift (object_offset_in_bits, LOG2_BITS_PER_UNIT);
      if (ctx->variant_part_offset == NULL_TREE)
	{
	  *cst_offset = object_offset_in_bytes.to_shwi ();
	  return NULL;
	}
      tree_result = wide_int_to_tree (sizetype, object_offset_in_bytes);
    }
  else
    tree_result = byte_position (decl);

  if (ctx->variant_part_offset != NULL_TREE)
    tree_result = fold_build2 (PLUS_EXPR, TREE_TYPE (tree_result),
			       ctx->variant_part_offset, tree_result);

  /* If the byte offset is a constant, it's simplier to handle a native
     constant rather than a DWARF expression.  */
  if (TREE_CODE (tree_result) == INTEGER_CST)
    {
      *cst_offset = wi::to_offset (tree_result).to_shwi ();
      return NULL;
    }

  struct loc_descr_context loc_ctx = {
    ctx->struct_type, /* context_type */
    NULL_TREE,	      /* base_decl */
    NULL,	      /* dpi */
    false,	      /* placeholder_arg */
    false,	      /* placeholder_seen */
    false	      /* strict_signedness */
  };
  loc_result = loc_list_from_tree (tree_result, 0, &loc_ctx);

  /* We want a DWARF expression: abort if we only have a location list with
     multiple elements.  */
  if (!loc_result || !single_element_loc_list_p (loc_result))
    return NULL;
  else
    return loc_result->expr;
}

/* The following routines define various Dwarf attributes and any data
   associated with them.  */

/* Add a location description attribute value to a DIE.

   This emits location attributes suitable for whole variables and
   whole parameters.  Note that the location attributes for struct fields are
   generated by the routine `data_member_location_attribute' below.  */

static inline void
add_AT_location_description (dw_die_ref die, enum dwarf_attribute attr_kind,
			     dw_loc_list_ref descr)
{
  bool check_no_locviews = true;
  if (descr == 0)
    return;
  if (single_element_loc_list_p (descr))
    add_AT_loc (die, attr_kind, descr->expr);
  else
    {
      add_AT_loc_list (die, attr_kind, descr);
      gcc_assert (descr->ll_symbol);
      if (attr_kind == DW_AT_location && descr->vl_symbol
	  && dwarf2out_locviews_in_attribute ())
	{
	  add_AT_view_list (die, DW_AT_GNU_locviews);
	  check_no_locviews = false;
	}
    }

  if (check_no_locviews)
    gcc_assert (!get_AT (die, DW_AT_GNU_locviews));
}

/* Add DW_AT_accessibility attribute to DIE if needed.  */

static void
add_accessibility_attribute (dw_die_ref die, tree decl)
{
  /* In DWARF3+ the default is DW_ACCESS_private only in DW_TAG_class_type
     children, otherwise the default is DW_ACCESS_public.  In DWARF2
     the default has always been DW_ACCESS_public.  */
  if (TREE_PROTECTED (decl))
    add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_protected);
  else if (TREE_PRIVATE (decl))
    {
      if (dwarf_version == 2
	  || die->die_parent == NULL
	  || die->die_parent->die_tag != DW_TAG_class_type)
	add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_private);
    }
  else if (dwarf_version > 2
	   && die->die_parent
	   && die->die_parent->die_tag == DW_TAG_class_type)
    add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_public);
}

/* Attach the specialized form of location attribute used for data members of
   struct and union types.  In the special case of a FIELD_DECL node which
   represents a bit-field, the "offset" part of this special location
   descriptor must indicate the distance in bytes from the lowest-addressed
   byte of the containing struct or union type to the lowest-addressed byte of
   the "containing object" for the bit-field.  (See the `field_byte_offset'
   function above).

   For any given bit-field, the "containing object" is a hypothetical object
   (of some integral or enum type) within which the given bit-field lives.  The
   type of this hypothetical "containing object" is always the same as the
   declared type of the individual bit-field itself (for GCC anyway... the
   DWARF spec doesn't actually mandate this).  Note that it is the size (in
   bytes) of the hypothetical "containing object" which will be given in the
   DW_AT_byte_size attribute for this bit-field.  (See the
   `byte_size_attribute' function below.)  It is also used when calculating the
   value of the DW_AT_bit_offset attribute.  (See the `bit_offset_attribute'
   function below.)

   CTX is required: see the comment for VLR_CONTEXT.  */

static void
add_data_member_location_attribute (dw_die_ref die,
				    tree decl,
				    struct vlr_context *ctx)
{
  HOST_WIDE_INT offset;
  dw_loc_descr_ref loc_descr = 0;

  if (TREE_CODE (decl) == TREE_BINFO)
    {
      /* We're working on the TAG_inheritance for a base class.  */
      if (BINFO_VIRTUAL_P (decl) && is_cxx ())
	{
	  /* For C++ virtual bases we can't just use BINFO_OFFSET, as they
	     aren't at a fixed offset from all (sub)objects of the same
	     type.  We need to extract the appropriate offset from our
	     vtable.  The following dwarf expression means

	       BaseAddr = ObAddr + *((*ObAddr) - Offset)

	     This is specific to the V3 ABI, of course.  */

	  dw_loc_descr_ref tmp;

	  /* Make a copy of the object address.  */
	  tmp = new_loc_descr (DW_OP_dup, 0, 0);
	  add_loc_descr (&loc_descr, tmp);

	  /* Extract the vtable address.  */
	  tmp = new_loc_descr (DW_OP_deref, 0, 0);
	  add_loc_descr (&loc_descr, tmp);

	  /* Calculate the address of the offset.  */
	  offset = tree_to_shwi (BINFO_VPTR_FIELD (decl));
	  gcc_assert (offset < 0);

	  tmp = int_loc_descriptor (-offset);
	  add_loc_descr (&loc_descr, tmp);
	  tmp = new_loc_descr (DW_OP_minus, 0, 0);
	  add_loc_descr (&loc_descr, tmp);

	  /* Extract the offset.  */
	  tmp = new_loc_descr (DW_OP_deref, 0, 0);
	  add_loc_descr (&loc_descr, tmp);

	  /* Add it to the object address.  */
	  tmp = new_loc_descr (DW_OP_plus, 0, 0);
	  add_loc_descr (&loc_descr, tmp);
	}
      else
	offset = tree_to_shwi (BINFO_OFFSET (decl));
    }
  else
    {
      loc_descr = field_byte_offset (decl, ctx, &offset);

      if (!loc_descr)
	;

      /* If loc_descr is available, then we know the offset is dynamic.  */
      else if (gnat_encodings == DWARF_GNAT_ENCODINGS_ALL)
	{
	  loc_descr = NULL;
	  offset = 0;
	}

      /* Data member location evaluation starts with the base address on the
	 stack.  Compute the field offset and add it to this base address.  */
      else
	add_loc_descr (&loc_descr, new_loc_descr (DW_OP_plus, 0, 0));
    }

  if (!loc_descr)
    {
      /* While DW_AT_data_bit_offset has been added already in DWARF4,
	 e.g. GDB only added support to it in November 2016.  For DWARF5
	 we need newer debug info consumers anyway.  We might change this
	 to dwarf_version >= 4 once most consumers catched up.  */
      if (dwarf_version >= 5
	  && TREE_CODE (decl) == FIELD_DECL
	  && DECL_BIT_FIELD_TYPE (decl)
	  && (ctx->variant_part_offset == NULL_TREE
	      || TREE_CODE (ctx->variant_part_offset) == INTEGER_CST))
	{
	  tree off = bit_position (decl);
	  if (ctx->variant_part_offset)
	    off = bit_from_pos (ctx->variant_part_offset, off);
	  if (tree_fits_uhwi_p (off) && get_AT (die, DW_AT_bit_size))
	    {
	      remove_AT (die, DW_AT_byte_size);
	      remove_AT (die, DW_AT_bit_offset);
	      add_AT_unsigned (die, DW_AT_data_bit_offset, tree_to_uhwi (off));
	      return;
	    }
	}
      if (dwarf_version > 2)
	{
	  /* Don't need to output a location expression, just the constant. */
	  if (offset < 0)
	    add_AT_int (die, DW_AT_data_member_location, offset);
	  else
	    add_AT_unsigned (die, DW_AT_data_member_location, offset);
	  return;
	}
      else
	{
	  enum dwarf_location_atom op;

	  /* The DWARF2 standard says that we should assume that the structure
	     address is already on the stack, so we can specify a structure
	     field address by using DW_OP_plus_uconst.  */
	  op = DW_OP_plus_uconst;
	  loc_descr = new_loc_descr (op, offset, 0);
	}
    }

  add_AT_loc (die, DW_AT_data_member_location, loc_descr);
}

/* Writes integer values to dw_vec_const array.  */

static void
insert_int (HOST_WIDE_INT val, unsigned int size, unsigned char *dest)
{
  while (size != 0)
    {
      *dest++ = val & 0xff;
      val >>= 8;
      --size;
    }
}

/* Reads integers from dw_vec_const array.  Inverse of insert_int.  */

static HOST_WIDE_INT
extract_int (const unsigned char *src, unsigned int size)
{
  HOST_WIDE_INT val = 0;

  src += size;
  while (size != 0)
    {
      val <<= 8;
      val |= *--src & 0xff;
      --size;
    }
  return val;
}

/* Writes wide_int values to dw_vec_const array.  */

static void
insert_wide_int (const wide_int &val, unsigned char *dest, int elt_size)
{
  int i;

  if (elt_size <= HOST_BITS_PER_WIDE_INT/BITS_PER_UNIT)
    {
      insert_int ((HOST_WIDE_INT) val.elt (0), elt_size, dest);
      return;
    }

  /* We'd have to extend this code to support odd sizes.  */
  gcc_assert (elt_size % (HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT) == 0);

  int n = elt_size / (HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT);

  if (WORDS_BIG_ENDIAN)
    for (i = n - 1; i >= 0; i--)
      {
	insert_int ((HOST_WIDE_INT) val.elt (i), sizeof (HOST_WIDE_INT), dest);
	dest += sizeof (HOST_WIDE_INT);
      }
  else
    for (i = 0; i < n; i++)
      {
	insert_int ((HOST_WIDE_INT) val.elt (i), sizeof (HOST_WIDE_INT), dest);
	dest += sizeof (HOST_WIDE_INT);
      }
}

/* Writes floating point values to dw_vec_const array.  */

static unsigned
insert_float (const_rtx rtl, unsigned char *array)
{
  long val[4];
  int i;
  scalar_float_mode mode = as_a <scalar_float_mode> (GET_MODE (rtl));

  real_to_target (val, CONST_DOUBLE_REAL_VALUE (rtl), mode);

  /* real_to_target puts 32-bit pieces in each long.  Pack them.  */
  if (GET_MODE_SIZE (mode) < 4)
    {
      gcc_assert (GET_MODE_SIZE (mode) == 2);
      insert_int (val[0], 2, array);
      return 2;
    }

  for (i = 0; i < GET_MODE_SIZE (mode) / 4; i++)
    {
      insert_int (val[i], 4, array);
      array += 4;
    }
  return 4;
}

/* Attach a DW_AT_const_value attribute for a variable or a parameter which
   does not have a "location" either in memory or in a register.  These
   things can arise in GNU C when a constant is passed as an actual parameter
   to an inlined function.  They can also arise in C++ where declared
   constants do not necessarily get memory "homes".  */

static bool
add_const_value_attribute (dw_die_ref die, rtx rtl)
{
  switch (GET_CODE (rtl))
    {
    case CONST_INT:
      {
	HOST_WIDE_INT val = INTVAL (rtl);

	if (val < 0)
	  add_AT_int (die, DW_AT_const_value, val);
	else
	  add_AT_unsigned (die, DW_AT_const_value, (unsigned HOST_WIDE_INT) val);
      }
      return true;

    case CONST_WIDE_INT:
      {
	wide_int w1 = rtx_mode_t (rtl, MAX_MODE_INT);
	unsigned int prec = MIN (wi::min_precision (w1, UNSIGNED),
				 (unsigned int) CONST_WIDE_INT_NUNITS (rtl)
				 * HOST_BITS_PER_WIDE_INT);
	wide_int w = wide_int::from (w1, prec, UNSIGNED);
	add_AT_wide (die, DW_AT_const_value, w);
      }
      return true;

    case CONST_DOUBLE:
      /* Note that a CONST_DOUBLE rtx could represent either an integer or a
	 floating-point constant.  A CONST_DOUBLE is used whenever the
	 constant requires more than one word in order to be adequately
	 represented.  */
      if (TARGET_SUPPORTS_WIDE_INT == 0
	  && !SCALAR_FLOAT_MODE_P (GET_MODE (rtl)))
	add_AT_double (die, DW_AT_const_value,
		       CONST_DOUBLE_HIGH (rtl), CONST_DOUBLE_LOW (rtl));
      else
	{
	  scalar_float_mode mode = as_a <scalar_float_mode> (GET_MODE (rtl));
	  unsigned int length = GET_MODE_SIZE (mode);
	  unsigned char *array = ggc_vec_alloc<unsigned char> (length);
	  unsigned int elt_size = insert_float (rtl, array);

	  add_AT_vec (die, DW_AT_const_value, length / elt_size, elt_size,
		      array);
	}
      return true;

    case CONST_VECTOR:
      {
	unsigned int length;
	if (!CONST_VECTOR_NUNITS (rtl).is_constant (&length))
	  return false;

	machine_mode mode = GET_MODE (rtl);
	/* The combination of a length and byte elt_size doesn't extend
	   naturally to boolean vectors, where several elements are packed
	   into the same byte.  */
	if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
	  return false;

	unsigned int elt_size = GET_MODE_UNIT_SIZE (mode);
	unsigned char *array
	  = ggc_vec_alloc<unsigned char> (length * elt_size);
	unsigned int i;
	unsigned char *p;
	machine_mode imode = GET_MODE_INNER (mode);

	switch (GET_MODE_CLASS (mode))
	  {
	  case MODE_VECTOR_INT:
	    for (i = 0, p = array; i < length; i++, p += elt_size)
	      {
		rtx elt = CONST_VECTOR_ELT (rtl, i);
		insert_wide_int (rtx_mode_t (elt, imode), p, elt_size);
	      }
	    break;

	  case MODE_VECTOR_FLOAT:
	    for (i = 0, p = array; i < length; i++, p += elt_size)
	      {
		rtx elt = CONST_VECTOR_ELT (rtl, i);
		insert_float (elt, p);
	      }
	    break;

	  default:
	    gcc_unreachable ();
	  }

	add_AT_vec (die, DW_AT_const_value, length, elt_size, array);
      }
      return true;

    case CONST_STRING:
      if (dwarf_version >= 4 || !dwarf_strict)
	{
	  dw_loc_descr_ref loc_result;
	  resolve_one_addr (&rtl);
	rtl_addr:
          loc_result = new_addr_loc_descr (rtl, dtprel_false);
	  add_loc_descr (&loc_result, new_loc_descr (DW_OP_stack_value, 0, 0));
	  add_AT_loc (die, DW_AT_location, loc_result);
	  vec_safe_push (used_rtx_array, rtl);
	  return true;
	}
      return false;

    case CONST:
      if (CONSTANT_P (XEXP (rtl, 0)))
	return add_const_value_attribute (die, XEXP (rtl, 0));
      /* FALLTHROUGH */
    case SYMBOL_REF:
      if (!const_ok_for_output (rtl))
	return false;
      /* FALLTHROUGH */
    case LABEL_REF:
      if (dwarf_version >= 4 || !dwarf_strict)
	goto rtl_addr;
      return false;

    case PLUS:
      /* In cases where an inlined instance of an inline function is passed
	 the address of an `auto' variable (which is local to the caller) we
	 can get a situation where the DECL_RTL of the artificial local
	 variable (for the inlining) which acts as a stand-in for the
	 corresponding formal parameter (of the inline function) will look
	 like (plus:SI (reg:SI FRAME_PTR) (const_int ...)).  This is not
	 exactly a compile-time constant expression, but it isn't the address
	 of the (artificial) local variable either.  Rather, it represents the
	 *value* which the artificial local variable always has during its
	 lifetime.  We currently have no way to represent such quasi-constant
	 values in Dwarf, so for now we just punt and generate nothing.  */
      return false;

    case HIGH:
    case CONST_FIXED:
    case MINUS:
    case SIGN_EXTEND:
    case ZERO_EXTEND:
    case CONST_POLY_INT:
      return false;

    case MEM:
      if (GET_CODE (XEXP (rtl, 0)) == CONST_STRING
	  && MEM_READONLY_P (rtl)
	  && GET_MODE (rtl) == BLKmode)
	{
	  add_AT_string (die, DW_AT_const_value, XSTR (XEXP (rtl, 0), 0));
	  return true;
	}
      return false;

    default:
      /* No other kinds of rtx should be possible here.  */
      gcc_unreachable ();
    }
  return false;
}

/* Determine whether the evaluation of EXPR references any variables
   or functions which aren't otherwise used (and therefore may not be
   output).  */
static tree
reference_to_unused (tree * tp, int * walk_subtrees,
		     void * data ATTRIBUTE_UNUSED)
{
  if (! EXPR_P (*tp) && ! CONSTANT_CLASS_P (*tp))
    *walk_subtrees = 0;

  if (DECL_P (*tp) && ! TREE_PUBLIC (*tp) && ! TREE_USED (*tp)
      && ! TREE_ASM_WRITTEN (*tp))
    return *tp;
  /* ???  The C++ FE emits debug information for using decls, so
     putting gcc_unreachable here falls over.  See PR31899.  For now
     be conservative.  */
  else if (!symtab->global_info_ready && VAR_P (*tp))
    return *tp;
  else if (VAR_P (*tp))
    {
      varpool_node *node = varpool_node::get (*tp);
      if (!node || !node->definition)
	return *tp;
    }
  else if (TREE_CODE (*tp) == FUNCTION_DECL
	   && (!DECL_EXTERNAL (*tp) || DECL_DECLARED_INLINE_P (*tp)))
    {
      /* The call graph machinery must have finished analyzing,
         optimizing and gimplifying the CU by now.
	 So if *TP has no call graph node associated
	 to it, it means *TP will not be emitted.  */
      if (!symtab->global_info_ready || !cgraph_node::get (*tp))
	return *tp;
    }
  else if (TREE_CODE (*tp) == STRING_CST && !TREE_ASM_WRITTEN (*tp))
    return *tp;

  return NULL_TREE;
}

/* Generate an RTL constant from a decl initializer INIT with decl type TYPE,
   for use in a later add_const_value_attribute call.  */

static rtx
rtl_for_decl_init (tree init, tree type)
{
  rtx rtl = NULL_RTX;

  STRIP_NOPS (init);

  /* If a variable is initialized with a string constant without embedded
     zeros, build CONST_STRING.  */
  if (TREE_CODE (init) == STRING_CST && TREE_CODE (type) == ARRAY_TYPE)
    {
      tree enttype = TREE_TYPE (type);
      tree domain = TYPE_DOMAIN (type);
      scalar_int_mode mode;

      if (is_int_mode (TYPE_MODE (enttype), &mode)
	  && GET_MODE_SIZE (mode) == 1
	  && domain
	  && TYPE_MAX_VALUE (domain)
	  && TREE_CODE (TYPE_MAX_VALUE (domain)) == INTEGER_CST
	  && integer_zerop (TYPE_MIN_VALUE (domain))
	  && compare_tree_int (TYPE_MAX_VALUE (domain),
			       TREE_STRING_LENGTH (init) - 1) == 0
	  && ((size_t) TREE_STRING_LENGTH (init)
	      == strlen (TREE_STRING_POINTER (init)) + 1))
	{
	  rtl = gen_rtx_CONST_STRING (VOIDmode,
				      ggc_strdup (TREE_STRING_POINTER (init)));
	  rtl = gen_rtx_MEM (BLKmode, rtl);
	  MEM_READONLY_P (rtl) = 1;
	}
    }
  /* Other aggregates, and complex values, could be represented using
     CONCAT: FIXME!  */
  else if (AGGREGATE_TYPE_P (type)
	   || (TREE_CODE (init) == VIEW_CONVERT_EXPR
	       && AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (init, 0))))
	   || TREE_CODE (type) == COMPLEX_TYPE)
    ;
  /* Vectors only work if their mode is supported by the target.
     FIXME: generic vectors ought to work too.  */
  else if (TREE_CODE (type) == VECTOR_TYPE
	   && !VECTOR_MODE_P (TYPE_MODE (type)))
    ;
  /* If the initializer is something that we know will expand into an
     immediate RTL constant, expand it now.  We must be careful not to
     reference variables which won't be output.  */
  else if (initializer_constant_valid_p (init, type)
	   && ! walk_tree (&init, reference_to_unused, NULL, NULL))
    {
      /* Convert vector CONSTRUCTOR initializers to VECTOR_CST if
	 possible.  */
      if (TREE_CODE (type) == VECTOR_TYPE)
	switch (TREE_CODE (init))
	  {
	  case VECTOR_CST:
	    break;
	  case CONSTRUCTOR:
	    if (TREE_CONSTANT (init))
	      {
		vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (init);
		bool constant_p = true;
		tree value;
		unsigned HOST_WIDE_INT ix;

		/* Even when ctor is constant, it might contain non-*_CST
		   elements (e.g. { 1.0/0.0 - 1.0/0.0, 0.0 }) and those don't
		   belong into VECTOR_CST nodes.  */
		FOR_EACH_CONSTRUCTOR_VALUE (elts, ix, value)
		  if (!CONSTANT_CLASS_P (value))
		    {
		      constant_p = false;
		      break;
		    }

		if (constant_p)
		  {
		    init = build_vector_from_ctor (type, elts);
		    break;
		  }
	      }
	    /* FALLTHRU */

	  default:
	    return NULL;
	  }

      rtl = expand_expr (init, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);

      /* If expand_expr returns a MEM, it wasn't immediate.  */
      gcc_assert (!rtl || !MEM_P (rtl));
    }

  return rtl;
}

/* Generate RTL for the variable DECL to represent its location.  */

static rtx
rtl_for_decl_location (tree decl)
{
  rtx rtl;

  /* Here we have to decide where we are going to say the parameter "lives"
     (as far as the debugger is concerned).  We only have a couple of
     choices.  GCC provides us with DECL_RTL and with DECL_INCOMING_RTL.

     DECL_RTL normally indicates where the parameter lives during most of the
     activation of the function.  If optimization is enabled however, this
     could be either NULL or else a pseudo-reg.  Both of those cases indicate
     that the parameter doesn't really live anywhere (as far as the code
     generation parts of GCC are concerned) during most of the function's
     activation.  That will happen (for example) if the parameter is never
     referenced within the function.

     We could just generate a location descriptor here for all non-NULL
     non-pseudo values of DECL_RTL and ignore all of the rest, but we can be
     a little nicer than that if we also consider DECL_INCOMING_RTL in cases
     where DECL_RTL is NULL or is a pseudo-reg.

     Note however that we can only get away with using DECL_INCOMING_RTL as
     a backup substitute for DECL_RTL in certain limited cases.  In cases
     where DECL_ARG_TYPE (decl) indicates the same type as TREE_TYPE (decl),
     we can be sure that the parameter was passed using the same type as it is
     declared to have within the function, and that its DECL_INCOMING_RTL
     points us to a place where a value of that type is passed.

     In cases where DECL_ARG_TYPE (decl) and TREE_TYPE (decl) are different,
     we cannot (in general) use DECL_INCOMING_RTL as a substitute for DECL_RTL
     because in these cases DECL_INCOMING_RTL points us to a value of some
     type which is *different* from the type of the parameter itself.  Thus,
     if we tried to use DECL_INCOMING_RTL to generate a location attribute in
     such cases, the debugger would end up (for example) trying to fetch a
     `float' from a place which actually contains the first part of a
     `double'.  That would lead to really incorrect and confusing
     output at debug-time.

     So, in general, we *do not* use DECL_INCOMING_RTL as a backup for DECL_RTL
     in cases where DECL_ARG_TYPE (decl) != TREE_TYPE (decl).  There
     are a couple of exceptions however.  On little-endian machines we can
     get away with using DECL_INCOMING_RTL even when DECL_ARG_TYPE (decl) is
     not the same as TREE_TYPE (decl), but only when DECL_ARG_TYPE (decl) is
     an integral type that is smaller than TREE_TYPE (decl). These cases arise
     when (on a little-endian machine) a non-prototyped function has a
     parameter declared to be of type `short' or `char'.  In such cases,
     TREE_TYPE (decl) will be `short' or `char', DECL_ARG_TYPE (decl) will
     be `int', and DECL_INCOMING_RTL will point to the lowest-order byte of the
     passed `int' value.  If the debugger then uses that address to fetch
     a `short' or a `char' (on a little-endian machine) the result will be
     the correct data, so we allow for such exceptional cases below.

     Note that our goal here is to describe the place where the given formal
     parameter lives during most of the function's activation (i.e. between the
     end of the prologue and the start of the epilogue).  We'll do that as best
     as we can. Note however that if the given formal parameter is modified
     sometime during the execution of the function, then a stack backtrace (at
     debug-time) will show the function as having been called with the *new*
     value rather than the value which was originally passed in.  This happens
     rarely enough that it is not a major problem, but it *is* a problem, and
     I'd like to fix it.

     A future version of dwarf2out.c may generate two additional attributes for
     any given DW_TAG_formal_parameter DIE which will describe the "passed
     type" and the "passed location" for the given formal parameter in addition
     to the attributes we now generate to indicate the "declared type" and the
     "active location" for each parameter.  This additional set of attributes
     could be used by debuggers for stack backtraces. Separately, note that
     sometimes DECL_RTL can be NULL and DECL_INCOMING_RTL can be NULL also.
     This happens (for example) for inlined-instances of inline function formal
     parameters which are never referenced.  This really shouldn't be
     happening.  All PARM_DECL nodes should get valid non-NULL
     DECL_INCOMING_RTL values.  FIXME.  */

  /* Use DECL_RTL as the "location" unless we find something better.  */
  rtl = DECL_RTL_IF_SET (decl);

  /* When generating abstract instances, ignore everything except
     constants, symbols living in memory, and symbols living in
     fixed registers.  */
  if (! reload_completed)
    {
      if (rtl
	  && (CONSTANT_P (rtl)
	      || (MEM_P (rtl)
	          && CONSTANT_P (XEXP (rtl, 0)))
	      || (REG_P (rtl)
	          && VAR_P (decl)
		  && TREE_STATIC (decl))))
	{
	  rtl = targetm.delegitimize_address (rtl);
	  return rtl;
	}
      rtl = NULL_RTX;
    }
  else if (TREE_CODE (decl) == PARM_DECL)
    {
      if (rtl == NULL_RTX
	  || is_pseudo_reg (rtl)
	  || (MEM_P (rtl)
	      && is_pseudo_reg (XEXP (rtl, 0))
	      && DECL_INCOMING_RTL (decl)
	      && MEM_P (DECL_INCOMING_RTL (decl))
	      && GET_MODE (rtl) == GET_MODE (DECL_INCOMING_RTL (decl))))
	{
	  tree declared_type = TREE_TYPE (decl);
	  tree passed_type = DECL_ARG_TYPE (decl);
	  machine_mode dmode = TYPE_MODE (declared_type);
	  machine_mode pmode = TYPE_MODE (passed_type);

	  /* This decl represents a formal parameter which was optimized out.
	     Note that DECL_INCOMING_RTL may be NULL in here, but we handle
	     all cases where (rtl == NULL_RTX) just below.  */
	  if (dmode == pmode)
	    rtl = DECL_INCOMING_RTL (decl);
	  else if ((rtl == NULL_RTX || is_pseudo_reg (rtl))
		   && SCALAR_INT_MODE_P (dmode)
		   && known_le (GET_MODE_SIZE (dmode), GET_MODE_SIZE (pmode))
		   && DECL_INCOMING_RTL (decl))
	    {
	      rtx inc = DECL_INCOMING_RTL (decl);
	      if (REG_P (inc))
		rtl = inc;
	      else if (MEM_P (inc))
		{
		  if (BYTES_BIG_ENDIAN)
		    rtl = adjust_address_nv (inc, dmode,
					     GET_MODE_SIZE (pmode)
					     - GET_MODE_SIZE (dmode));
		  else
		    rtl = inc;
		}
	    }
	}

      /* If the parm was passed in registers, but lives on the stack, then
	 make a big endian correction if the mode of the type of the
	 parameter is not the same as the mode of the rtl.  */
      /* ??? This is the same series of checks that are made in dbxout.c before
	 we reach the big endian correction code there.  It isn't clear if all
	 of these checks are necessary here, but keeping them all is the safe
	 thing to do.  */
      else if (MEM_P (rtl)
	       && XEXP (rtl, 0) != const0_rtx
	       && ! CONSTANT_P (XEXP (rtl, 0))
	       /* Not passed in memory.  */
	       && !MEM_P (DECL_INCOMING_RTL (decl))
	       /* Not passed by invisible reference.  */
	       && (!REG_P (XEXP (rtl, 0))
		   || REGNO (XEXP (rtl, 0)) == HARD_FRAME_POINTER_REGNUM
		   || REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM
#if !HARD_FRAME_POINTER_IS_ARG_POINTER
		   || REGNO (XEXP (rtl, 0)) == ARG_POINTER_REGNUM
#endif
		     )
	       /* Big endian correction check.  */
	       && BYTES_BIG_ENDIAN
	       && TYPE_MODE (TREE_TYPE (decl)) != GET_MODE (rtl)
	       && known_lt (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl))),
			    UNITS_PER_WORD))
	{
	  machine_mode addr_mode = get_address_mode (rtl);
	  poly_int64 offset = (UNITS_PER_WORD
			       - GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (decl))));

	  rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (decl)),
			     plus_constant (addr_mode, XEXP (rtl, 0), offset));
	}
    }
  else if (VAR_P (decl)
	   && rtl
	   && MEM_P (rtl)
	   && GET_MODE (rtl) != TYPE_MODE (TREE_TYPE (decl)))
    {
      machine_mode addr_mode = get_address_mode (rtl);
      poly_int64 offset = byte_lowpart_offset (TYPE_MODE (TREE_TYPE (decl)),
					       GET_MODE (rtl));

      /* If a variable is declared "register" yet is smaller than
	 a register, then if we store the variable to memory, it
	 looks like we're storing a register-sized value, when in
	 fact we are not.  We need to adjust the offset of the
	 storage location to reflect the actual value's bytes,
	 else gdb will not be able to display it.  */
      if (maybe_ne (offset, 0))
	rtl = gen_rtx_MEM (TYPE_MODE (TREE_TYPE (decl)),
			   plus_constant (addr_mode, XEXP (rtl, 0), offset));
    }

  /* A variable with no DECL_RTL but a DECL_INITIAL is a compile-time constant,
     and will have been substituted directly into all expressions that use it.
     C does not have such a concept, but C++ and other languages do.  */
  if (!rtl && VAR_P (decl) && DECL_INITIAL (decl))
    rtl = rtl_for_decl_init (DECL_INITIAL (decl), TREE_TYPE (decl));

  if (rtl)
    rtl = targetm.delegitimize_address (rtl);

  /* If we don't look past the constant pool, we risk emitting a
     reference to a constant pool entry that isn't referenced from
     code, and thus is not emitted.  */
  if (rtl)
    rtl = avoid_constant_pool_reference (rtl);

  /* Try harder to get a rtl.  If this symbol ends up not being emitted
     in the current CU, resolve_addr will remove the expression referencing
     it.  */
  if (rtl == NULL_RTX
      && !(early_dwarf && (flag_generate_lto || flag_generate_offload))
      && VAR_P (decl)
      && !DECL_EXTERNAL (decl)
      && TREE_STATIC (decl)
      && DECL_NAME (decl)
      && !DECL_HARD_REGISTER (decl)
      && DECL_MODE (decl) != VOIDmode)
    {
      rtl = make_decl_rtl_for_debug (decl);
      if (!MEM_P (rtl)
	  || GET_CODE (XEXP (rtl, 0)) != SYMBOL_REF
	  || SYMBOL_REF_DECL (XEXP (rtl, 0)) != decl)
	rtl = NULL_RTX;
    }

  return rtl;
}

/* Check whether decl is a Fortran COMMON symbol.  If not, NULL_TREE is
   returned.  If so, the decl for the COMMON block is returned, and the
   value is the offset into the common block for the symbol.  */

static tree
fortran_common (tree decl, HOST_WIDE_INT *value)
{
  tree val_expr, cvar;
  machine_mode mode;
  poly_int64 bitsize, bitpos;
  tree offset;
  HOST_WIDE_INT cbitpos;
  int unsignedp, reversep, volatilep = 0;

  /* If the decl isn't a VAR_DECL, or if it isn't static, or if
     it does not have a value (the offset into the common area), or if it
     is thread local (as opposed to global) then it isn't common, and shouldn't
     be handled as such.  */
  if (!VAR_P (decl)
      || !TREE_STATIC (decl)
      || !DECL_HAS_VALUE_EXPR_P (decl)
      || !is_fortran ())
    return NULL_TREE;

  val_expr = DECL_VALUE_EXPR (decl);
  if (TREE_CODE (val_expr) != COMPONENT_REF)
    return NULL_TREE;

  cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset, &mode,
			      &unsignedp, &reversep, &volatilep);

  if (cvar == NULL_TREE
      || !VAR_P (cvar)
      || DECL_ARTIFICIAL (cvar)
      || !TREE_PUBLIC (cvar)
      /* We don't expect to have to cope with variable offsets,
	 since at present all static data must have a constant size.  */
      || !bitpos.is_constant (&cbitpos))
    return NULL_TREE;

  *value = 0;
  if (offset != NULL)
    {
      if (!tree_fits_shwi_p (offset))
	return NULL_TREE;
      *value = tree_to_shwi (offset);
    }
  if (cbitpos != 0)
    *value += cbitpos / BITS_PER_UNIT;

  return cvar;
}

/* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
   data attribute for a variable or a parameter.  We generate the
   DW_AT_const_value attribute only in those cases where the given variable
   or parameter does not have a true "location" either in memory or in a
   register.  This can happen (for example) when a constant is passed as an
   actual argument in a call to an inline function.  (It's possible that
   these things can crop up in other ways also.)  Note that one type of
   constant value which can be passed into an inlined function is a constant
   pointer.  This can happen for example if an actual argument in an inlined
   function call evaluates to a compile-time constant address.

   CACHE_P is true if it is worth caching the location list for DECL,
   so that future calls can reuse it rather than regenerate it from scratch.
   This is true for BLOCK_NONLOCALIZED_VARS in inlined subroutines,
   since we will need to refer to them each time the function is inlined.  */

static bool
add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p)
{
  rtx rtl;
  dw_loc_list_ref list;
  var_loc_list *loc_list;
  cached_dw_loc_list *cache;

  if (early_dwarf)
    return false;

  if (TREE_CODE (decl) == ERROR_MARK)
    return false;

  if (get_AT (die, DW_AT_location)
      || get_AT (die, DW_AT_const_value))
    return true;

  gcc_assert (VAR_P (decl) || TREE_CODE (decl) == PARM_DECL
	      || TREE_CODE (decl) == RESULT_DECL);

  /* Try to get some constant RTL for this decl, and use that as the value of
     the location.  */

  rtl = rtl_for_decl_location (decl);
  if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)
      && add_const_value_attribute (die, rtl))
    return true;

  /* See if we have single element location list that is equivalent to
     a constant value.  That way we are better to use add_const_value_attribute
     rather than expanding constant value equivalent.  */
  loc_list = lookup_decl_loc (decl);
  if (loc_list
      && loc_list->first
      && loc_list->first->next == NULL
      && NOTE_P (loc_list->first->loc)
      && NOTE_VAR_LOCATION (loc_list->first->loc)
      && NOTE_VAR_LOCATION_LOC (loc_list->first->loc))
    {
      struct var_loc_node *node;

      node = loc_list->first;
      rtl = NOTE_VAR_LOCATION_LOC (node->loc);
      if (GET_CODE (rtl) == EXPR_LIST)
	rtl = XEXP (rtl, 0);
      if ((CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)
	  && add_const_value_attribute (die, rtl))
	 return true;
    }
  /* If this decl is from BLOCK_NONLOCALIZED_VARS, we might need its
     list several times.  See if we've already cached the contents.  */
  list = NULL;
  if (loc_list == NULL || cached_dw_loc_list_table == NULL)
    cache_p = false;
  if (cache_p)
    {
      cache = cached_dw_loc_list_table->find_with_hash (decl, DECL_UID (decl));
      if (cache)
	list = cache->loc_list;
    }
  if (list == NULL)
    {
      list = loc_list_from_tree (decl, decl_by_reference_p (decl) ? 0 : 2,
				 NULL);
      /* It is usually worth caching this result if the decl is from
	 BLOCK_NONLOCALIZED_VARS and if the list has at least two elements.  */
      if (cache_p && list && list->dw_loc_next)
	{
	  cached_dw_loc_list **slot
	    = cached_dw_loc_list_table->find_slot_with_hash (decl,
							     DECL_UID (decl),
							     INSERT);
	  cache = ggc_cleared_alloc<cached_dw_loc_list> ();
	  cache->decl_id = DECL_UID (decl);
	  cache->loc_list = list;
	  *slot = cache;
	}
    }
  if (list)
    {
      add_AT_location_description (die, DW_AT_location, list);
      return true;
    }
  /* None of that worked, so it must not really have a location;
     try adding a constant value attribute from the DECL_INITIAL.  */
  return tree_add_const_value_attribute_for_decl (die, decl);
}

/* Attach a DW_AT_const_value attribute to DIE. The value of the
   attribute is the const value T.  */

static bool
tree_add_const_value_attribute (dw_die_ref die, tree t)
{
  tree init;
  tree type = TREE_TYPE (t);
  rtx rtl;

  if (!t || !TREE_TYPE (t) || TREE_TYPE (t) == error_mark_node)
    return false;

  init = t;
  gcc_assert (!DECL_P (init));

  if (TREE_CODE (init) == INTEGER_CST)
    {
      if (tree_fits_uhwi_p (init))
	{
	  add_AT_unsigned (die, DW_AT_const_value, tree_to_uhwi (init));
	  return true;
	}
      if (tree_fits_shwi_p (init))
	{
	  add_AT_int (die, DW_AT_const_value, tree_to_shwi (init));
	  return true;
	}
    }
  /* Generate the RTL even if early_dwarf to force mangling of all refered to
     symbols.  */
  rtl = rtl_for_decl_init (init, type);
  if (rtl && !early_dwarf)
    return add_const_value_attribute (die, rtl);
  /* If the host and target are sane, try harder.  */
  if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
      && initializer_constant_valid_p (init, type))
    {
      HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (init));
      if (size > 0 && (int) size == size)
	{
	  unsigned char *array = ggc_cleared_vec_alloc<unsigned char> (size);

	  if (native_encode_initializer (init, array, size) == size)
	    {
	      add_AT_vec (die, DW_AT_const_value, size, 1, array);
	      return true;
	    }
	  ggc_free (array);
	}
    }
  return false;
}

/* Attach a DW_AT_const_value attribute to VAR_DIE. The value of the
   attribute is the const value of T, where T is an integral constant
   variable with static storage duration
   (so it can't be a PARM_DECL or a RESULT_DECL).  */

static bool
tree_add_const_value_attribute_for_decl (dw_die_ref var_die, tree decl)
{

  if (!decl
      || (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
      || (VAR_P (decl) && !TREE_STATIC (decl)))
    return false;

  if (TREE_READONLY (decl)
      && ! TREE_THIS_VOLATILE (decl)
      && DECL_INITIAL (decl))
    /* OK */;
  else
    return false;

  /* Don't add DW_AT_const_value if abstract origin already has one.  */
  if (get_AT (var_die, DW_AT_const_value))
    return false;

  return tree_add_const_value_attribute (var_die, DECL_INITIAL (decl));
}

/* Convert the CFI instructions for the current function into a
   location list.  This is used for DW_AT_frame_base when we targeting
   a dwarf2 consumer that does not support the dwarf3
   DW_OP_call_frame_cfa.  OFFSET is a constant to be added to all CFA
   expressions.  */

static dw_loc_list_ref
convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset)
{
  int ix;
  dw_fde_ref fde;
  dw_loc_list_ref list, *list_tail;
  dw_cfi_ref cfi;
  dw_cfa_location last_cfa, next_cfa;
  const char *start_label, *last_label, *section;
  dw_cfa_location remember;

  fde = cfun->fde;
  gcc_assert (fde != NULL);

  section = secname_for_decl (current_function_decl);
  list_tail = &list;
  list = NULL;

  memset (&next_cfa, 0, sizeof (next_cfa));
  next_cfa.reg = INVALID_REGNUM;
  remember = next_cfa;

  start_label = fde->dw_fde_begin;

  /* ??? Bald assumption that the CIE opcode list does not contain
     advance opcodes.  */
  FOR_EACH_VEC_ELT (*cie_cfi_vec, ix, cfi)
    lookup_cfa_1 (cfi, &next_cfa, &remember);

  last_cfa = next_cfa;
  last_label = start_label;

  if (fde->dw_fde_second_begin && fde->dw_fde_switch_cfi_index == 0)
    {
      /* If the first partition contained no CFI adjustments, the
	 CIE opcodes apply to the whole first partition.  */
      *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
				 fde->dw_fde_begin, 0, fde->dw_fde_end, 0, section);
      list_tail =&(*list_tail)->dw_loc_next;
      start_label = last_label = fde->dw_fde_second_begin;
    }

  FOR_EACH_VEC_SAFE_ELT (fde->dw_fde_cfi, ix, cfi)
    {
      switch (cfi->dw_cfi_opc)
	{
	case DW_CFA_set_loc:
	case DW_CFA_advance_loc1:
	case DW_CFA_advance_loc2:
	case DW_CFA_advance_loc4:
	  if (!cfa_equal_p (&last_cfa, &next_cfa))
	    {
	      *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
					 start_label, 0, last_label, 0, section);

	      list_tail = &(*list_tail)->dw_loc_next;
	      last_cfa = next_cfa;
	      start_label = last_label;
	    }
	  last_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
	  break;

	case DW_CFA_advance_loc:
	  /* The encoding is complex enough that we should never emit this.  */
	  gcc_unreachable ();

	default:
	  lookup_cfa_1 (cfi, &next_cfa, &remember);
	  break;
	}
      if (ix + 1 == fde->dw_fde_switch_cfi_index)
	{
	  if (!cfa_equal_p (&last_cfa, &next_cfa))
	    {
	      *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
					 start_label, 0, last_label, 0, section);

	      list_tail = &(*list_tail)->dw_loc_next;
	      last_cfa = next_cfa;
	      start_label = last_label;
	    }
	  *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
				     start_label, 0, fde->dw_fde_end, 0, section);
	  list_tail = &(*list_tail)->dw_loc_next;
	  start_label = last_label = fde->dw_fde_second_begin;
	}
    }

  if (!cfa_equal_p (&last_cfa, &next_cfa))
    {
      *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset),
				 start_label, 0, last_label, 0, section);
      list_tail = &(*list_tail)->dw_loc_next;
      start_label = last_label;
    }

  *list_tail = new_loc_list (build_cfa_loc (&next_cfa, offset),
			     start_label, 0,
			     fde->dw_fde_second_begin
			     ? fde->dw_fde_second_end : fde->dw_fde_end, 0,
			     section);

  maybe_gen_llsym (list);

  return list;
}

/* Compute a displacement from the "steady-state frame pointer" to the
   frame base (often the same as the CFA), and store it in
   frame_pointer_fb_offset.  OFFSET is added to the displacement
   before the latter is negated.  */

static void
compute_frame_pointer_to_fb_displacement (poly_int64 offset)
{
  rtx reg, elim;

#ifdef FRAME_POINTER_CFA_OFFSET
  reg = frame_pointer_rtx;
  offset += FRAME_POINTER_CFA_OFFSET (current_function_decl);
#else
  reg = arg_pointer_rtx;
  offset += ARG_POINTER_CFA_OFFSET (current_function_decl);
#endif

  elim = (ira_use_lra_p
	  ? lra_eliminate_regs (reg, VOIDmode, NULL_RTX)
	  : eliminate_regs (reg, VOIDmode, NULL_RTX));
  elim = strip_offset_and_add (elim, &offset);

  frame_pointer_fb_offset = -offset;

  /* ??? AVR doesn't set up valid eliminations when there is no stack frame
     in which to eliminate.  This is because it's stack pointer isn't 
     directly accessible as a register within the ISA.  To work around
     this, assume that while we cannot provide a proper value for
     frame_pointer_fb_offset, we won't need one either.  We can use
     hard frame pointer in debug info even if frame pointer isn't used
     since hard frame pointer in debug info is encoded with DW_OP_fbreg
     which uses the DW_AT_frame_base attribute, not hard frame pointer
     directly.  */
  frame_pointer_fb_offset_valid
    = (elim == hard_frame_pointer_rtx || elim == stack_pointer_rtx);
}

/* Generate a DW_AT_name attribute given some string value to be included as
   the value of the attribute.  */

void
add_name_attribute (dw_die_ref die, const char *name_string)
{
  if (name_string != NULL && *name_string != 0)
    {
      if (demangle_name_func)
	name_string = (*demangle_name_func) (name_string);

      add_AT_string (die, DW_AT_name, name_string);
    }
}

/* Generate a DW_AT_name attribute given some string value representing a
   file or filepath to be included as value of the attribute.  */
static void
add_filename_attribute (dw_die_ref die, const char *name_string)
{
  if (name_string != NULL && *name_string != 0)
    add_filepath_AT_string (die, DW_AT_name, name_string);
}

/* Generate a DW_AT_description attribute given some string value to be included
   as the value of the attribute.  */

static void
add_desc_attribute (dw_die_ref die, const char *name_string)
{
  if (!flag_describe_dies || (dwarf_version < 3 && dwarf_strict))
    return;

  if (name_string == NULL || *name_string == 0)
    return;

  if (demangle_name_func)
    name_string = (*demangle_name_func) (name_string);

  add_AT_string (die, DW_AT_description, name_string);
}

/* Generate a DW_AT_description attribute given some decl to be included
   as the value of the attribute.  */

static void
add_desc_attribute (dw_die_ref die, tree decl)
{
  tree decl_name;

  if (!flag_describe_dies || (dwarf_version < 3 && dwarf_strict))
    return;

  if (decl == NULL_TREE || !DECL_P (decl))
    return;
  decl_name = DECL_NAME (decl);

  if (decl_name != NULL && IDENTIFIER_POINTER (decl_name) != NULL)
    {
      const char *name = dwarf2_name (decl, 0);
      add_desc_attribute (die, name ? name : IDENTIFIER_POINTER (decl_name));
    }
  else
    {
      char *desc = print_generic_expr_to_str (decl);
      add_desc_attribute (die, desc);
      free (desc);
    }
}

/* Retrieve the descriptive type of TYPE, if any, make sure it has a
   DIE and attach a DW_AT_GNAT_descriptive_type attribute to the DIE
   of TYPE accordingly.

   ??? This is a temporary measure until after we're able to generate
   regular DWARF for the complex Ada type system.  */

static void 
add_gnat_descriptive_type_attribute (dw_die_ref die, tree type,
				     dw_die_ref context_die)
{
  tree dtype;
  dw_die_ref dtype_die;

  if (!lang_hooks.types.descriptive_type)
    return;

  dtype = lang_hooks.types.descriptive_type (type);
  if (!dtype)
    return;

  dtype_die = lookup_type_die (dtype);
  if (!dtype_die)
    {
      gen_type_die (dtype, context_die);
      dtype_die = lookup_type_die (dtype);
      gcc_assert (dtype_die);
    }

  add_AT_die_ref (die, DW_AT_GNAT_descriptive_type, dtype_die);
}

/* Retrieve the comp_dir string suitable for use with DW_AT_comp_dir.  */

static const char *
comp_dir_string (void)
{
  const char *wd;
  char *wd_plus_sep = NULL;
  static const char *cached_wd = NULL;

  if (cached_wd != NULL)
    return cached_wd;

  wd = get_src_pwd ();
  if (wd == NULL)
    return NULL;

  if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR)
    {
      size_t wdlen = strlen (wd);
      wd_plus_sep = XNEWVEC (char, wdlen + 2);
      strcpy (wd_plus_sep, wd);
      wd_plus_sep [wdlen] = DIR_SEPARATOR;
      wd_plus_sep [wdlen + 1] = 0;
      wd = wd_plus_sep;
    }

  cached_wd = remap_debug_filename (wd);

  /* remap_debug_filename can just pass through wd or return a new gc string.
     These two types can't be both stored in a GTY(())-tagged string, but since
     the cached value lives forever just copy it if needed.  */
  if (cached_wd != wd)
    {
      cached_wd = xstrdup (cached_wd);
      if (DWARF2_DIR_SHOULD_END_WITH_SEPARATOR && wd_plus_sep != NULL)
        free (wd_plus_sep);
    }

  return cached_wd;
}

/* Generate a DW_AT_comp_dir attribute for DIE.  */

static void
add_comp_dir_attribute (dw_die_ref die)
{
  const char * wd = comp_dir_string ();
  if (wd != NULL)
    add_filepath_AT_string (die, DW_AT_comp_dir, wd);
}

/* Given a tree node VALUE describing a scalar attribute ATTR (i.e. a bound, a
   pointer computation, ...), output a representation for that bound according
   to the accepted FORMS (see enum dw_scalar_form) and add it to DIE.  See
   loc_list_from_tree for the meaning of CONTEXT.  */

static void
add_scalar_info (dw_die_ref die, enum dwarf_attribute attr, tree value,
		 int forms, struct loc_descr_context *context)
{
  dw_die_ref context_die, decl_die = NULL;
  dw_loc_list_ref list;
  bool strip_conversions = true;
  bool placeholder_seen = false;

  while (strip_conversions)
    switch (TREE_CODE (value))
      {
      case ERROR_MARK:
      case SAVE_EXPR:
	return;

      CASE_CONVERT:
      case VIEW_CONVERT_EXPR:
	value = TREE_OPERAND (value, 0);
	break;

      default:
	strip_conversions = false;
	break;
      }

  /* If possible and permitted, output the attribute as a constant.  */
  if ((forms & dw_scalar_form_constant) != 0
      && TREE_CODE (value) == INTEGER_CST)
    {
      unsigned int prec = simple_type_size_in_bits (TREE_TYPE (value));

      /* If HOST_WIDE_INT is big enough then represent the bound as
	 a constant value.  We need to choose a form based on
	 whether the type is signed or unsigned.  We cannot just
	 call add_AT_unsigned if the value itself is positive
	 (add_AT_unsigned might add the unsigned value encoded as
	 DW_FORM_data[1248]).  Some DWARF consumers will lookup the
	 bounds type and then sign extend any unsigned values found
	 for signed types.  This is needed only for
	 DW_AT_{lower,upper}_bound, since for most other attributes,
	 consumers will treat DW_FORM_data[1248] as unsigned values,
	 regardless of the underlying type.  */
      if (prec <= HOST_BITS_PER_WIDE_INT
	  || tree_fits_uhwi_p (value))
	{
	  if (TYPE_UNSIGNED (TREE_TYPE (value)))
	    add_AT_unsigned (die, attr, TREE_INT_CST_LOW (value));
	  else
	    add_AT_int (die, attr, TREE_INT_CST_LOW (value));
	}
      else if (dwarf_version >= 5
	       && TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (value))) == 128)
	/* Otherwise represent the bound as an unsigned value with
	   the precision of its type.  The precision and signedness
	   of the type will be necessary to re-interpret it
	   unambiguously.  */
	add_AT_wide (die, attr, wi::to_wide (value));
      else
	{
	  rtx v = immed_wide_int_const (wi::to_wide (value),
					TYPE_MODE (TREE_TYPE (value)));
	  dw_loc_descr_ref loc
	    = loc_descriptor (v, TYPE_MODE (TREE_TYPE (value)),
			      VAR_INIT_STATUS_INITIALIZED);
	  if (loc)
	    add_AT_loc (die, attr, loc);
	}
      return;
    }

  /* Otherwise, if it's possible and permitted too, output a reference to
     another DIE.  */
  if ((forms & dw_scalar_form_reference) != 0)
    {
      tree decl = NULL_TREE;

      /* Some type attributes reference an outer type.  For instance, the upper
	 bound of an array may reference an embedding record (this happens in
	 Ada).  */
      if (TREE_CODE (value) == COMPONENT_REF
	  && TREE_CODE (TREE_OPERAND (value, 0)) == PLACEHOLDER_EXPR
	  && TREE_CODE (TREE_OPERAND (value, 1)) == FIELD_DECL)
	decl = TREE_OPERAND (value, 1);

      else if (VAR_P (value)
	       || TREE_CODE (value) == PARM_DECL
	       || TREE_CODE (value) == RESULT_DECL)
	decl = value;

      if (decl != NULL_TREE)
	{
	  decl_die = lookup_decl_die (decl);

	  /* ??? Can this happen, or should the variable have been bound
	     first?  Probably it can, since I imagine that we try to create
	     the types of parameters in the order in which they exist in
	     the list, and won't have created a forward reference to a
	     later parameter.  */
	  if (decl_die != NULL)
	    {
	      if (get_AT (decl_die, DW_AT_location)
		  || get_AT (decl_die, DW_AT_data_member_location)
		  || get_AT (decl_die, DW_AT_data_bit_offset)
		  || get_AT (decl_die, DW_AT_const_value))
		{
		  add_AT_die_ref (die, attr, decl_die);
		  return;
		}
	    }
	}
    }

  /* Last chance: try to create a stack operation procedure to evaluate the
     value.  Do nothing if even that is not possible or permitted.  */
  if ((forms & dw_scalar_form_exprloc) == 0)
    return;

  list = loc_list_from_tree (value, 2, context);
  if (context && context->placeholder_arg)
    {
      placeholder_seen = context->placeholder_seen;
      context->placeholder_seen = false;
    }
  if (list == NULL || single_element_loc_list_p (list))
    {
      /* If this attribute is not a reference nor constant, it is
	 a DWARF expression rather than location description.  For that
	 loc_list_from_tree (value, 0, &context) is needed.  */
      dw_loc_list_ref list2 = loc_list_from_tree (value, 0, context);
      if (list2 && single_element_loc_list_p (list2))
	{
	  if (placeholder_seen)
	    {
	      struct dwarf_procedure_info dpi;
	      dpi.fndecl = NULL_TREE;
	      dpi.args_count = 1;
	      if (!resolve_args_picking (list2->expr, 1, &dpi))
		return;
	    }
	  add_AT_loc (die, attr, list2->expr);
	  return;
	}
    }

  /* If that failed to give a single element location list, fall back to
     outputting this as a reference... still if permitted.  */
  if (list == NULL
      || (forms & dw_scalar_form_reference) == 0
      || placeholder_seen)
    return;

  if (!decl_die)
    {
      if (current_function_decl == 0)
	context_die = comp_unit_die ();
      else
	context_die = lookup_decl_die (current_function_decl);

      decl_die = new_die (DW_TAG_variable, context_die, value);
      add_AT_flag (decl_die, DW_AT_artificial, 1);
      add_type_attribute (decl_die, TREE_TYPE (value), TYPE_QUAL_CONST, false,
			  context_die);
    }

  add_AT_location_description (decl_die, DW_AT_location, list);
  add_AT_die_ref (die, attr, decl_die);
}

/* Return the default for DW_AT_lower_bound, or -1 if there is not any
   default.  */

static int
lower_bound_default (void)
{
  switch (get_AT_unsigned (comp_unit_die (), DW_AT_language))
    {
    case DW_LANG_C:
    case DW_LANG_C89:
    case DW_LANG_C99:
    case DW_LANG_C11:
    case DW_LANG_C_plus_plus:
    case DW_LANG_C_plus_plus_11:
    case DW_LANG_C_plus_plus_14:
    case DW_LANG_ObjC:
    case DW_LANG_ObjC_plus_plus:
      return 0;
    case DW_LANG_Fortran77:
    case DW_LANG_Fortran90:
    case DW_LANG_Fortran95:
    case DW_LANG_Fortran03:
    case DW_LANG_Fortran08:
      return 1;
    case DW_LANG_UPC:
    case DW_LANG_D:
    case DW_LANG_Python:
      return dwarf_version >= 4 ? 0 : -1;
    case DW_LANG_Ada95:
    case DW_LANG_Ada83:
    case DW_LANG_Cobol74:
    case DW_LANG_Cobol85:
    case DW_LANG_Modula2:
    case DW_LANG_PLI:
      return dwarf_version >= 4 ? 1 : -1;
    default:
      return -1;
    }
}

/* Given a tree node describing an array bound (either lower or upper) output
   a representation for that bound.  */

static void
add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr,
		tree bound, struct loc_descr_context *context)
{
  int dflt;

  while (1)
    switch (TREE_CODE (bound))
      {
      /* Strip all conversions.  */
      CASE_CONVERT:
      case VIEW_CONVERT_EXPR:
	bound = TREE_OPERAND (bound, 0);
	break;

      /* All fixed-bounds are represented by INTEGER_CST nodes.  Lower bounds
	 are even omitted when they are the default.  */
      case INTEGER_CST:
	/* If the value for this bound is the default one, we can even omit the
	   attribute.  */
	if (bound_attr == DW_AT_lower_bound
	    && tree_fits_shwi_p (bound)
	    && (dflt = lower_bound_default ()) != -1
	    && tree_to_shwi (bound) == dflt)
	  return;

	/* FALLTHRU */

      default:
	/* Let GNAT encodings do the magic for self-referential bounds.  */
	if (is_ada ()
	    && gnat_encodings == DWARF_GNAT_ENCODINGS_ALL
	    && contains_placeholder_p (bound))
	  return;

	add_scalar_info (subrange_die, bound_attr, bound,
			 dw_scalar_form_constant
			 | dw_scalar_form_exprloc
			 | dw_scalar_form_reference,
			 context);
	return;
      }
}

/* Add subscript info to TYPE_DIE, describing an array TYPE, collapsing
   possibly nested array subscripts in a flat sequence if COLLAPSE_P is true.

   This function reuses previously set type and bound information if
   available.  */

static void
add_subscript_info (dw_die_ref type_die, tree type, bool collapse_p)
{
  dw_die_ref child = type_die->die_child;
  struct array_descr_info info;
  int dimension_number;

  if (lang_hooks.types.get_array_descr_info)
    {
      memset (&info, 0, sizeof (info));
      if (lang_hooks.types.get_array_descr_info (type, &info))
	/* Fortran sometimes emits array types with no dimension.  */
	gcc_assert (info.ndimensions >= 0
		    && info.ndimensions
		       <= DWARF2OUT_ARRAY_DESCR_INFO_MAX_DIMEN);
    }
  else
    info.ndimensions = 0;

  for (dimension_number = 0;
       TREE_CODE (type) == ARRAY_TYPE && (dimension_number == 0 || collapse_p);
       type = TREE_TYPE (type), dimension_number++)
    {
      tree domain = TYPE_DOMAIN (type);

      if (TYPE_STRING_FLAG (type) && is_fortran () && dimension_number > 0)
	break;

      /* Arrays come in three flavors: Unspecified bounds, fixed bounds,
	 and (in GNU C only) variable bounds.  Handle all three forms
	 here.  */

      /* Find and reuse a previously generated DW_TAG_subrange_type if
	 available.

         For multi-dimensional arrays, as we iterate through the
         various dimensions in the enclosing for loop above, we also
         iterate through the DIE children and pick at each
         DW_TAG_subrange_type previously generated (if available).
         Each child DW_TAG_subrange_type DIE describes the range of
         the current dimension.  At this point we should have as many
         DW_TAG_subrange_type's as we have dimensions in the
         array.  */
      dw_die_ref subrange_die = NULL;
      if (child)
	while (1)
	  {
	    child = child->die_sib;
	    if (child->die_tag == DW_TAG_subrange_type)
	      subrange_die = child;
	    if (child == type_die->die_child)
	      {
		/* If we wrapped around, stop looking next time.  */
		child = NULL;
		break;
	      }
	    if (child->die_tag == DW_TAG_subrange_type)
	      break;
	  }
      if (!subrange_die)
	subrange_die = new_die (DW_TAG_subrange_type, type_die, NULL);

      if (domain)
	{
	  /* We have an array type with specified bounds.  */
	  tree lower = TYPE_MIN_VALUE (domain);
	  tree upper = TYPE_MAX_VALUE (domain);
	  tree index_type = TREE_TYPE (domain);

	  if (dimension_number <= info.ndimensions - 1)
	    {
	      lower = info.dimen[dimension_number].lower_bound;
	      upper = info.dimen[dimension_number].upper_bound;
	      index_type = info.dimen[dimension_number].bounds_type;
	    }

	  /* Define the index type.  */
	  if (index_type && !get_AT (subrange_die, DW_AT_type))
	    add_type_attribute (subrange_die, index_type, TYPE_UNQUALIFIED,
				false, type_die);

	  /* ??? If upper is NULL, the array has unspecified length,
	     but it does have a lower bound.  This happens with Fortran
	       dimension arr(N:*)
	     Since the debugger is definitely going to need to know N
	     to produce useful results, go ahead and output the lower
	     bound solo, and hope the debugger can cope.  */

	  if (lower && !get_AT (subrange_die, DW_AT_lower_bound))
	    add_bound_info (subrange_die, DW_AT_lower_bound, lower, NULL);

	  if (!get_AT (subrange_die, DW_AT_upper_bound)
	      && !get_AT (subrange_die, DW_AT_count))
	    {
	      if (upper)
		add_bound_info (subrange_die, DW_AT_upper_bound, upper, NULL);
	      else if ((is_c () || is_cxx ()) && COMPLETE_TYPE_P (type))
		/* Zero-length array.  */
		add_bound_info (subrange_die, DW_AT_count,
				build_int_cst (TREE_TYPE (lower), 0), NULL);
	    }
	}

      /* Otherwise we have an array type with an unspecified length.  The
	 DWARF-2 spec does not say how to handle this; let's just leave out the
	 bounds.  */
    }
}

/* Add a DW_AT_byte_size attribute to DIE with TREE_NODE's size.  */

static void
add_byte_size_attribute (dw_die_ref die, tree tree_node)
{
  dw_die_ref decl_die;
  HOST_WIDE_INT size;

  switch (TREE_CODE (tree_node))
    {
    case ERROR_MARK:
      size = 0;
      break;
    case ENUMERAL_TYPE:
    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      if (TREE_CODE (TYPE_SIZE_UNIT (tree_node)) == VAR_DECL
	  && (decl_die = lookup_decl_die (TYPE_SIZE_UNIT (tree_node))))
	{
	  add_AT_die_ref (die, DW_AT_byte_size, decl_die);
	  return;
	}
      size = int_size_in_bytes (tree_node);
      break;
    case FIELD_DECL:
      /* For a data member of a struct or union, the DW_AT_byte_size is
	 generally given as the number of bytes normally allocated for an
	 object of the *declared* type of the member itself.  This is true
	 even for bit-fields.  */
      size = int_size_in_bytes (field_type (tree_node));
      break;
    default:
      gcc_unreachable ();
    }

  /* Note that `size' might be -1 when we get to this point.  If it is, that
     indicates that the byte size of the entity in question is variable.  */
  if (size >= 0)
    add_AT_unsigned (die, DW_AT_byte_size, size);

  /* Support for dynamically-sized objects was introduced in DWARF3.  */
  else if (TYPE_P (tree_node)
	   && (dwarf_version >= 3 || !dwarf_strict)
	   && gnat_encodings != DWARF_GNAT_ENCODINGS_ALL)
    {
      struct loc_descr_context ctx = {
	const_cast<tree> (tree_node),	/* context_type */
	NULL_TREE,	      		/* base_decl */
	NULL,	      		/* dpi */
	false,	      		/* placeholder_arg */
	false,	      		/* placeholder_seen */
	false	      		/* strict_signedness */
      };

      tree tree_size = TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (tree_node));
      add_scalar_info (die, DW_AT_byte_size, tree_size,
		       dw_scalar_form_constant
		       | dw_scalar_form_exprloc
		       | dw_scalar_form_reference,
		       &ctx);
    }
}

/* Add a DW_AT_alignment attribute to DIE with TREE_NODE's non-default
   alignment.  */

static void
add_alignment_attribute (dw_die_ref die, tree tree_node)
{
  if (dwarf_version < 5 && dwarf_strict)
    return;

  unsigned align;

  if (DECL_P (tree_node))
    {
      if (!DECL_USER_ALIGN (tree_node))
	return;

      align = DECL_ALIGN_UNIT (tree_node);
    }
  else if (TYPE_P (tree_node))
    {
      if (!TYPE_USER_ALIGN (tree_node))
	return;

      align = TYPE_ALIGN_UNIT (tree_node);
    }
  else
    gcc_unreachable ();

  add_AT_unsigned (die, DW_AT_alignment, align);
}

/* For a FIELD_DECL node which represents a bit-field, output an attribute
   which specifies the distance in bits from the highest order bit of the
   "containing object" for the bit-field to the highest order bit of the
   bit-field itself.

   For any given bit-field, the "containing object" is a hypothetical object
   (of some integral or enum type) within which the given bit-field lives.  The
   type of this hypothetical "containing object" is always the same as the
   declared type of the individual bit-field itself.  The determination of the
   exact location of the "containing object" for a bit-field is rather
   complicated.  It's handled by the `field_byte_offset' function (above).

   Note that it is the size (in bytes) of the hypothetical "containing object"
   which will be given in the DW_AT_byte_size attribute for this bit-field.
   (See `byte_size_attribute' above).  */

static inline void
add_bit_offset_attribute (dw_die_ref die, tree decl)
{
  HOST_WIDE_INT object_offset_in_bytes;
  tree original_type = DECL_BIT_FIELD_TYPE (decl);
  HOST_WIDE_INT bitpos_int;
  HOST_WIDE_INT highest_order_object_bit_offset;
  HOST_WIDE_INT highest_order_field_bit_offset;
  HOST_WIDE_INT bit_offset;

  /* The containing object is within the DECL_CONTEXT.  */
  struct vlr_context ctx = { DECL_CONTEXT (decl), NULL_TREE };

  field_byte_offset (decl, &ctx, &object_offset_in_bytes);

  /* Must be a field and a bit field.  */
  gcc_assert (original_type && TREE_CODE (decl) == FIELD_DECL);

  /* We can't yet handle bit-fields whose offsets are variable, so if we
     encounter such things, just return without generating any attribute
     whatsoever.  Likewise for variable or too large size.  */
  if (! tree_fits_shwi_p (bit_position (decl))
      || ! tree_fits_uhwi_p (DECL_SIZE (decl)))
    return;

  bitpos_int = int_bit_position (decl);

  /* Note that the bit offset is always the distance (in bits) from the
     highest-order bit of the "containing object" to the highest-order bit of
     the bit-field itself.  Since the "high-order end" of any object or field
     is different on big-endian and little-endian machines, the computation
     below must take account of these differences.  */
  highest_order_object_bit_offset = object_offset_in_bytes * BITS_PER_UNIT;
  highest_order_field_bit_offset = bitpos_int;

  if (! BYTES_BIG_ENDIAN)
    {
      highest_order_field_bit_offset += tree_to_shwi (DECL_SIZE (decl));
      highest_order_object_bit_offset +=
        simple_type_size_in_bits (original_type);
    }

  bit_offset
    = (! BYTES_BIG_ENDIAN
       ? highest_order_object_bit_offset - highest_order_field_bit_offset
       : highest_order_field_bit_offset - highest_order_object_bit_offset);

  if (bit_offset < 0)
    add_AT_int (die, DW_AT_bit_offset, bit_offset);
  else
    add_AT_unsigned (die, DW_AT_bit_offset, (unsigned HOST_WIDE_INT) bit_offset);
}

/* For a FIELD_DECL node which represents a bit field, output an attribute
   which specifies the length in bits of the given field.  */

static inline void
add_bit_size_attribute (dw_die_ref die, tree decl)
{
  /* Must be a field and a bit field.  */
  gcc_assert (TREE_CODE (decl) == FIELD_DECL
	      && DECL_BIT_FIELD_TYPE (decl));

  if (tree_fits_uhwi_p (DECL_SIZE (decl)))
    add_AT_unsigned (die, DW_AT_bit_size, tree_to_uhwi (DECL_SIZE (decl)));
}

/* If the compiled language is ANSI C, then add a 'prototyped'
   attribute, if arg types are given for the parameters of a function.  */

static inline void
add_prototyped_attribute (dw_die_ref die, tree func_type)
{
  switch (get_AT_unsigned (comp_unit_die (), DW_AT_language))
    {
    case DW_LANG_C:
    case DW_LANG_C89:
    case DW_LANG_C99:
    case DW_LANG_C11:
    case DW_LANG_ObjC:
      if (prototype_p (func_type))
	add_AT_flag (die, DW_AT_prototyped, 1);
      break;
    default:
      break;
    }
}

/* Add an 'abstract_origin' attribute below a given DIE.  The DIE is found
   by looking in the type declaration, the object declaration equate table or
   the block mapping.  */

static inline void
add_abstract_origin_attribute (dw_die_ref die, tree origin)
{
  dw_die_ref origin_die = NULL;

  /* For late LTO debug output we want to refer directly to the abstract
     DIE in the early debug rather to the possibly existing concrete
     instance and avoid creating that just for this purpose.  */
  sym_off_pair *desc;
  if (in_lto_p
      && external_die_map
      && (desc = external_die_map->get (origin)))
    {
      add_AT_external_die_ref (die, DW_AT_abstract_origin,
			       desc->sym, desc->off);
      return;
    }

  if (DECL_P (origin))
    origin_die = lookup_decl_die (origin);
  else if (TYPE_P (origin))
    origin_die = lookup_type_die (origin);
  else if (TREE_CODE (origin) == BLOCK)
    origin_die = lookup_block_die (origin);

  /* XXX: Functions that are never lowered don't always have correct block
     trees (in the case of java, they simply have no block tree, in some other
     languages).  For these functions, there is nothing we can really do to
     output correct debug info for inlined functions in all cases.  Rather
     than die, we'll just produce deficient debug info now, in that we will
     have variables without a proper abstract origin.  In the future, when all
     functions are lowered, we should re-add a gcc_assert (origin_die)
     here.  */

  if (origin_die)
    {
      dw_attr_node *a;
      /* Like above, if we already created a concrete instance DIE
	 do not use that for the abstract origin but the early DIE
	 if present.  */
      if (in_lto_p
	  && (a = get_AT (origin_die, DW_AT_abstract_origin)))
	origin_die = AT_ref (a);
      add_AT_die_ref (die, DW_AT_abstract_origin, origin_die);
    }
}

/* We do not currently support the pure_virtual attribute.  */

static inline void
add_pure_or_virtual_attribute (dw_die_ref die, tree func_decl)
{
  if (DECL_VINDEX (func_decl))
    {
      add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual);

      if (tree_fits_shwi_p (DECL_VINDEX (func_decl)))
	add_AT_loc (die, DW_AT_vtable_elem_location,
		    new_loc_descr (DW_OP_constu,
				   tree_to_shwi (DECL_VINDEX (func_decl)),
				   0));

      /* GNU extension: Record what type this method came from originally.  */
      if (debug_info_level > DINFO_LEVEL_TERSE
	  && DECL_CONTEXT (func_decl))
	add_AT_die_ref (die, DW_AT_containing_type,
			lookup_type_die (DECL_CONTEXT (func_decl)));
    }
}

/* Add a DW_AT_linkage_name or DW_AT_MIPS_linkage_name attribute for the
   given decl.  This used to be a vendor extension until after DWARF 4
   standardized it.  */

static void
add_linkage_attr (dw_die_ref die, tree decl)
{
  const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));

  /* Mimic what assemble_name_raw does with a leading '*'.  */
  if (name[0] == '*')
    name = &name[1];

  if (dwarf_version >= 4)
    add_AT_string (die, DW_AT_linkage_name, name);
  else
    add_AT_string (die, DW_AT_MIPS_linkage_name, name);
}

/* Add source coordinate attributes for the given decl.  */

static void
add_src_coords_attributes (dw_die_ref die, tree decl)
{
  expanded_location s;

  if (LOCATION_LOCUS (DECL_SOURCE_LOCATION (decl)) == UNKNOWN_LOCATION)
    return;
  s = expand_location (DECL_SOURCE_LOCATION (decl));
  add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
  add_AT_unsigned (die, DW_AT_decl_line, s.line);
  if (debug_column_info && s.column)
    add_AT_unsigned (die, DW_AT_decl_column, s.column);
}

/* Add DW_AT_{,MIPS_}linkage_name attribute for the given decl.  */

static void
add_linkage_name_raw (dw_die_ref die, tree decl)
{
  /* Defer until we have an assembler name set.  */
  if (!DECL_ASSEMBLER_NAME_SET_P (decl))
    {
      limbo_die_node *asm_name;

      asm_name = ggc_cleared_alloc<limbo_die_node> ();
      asm_name->die = die;
      asm_name->created_for = decl;
      asm_name->next = deferred_asm_name;
      deferred_asm_name = asm_name;
    }
  else if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl))
    add_linkage_attr (die, decl);
}

/* Add DW_AT_{,MIPS_}linkage_name attribute for the given decl if desired.  */

static void
add_linkage_name (dw_die_ref die, tree decl)
{
  if (debug_info_level > DINFO_LEVEL_NONE
      && VAR_OR_FUNCTION_DECL_P (decl)
      && TREE_PUBLIC (decl)
      && !(VAR_P (decl) && DECL_REGISTER (decl))
      && die->die_tag != DW_TAG_member)
    add_linkage_name_raw (die, decl);
}

/* Add a DW_AT_name attribute and source coordinate attribute for the
   given decl, but only if it actually has a name.  */

static void
add_name_and_src_coords_attributes (dw_die_ref die, tree decl,
				    bool no_linkage_name)
{
  tree decl_name;

  decl_name = DECL_NAME (decl);
  if (decl_name != NULL && IDENTIFIER_POINTER (decl_name) != NULL)
    {
      const char *name = dwarf2_name (decl, 0);
      if (name)
	add_name_attribute (die, name);
      else
	add_desc_attribute (die, decl);

      if (! DECL_ARTIFICIAL (decl))
	add_src_coords_attributes (die, decl);

      if (!no_linkage_name)
	add_linkage_name (die, decl);
    }
  else
    add_desc_attribute (die, decl);

#ifdef VMS_DEBUGGING_INFO
  /* Get the function's name, as described by its RTL.  This may be different
     from the DECL_NAME name used in the source file.  */
  if (TREE_CODE (decl) == FUNCTION_DECL && TREE_ASM_WRITTEN (decl))
    {
      add_AT_addr (die, DW_AT_VMS_rtnbeg_pd_address,
                  XEXP (DECL_RTL (decl), 0), false);
      vec_safe_push (used_rtx_array, XEXP (DECL_RTL (decl), 0));
    }
#endif /* VMS_DEBUGGING_INFO */
}

/* Add VALUE as a DW_AT_discr_value attribute to DIE.  */

static void
add_discr_value (dw_die_ref die, dw_discr_value *value)
{
  dw_attr_node attr;

  attr.dw_attr = DW_AT_discr_value;
  attr.dw_attr_val.val_class = dw_val_class_discr_value;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_discr_value.pos = value->pos;
  if (value->pos)
    attr.dw_attr_val.v.val_discr_value.v.uval = value->v.uval;
  else
    attr.dw_attr_val.v.val_discr_value.v.sval = value->v.sval;
  add_dwarf_attr (die, &attr);
}

/* Add DISCR_LIST as a DW_AT_discr_list to DIE.  */

static void
add_discr_list (dw_die_ref die, dw_discr_list_ref discr_list)
{
  dw_attr_node attr;

  attr.dw_attr = DW_AT_discr_list;
  attr.dw_attr_val.val_class = dw_val_class_discr_list;
  attr.dw_attr_val.val_entry = NULL;
  attr.dw_attr_val.v.val_discr_list = discr_list;
  add_dwarf_attr (die, &attr);
}

static inline dw_discr_list_ref
AT_discr_list (dw_attr_node *attr)
{
  return attr->dw_attr_val.v.val_discr_list;
}

#ifdef VMS_DEBUGGING_INFO
/* Output the debug main pointer die for VMS */

void
dwarf2out_vms_debug_main_pointer (void)
{
  char label[MAX_ARTIFICIAL_LABEL_BYTES];
  dw_die_ref die;

  /* Allocate the VMS debug main subprogram die.  */
  die = new_die_raw (DW_TAG_subprogram);
  add_name_attribute (die, VMS_DEBUG_MAIN_POINTER);
  ASM_GENERATE_INTERNAL_LABEL (label, PROLOGUE_END_LABEL,
			       current_function_funcdef_no);
  add_AT_lbl_id (die, DW_AT_entry_pc, label);

  /* Make it the first child of comp_unit_die ().  */
  die->die_parent = comp_unit_die ();
  if (comp_unit_die ()->die_child)
    {
      die->die_sib = comp_unit_die ()->die_child->die_sib;
      comp_unit_die ()->die_child->die_sib = die;
    }
  else
    {
      die->die_sib = die;
      comp_unit_die ()->die_child = die;
    }
}
#endif /* VMS_DEBUGGING_INFO */

/* walk_tree helper function for uses_local_type, below.  */

static tree
uses_local_type_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
{
  if (!TYPE_P (*tp))
    *walk_subtrees = 0;
  else
    {
      tree name = TYPE_NAME (*tp);
      if (name && DECL_P (name) && decl_function_context (name))
	return *tp;
    }
  return NULL_TREE;
}

/* If TYPE involves a function-local type (including a local typedef to a
   non-local type), returns that type; otherwise returns NULL_TREE.  */

static tree
uses_local_type (tree type)
{
  tree used = walk_tree_without_duplicates (&type, uses_local_type_r, NULL);
  return used;
}

/* Return the DIE for the scope that immediately contains this type.
   Non-named types that do not involve a function-local type get global
   scope.  Named types nested in namespaces or other types get their
   containing scope.  All other types (i.e. function-local named types) get
   the current active scope.  */

static dw_die_ref
scope_die_for (tree t, dw_die_ref context_die)
{
  dw_die_ref scope_die = NULL;
  tree containing_scope;

  /* Non-types always go in the current scope.  */
  gcc_assert (TYPE_P (t));

  /* Use the scope of the typedef, rather than the scope of the type
     it refers to.  */
  if (TYPE_NAME (t) && DECL_P (TYPE_NAME (t)))
    containing_scope = DECL_CONTEXT (TYPE_NAME (t));
  else
    containing_scope = TYPE_CONTEXT (t);

  /* Use the containing namespace if there is one.  */
  if (containing_scope && TREE_CODE (containing_scope) == NAMESPACE_DECL)
    {
      if (context_die == lookup_decl_die (containing_scope))
	/* OK */;
      else if (debug_info_level > DINFO_LEVEL_TERSE)
	context_die = get_context_die (containing_scope);
      else
	containing_scope = NULL_TREE;
    }

  /* Ignore function type "scopes" from the C frontend.  They mean that
     a tagged type is local to a parmlist of a function declarator, but
     that isn't useful to DWARF.  */
  if (containing_scope && TREE_CODE (containing_scope) == FUNCTION_TYPE)
    containing_scope = NULL_TREE;

  if (SCOPE_FILE_SCOPE_P (containing_scope))
    {
      /* If T uses a local type keep it local as well, to avoid references
	 to function-local DIEs from outside the function.  */
      if (current_function_decl && uses_local_type (t))
	scope_die = context_die;
      else
	scope_die = comp_unit_die ();
    }
  else if (TYPE_P (containing_scope))
    {
      /* For types, we can just look up the appropriate DIE.  */
      if (debug_info_level > DINFO_LEVEL_TERSE)
	scope_die = get_context_die (containing_scope);
      else
	{
	  scope_die = lookup_type_die_strip_naming_typedef (containing_scope);
	  if (scope_die == NULL)
	    scope_die = comp_unit_die ();
	}
    }
  else
    scope_die = context_die;

  return scope_die;
}

/* Returns nonzero if CONTEXT_DIE is internal to a function.  */

static inline int
local_scope_p (dw_die_ref context_die)
{
  for (; context_die; context_die = context_die->die_parent)
    if (context_die->die_tag == DW_TAG_inlined_subroutine
	|| context_die->die_tag == DW_TAG_subprogram)
      return 1;

  return 0;
}

/* Returns nonzero if CONTEXT_DIE is a class.  */

static inline int
class_scope_p (dw_die_ref context_die)
{
  return (context_die
	  && (context_die->die_tag == DW_TAG_structure_type
	      || context_die->die_tag == DW_TAG_class_type
	      || context_die->die_tag == DW_TAG_interface_type
	      || context_die->die_tag == DW_TAG_union_type));
}

/* Returns nonzero if CONTEXT_DIE is a class or namespace, for deciding
   whether or not to treat a DIE in this context as a declaration.  */

static inline int
class_or_namespace_scope_p (dw_die_ref context_die)
{
  return (class_scope_p (context_die)
	  || (context_die && context_die->die_tag == DW_TAG_namespace));
}

/* Many forms of DIEs require a "type description" attribute.  This
   routine locates the proper "type descriptor" die for the type given
   by 'type' plus any additional qualifiers given by 'cv_quals', and
   adds a DW_AT_type attribute below the given die.  */

static void
add_type_attribute (dw_die_ref object_die, tree type, int cv_quals,
		    bool reverse, dw_die_ref context_die)
{
  enum tree_code code  = TREE_CODE (type);
  dw_die_ref type_die  = NULL;

  if (debug_info_level <= DINFO_LEVEL_TERSE)
    return;

  /* ??? If this type is an unnamed subrange type of an integral, floating-point
     or fixed-point type, use the inner type.  This is because we have no
     support for unnamed types in base_type_die.  This can happen if this is
     an Ada subrange type.  Correct solution is emit a subrange type die.  */
  if ((code == INTEGER_TYPE || code == REAL_TYPE || code == FIXED_POINT_TYPE)
      && TREE_TYPE (type) != 0 && TYPE_NAME (type) == 0)
    type = TREE_TYPE (type), code = TREE_CODE (type);

  if (code == ERROR_MARK
      /* Handle a special case.  For functions whose return type is void, we
	 generate *no* type attribute.  (Note that no object may have type
	 `void', so this only applies to function return types).  */
      || code == VOID_TYPE)
    return;

  type_die = modified_type_die (type,
				cv_quals | TYPE_QUALS (type),
				reverse,
				context_die);

  if (type_die != NULL)
    add_AT_die_ref (object_die, DW_AT_type, type_die);
}

/* Given an object die, add the calling convention attribute for the
   function call type.  */
static void
add_calling_convention_attribute (dw_die_ref subr_die, tree decl)
{
  enum dwarf_calling_convention value = DW_CC_normal;

  value = ((enum dwarf_calling_convention)
	   targetm.dwarf_calling_convention (TREE_TYPE (decl)));

  if (is_fortran ()
      && id_equal (DECL_ASSEMBLER_NAME (decl), "MAIN__"))
    {
      /* DWARF 2 doesn't provide a way to identify a program's source-level
	entry point.  DW_AT_calling_convention attributes are only meant
	to describe functions' calling conventions.  However, lacking a
	better way to signal the Fortran main program, we used this for 
	a long time, following existing custom.  Now, DWARF 4 has 
	DW_AT_main_subprogram, which we add below, but some tools still
	rely on the old way, which we thus keep.  */
      value = DW_CC_program;

      if (dwarf_version >= 4 || !dwarf_strict)
	add_AT_flag (subr_die, DW_AT_main_subprogram, 1);
    }

  /* Only add the attribute if the backend requests it, and
     is not DW_CC_normal.  */
  if (value && (value != DW_CC_normal))
    add_AT_unsigned (subr_die, DW_AT_calling_convention, value);
}

/* Given a tree pointer to a struct, class, union, or enum type node, return
   a pointer to the (string) tag name for the given type, or zero if the type
   was declared without a tag.  */

static const char *
type_tag (const_tree type)
{
  const char *name = 0;

  if (TYPE_NAME (type) != 0)
    {
      tree t = 0;

      /* Find the IDENTIFIER_NODE for the type name.  */
      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE
	  && !TYPE_NAMELESS (type))
	t = TYPE_NAME (type);

      /* The g++ front end makes the TYPE_NAME of *each* tagged type point to
	 a TYPE_DECL node, regardless of whether or not a `typedef' was
	 involved.  */
      else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
	       && ! DECL_IGNORED_P (TYPE_NAME (type)))
	{
	  /* We want to be extra verbose.  Don't call dwarf_name if
	     DECL_NAME isn't set.  The default hook for decl_printable_name
	     doesn't like that, and in this context it's correct to return
	     0, instead of "<anonymous>" or the like.  */
	  if (DECL_NAME (TYPE_NAME (type))
	      && !DECL_NAMELESS (TYPE_NAME (type)))
	    name = lang_hooks.dwarf_name (TYPE_NAME (type), 2);
	}

      /* Now get the name as a string, or invent one.  */
      if (!name && t != 0)
	name = IDENTIFIER_POINTER (t);
    }

  return (name == 0 || *name == '\0') ? 0 : name;
}

/* Return the type associated with a data member, make a special check
   for bit field types.  */

static inline tree
member_declared_type (const_tree member)
{
  return (DECL_BIT_FIELD_TYPE (member)
	  ? DECL_BIT_FIELD_TYPE (member) : TREE_TYPE (member));
}

/* Get the decl's label, as described by its RTL. This may be different
   from the DECL_NAME name used in the source file.  */

#if 0
static const char *
decl_start_label (tree decl)
{
  rtx x;
  const char *fnname;

  x = DECL_RTL (decl);
  gcc_assert (MEM_P (x));

  x = XEXP (x, 0);
  gcc_assert (GET_CODE (x) == SYMBOL_REF);

  fnname = XSTR (x, 0);
  return fnname;
}
#endif

/* For variable-length arrays that have been previously generated, but
   may be incomplete due to missing subscript info, fill the subscript
   info.  Return TRUE if this is one of those cases.  */

static bool
fill_variable_array_bounds (tree type)
{
  if (TREE_ASM_WRITTEN (type)
      && TREE_CODE (type) == ARRAY_TYPE
      && variably_modified_type_p (type, NULL))
    {
      dw_die_ref array_die = lookup_type_die (type);
      if (!array_die)
	return false;
      add_subscript_info (array_die, type, !is_ada ());
      return true;
    }
  return false;
}

/* These routines generate the internal representation of the DIE's for
   the compilation unit.  Debugging information is collected by walking
   the declaration trees passed in from dwarf2out_decl().  */

static void
gen_array_type_die (tree type, dw_die_ref context_die)
{
  dw_die_ref array_die;

  /* GNU compilers represent multidimensional array types as sequences of one
     dimensional array types whose element types are themselves array types.
     We sometimes squish that down to a single array_type DIE with multiple
     subscripts in the Dwarf debugging info.  The draft Dwarf specification
     say that we are allowed to do this kind of compression in C, because
     there is no difference between an array of arrays and a multidimensional
     array.  We don't do this for Ada to remain as close as possible to the
     actual representation, which is especially important against the language
     flexibilty wrt arrays of variable size.  */

  bool collapse_nested_arrays = !is_ada ();

  if (fill_variable_array_bounds (type))
    return;

  dw_die_ref scope_die = scope_die_for (type, context_die);
  tree element_type;

  /* Emit DW_TAG_string_type for Fortran character types (with kind 1 only, as
     DW_TAG_string_type doesn't have DW_AT_type attribute).  */
  if (TREE_CODE (type) == ARRAY_TYPE
      && TYPE_STRING_FLAG (type)
      && is_fortran ()
      && TYPE_MODE (TREE_TYPE (type)) == TYPE_MODE (char_type_node))
    {
      HOST_WIDE_INT size;

      array_die = new_die (DW_TAG_string_type, scope_die, type);
      add_name_attribute (array_die, type_tag (type));
      equate_type_number_to_die (type, array_die);
      size = int_size_in_bytes (type);
      if (size >= 0)
	add_AT_unsigned (array_die, DW_AT_byte_size, size);
      /* ???  We can't annotate types late, but for LTO we may not
	 generate a location early either (gfortran.dg/save_6.f90).  */
      else if (! (early_dwarf && (flag_generate_lto || flag_generate_offload))
	       && TYPE_DOMAIN (type) != NULL_TREE
	       && TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != NULL_TREE)
	{
	  tree szdecl = TYPE_MAX_VALUE (TYPE_DOMAIN (type));
	  tree rszdecl = szdecl;

	  size = int_size_in_bytes (TREE_TYPE (szdecl));
	  if (!DECL_P (szdecl))
	    {
	      if (TREE_CODE (szdecl) == INDIRECT_REF
		  && DECL_P (TREE_OPERAND (szdecl, 0)))
		{
		  rszdecl = TREE_OPERAND (szdecl, 0);
		  if (int_size_in_bytes (TREE_TYPE (rszdecl))
		      != DWARF2_ADDR_SIZE)
		    size = 0;
		}
	      else
		size = 0;
	    }
	  if (size > 0)
	    {
	      dw_loc_list_ref loc
		= loc_list_from_tree (rszdecl, szdecl == rszdecl ? 2 : 0,
				      NULL);
	      if (loc)
		{
		  add_AT_location_description (array_die, DW_AT_string_length,
					       loc);
		  if (size != DWARF2_ADDR_SIZE)
		    add_AT_unsigned (array_die, dwarf_version >= 5
						? DW_AT_string_length_byte_size
						: DW_AT_byte_size, size);
		}
	    }
	}
      return;
    }

  array_die = new_die (DW_TAG_array_type, scope_die, type);
  add_name_attribute (array_die, type_tag (type));
  equate_type_number_to_die (type, array_die);

  if (TREE_CODE (type) == VECTOR_TYPE)
    add_AT_flag (array_die, DW_AT_GNU_vector, 1);

  /* For Fortran multidimensional arrays use DW_ORD_col_major ordering.  */
  if (is_fortran ()
      && TREE_CODE (type) == ARRAY_TYPE
      && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE
      && !TYPE_STRING_FLAG (TREE_TYPE (type)))
    add_AT_unsigned (array_die, DW_AT_ordering, DW_ORD_col_major);

#if 0
  /* We default the array ordering.  Debuggers will probably do the right
     things even if DW_AT_ordering is not present.  It's not even an issue
     until we start to get into multidimensional arrays anyway.  If a debugger
     is ever caught doing the Wrong Thing for multi-dimensional arrays,
     then we'll have to put the DW_AT_ordering attribute back in.  (But if
     and when we find out that we need to put these in, we will only do so
     for multidimensional arrays.  */
  add_AT_unsigned (array_die, DW_AT_ordering, DW_ORD_row_major);
#endif

  if (TREE_CODE (type) == VECTOR_TYPE)
    {
      /* For VECTOR_TYPEs we use an array die with appropriate bounds.  */
      dw_die_ref subrange_die = new_die (DW_TAG_subrange_type, array_die, NULL);
      add_bound_info (subrange_die, DW_AT_lower_bound, size_zero_node, NULL);
      add_bound_info (subrange_die, DW_AT_upper_bound,
		      size_int (TYPE_VECTOR_SUBPARTS (type) - 1), NULL);
    }
  else
    add_subscript_info (array_die, type, collapse_nested_arrays);

  /* Add representation of the type of the elements of this array type and
     emit the corresponding DIE if we haven't done it already.  */
  element_type = TREE_TYPE (type);
  if (collapse_nested_arrays)
    while (TREE_CODE (element_type) == ARRAY_TYPE)
      {
	if (TYPE_STRING_FLAG (element_type) && is_fortran ())
	  break;
	element_type = TREE_TYPE (element_type);
      }

  add_type_attribute (array_die, element_type, TYPE_UNQUALIFIED,
		      TREE_CODE (type) == ARRAY_TYPE
		      && TYPE_REVERSE_STORAGE_ORDER (type),
		      context_die);

  add_gnat_descriptive_type_attribute (array_die, type, context_die);
  if (TYPE_ARTIFICIAL (type))
    add_AT_flag (array_die, DW_AT_artificial, 1);

  if (get_AT (array_die, DW_AT_name))
    add_pubtype (type, array_die);

  add_alignment_attribute (array_die, type);
}

/* This routine generates DIE for array with hidden descriptor, details
   are filled into *info by a langhook.  */

static void
gen_descr_array_type_die (tree type, struct array_descr_info *info,
			  dw_die_ref context_die)
{
  const dw_die_ref scope_die = scope_die_for (type, context_die);
  const dw_die_ref array_die = new_die (DW_TAG_array_type, scope_die, type);
  struct loc_descr_context context = {
    type, 		/* context_type */
    info->base_decl,	/* base_decl */
    NULL,		/* dpi */
    false,		/* placeholder_arg */
    false,		/* placeholder_seen */
    false		/* strict_signedness */
  };
  enum dwarf_tag subrange_tag = DW_TAG_subrange_type;
  int dim;

  add_name_attribute (array_die, type_tag (type));
  equate_type_number_to_die (type, array_die);

  if (info->ndimensions > 1)
    switch (info->ordering)
      {
      case array_descr_ordering_row_major:
	add_AT_unsigned (array_die, DW_AT_ordering, DW_ORD_row_major);
	break;
      case array_descr_ordering_column_major:
	add_AT_unsigned (array_die, DW_AT_ordering, DW_ORD_col_major);
	break;
      default:
	break;
      }

  if (dwarf_version >= 3 || !dwarf_strict)
    {
      if (info->data_location)
	add_scalar_info (array_die, DW_AT_data_location, info->data_location,
			 dw_scalar_form_exprloc, &context);
      if (info->associated)
	add_scalar_info (array_die, DW_AT_associated, info->associated,
			 dw_scalar_form_constant
			 | dw_scalar_form_exprloc
			 | dw_scalar_form_reference, &context);
      if (info->allocated)
	add_scalar_info (array_die, DW_AT_allocated, info->allocated,
			 dw_scalar_form_constant
			 | dw_scalar_form_exprloc
			 | dw_scalar_form_reference, &context);
      if (info->stride)
	{
	  const enum dwarf_attribute attr
	    = (info->stride_in_bits) ? DW_AT_bit_stride : DW_AT_byte_stride;
	  const int forms
	    = (info->stride_in_bits)
	      ? dw_scalar_form_constant
	      : (dw_scalar_form_constant
		 | dw_scalar_form_exprloc
		 | dw_scalar_form_reference);

	  add_scalar_info (array_die, attr, info->stride, forms, &context);
	}
    }
  if (dwarf_version >= 5)
    {
      if (info->rank)
	{
	  add_scalar_info (array_die, DW_AT_rank, info->rank,
			   dw_scalar_form_constant
			   | dw_scalar_form_exprloc, &context);
	  subrange_tag = DW_TAG_generic_subrange;
	  context.placeholder_arg = true;
	}
    }

  add_gnat_descriptive_type_attribute (array_die, type, context_die);

  for (dim = 0; dim < info->ndimensions; dim++)
    {
      dw_die_ref subrange_die = new_die (subrange_tag, array_die, NULL);

      if (info->dimen[dim].bounds_type)
	add_type_attribute (subrange_die,
			    info->dimen[dim].bounds_type, TYPE_UNQUALIFIED,
			    false, context_die);
      if (info->dimen[dim].lower_bound)
	add_bound_info (subrange_die, DW_AT_lower_bound,
			info->dimen[dim].lower_bound, &context);
      if (info->dimen[dim].upper_bound)
	add_bound_info (subrange_die, DW_AT_upper_bound,
			info->dimen[dim].upper_bound, &context);
      if ((dwarf_version >= 3 || !dwarf_strict) && info->dimen[dim].stride)
	add_scalar_info (subrange_die, DW_AT_byte_stride,
			 info->dimen[dim].stride,
			 dw_scalar_form_constant
			 | dw_scalar_form_exprloc
			 | dw_scalar_form_reference,
			 &context);
    }

  gen_type_die (info->element_type, context_die);
  add_type_attribute (array_die, info->element_type, TYPE_UNQUALIFIED,
		      TREE_CODE (type) == ARRAY_TYPE
		      && TYPE_REVERSE_STORAGE_ORDER (type),
		      context_die);

  if (get_AT (array_die, DW_AT_name))
    add_pubtype (type, array_die);

  add_alignment_attribute (array_die, type);
}

#if 0
static void
gen_entry_point_die (tree decl, dw_die_ref context_die)
{
  tree origin = decl_ultimate_origin (decl);
  dw_die_ref decl_die = new_die (DW_TAG_entry_point, context_die, decl);

  if (origin != NULL)
    add_abstract_origin_attribute (decl_die, origin);
  else
    {
      add_name_and_src_coords_attributes (decl_die, decl);
      add_type_attribute (decl_die, TREE_TYPE (TREE_TYPE (decl)),
			  TYPE_UNQUALIFIED, false, context_die);
    }

  if (DECL_ABSTRACT_P (decl))
    equate_decl_number_to_die (decl, decl_die);
  else
    add_AT_lbl_id (decl_die, DW_AT_low_pc, decl_start_label (decl));
}
#endif

/* Walk through the list of incomplete types again, trying once more to
   emit full debugging info for them.  */

static void
retry_incomplete_types (void)
{
  set_early_dwarf s;
  int i;

  for (i = vec_safe_length (incomplete_types) - 1; i >= 0; i--)
    if (should_emit_struct_debug ((*incomplete_types)[i], DINFO_USAGE_DIR_USE))
      gen_type_die ((*incomplete_types)[i], comp_unit_die ());
  vec_safe_truncate (incomplete_types, 0);
}

/* Determine what tag to use for a record type.  */

static enum dwarf_tag
record_type_tag (tree type)
{
  if (! lang_hooks.types.classify_record)
    return DW_TAG_structure_type;

  switch (lang_hooks.types.classify_record (type))
    {
    case RECORD_IS_STRUCT:
      return DW_TAG_structure_type;

    case RECORD_IS_CLASS:
      return DW_TAG_class_type;

    case RECORD_IS_INTERFACE:
      if (dwarf_version >= 3 || !dwarf_strict)
	return DW_TAG_interface_type;
      return DW_TAG_structure_type;

    default:
      gcc_unreachable ();
    }
}

/* Generate a DIE to represent an enumeration type.  Note that these DIEs
   include all of the information about the enumeration values also. Each
   enumerated type name/value is listed as a child of the enumerated type
   DIE.  */

static dw_die_ref
gen_enumeration_type_die (tree type, dw_die_ref context_die)
{
  dw_die_ref type_die = lookup_type_die (type);
  dw_die_ref orig_type_die = type_die;

  if (type_die == NULL)
    {
      type_die = new_die (DW_TAG_enumeration_type,
			  scope_die_for (type, context_die), type);
      equate_type_number_to_die (type, type_die);
      add_name_attribute (type_die, type_tag (type));
      if ((dwarf_version >= 4 || !dwarf_strict)
	  && ENUM_IS_SCOPED (type))
	add_AT_flag (type_die, DW_AT_enum_class, 1);
      if (ENUM_IS_OPAQUE (type) && TYPE_SIZE (type))
	add_AT_flag (type_die, DW_AT_declaration, 1);
      if (!dwarf_strict)
	add_AT_unsigned (type_die, DW_AT_encoding,
			 TYPE_UNSIGNED (type)
			 ? DW_ATE_unsigned
			 : DW_ATE_signed);
    }
  else if (! TYPE_SIZE (type) || ENUM_IS_OPAQUE (type))
    return type_die;
  else
    remove_AT (type_die, DW_AT_declaration);

  /* Handle a GNU C/C++ extension, i.e. incomplete enum types.  If the
     given enum type is incomplete, do not generate the DW_AT_byte_size
     attribute or the DW_AT_element_list attribute.  */
  if (TYPE_SIZE (type))
    {
      tree link;

      if (!ENUM_IS_OPAQUE (type))
	TREE_ASM_WRITTEN (type) = 1;
      if (!orig_type_die || !get_AT (type_die, DW_AT_byte_size))
	add_byte_size_attribute (type_die, type);
      if (!orig_type_die || !get_AT (type_die, DW_AT_alignment))
	add_alignment_attribute (type_die, type);
      if ((dwarf_version >= 3 || !dwarf_strict)
	  && (!orig_type_die || !get_AT (type_die, DW_AT_type)))
	{
	  tree underlying = lang_hooks.types.enum_underlying_base_type (type);
	  add_type_attribute (type_die, underlying, TYPE_UNQUALIFIED, false,
			      context_die);
	}
      if (TYPE_STUB_DECL (type) != NULL_TREE)
	{
	  if (!orig_type_die || !get_AT (type_die, DW_AT_decl_file))
	    add_src_coords_attributes (type_die, TYPE_STUB_DECL (type));
	  if (!orig_type_die || !get_AT (type_die, DW_AT_accessibility))
	    add_accessibility_attribute (type_die, TYPE_STUB_DECL (type));
	}

      /* If the first reference to this type was as the return type of an
	 inline function, then it may not have a parent.  Fix this now.  */
      if (type_die->die_parent == NULL)
	add_child_die (scope_die_for (type, context_die), type_die);

      for (link = TYPE_VALUES (type);
	   link != NULL; link = TREE_CHAIN (link))
	{
	  dw_die_ref enum_die = new_die (DW_TAG_enumerator, type_die, link);
	  tree value = TREE_VALUE (link);

	  if (DECL_P (value))
	    equate_decl_number_to_die (value, enum_die);

	  gcc_assert (!ENUM_IS_OPAQUE (type));
	  add_name_attribute (enum_die,
			      IDENTIFIER_POINTER (TREE_PURPOSE (link)));

	  if (TREE_CODE (value) == CONST_DECL)
	    value = DECL_INITIAL (value);

	  if (simple_type_size_in_bits (TREE_TYPE (value))
	      <= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value))
	    {
	      /* For constant forms created by add_AT_unsigned DWARF
		 consumers (GDB, elfutils, etc.) always zero extend
		 the value.  Only when the actual value is negative
		 do we need to use add_AT_int to generate a constant
		 form that can represent negative values.  */
	      HOST_WIDE_INT val = TREE_INT_CST_LOW (value);
	      if (TYPE_UNSIGNED (TREE_TYPE (value)) || val >= 0)
		add_AT_unsigned (enum_die, DW_AT_const_value,
				 (unsigned HOST_WIDE_INT) val);
	      else
		add_AT_int (enum_die, DW_AT_const_value, val);
	    }
	  else
	    /* Enumeration constants may be wider than HOST_WIDE_INT.  Handle
	       that here.  TODO: This should be re-worked to use correct
	       signed/unsigned double tags for all cases.  */
	    add_AT_wide (enum_die, DW_AT_const_value, wi::to_wide (value));
	}

      add_gnat_descriptive_type_attribute (type_die, type, context_die);
      if (TYPE_ARTIFICIAL (type)
	  && (!orig_type_die || !get_AT (type_die, DW_AT_artificial)))
	add_AT_flag (type_die, DW_AT_artificial, 1);
    }
  else
    add_AT_flag (type_die, DW_AT_declaration, 1);

  add_pubtype (type, type_die);

  return type_die;
}

/* Generate a DIE to represent either a real live formal parameter decl or to
   represent just the type of some formal parameter position in some function
   type.

   Note that this routine is a bit unusual because its argument may be a
   ..._DECL node (i.e. either a PARM_DECL or perhaps a VAR_DECL which
   represents an inlining of some PARM_DECL) or else some sort of a ..._TYPE
   node.  If it's the former then this function is being called to output a
   DIE to represent a formal parameter object (or some inlining thereof).  If
   it's the latter, then this function is only being called to output a
   DW_TAG_formal_parameter DIE to stand as a placeholder for some formal
   argument type of some subprogram type.
   If EMIT_NAME_P is true, name and source coordinate attributes
   are emitted.  */

static dw_die_ref
gen_formal_parameter_die (tree node, tree origin, bool emit_name_p,
			  dw_die_ref context_die)
{
  tree node_or_origin = node ? node : origin;
  tree ultimate_origin;
  dw_die_ref parm_die = NULL;
  
  if (DECL_P (node_or_origin))
    {
      parm_die = lookup_decl_die (node);

      /* If the contexts differ, we may not be talking about the same
	 thing.
	 ???  When in LTO the DIE parent is the "abstract" copy and the
	 context_die is the specification "copy".  */
      if (parm_die
	  && parm_die->die_parent != context_die
	  && (parm_die->die_parent->die_tag != DW_TAG_GNU_formal_parameter_pack
	      || parm_die->die_parent->die_parent != context_die)
	  && !in_lto_p)
	{
	  gcc_assert (!DECL_ABSTRACT_P (node));
	  /* This can happen when creating a concrete instance, in
	     which case we need to create a new DIE that will get
	     annotated with DW_AT_abstract_origin.  */
	  parm_die = NULL;
	}

      if (parm_die && parm_die->die_parent == NULL)
	{
	  /* Check that parm_die already has the right attributes that
	     we would have added below.  If any attributes are
	     missing, fall through to add them.  */
	  if (! DECL_ABSTRACT_P (node_or_origin)
	      && !get_AT (parm_die, DW_AT_location)
	      && !get_AT (parm_die, DW_AT_const_value))
	    /* We are missing  location info, and are about to add it.  */
	    ;
	  else
	    {
	      add_child_die (context_die, parm_die);
	      return parm_die;
	    }
	}
    }

  /* If we have a previously generated DIE, use it, unless this is an
     concrete instance (origin != NULL), in which case we need a new
     DIE with a corresponding DW_AT_abstract_origin.  */
  bool reusing_die;
  if (parm_die && origin == NULL)
    reusing_die = true;
  else
    {
      parm_die = new_die (DW_TAG_formal_parameter, context_die, node);
      reusing_die = false;
    }

  switch (TREE_CODE_CLASS (TREE_CODE (node_or_origin)))
    {
    case tcc_declaration:
      ultimate_origin = decl_ultimate_origin (node_or_origin);
      if (node || ultimate_origin)
	origin = ultimate_origin;

      if (reusing_die)
	goto add_location;

      if (origin != NULL)
	add_abstract_origin_attribute (parm_die, origin);
      else if (emit_name_p)
	add_name_and_src_coords_attributes (parm_die, node);
      if (origin == NULL
	  || (! DECL_ABSTRACT_P (node_or_origin)
	      && variably_modified_type_p (TREE_TYPE (node_or_origin),
					   decl_function_context
							    (node_or_origin))))
	{
	  tree type = TREE_TYPE (node_or_origin);
	  if (decl_by_reference_p (node_or_origin))
	    add_type_attribute (parm_die, TREE_TYPE (type),
				TYPE_UNQUALIFIED,
				false, context_die);
	  else
	    add_type_attribute (parm_die, type,
				decl_quals (node_or_origin),
				false, context_die);
	}
      if (origin == NULL && DECL_ARTIFICIAL (node))
	add_AT_flag (parm_die, DW_AT_artificial, 1);
    add_location:
      if (node && node != origin)
        equate_decl_number_to_die (node, parm_die);
      if (! DECL_ABSTRACT_P (node_or_origin))
	add_location_or_const_value_attribute (parm_die, node_or_origin,
					       node == NULL);

      break;

    case tcc_type:
      /* We were called with some kind of a ..._TYPE node.  */
      add_type_attribute (parm_die, node_or_origin, TYPE_UNQUALIFIED, false,
			  context_die);
      break;

    default:
      gcc_unreachable ();
    }

  return parm_die;
}

/* Generate and return a DW_TAG_GNU_formal_parameter_pack. Also generate
   children DW_TAG_formal_parameter DIEs representing the arguments of the
   parameter pack.

   PARM_PACK must be a function parameter pack.
   PACK_ARG is the first argument of the parameter pack. Its TREE_CHAIN
   must point to the subsequent arguments of the function PACK_ARG belongs to.
   SUBR_DIE is the DIE of the function PACK_ARG belongs to.
   If NEXT_ARG is non NULL, *NEXT_ARG is set to the function argument
   following the last one for which a DIE was generated.  */

static dw_die_ref
gen_formal_parameter_pack_die  (tree parm_pack,
				tree pack_arg,
				dw_die_ref subr_die,
				tree *next_arg)
{
  tree arg;
  dw_die_ref parm_pack_die;

  gcc_assert (parm_pack
	      && lang_hooks.function_parameter_pack_p (parm_pack)
	      && subr_die);

  parm_pack_die = new_die (DW_TAG_GNU_formal_parameter_pack, subr_die, parm_pack);
  add_src_coords_attributes (parm_pack_die, parm_pack);

  for (arg = pack_arg; arg; arg = DECL_CHAIN (arg))
    {
      if (! lang_hooks.decls.function_parm_expanded_from_pack_p (arg,
								 parm_pack))
	break;
      gen_formal_parameter_die (arg, NULL,
				false /* Don't emit name attribute.  */,
				parm_pack_die);
    }
  if (next_arg)
    *next_arg = arg;
  return parm_pack_die;
}

/* Generate a special type of DIE used as a stand-in for a trailing ellipsis
   at the end of an (ANSI prototyped) formal parameters list.  */

static void
gen_unspecified_parameters_die (tree decl_or_type, dw_die_ref context_die)
{
  new_die (DW_TAG_unspecified_parameters, context_die, decl_or_type);
}

/* Generate a list of nameless DW_TAG_formal_parameter DIEs (and perhaps a
   DW_TAG_unspecified_parameters DIE) to represent the types of the formal
   parameters as specified in some function type specification (except for
   those which appear as part of a function *definition*).  */

static void
gen_formal_types_die (tree function_or_method_type, dw_die_ref context_die)
{
  tree link;
  tree formal_type = NULL;
  tree first_parm_type;
  tree arg;

  if (TREE_CODE (function_or_method_type) == FUNCTION_DECL)
    {
      arg = DECL_ARGUMENTS (function_or_method_type);
      function_or_method_type = TREE_TYPE (function_or_method_type);
    }
  else
    arg = NULL_TREE;

  first_parm_type = TYPE_ARG_TYPES (function_or_method_type);

  /* Make our first pass over the list of formal parameter types and output a
     DW_TAG_formal_parameter DIE for each one.  */
  for (link = first_parm_type; link; )
    {
      dw_die_ref parm_die;

      formal_type = TREE_VALUE (link);
      if (formal_type == void_type_node)
	break;

      /* Output a (nameless) DIE to represent the formal parameter itself.  */
      parm_die = gen_formal_parameter_die (formal_type, NULL,
					   true /* Emit name attribute.  */,
					   context_die);
      if (TREE_CODE (function_or_method_type) == METHOD_TYPE
	  && link == first_parm_type)
	{
	  add_AT_flag (parm_die, DW_AT_artificial, 1);
	  if (dwarf_version >= 3 || !dwarf_strict)
	    add_AT_die_ref (context_die, DW_AT_object_pointer, parm_die);
	}
      else if (arg && DECL_ARTIFICIAL (arg))
	add_AT_flag (parm_die, DW_AT_artificial, 1);

      link = TREE_CHAIN (link);
      if (arg)
	arg = DECL_CHAIN (arg);
    }

  /* If this function type has an ellipsis, add a
     DW_TAG_unspecified_parameters DIE to the end of the parameter list.  */
  if (formal_type != void_type_node)
    gen_unspecified_parameters_die (function_or_method_type, context_die);

  /* Make our second (and final) pass over the list of formal parameter types
     and output DIEs to represent those types (as necessary).  */
  for (link = TYPE_ARG_TYPES (function_or_method_type);
       link && TREE_VALUE (link);
       link = TREE_CHAIN (link))
    gen_type_die (TREE_VALUE (link), context_die);
}

/* We want to generate the DIE for TYPE so that we can generate the
   die for MEMBER, which has been defined; we will need to refer back
   to the member declaration nested within TYPE.  If we're trying to
   generate minimal debug info for TYPE, processing TYPE won't do the
   trick; we need to attach the member declaration by hand.  */

static void
gen_type_die_for_member (tree type, tree member, dw_die_ref context_die)
{
  gen_type_die (type, context_die);

  /* If we're trying to avoid duplicate debug info, we may not have
     emitted the member decl for this function.  Emit it now.  */
  if (TYPE_STUB_DECL (type)
      && TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))
      && ! lookup_decl_die (member))
    {
      dw_die_ref type_die;
      gcc_assert (!decl_ultimate_origin (member));

      type_die = lookup_type_die_strip_naming_typedef (type);
      if (TREE_CODE (member) == FUNCTION_DECL)
	gen_subprogram_die (member, type_die);
      else if (TREE_CODE (member) == FIELD_DECL)
	{
	  /* Ignore the nameless fields that are used to skip bits but handle
	     C++ anonymous unions and structs.  */
	  if (DECL_NAME (member) != NULL_TREE
	      || TREE_CODE (TREE_TYPE (member)) == UNION_TYPE
	      || TREE_CODE (TREE_TYPE (member)) == RECORD_TYPE)
	    {
	      struct vlr_context vlr_ctx = {
		DECL_CONTEXT (member), /* struct_type */
		NULL_TREE /* variant_part_offset */
	      };
	      gen_type_die (member_declared_type (member), type_die);
	      gen_field_die (member, &vlr_ctx, type_die);
	    }
	}
      else
	gen_variable_die (member, NULL_TREE, type_die);
    }
}

/* Forward declare these functions, because they are mutually recursive
  with their set_block_* pairing functions.  */
static void set_decl_origin_self (tree);

/* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the
   given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so
   that it points to the node itself, thus indicating that the node is its
   own (abstract) origin.  Additionally, if the BLOCK_ABSTRACT_ORIGIN for
   the given node is NULL, recursively descend the decl/block tree which
   it is the root of, and for each other ..._DECL or BLOCK node contained
   therein whose DECL_ABSTRACT_ORIGINs or BLOCK_ABSTRACT_ORIGINs are also
   still NULL, set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN
   values to point to themselves.  */

static void
set_block_origin_self (tree stmt)
{
  if (BLOCK_ABSTRACT_ORIGIN (stmt) == NULL_TREE)
    {
      BLOCK_ABSTRACT_ORIGIN (stmt) = stmt;

      {
	tree local_decl;

	for (local_decl = BLOCK_VARS (stmt);
	     local_decl != NULL_TREE;
	     local_decl = DECL_CHAIN (local_decl))
	  /* Do not recurse on nested functions since the inlining status
	     of parent and child can be different as per the DWARF spec.  */
	  if (TREE_CODE (local_decl) != FUNCTION_DECL
	      && !DECL_EXTERNAL (local_decl))
	    set_decl_origin_self (local_decl);
      }

      {
	tree subblock;

	for (subblock = BLOCK_SUBBLOCKS (stmt);
	     subblock != NULL_TREE;
	     subblock = BLOCK_CHAIN (subblock))
	  set_block_origin_self (subblock);	/* Recurse.  */
      }
    }
}

/* Given a pointer to some ..._DECL node, if the DECL_ABSTRACT_ORIGIN for
   the given ..._DECL node is NULL, set the DECL_ABSTRACT_ORIGIN for the
   node to so that it points to the node itself, thus indicating that the
   node represents its own (abstract) origin.  Additionally, if the
   DECL_ABSTRACT_ORIGIN for the given node is NULL, recursively descend
   the decl/block tree of which the given node is the root of, and for
   each other ..._DECL or BLOCK node contained therein whose
   DECL_ABSTRACT_ORIGINs or BLOCK_ABSTRACT_ORIGINs are also still NULL,
   set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN values to
   point to themselves.  */

static void
set_decl_origin_self (tree decl)
{
  if (DECL_ABSTRACT_ORIGIN (decl) == NULL_TREE)
    {
      DECL_ABSTRACT_ORIGIN (decl) = decl;
      if (TREE_CODE (decl) == FUNCTION_DECL)
	{
	  tree arg;

	  for (arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg))
	    DECL_ABSTRACT_ORIGIN (arg) = arg;
	  if (DECL_INITIAL (decl) != NULL_TREE
	      && DECL_INITIAL (decl) != error_mark_node)
	    set_block_origin_self (DECL_INITIAL (decl));
	}
    }
}

/* Mark the early DIE for DECL as the abstract instance.  */

static void
dwarf2out_abstract_function (tree decl)
{
  dw_die_ref old_die;

  /* Make sure we have the actual abstract inline, not a clone.  */
  decl = DECL_ORIGIN (decl);

  if (DECL_IGNORED_P (decl))
    return;

  /* In LTO we're all set.  We already created abstract instances
     early and we want to avoid creating a concrete instance of that
     if we don't output it.  */
  if (in_lto_p)
    return;

  old_die = lookup_decl_die (decl);
  gcc_assert (old_die != NULL);
  if (get_AT (old_die, DW_AT_inline))
    /* We've already generated the abstract instance.  */
    return;

  /* Go ahead and put DW_AT_inline on the DIE.  */
  if (DECL_DECLARED_INLINE_P (decl))
    {
      if (cgraph_function_possibly_inlined_p (decl))
	add_AT_unsigned (old_die, DW_AT_inline, DW_INL_declared_inlined);
      else
	add_AT_unsigned (old_die, DW_AT_inline, DW_INL_declared_not_inlined);
    }
  else
    {
      if (cgraph_function_possibly_inlined_p (decl))
	add_AT_unsigned (old_die, DW_AT_inline, DW_INL_inlined);
      else
	add_AT_unsigned (old_die, DW_AT_inline, DW_INL_not_inlined);
    }

  if (DECL_DECLARED_INLINE_P (decl)
      && lookup_attribute ("artificial", DECL_ATTRIBUTES (decl)))
    add_AT_flag (old_die, DW_AT_artificial, 1);

  set_decl_origin_self (decl);
}

/* Helper function of premark_used_types() which gets called through
   htab_traverse.

   Marks the DIE of a given type in *SLOT as perennial, so it never gets
   marked as unused by prune_unused_types.  */

bool
premark_used_types_helper (tree const &type, void *)
{
  dw_die_ref die;

  die = lookup_type_die (type);
  if (die != NULL)
    die->die_perennial_p = 1;
  return true;
}

/* Helper function of premark_types_used_by_global_vars which gets called
   through htab_traverse.

   Marks the DIE of a given type in *SLOT as perennial, so it never gets
   marked as unused by prune_unused_types. The DIE of the type is marked
   only if the global variable using the type will actually be emitted.  */

int
premark_types_used_by_global_vars_helper (types_used_by_vars_entry **slot,
					  void *)
{
  struct types_used_by_vars_entry *entry;
  dw_die_ref die;

  entry = (struct types_used_by_vars_entry *) *slot;
  gcc_assert (entry->type != NULL
	      && entry->var_decl != NULL);
  die = lookup_type_die (entry->type);
  if (die)
    {
      /* Ask cgraph if the global variable really is to be emitted.
         If yes, then we'll keep the DIE of ENTRY->TYPE.  */
      varpool_node *node = varpool_node::get (entry->var_decl);
      if (node && node->definition)
	{
	  die->die_perennial_p = 1;
	  /* Keep the parent DIEs as well.  */
	  while ((die = die->die_parent) && die->die_perennial_p == 0)
	    die->die_perennial_p = 1;
	}
    }
  return 1;
}

/* Mark all members of used_types_hash as perennial.  */

static void
premark_used_types (struct function *fun)
{
  if (fun && fun->used_types_hash)
    fun->used_types_hash->traverse<void *, premark_used_types_helper> (NULL);
}

/* Mark all members of types_used_by_vars_entry as perennial.  */

static void
premark_types_used_by_global_vars (void)
{
  if (types_used_by_vars_hash)
    types_used_by_vars_hash
      ->traverse<void *, premark_types_used_by_global_vars_helper> (NULL);
}

/* Mark all variables used by the symtab as perennial.  */

static void
premark_used_variables (void)
{
  /* Mark DIEs in the symtab as used.  */
  varpool_node *var;
  FOR_EACH_VARIABLE (var)
    {
      dw_die_ref die = lookup_decl_die (var->decl);
      if (die)
	die->die_perennial_p = 1;
    }
}

/* Generate a DW_TAG_call_site DIE in function DECL under SUBR_DIE
   for CA_LOC call arg loc node.  */

static dw_die_ref
gen_call_site_die (tree decl, dw_die_ref subr_die,
		   struct call_arg_loc_node *ca_loc)
{
  dw_die_ref stmt_die = NULL, die;
  tree block = ca_loc->block;

  while (block
	 && block != DECL_INITIAL (decl)
	 && TREE_CODE (block) == BLOCK)
    {
      stmt_die = lookup_block_die (block);
      if (stmt_die)
	break;
      block = BLOCK_SUPERCONTEXT (block);
    }
  if (stmt_die == NULL)
    stmt_die = subr_die;
  die = new_die (dwarf_TAG (DW_TAG_call_site), stmt_die, NULL_TREE);
  add_AT_lbl_id (die, dwarf_AT (DW_AT_call_return_pc), ca_loc->label);
  if (ca_loc->tail_call_p)
    add_AT_flag (die, dwarf_AT (DW_AT_call_tail_call), 1);
  if (ca_loc->symbol_ref)
    {
      dw_die_ref tdie = lookup_decl_die (SYMBOL_REF_DECL (ca_loc->symbol_ref));
      if (tdie)
	add_AT_die_ref (die, dwarf_AT (DW_AT_call_origin), tdie);
      else
	add_AT_addr (die, dwarf_AT (DW_AT_call_origin), ca_loc->symbol_ref,
		     false);
    }
  return die;
}

/* Generate a DIE to represent a declared function (either file-scope or
   block-local).  */

static void
gen_subprogram_die (tree decl, dw_die_ref context_die)
{
  tree origin = decl_ultimate_origin (decl);
  dw_die_ref subr_die;
  dw_die_ref old_die = lookup_decl_die (decl);
  bool old_die_had_no_children = false;

  /* This function gets called multiple times for different stages of
     the debug process.  For example, for func() in this code:

	namespace S
	{
	  void func() { ... }
	}

     ...we get called 4 times.  Twice in early debug and twice in
     late debug:

     Early debug
     -----------

       1. Once while generating func() within the namespace.  This is
          the declaration.  The declaration bit below is set, as the
          context is the namespace.

	  A new DIE will be generated with DW_AT_declaration set.

       2. Once for func() itself.  This is the specification.  The
          declaration bit below is clear as the context is the CU.

	  We will use the cached DIE from (1) to create a new DIE with
	  DW_AT_specification pointing to the declaration in (1).

     Late debug via rest_of_handle_final()
     -------------------------------------

       3. Once generating func() within the namespace.  This is also the
          declaration, as in (1), but this time we will early exit below
          as we have a cached DIE and a declaration needs no additional
          annotations (no locations), as the source declaration line
          info is enough.

       4. Once for func() itself.  As in (2), this is the specification,
          but this time we will re-use the cached DIE, and just annotate
          it with the location information that should now be available.

     For something without namespaces, but with abstract instances, we
     are also called a multiple times:

        class Base
	{
	public:
	  Base ();	  // constructor declaration (1)
	};

	Base::Base () { } // constructor specification (2)

    Early debug
    -----------

       1. Once for the Base() constructor by virtue of it being a
          member of the Base class.  This is done via
          rest_of_type_compilation.

	  This is a declaration, so a new DIE will be created with
	  DW_AT_declaration.

       2. Once for the Base() constructor definition, but this time
          while generating the abstract instance of the base
          constructor (__base_ctor) which is being generated via early
          debug of reachable functions.

	  Even though we have a cached version of the declaration (1),
	  we will create a DW_AT_specification of the declaration DIE
	  in (1).

       3. Once for the __base_ctor itself, but this time, we generate
          an DW_AT_abstract_origin version of the DW_AT_specification in
	  (2).

    Late debug via rest_of_handle_final
    -----------------------------------

       4. One final time for the __base_ctor (which will have a cached
          DIE with DW_AT_abstract_origin created in (3).  This time,
          we will just annotate the location information now
          available.
  */
  int declaration = (current_function_decl != decl
		     || (!DECL_INITIAL (decl) && !origin)
		     || class_or_namespace_scope_p (context_die));

  /* A declaration that has been previously dumped needs no
     additional information.  */
  if (old_die && declaration)
    return;

  if (in_lto_p && old_die && old_die->die_child == NULL)
    old_die_had_no_children = true;

  /* Now that the C++ front end lazily declares artificial member fns, we
     might need to retrofit the declaration into its class.  */
  if (!declaration && !origin && !old_die
      && DECL_CONTEXT (decl) && TYPE_P (DECL_CONTEXT (decl))
      && !class_or_namespace_scope_p (context_die)
      && debug_info_level > DINFO_LEVEL_TERSE)
    old_die = force_decl_die (decl);

  /* A concrete instance, tag a new DIE with DW_AT_abstract_origin.  */
  if (origin != NULL)
    {
      gcc_assert (!declaration || local_scope_p (context_die));

      /* Fixup die_parent for the abstract instance of a nested
	 inline function.  */
      if (old_die && old_die->die_parent == NULL)
	add_child_die (context_die, old_die);

      if (old_die && get_AT_ref (old_die, DW_AT_abstract_origin))
	{
	  /* If we have a DW_AT_abstract_origin we have a working
	     cached version.  */
	  subr_die = old_die;
	}
      else
	{
	  subr_die = new_die (DW_TAG_subprogram, context_die, decl);
	  add_abstract_origin_attribute (subr_die, origin);
	  /*  This is where the actual code for a cloned function is.
	      Let's emit linkage name attribute for it.  This helps
	      debuggers to e.g, set breakpoints into
	      constructors/destructors when the user asks "break
	      K::K".  */
	  add_linkage_name (subr_die, decl);
	}
    }
  /* A cached copy, possibly from early dwarf generation.  Reuse as
     much as possible.  */
  else if (old_die)
    {
      if (!get_AT_flag (old_die, DW_AT_declaration)
	  /* We can have a normal definition following an inline one in the
	     case of redefinition of GNU C extern inlines.
	     It seems reasonable to use AT_specification in this case.  */
	  && !get_AT (old_die, DW_AT_inline))
	{
	  /* Detect and ignore this case, where we are trying to output
	     something we have already output.  */
	  if (get_AT (old_die, DW_AT_low_pc)
	      || get_AT (old_die, DW_AT_ranges))
	    return;

	  /* If we have no location information, this must be a
	     partially generated DIE from early dwarf generation.
	     Fall through and generate it.  */
	}

      /* If the definition comes from the same place as the declaration,
	 maybe use the old DIE.  We always want the DIE for this function
	 that has the *_pc attributes to be under comp_unit_die so the
	 debugger can find it.  We also need to do this for abstract
	 instances of inlines, since the spec requires the out-of-line copy
	 to have the same parent.  For local class methods, this doesn't
	 apply; we just use the old DIE.  */
      expanded_location s = expand_location (DECL_SOURCE_LOCATION (decl));
      struct dwarf_file_data * file_index = lookup_filename (s.file);
      if (((is_unit_die (old_die->die_parent)
	    /* This condition fixes the inconsistency/ICE with the
	       following Fortran test (or some derivative thereof) while
	       building libgfortran:

		  module some_m
		  contains
		     logical function funky (FLAG)
		       funky = .true.
		    end function
		  end module
	     */
	    || (old_die->die_parent
		&& old_die->die_parent->die_tag == DW_TAG_module)
	    || local_scope_p (old_die->die_parent)
	    || context_die == NULL)
	   && (DECL_ARTIFICIAL (decl)
	       || (get_AT_file (old_die, DW_AT_decl_file) == file_index
		   && (get_AT_unsigned (old_die, DW_AT_decl_line)
		       == (unsigned) s.line)
		   && (!debug_column_info
		       || s.column == 0
		       || (get_AT_unsigned (old_die, DW_AT_decl_column)
			   == (unsigned) s.column)))))
	  /* With LTO if there's an abstract instance for
	     the old DIE, this is a concrete instance and
	     thus re-use the DIE.  */
	  || get_AT (old_die, DW_AT_abstract_origin))
	{
	  subr_die = old_die;

	  /* Clear out the declaration attribute, but leave the
	     parameters so they can be augmented with location
	     information later.  Unless this was a declaration, in
	     which case, wipe out the nameless parameters and recreate
	     them further down.  */
	  if (remove_AT (subr_die, DW_AT_declaration))
	    {

	      remove_AT (subr_die, DW_AT_object_pointer);
	      remove_child_TAG (subr_die, DW_TAG_formal_parameter);
	    }
	}
      /* Make a specification pointing to the previously built
	 declaration.  */
      else
	{
	  subr_die = new_die (DW_TAG_subprogram, context_die, decl);
	  add_AT_specification (subr_die, old_die);
          add_pubname (decl, subr_die);
	  if (get_AT_file (old_die, DW_AT_decl_file) != file_index)
	    add_AT_file (subr_die, DW_AT_decl_file, file_index);
	  if (get_AT_unsigned (old_die, DW_AT_decl_line) != (unsigned) s.line)
	    add_AT_unsigned (subr_die, DW_AT_decl_line, s.line);
	  if (debug_column_info
	      && s.column
	      && (get_AT_unsigned (old_die, DW_AT_decl_column)
		  != (unsigned) s.column))
	    add_AT_unsigned (subr_die, DW_AT_decl_column, s.column);

	  /* If the prototype had an 'auto' or 'decltype(auto)' in
	     the return type, emit the real type on the definition die.  */
	  if (is_cxx () && debug_info_level > DINFO_LEVEL_TERSE)
	    {
	      dw_die_ref die = get_AT_ref (old_die, DW_AT_type);
	      while (die
		     && (die->die_tag == DW_TAG_reference_type
			 || die->die_tag == DW_TAG_rvalue_reference_type
			 || die->die_tag == DW_TAG_pointer_type
			 || die->die_tag == DW_TAG_const_type
			 || die->die_tag == DW_TAG_volatile_type
			 || die->die_tag == DW_TAG_restrict_type
			 || die->die_tag == DW_TAG_array_type
			 || die->die_tag == DW_TAG_ptr_to_member_type
			 || die->die_tag == DW_TAG_subroutine_type))
		die = get_AT_ref (die, DW_AT_type);
	      if (die == auto_die || die == decltype_auto_die)
		add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
				    TYPE_UNQUALIFIED, false, context_die);
	    }

	  /* When we process the method declaration, we haven't seen
	     the out-of-class defaulted definition yet, so we have to
	     recheck now.  */
	  if ((dwarf_version >= 5 || ! dwarf_strict)
	      && !get_AT (subr_die, DW_AT_defaulted))
	    {
	      int defaulted
		= lang_hooks.decls.decl_dwarf_attribute (decl,
							 DW_AT_defaulted);
	      if (defaulted != -1)
		{
		  /* Other values must have been handled before.  */
		  gcc_assert (defaulted == DW_DEFAULTED_out_of_class);
		  add_AT_unsigned (subr_die, DW_AT_defaulted, defaulted);
		}
	    }
	}
    }
  /* Create a fresh DIE for anything else.  */
  else
    {
      subr_die = new_die (DW_TAG_subprogram, context_die, decl);

      if (TREE_PUBLIC (decl))
	add_AT_flag (subr_die, DW_AT_external, 1);

      add_name_and_src_coords_attributes (subr_die, decl);
      add_pubname (decl, subr_die);
      if (debug_info_level > DINFO_LEVEL_TERSE)
	{
	  add_prototyped_attribute (subr_die, TREE_TYPE (decl));
	  add_type_attribute (subr_die, TREE_TYPE (TREE_TYPE (decl)),
			      TYPE_UNQUALIFIED, false, context_die);
	}

      add_pure_or_virtual_attribute (subr_die, decl);
      if (DECL_ARTIFICIAL (decl))
	add_AT_flag (subr_die, DW_AT_artificial, 1);

      if (TREE_THIS_VOLATILE (decl) && (dwarf_version >= 5 || !dwarf_strict))
	add_AT_flag (subr_die, DW_AT_noreturn, 1);

      add_alignment_attribute (subr_die, decl);

      add_accessibility_attribute (subr_die, decl);
    }

  /* Unless we have an existing non-declaration DIE, equate the new
     DIE.  */
  if (!old_die || is_declaration_die (old_die))
    equate_decl_number_to_die (decl, subr_die);

  if (declaration)
    {
      if (!old_die || !get_AT (old_die, DW_AT_inline))
	{
	  add_AT_flag (subr_die, DW_AT_declaration, 1);

	  /* If this is an explicit function declaration then generate
	     a DW_AT_explicit attribute.  */
	  if ((dwarf_version >= 3 || !dwarf_strict)
	      && lang_hooks.decls.decl_dwarf_attribute (decl,
							DW_AT_explicit) == 1)
	    add_AT_flag (subr_die, DW_AT_explicit, 1);

	  /* If this is a C++11 deleted special function member then generate
	     a DW_AT_deleted attribute.  */
	  if ((dwarf_version >= 5 || !dwarf_strict)
	      && lang_hooks.decls.decl_dwarf_attribute (decl,
							DW_AT_deleted) == 1)
	    add_AT_flag (subr_die, DW_AT_deleted, 1);

	  /* If this is a C++11 defaulted special function member then
	     generate a DW_AT_defaulted attribute.  */
	  if (dwarf_version >= 5 || !dwarf_strict)
	    {
	      int defaulted
		= lang_hooks.decls.decl_dwarf_attribute (decl,
							 DW_AT_defaulted);
	      if (defaulted != -1)
		add_AT_unsigned (subr_die, DW_AT_defaulted, defaulted);
	    }

	  /* If this is a C++11 non-static member function with & ref-qualifier
	     then generate a DW_AT_reference attribute.  */
	  if ((dwarf_version >= 5 || !dwarf_strict)
	      && lang_hooks.decls.decl_dwarf_attribute (decl,
							DW_AT_reference) == 1)
	    add_AT_flag (subr_die, DW_AT_reference, 1);

	  /* If this is a C++11 non-static member function with &&
	     ref-qualifier then generate a DW_AT_reference attribute.  */
	  if ((dwarf_version >= 5 || !dwarf_strict)
	      && lang_hooks.decls.decl_dwarf_attribute (decl,
							DW_AT_rvalue_reference)
		 == 1)
	    add_AT_flag (subr_die, DW_AT_rvalue_reference, 1);
	}
    }
  /* For non DECL_EXTERNALs, if range information is available, fill
     the DIE with it.  */
  else if (!DECL_EXTERNAL (decl) && !early_dwarf)
    {
      HOST_WIDE_INT cfa_fb_offset;

      struct function *fun = DECL_STRUCT_FUNCTION (decl);

      if (!crtl->has_bb_partition)
	{
	  dw_fde_ref fde = fun->fde;
	  if (fde->dw_fde_begin)
	    {
	      /* We have already generated the labels.  */
             add_AT_low_high_pc (subr_die, fde->dw_fde_begin,
                                 fde->dw_fde_end, false);
	    }
	  else
	    {
	      /* Create start/end labels and add the range.  */
	      char label_id_low[MAX_ARTIFICIAL_LABEL_BYTES];
	      char label_id_high[MAX_ARTIFICIAL_LABEL_BYTES];
	      ASM_GENERATE_INTERNAL_LABEL (label_id_low, FUNC_BEGIN_LABEL,
					   current_function_funcdef_no);
	      ASM_GENERATE_INTERNAL_LABEL (label_id_high, FUNC_END_LABEL,
					   current_function_funcdef_no);
             add_AT_low_high_pc (subr_die, label_id_low, label_id_high,
                                 false);
	    }

#if VMS_DEBUGGING_INFO
      /* HP OpenVMS Industry Standard 64: DWARF Extensions
	 Section 2.3 Prologue and Epilogue Attributes:
	 When a breakpoint is set on entry to a function, it is generally
	 desirable for execution to be suspended, not on the very first
	 instruction of the function, but rather at a point after the
	 function's frame has been set up, after any language defined local
	 declaration processing has been completed, and before execution of
	 the first statement of the function begins. Debuggers generally
	 cannot properly determine where this point is.  Similarly for a
	 breakpoint set on exit from a function. The prologue and epilogue
	 attributes allow a compiler to communicate the location(s) to use.  */

      {
        if (fde->dw_fde_vms_end_prologue)
          add_AT_vms_delta (subr_die, DW_AT_HP_prologue,
	    fde->dw_fde_begin, fde->dw_fde_vms_end_prologue);

        if (fde->dw_fde_vms_begin_epilogue)
          add_AT_vms_delta (subr_die, DW_AT_HP_epilogue,
	    fde->dw_fde_begin, fde->dw_fde_vms_begin_epilogue);
      }
#endif

	}
      else
	{
	  /* Generate pubnames entries for the split function code ranges.  */
	  dw_fde_ref fde = fun->fde;

	  if (fde->dw_fde_second_begin)
	    {
	      if (dwarf_version >= 3 || !dwarf_strict)
		{
		  /* We should use ranges for non-contiguous code section 
		     addresses.  Use the actual code range for the initial
		     section, since the HOT/COLD labels might precede an 
		     alignment offset.  */
		  bool range_list_added = false;
		  add_ranges_by_labels (subr_die, fde->dw_fde_begin,
					fde->dw_fde_end, &range_list_added,
					false);
		  add_ranges_by_labels (subr_die, fde->dw_fde_second_begin,
					fde->dw_fde_second_end,
					&range_list_added, false);
		  if (range_list_added)
		    add_ranges (NULL);
		}
	      else
		{
		  /* There is no real support in DW2 for this .. so we make
		     a work-around.  First, emit the pub name for the segment
		     containing the function label.  Then make and emit a
		     simplified subprogram DIE for the second segment with the
		     name pre-fixed by __hot/cold_sect_of_.  We use the same
		     linkage name for the second die so that gdb will find both
		     sections when given "b foo".  */
		  const char *name = NULL;
		  tree decl_name = DECL_NAME (decl);
		  dw_die_ref seg_die;

		  /* Do the 'primary' section.   */
		  add_AT_low_high_pc (subr_die, fde->dw_fde_begin,
                                      fde->dw_fde_end, false);

		  /* Build a minimal DIE for the secondary section.  */
		  seg_die = new_die (DW_TAG_subprogram,
				     subr_die->die_parent, decl);

		  if (TREE_PUBLIC (decl))
		    add_AT_flag (seg_die, DW_AT_external, 1);

		  if (decl_name != NULL 
		      && IDENTIFIER_POINTER (decl_name) != NULL)
		    {
		      name = dwarf2_name (decl, 1);
		      if (! DECL_ARTIFICIAL (decl))
			add_src_coords_attributes (seg_die, decl);

		      add_linkage_name (seg_die, decl);
		    }
		  gcc_assert (name != NULL);
		  add_pure_or_virtual_attribute (seg_die, decl);
		  if (DECL_ARTIFICIAL (decl))
		    add_AT_flag (seg_die, DW_AT_artificial, 1);

		  name = concat ("__second_sect_of_", name, NULL); 
		  add_AT_low_high_pc (seg_die, fde->dw_fde_second_begin,
                                      fde->dw_fde_second_end, false);
		  add_name_attribute (seg_die, name);
		  if (want_pubnames ())
		    add_pubname_string (name, seg_die);
		}
	    }
	  else
           add_AT_low_high_pc (subr_die, fde->dw_fde_begin, fde->dw_fde_end,
                               false);
	}

      cfa_fb_offset = CFA_FRAME_BASE_OFFSET (decl);

      /* We define the "frame base" as the function's CFA.  This is more
	 convenient for several reasons: (1) It's stable across the prologue
	 and epilogue, which makes it better than just a frame pointer,
	 (2) With dwarf3, there exists a one-byte encoding that allows us
	 to reference the .debug_frame data by proxy, but failing that,
	 (3) We can at least reuse the code inspection and interpretation
	 code that determines the CFA position at various points in the
	 function.  */
      if (dwarf_version >= 3 && targetm.debug_unwind_info () == UI_DWARF2)
	{
	  dw_loc_descr_ref op = new_loc_descr (DW_OP_call_frame_cfa, 0, 0);
	  add_AT_loc (subr_die, DW_AT_frame_base, op);
	}
      else
	{
	  dw_loc_list_ref list = convert_cfa_to_fb_loc_list (cfa_fb_offset);
	  if (list->dw_loc_next)
	    add_AT_loc_list (subr_die, DW_AT_frame_base, list);
	  else
	    add_AT_loc (subr_die, DW_AT_frame_base, list->expr);
	}

      /* Compute a displacement from the "steady-state frame pointer" to
	 the CFA.  The former is what all stack slots and argument slots
	 will reference in the rtl; the latter is what we've told the
	 debugger about.  We'll need to adjust all frame_base references
	 by this displacement.  */
      compute_frame_pointer_to_fb_displacement (cfa_fb_offset);

      if (fun->static_chain_decl)
	{
	  /* DWARF requires here a location expression that computes the
	     address of the enclosing subprogram's frame base.  The machinery
	     in tree-nested.c is supposed to store this specific address in the
	     last field of the FRAME record.  */
	  const tree frame_type
	    = TREE_TYPE (TREE_TYPE (fun->static_chain_decl));
	  const tree fb_decl = tree_last (TYPE_FIELDS (frame_type));

	  tree fb_expr
	    = build1 (INDIRECT_REF, frame_type, fun->static_chain_decl);
	  fb_expr = build3 (COMPONENT_REF, TREE_TYPE (fb_decl),
			    fb_expr, fb_decl, NULL_TREE);

	  add_AT_location_description (subr_die, DW_AT_static_link,
				       loc_list_from_tree (fb_expr, 0, NULL));
	}

      resolve_variable_values ();
    }

  /* Generate child dies for template parameters.  */
  if (early_dwarf && debug_info_level > DINFO_LEVEL_TERSE)
    gen_generic_params_dies (decl);

  /* Now output descriptions of the arguments for this function. This gets
     (unnecessarily?) complex because of the fact that the DECL_ARGUMENT list
     for a FUNCTION_DECL doesn't indicate cases where there was a trailing
     `...' at the end of the formal parameter list.  In order to find out if
     there was a trailing ellipsis or not, we must instead look at the type
     associated with the FUNCTION_DECL.  This will be a node of type
     FUNCTION_TYPE. If the chain of type nodes hanging off of this
     FUNCTION_TYPE node ends with a void_type_node then there should *not* be
     an ellipsis at the end.  */

  /* In the case where we are describing a mere function declaration, all we
     need to do here (and all we *can* do here) is to describe the *types* of
     its formal parameters.  */
  if (debug_info_level <= DINFO_LEVEL_TERSE)
    ;
  else if (declaration)
    gen_formal_types_die (decl, subr_die);
  else
    {
      /* Generate DIEs to represent all known formal parameters.  */
      tree parm = DECL_ARGUMENTS (decl);
      tree generic_decl = early_dwarf
	? lang_hooks.decls.get_generic_function_decl (decl) : NULL;
      tree generic_decl_parm = generic_decl
				? DECL_ARGUMENTS (generic_decl)
				: NULL;

      /* Now we want to walk the list of parameters of the function and
	 emit their relevant DIEs.

	 We consider the case of DECL being an instance of a generic function
	 as well as it being a normal function.

	 If DECL is an instance of a generic function we walk the
	 parameters of the generic function declaration _and_ the parameters of
	 DECL itself. This is useful because we want to emit specific DIEs for
	 function parameter packs and those are declared as part of the
	 generic function declaration. In that particular case,
	 the parameter pack yields a DW_TAG_GNU_formal_parameter_pack DIE.
	 That DIE has children DIEs representing the set of arguments
	 of the pack. Note that the set of pack arguments can be empty.
	 In that case, the DW_TAG_GNU_formal_parameter_pack DIE will not have any
	 children DIE.

	 Otherwise, we just consider the parameters of DECL.  */
      while (generic_decl_parm || parm)
	{
	  if (generic_decl_parm
	      && lang_hooks.function_parameter_pack_p (generic_decl_parm))
	    gen_formal_parameter_pack_die (generic_decl_parm,
					   parm, subr_die,
					   &parm);
	  else if (parm)
	    {
	      dw_die_ref parm_die = gen_decl_die (parm, NULL, NULL, subr_die);

	      if (early_dwarf
		  && parm == DECL_ARGUMENTS (decl)
		  && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
		  && parm_die
		  && (dwarf_version >= 3 || !dwarf_strict))
		add_AT_die_ref (subr_die, DW_AT_object_pointer, parm_die);

	      parm = DECL_CHAIN (parm);
	    }

	  if (generic_decl_parm)
	    generic_decl_parm = DECL_CHAIN (generic_decl_parm);
	}

      /* Decide whether we need an unspecified_parameters DIE at the end.
	 There are 2 more cases to do this for: 1) the ansi ... declaration -
	 this is detectable when the end of the arg list is not a
	 void_type_node 2) an unprototyped function declaration (not a
	 definition).  This just means that we have no info about the
	 parameters at all.  */
      if (early_dwarf)
	{
	  if (prototype_p (TREE_TYPE (decl)))
	    {
	      /* This is the prototyped case, check for....  */
	      if (stdarg_p (TREE_TYPE (decl)))
		gen_unspecified_parameters_die (decl, subr_die);
	    }
	  else if (DECL_INITIAL (decl) == NULL_TREE)
	    gen_unspecified_parameters_die (decl, subr_die);
	}
      else if ((subr_die != old_die || old_die_had_no_children)
	       && prototype_p (TREE_TYPE (decl))
	       && stdarg_p (TREE_TYPE (decl)))
	gen_unspecified_parameters_die (decl, subr_die);
    }

  if (subr_die != old_die)
    /* Add the calling convention attribute if requested.  */
    add_calling_convention_attribute (subr_die, decl);

  /* Output Dwarf info for all of the stuff within the body of the function
     (if it has one - it may be just a declaration).

     OUTER_SCOPE is a pointer to the outermost BLOCK node created to represent
     a function.  This BLOCK actually represents the outermost binding contour
     for the function, i.e. the contour in which the function's formal
     parameters and labels get declared. Curiously, it appears that the front
     end doesn't actually put the PARM_DECL nodes for the current function onto
     the BLOCK_VARS list for this outer scope, but are strung off of the
     DECL_ARGUMENTS list for the function instead.

     The BLOCK_VARS list for the `outer_scope' does provide us with a list of
     the LABEL_DECL nodes for the function however, and we output DWARF info
     for those in decls_for_scope.  Just within the `outer_scope' there will be
     a BLOCK node representing the function's outermost pair of curly braces,
     and any blocks used for the base and member initializers of a C++
     constructor function.  */
  tree outer_scope = DECL_INITIAL (decl);
  if (! declaration && outer_scope && TREE_CODE (outer_scope) != ERROR_MARK)
    {
      int call_site_note_count = 0;
      int tail_call_site_note_count = 0;

      /* Emit a DW_TAG_variable DIE for a named return value.  */
      if (DECL_NAME (DECL_RESULT (decl)))
	gen_decl_die (DECL_RESULT (decl), NULL, NULL, subr_die);

      /* The first time through decls_for_scope we will generate the
	 DIEs for the locals.  The second time, we fill in the
	 location info.  */
      decls_for_scope (outer_scope, subr_die);

      if (call_arg_locations && (!dwarf_strict || dwarf_version >= 5))
	{
	  struct call_arg_loc_node *ca_loc;
	  for (ca_loc = call_arg_locations; ca_loc; ca_loc = ca_loc->next)
	    {
	      dw_die_ref die = NULL;
	      rtx tloc = NULL_RTX, tlocc = NULL_RTX;
	      rtx arg, next_arg;
	      tree arg_decl = NULL_TREE;

	      for (arg = (ca_loc->call_arg_loc_note != NULL_RTX
			  ? XEXP (ca_loc->call_arg_loc_note, 0)
			  : NULL_RTX);
		   arg; arg = next_arg)
		{
		  dw_loc_descr_ref reg, val;
		  machine_mode mode = GET_MODE (XEXP (XEXP (arg, 0), 1));
		  dw_die_ref cdie, tdie = NULL;

		  next_arg = XEXP (arg, 1);
		  if (REG_P (XEXP (XEXP (arg, 0), 0))
		      && next_arg
		      && MEM_P (XEXP (XEXP (next_arg, 0), 0))
		      && REG_P (XEXP (XEXP (XEXP (next_arg, 0), 0), 0))
		      && REGNO (XEXP (XEXP (arg, 0), 0))
			 == REGNO (XEXP (XEXP (XEXP (next_arg, 0), 0), 0)))
		    next_arg = XEXP (next_arg, 1);
		  if (mode == VOIDmode)
		    {
		      mode = GET_MODE (XEXP (XEXP (arg, 0), 0));
		      if (mode == VOIDmode)
			mode = GET_MODE (XEXP (arg, 0));
		    }
		  if (mode == VOIDmode || mode == BLKmode)
		    continue;
		  /* Get dynamic information about call target only if we
		     have no static information: we cannot generate both
		     DW_AT_call_origin and DW_AT_call_target
		     attributes.  */
		  if (ca_loc->symbol_ref == NULL_RTX)
		    {
		      if (XEXP (XEXP (arg, 0), 0) == pc_rtx)
			{
			  tloc = XEXP (XEXP (arg, 0), 1);
			  continue;
			}
		      else if (GET_CODE (XEXP (XEXP (arg, 0), 0)) == CLOBBER
			       && XEXP (XEXP (XEXP (arg, 0), 0), 0) == pc_rtx)
			{
			  tlocc = XEXP (XEXP (arg, 0), 1);
			  continue;
			}
		    }
		  reg = NULL;
		  if (REG_P (XEXP (XEXP (arg, 0), 0)))
		    reg = reg_loc_descriptor (XEXP (XEXP (arg, 0), 0),
					      VAR_INIT_STATUS_INITIALIZED);
		  else if (MEM_P (XEXP (XEXP (arg, 0), 0)))
		    {
		      rtx mem = XEXP (XEXP (arg, 0), 0);
		      reg = mem_loc_descriptor (XEXP (mem, 0),
						get_address_mode (mem),
						GET_MODE (mem),
						VAR_INIT_STATUS_INITIALIZED);
		    }
		  else if (GET_CODE (XEXP (XEXP (arg, 0), 0))
			   == DEBUG_PARAMETER_REF)
		    {
		      tree tdecl
			= DEBUG_PARAMETER_REF_DECL (XEXP (XEXP (arg, 0), 0));
		      tdie = lookup_decl_die (tdecl);
		      if (tdie == NULL)
			continue;
		      arg_decl = tdecl;
		    }
		  else
		    continue;
		  if (reg == NULL
		      && GET_CODE (XEXP (XEXP (arg, 0), 0))
			 != DEBUG_PARAMETER_REF)
		    continue;
		  val = mem_loc_descriptor (XEXP (XEXP (arg, 0), 1), mode,
					    VOIDmode,
					    VAR_INIT_STATUS_INITIALIZED);
		  if (val == NULL)
		    continue;
		  if (die == NULL)
		    die = gen_call_site_die (decl, subr_die, ca_loc);
		  cdie = new_die (dwarf_TAG (DW_TAG_call_site_parameter), die,
				  NULL_TREE);
		  add_desc_attribute (cdie, arg_decl);
		  if (reg != NULL)
		    add_AT_loc (cdie, DW_AT_location, reg);
		  else if (tdie != NULL)
		    add_AT_die_ref (cdie, dwarf_AT (DW_AT_call_parameter),
				    tdie);
		  add_AT_loc (cdie, dwarf_AT (DW_AT_call_value), val);
		  if (next_arg != XEXP (arg, 1))
		    {
		      mode = GET_MODE (XEXP (XEXP (XEXP (arg, 1), 0), 1));
		      if (mode == VOIDmode)
			mode = GET_MODE (XEXP (XEXP (XEXP (arg, 1), 0), 0));
		      val = mem_loc_descriptor (XEXP (XEXP (XEXP (arg, 1),
							    0), 1),
						mode, VOIDmode,
						VAR_INIT_STATUS_INITIALIZED);
		      if (val != NULL)
			add_AT_loc (cdie, dwarf_AT (DW_AT_call_data_value),
				    val);
		    }
		}
	      if (die == NULL
		  && (ca_loc->symbol_ref || tloc))
		die = gen_call_site_die (decl, subr_die, ca_loc);
	      if (die != NULL && (tloc != NULL_RTX || tlocc != NULL_RTX))
		{
		  dw_loc_descr_ref tval = NULL;

		  if (tloc != NULL_RTX)
		    tval = mem_loc_descriptor (tloc,
					       GET_MODE (tloc) == VOIDmode
					       ? Pmode : GET_MODE (tloc),
					       VOIDmode,
					       VAR_INIT_STATUS_INITIALIZED);
		  if (tval)
		    add_AT_loc (die, dwarf_AT (DW_AT_call_target), tval);
		  else if (tlocc != NULL_RTX)
		    {
		      tval = mem_loc_descriptor (tlocc,
						 GET_MODE (tlocc) == VOIDmode
						 ? Pmode : GET_MODE (tlocc),
						 VOIDmode,
						 VAR_INIT_STATUS_INITIALIZED);
		      if (tval)
			add_AT_loc (die,
				    dwarf_AT (DW_AT_call_target_clobbered),
				    tval);
		    }
		}
	      if (die != NULL)
		{
		  call_site_note_count++;
		  if (ca_loc->tail_call_p)
		    tail_call_site_note_count++;
		}
	    }
	}
      call_arg_locations = NULL;
      call_arg_loc_last = NULL;
      if (tail_call_site_count >= 0
	  && tail_call_site_count == tail_call_site_note_count
	  && (!dwarf_strict || dwarf_version >= 5))
	{
	  if (call_site_count >= 0
	      && call_site_count == call_site_note_count)
	    add_AT_flag (subr_die, dwarf_AT (DW_AT_call_all_calls), 1);
	  else
	    add_AT_flag (subr_die, dwarf_AT (DW_AT_call_all_tail_calls), 1);
	}
      call_site_count = -1;
      tail_call_site_count = -1;
    }

  /* Mark used types after we have created DIEs for the functions scopes.  */
  premark_used_types (DECL_STRUCT_FUNCTION (decl));
}

/* Returns a hash value for X (which really is a die_struct).  */

hashval_t
block_die_hasher::hash (die_struct *d)
{
  return (hashval_t) d->decl_id ^ htab_hash_pointer (d->die_parent);
}

/* Return nonzero if decl_id and die_parent of die_struct X is the same
   as decl_id and die_parent of die_struct Y.  */

bool
block_die_hasher::equal (die_struct *x, die_struct *y)
{
  return x->decl_id == y->decl_id && x->die_parent == y->die_parent;
}

/* Hold information about markers for inlined entry points.  */
struct GTY ((for_user)) inline_entry_data
{
  /* The block that's the inlined_function_outer_scope for an inlined
     function.  */
  tree block;

  /* The label at the inlined entry point.  */
  const char *label_pfx;
  unsigned int label_num;

  /* The view number to be used as the inlined entry point.  */
  var_loc_view view;
};

struct inline_entry_data_hasher : ggc_ptr_hash <inline_entry_data>
{
  typedef tree compare_type;
  static inline hashval_t hash (const inline_entry_data *);
  static inline bool equal (const inline_entry_data *, const_tree);
};

/* Hash table routines for inline_entry_data.  */

inline hashval_t
inline_entry_data_hasher::hash (const inline_entry_data *data)
{
  return htab_hash_pointer (data->block);
}

inline bool
inline_entry_data_hasher::equal (const inline_entry_data *data,
				 const_tree block)
{
  return data->block == block;
}

/* Inlined entry points pending DIE creation in this compilation unit.  */

static GTY(()) hash_table<inline_entry_data_hasher> *inline_entry_data_table;


/* Return TRUE if DECL, which may have been previously generated as
   OLD_DIE, is a candidate for a DW_AT_specification.  DECLARATION is
   true if decl (or its origin) is either an extern declaration or a
   class/namespace scoped declaration.

   The declare_in_namespace support causes us to get two DIEs for one
   variable, both of which are declarations.  We want to avoid
   considering one to be a specification, so we must test for
   DECLARATION and DW_AT_declaration.  */
static inline bool
decl_will_get_specification_p (dw_die_ref old_die, tree decl, bool declaration)
{
  return (old_die && TREE_STATIC (decl) && !declaration
	  && get_AT_flag (old_die, DW_AT_declaration) == 1);
}

/* Return true if DECL is a local static.  */

static inline bool
local_function_static (tree decl)
{
  gcc_assert (VAR_P (decl));
  return TREE_STATIC (decl)
    && DECL_CONTEXT (decl)
    && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL;
}

/* Return true iff DECL overrides (presumably completes) the type of
   OLD_DIE within CONTEXT_DIE.  */

static bool
override_type_for_decl_p (tree decl, dw_die_ref old_die,
			  dw_die_ref context_die)
{
  tree type = TREE_TYPE (decl);
  int cv_quals;

  if (decl_by_reference_p (decl))
    {
      type = TREE_TYPE (type);
      cv_quals = TYPE_UNQUALIFIED;
    }
  else
    cv_quals = decl_quals (decl);

  dw_die_ref type_die = modified_type_die (type,
					   cv_quals | TYPE_QUALS (type),
					   false,
					   context_die);

  dw_die_ref old_type_die = get_AT_ref (old_die, DW_AT_type);

  return type_die != old_type_die;
}

/* Generate a DIE to represent a declared data object.
   Either DECL or ORIGIN must be non-null.  */

static void
gen_variable_die (tree decl, tree origin, dw_die_ref context_die)
{
  HOST_WIDE_INT off = 0;
  tree com_decl;
  tree decl_or_origin = decl ? decl : origin;
  tree ultimate_origin;
  dw_die_ref var_die;
  dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL;
  bool declaration = (DECL_EXTERNAL (decl_or_origin)
		      || class_or_namespace_scope_p (context_die));
  bool specialization_p = false;
  bool no_linkage_name = false;

  /* While C++ inline static data members have definitions inside of the
     class, force the first DIE to be a declaration, then let gen_member_die
     reparent it to the class context and call gen_variable_die again
     to create the outside of the class DIE for the definition.  */
  if (!declaration
      && old_die == NULL
      && decl
      && DECL_CONTEXT (decl)
      && TYPE_P (DECL_CONTEXT (decl))
      && lang_hooks.decls.decl_dwarf_attribute (decl, DW_AT_inline) != -1)
    {
      declaration = true;
      if (dwarf_version < 5)
	no_linkage_name = true;
    }

  ultimate_origin = decl_ultimate_origin (decl_or_origin);
  if (decl || ultimate_origin)
    origin = ultimate_origin;
  com_decl = fortran_common (decl_or_origin, &off);

  /* Symbol in common gets emitted as a child of the common block, in the form
     of a data member.  */
  if (com_decl)
    {
      dw_die_ref com_die;
      dw_loc_list_ref loc = NULL;
      die_node com_die_arg;

      var_die = lookup_decl_die (decl_or_origin);
      if (var_die)
	{
	  if (! early_dwarf && get_AT (var_die, DW_AT_location) == NULL)
	    {
	      loc = loc_list_from_tree (com_decl, off ? 1 : 2, NULL);
	      if (loc)
		{
		  if (off)
		    {
		      /* Optimize the common case.  */
		      if (single_element_loc_list_p (loc)
			  && loc->expr->dw_loc_opc == DW_OP_addr
			  && loc->expr->dw_loc_next == NULL
			  && GET_CODE (loc->expr->dw_loc_oprnd1.v.val_addr)
			     == SYMBOL_REF)
			{
			  rtx x = loc->expr->dw_loc_oprnd1.v.val_addr;
			  loc->expr->dw_loc_oprnd1.v.val_addr
			    = plus_constant (GET_MODE (x), x , off);
			}
		      else
			loc_list_plus_const (loc, off);
		    }
		  add_AT_location_description (var_die, DW_AT_location, loc);
		  remove_AT (var_die, DW_AT_declaration);
		}
	    }
	  return;
	}

      if (common_block_die_table == NULL)
	common_block_die_table = hash_table<block_die_hasher>::create_ggc (10);

      com_die_arg.decl_id = DECL_UID (com_decl);
      com_die_arg.die_parent = context_die;
      com_die = common_block_die_table->find (&com_die_arg);
      if (! early_dwarf)
	loc = loc_list_from_tree (com_decl, 2, NULL);
      if (com_die == NULL)
	{
	  const char *cnam
	    = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
	  die_node **slot;

	  com_die = new_die (DW_TAG_common_block, context_die, decl);
	  add_name_and_src_coords_attributes (com_die, com_decl);
	  if (loc)
	    {
	      add_AT_location_description (com_die, DW_AT_location, loc);
	      /* Avoid sharing the same loc descriptor between
		 DW_TAG_common_block and DW_TAG_variable.  */
	      loc = loc_list_from_tree (com_decl, 2, NULL);
	    }
	  else if (DECL_EXTERNAL (decl_or_origin))
	    add_AT_flag (com_die, DW_AT_declaration, 1);
	  if (want_pubnames ())
	    add_pubname_string (cnam, com_die); /* ??? needed? */
	  com_die->decl_id = DECL_UID (com_decl);
	  slot = common_block_die_table->find_slot (com_die, INSERT);
	  *slot = com_die;
	}
      else if (get_AT (com_die, DW_AT_location) == NULL && loc)
	{
	  add_AT_location_description (com_die, DW_AT_location, loc);
	  loc = loc_list_from_tree (com_decl, 2, NULL);
	  remove_AT (com_die, DW_AT_declaration);
	}
      var_die = new_die (DW_TAG_variable, com_die, decl);
      add_name_and_src_coords_attributes (var_die, decl_or_origin);
      add_type_attribute (var_die, TREE_TYPE (decl_or_origin),
			  decl_quals (decl_or_origin), false,
			  context_die);
      add_alignment_attribute (var_die, decl);
      add_AT_flag (var_die, DW_AT_external, 1);
      if (loc)
	{
	  if (off)
	    {
	      /* Optimize the common case.  */
	      if (single_element_loc_list_p (loc)
                  && loc->expr->dw_loc_opc == DW_OP_addr
		  && loc->expr->dw_loc_next == NULL
		  && GET_CODE (loc->expr->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF)
		{
		  rtx x = loc->expr->dw_loc_oprnd1.v.val_addr;
		  loc->expr->dw_loc_oprnd1.v.val_addr
		    = plus_constant (GET_MODE (x), x, off);
		}
	      else
		loc_list_plus_const (loc, off);
	    }
	  add_AT_location_description (var_die, DW_AT_location, loc);
	}
      else if (DECL_EXTERNAL (decl_or_origin))
	add_AT_flag (var_die, DW_AT_declaration, 1);
      if (decl)
	equate_decl_number_to_die (decl, var_die);
      return;
    }

  if (old_die)
    {
      if (declaration)
	{
	  /* A declaration that has been previously dumped, needs no
	     further annotations, since it doesn't need location on
	     the second pass.  */
	  return;
	}
      else if (decl_will_get_specification_p (old_die, decl, declaration)
	       && !get_AT (old_die, DW_AT_specification))
	{
	  /* Fall-thru so we can make a new variable die along with a
	     DW_AT_specification.  */
	}
      else if (origin && old_die->die_parent != context_die)
	{
	  /* If we will be creating an inlined instance, we need a
	     new DIE that will get annotated with
	     DW_AT_abstract_origin.  */
	  gcc_assert (!DECL_ABSTRACT_P (decl));
	}
      else
	{
	  /* If a DIE was dumped early, it still needs location info.
	     Skip to where we fill the location bits.  */
	  var_die = old_die;

	  /* ???  In LTRANS we cannot annotate early created variably
	     modified type DIEs without copying them and adjusting all
	     references to them.  Thus we dumped them again.  Also add a
	     reference to them but beware of -g0 compile and -g link
	     in which case the reference will be already present.  */
	  tree type = TREE_TYPE (decl_or_origin);
	  if (in_lto_p
	      && ! get_AT (var_die, DW_AT_type)
	      && variably_modified_type_p
		   (type, decl_function_context (decl_or_origin)))
	    {
	      if (decl_by_reference_p (decl_or_origin))
		add_type_attribute (var_die, TREE_TYPE (type),
				    TYPE_UNQUALIFIED, false, context_die);
	      else
		add_type_attribute (var_die, type, decl_quals (decl_or_origin),
				    false, context_die);
	    }

	  goto gen_variable_die_location;
	}
    }

  /* For static data members, the declaration in the class is supposed
     to have DW_TAG_member tag in DWARF{3,4} and we emit it for compatibility
     also in DWARF2; the specification should still be DW_TAG_variable
     referencing the DW_TAG_member DIE.  */
  if (declaration && class_scope_p (context_die) && dwarf_version < 5)
    var_die = new_die (DW_TAG_member, context_die, decl);
  else
    var_die = new_die (DW_TAG_variable, context_die, decl);

  if (origin != NULL)
    add_abstract_origin_attribute (var_die, origin);

  /* Loop unrolling can create multiple blocks that refer to the same
     static variable, so we must test for the DW_AT_declaration flag.

     ??? Loop unrolling/reorder_blocks should perhaps be rewritten to
     copy decls and set the DECL_ABSTRACT_P flag on them instead of
     sharing them.

     ??? Duplicated blocks have been rewritten to use .debug_ranges.  */
  else if (decl_will_get_specification_p (old_die, decl, declaration))
    {
      /* This is a definition of a C++ class level static.  */
      add_AT_specification (var_die, old_die);
      specialization_p = true;
      if (DECL_NAME (decl))
	{
	  expanded_location s = expand_location (DECL_SOURCE_LOCATION (decl));
	  struct dwarf_file_data * file_index = lookup_filename (s.file);

	  if (get_AT_file (old_die, DW_AT_decl_file) != file_index)
	    add_AT_file (var_die, DW_AT_decl_file, file_index);

	  if (get_AT_unsigned (old_die, DW_AT_decl_line) != (unsigned) s.line)
	    add_AT_unsigned (var_die, DW_AT_decl_line, s.line);

	  if (debug_column_info
	      && s.column
	      && (get_AT_unsigned (old_die, DW_AT_decl_column)
		  != (unsigned) s.column))
	    add_AT_unsigned (var_die, DW_AT_decl_column, s.column);

	  if (old_die->die_tag == DW_TAG_member)
	    add_linkage_name (var_die, decl);
	}
    }
  else
    add_name_and_src_coords_attributes (var_die, decl, no_linkage_name);

  if ((origin == NULL && !specialization_p)
      || (origin != NULL
	  && !DECL_ABSTRACT_P (decl_or_origin)
	  && variably_modified_type_p (TREE_TYPE (decl_or_origin),
				       decl_function_context
				       (decl_or_origin)))
      || (old_die && specialization_p
	  && override_type_for_decl_p (decl_or_origin, old_die, context_die)))
    {
      tree type = TREE_TYPE (decl_or_origin);

      if (decl_by_reference_p (decl_or_origin))
	add_type_attribute (var_die, TREE_TYPE (type), TYPE_UNQUALIFIED, false,
			    context_die);
      else
	add_type_attribute (var_die, type, decl_quals (decl_or_origin), false,
			    context_die);
    }

  if (origin == NULL && !specialization_p)
    {
      if (TREE_PUBLIC (decl))
	add_AT_flag (var_die, DW_AT_external, 1);

      if (DECL_ARTIFICIAL (decl))
	add_AT_flag (var_die, DW_AT_artificial, 1);

      add_alignment_attribute (var_die, decl);

      add_accessibility_attribute (var_die, decl);
    }

  if (declaration)
    add_AT_flag (var_die, DW_AT_declaration, 1);

  if (decl && (DECL_ABSTRACT_P (decl)
	       || !old_die || is_declaration_die (old_die)))
    equate_decl_number_to_die (decl, var_die);

 gen_variable_die_location:
  if (! declaration
      && (! DECL_ABSTRACT_P (decl_or_origin)
	  /* Local static vars are shared between all clones/inlines,
	     so emit DW_AT_location on the abstract DIE if DECL_RTL is
	     already set.  */
	  || (VAR_P (decl_or_origin)
	      && TREE_STATIC (decl_or_origin)
	      && DECL_RTL_SET_P (decl_or_origin))))
    {
      if (early_dwarf)
	{
	  add_pubname (decl_or_origin, var_die);
	  /* For global register variables, emit DW_AT_location if possible
	     already during early_dwarf, as late_global_decl won't be usually
	     called.  */
	  if (DECL_HARD_REGISTER (decl_or_origin)
	      && TREE_STATIC (decl_or_origin)
	      && !decl_by_reference_p (decl_or_origin)
	      && !get_AT (var_die, DW_AT_location)
	      && !get_AT (var_die, DW_AT_const_value)
	      && DECL_RTL_SET_P (decl_or_origin)
	      && REG_P (DECL_RTL (decl_or_origin)))
	    {
	      dw_loc_descr_ref descr
		= reg_loc_descriptor (DECL_RTL (decl_or_origin),
				      VAR_INIT_STATUS_INITIALIZED);
	      if (descr)
		add_AT_loc (var_die, DW_AT_location, descr);
	    }
	}
      else
	add_location_or_const_value_attribute (var_die, decl_or_origin,
					       decl == NULL);
    }
  else
    tree_add_const_value_attribute_for_decl (var_die, decl_or_origin);

  if ((dwarf_version >= 4 || !dwarf_strict)
      && lang_hooks.decls.decl_dwarf_attribute (decl_or_origin,
						DW_AT_const_expr) == 1
      && !get_AT (var_die, DW_AT_const_expr)
      && !specialization_p)
    add_AT_flag (var_die, DW_AT_const_expr, 1);

  if (!dwarf_strict)
    {
      int inl = lang_hooks.decls.decl_dwarf_attribute (decl_or_origin,
						       DW_AT_inline);
      if (inl != -1
	  && !get_AT (var_die, DW_AT_inline)
	  && !specialization_p)
	add_AT_unsigned (var_die, DW_AT_inline, inl);
    }
}

/* Generate a DIE to represent a named constant.  */

static void
gen_const_die (tree decl, dw_die_ref context_die)
{
  dw_die_ref const_die;
  tree type = TREE_TYPE (decl);

  const_die = lookup_decl_die (decl);
  if (const_die)
    return;

  const_die = new_die (DW_TAG_constant, context_die, decl);
  equate_decl_number_to_die (decl, const_die);
  add_name_and_src_coords_attributes (const_die, decl);
  add_type_attribute (const_die, type, TYPE_QUAL_CONST, false, context_die);
  if (TREE_PUBLIC (decl))
    add_AT_flag (const_die, DW_AT_external, 1);
  if (DECL_ARTIFICIAL (decl))
    add_AT_flag (const_die, DW_AT_artificial, 1);
  tree_add_const_value_attribute_for_decl (const_die, decl);
}

/* Generate a DIE to represent a label identifier.  */

static void
gen_label_die (tree decl, dw_die_ref context_die)
{
  tree origin = decl_ultimate_origin (decl);
  dw_die_ref lbl_die = lookup_decl_die (decl);
  rtx insn;
  char label[MAX_ARTIFICIAL_LABEL_BYTES];

  if (!lbl_die)
    {
      lbl_die = new_die (DW_TAG_label, context_die, decl);
      equate_decl_number_to_die (decl, lbl_die);

      if (origin != NULL)
	add_abstract_origin_attribute (lbl_die, origin);
      else
	add_name_and_src_coords_attributes (lbl_die, decl);
    }

  if (DECL_ABSTRACT_P (decl))
    equate_decl_number_to_die (decl, lbl_die);
  else if (! early_dwarf)
    {
      insn = DECL_RTL_IF_SET (decl);

      /* Deleted labels are programmer specified labels which have been
	 eliminated because of various optimizations.  We still emit them
	 here so that it is possible to put breakpoints on them.  */
      if (insn
	  && (LABEL_P (insn)
	      || ((NOTE_P (insn)
	           && NOTE_KIND (insn) == NOTE_INSN_DELETED_LABEL))))
	{
	  /* When optimization is enabled (via -O) some parts of the compiler
	     (e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which
	     represent source-level labels which were explicitly declared by
	     the user.  This really shouldn't be happening though, so catch
	     it if it ever does happen.  */
	  gcc_assert (!as_a<rtx_insn *> (insn)->deleted ());

	  ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (insn));
          add_AT_lbl_id (lbl_die, DW_AT_low_pc, label);
	}
      else if (insn
	       && NOTE_P (insn)
	       && NOTE_KIND (insn) == NOTE_INSN_DELETED_DEBUG_LABEL
	       && CODE_LABEL_NUMBER (insn) != -1)
	{
	  ASM_GENERATE_INTERNAL_LABEL (label, "LDL", CODE_LABEL_NUMBER (insn));
          add_AT_lbl_id (lbl_die, DW_AT_low_pc, label);
	}
    }
}

/* A helper function for gen_inlined_subroutine_die.  Add source coordinate
   attributes to the DIE for a block STMT, to describe where the inlined
   function was called from.  This is similar to add_src_coords_attributes.  */

static inline void
add_call_src_coords_attributes (tree stmt, dw_die_ref die)
{
  /* We can end up with BUILTINS_LOCATION here.  */
  if (RESERVED_LOCATION_P (BLOCK_SOURCE_LOCATION (stmt)))
    return;

  expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (stmt));

  if (dwarf_version >= 3 || !dwarf_strict)
    {
      add_AT_file (die, DW_AT_call_file, lookup_filename (s.file));
      add_AT_unsigned (die, DW_AT_call_line, s.line);
      if (debug_column_info && s.column)
	add_AT_unsigned (die, DW_AT_call_column, s.column);
    }
}


/* A helper function for gen_lexical_block_die and gen_inlined_subroutine_die.
   Add low_pc and high_pc attributes to the DIE for a block STMT.  */

static inline void
add_high_low_attributes (tree stmt, dw_die_ref die)
{
  char label[MAX_ARTIFICIAL_LABEL_BYTES];

  if (inline_entry_data **iedp
      = !inline_entry_data_table ? NULL
      : inline_entry_data_table->find_slot_with_hash (stmt,
						      htab_hash_pointer (stmt),
						      NO_INSERT))
    {
      inline_entry_data *ied = *iedp;
      gcc_assert (MAY_HAVE_DEBUG_MARKER_INSNS);
      gcc_assert (debug_inline_points);
      gcc_assert (inlined_function_outer_scope_p (stmt));

      ASM_GENERATE_INTERNAL_LABEL (label, ied->label_pfx, ied->label_num);
      add_AT_lbl_id (die, DW_AT_entry_pc, label);

      if (debug_variable_location_views && !ZERO_VIEW_P (ied->view)
	  && !dwarf_strict)
	{
	  if (!output_asm_line_debug_info ())
	    add_AT_unsigned (die, DW_AT_GNU_entry_view, ied->view);
	  else
	    {
	      ASM_GENERATE_INTERNAL_LABEL (label, "LVU", ied->view);
	      /* FIXME: this will resolve to a small number.  Could we
		 possibly emit smaller data?  Ideally we'd emit a
		 uleb128, but that would make the size of DIEs
		 impossible for the compiler to compute, since it's
		 the assembler that computes the value of the view
		 label in this case.  Ideally, we'd have a single form
		 encompassing both the address and the view, and
		 indirecting them through a table might make things
		 easier, but even that would be more wasteful,
		 space-wise, than what we have now.  */
	      add_AT_symview (die, DW_AT_GNU_entry_view, label);
	    }
	}

      inline_entry_data_table->clear_slot (iedp);
    }

  if (BLOCK_FRAGMENT_CHAIN (stmt)
      && (dwarf_version >= 3 || !dwarf_strict))
    {
      tree chain, superblock = NULL_TREE;
      dw_die_ref pdie;
      dw_attr_node *attr = NULL;

      if (!debug_inline_points && inlined_function_outer_scope_p (stmt))
	{
	  ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
				       BLOCK_NUMBER (stmt));
          add_AT_lbl_id (die, DW_AT_entry_pc, label);
	}

      /* Optimize duplicate .debug_ranges lists or even tails of
	 lists.  If this BLOCK has same ranges as its supercontext,
	 lookup DW_AT_ranges attribute in the supercontext (and
	 recursively so), verify that the ranges_table contains the
	 right values and use it instead of adding a new .debug_range.  */
      for (chain = stmt, pdie = die;
	   BLOCK_SAME_RANGE (chain);
	   chain = BLOCK_SUPERCONTEXT (chain))
	{
	  dw_attr_node *new_attr;

	  pdie = pdie->die_parent;
	  if (pdie == NULL)
	    break;
	  if (BLOCK_SUPERCONTEXT (chain) == NULL_TREE)
	    break;
	  new_attr = get_AT (pdie, DW_AT_ranges);
	  if (new_attr == NULL
	      || new_attr->dw_attr_val.val_class != dw_val_class_range_list)
	    break;
	  attr = new_attr;
	  superblock = BLOCK_SUPERCONTEXT (chain);
	}
      if (attr != NULL
	  && ((*ranges_table)[attr->dw_attr_val.v.val_offset].num
	      == (int)BLOCK_NUMBER (superblock))
	  && BLOCK_FRAGMENT_CHAIN (superblock))
	{
	  unsigned long off = attr->dw_attr_val.v.val_offset;
	  unsigned long supercnt = 0, thiscnt = 0;
	  for (chain = BLOCK_FRAGMENT_CHAIN (superblock);
	       chain; chain = BLOCK_FRAGMENT_CHAIN (chain))
	    {
	      ++supercnt;
	      gcc_checking_assert ((*ranges_table)[off + supercnt].num
				   == (int)BLOCK_NUMBER (chain));
	    }
	  gcc_checking_assert ((*ranges_table)[off + supercnt + 1].num == 0);
	  for (chain = BLOCK_FRAGMENT_CHAIN (stmt);
	       chain; chain = BLOCK_FRAGMENT_CHAIN (chain))
	    ++thiscnt;
	  gcc_assert (supercnt >= thiscnt);
	  add_AT_range_list (die, DW_AT_ranges, off + supercnt - thiscnt,
			     false);
	  note_rnglist_head (off + supercnt - thiscnt);
	  return;
	}

      unsigned int offset = add_ranges (stmt, true);
      add_AT_range_list (die, DW_AT_ranges, offset, false);
      note_rnglist_head (offset);

      bool prev_in_cold = BLOCK_IN_COLD_SECTION_P (stmt);
      chain = BLOCK_FRAGMENT_CHAIN (stmt);
      do
	{
	  add_ranges (chain, prev_in_cold != BLOCK_IN_COLD_SECTION_P (chain));
	  prev_in_cold = BLOCK_IN_COLD_SECTION_P (chain);
	  chain = BLOCK_FRAGMENT_CHAIN (chain);
	}
      while (chain);
      add_ranges (NULL);
    }
  else
    {
      char label_high[MAX_ARTIFICIAL_LABEL_BYTES];
      ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL,
				   BLOCK_NUMBER (stmt));
      ASM_GENERATE_INTERNAL_LABEL (label_high, BLOCK_END_LABEL,
				   BLOCK_NUMBER (stmt));
      add_AT_low_high_pc (die, label, label_high, false);
    }
}

/* Generate a DIE for a lexical block.  */

static void
gen_lexical_block_die (tree stmt, dw_die_ref context_die)
{
  dw_die_ref old_die = lookup_block_die (stmt);
  dw_die_ref stmt_die = NULL;
  if (!old_die)
    {
      stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);
      equate_block_to_die (stmt, stmt_die);
    }

  if (BLOCK_ABSTRACT_ORIGIN (stmt))
    {
      /* If this is an inlined or conrecte instance, create a new lexical
	 die for anything below to attach DW_AT_abstract_origin to.  */
      if (old_die)
	stmt_die = new_die (DW_TAG_lexical_block, context_die, stmt);

      tree origin = block_ultimate_origin (stmt);
      if (origin != NULL_TREE && (origin != stmt || old_die))
	add_abstract_origin_attribute (stmt_die, origin);

      old_die = NULL;
    }

  if (old_die)
    stmt_die = old_die;

  /* A non abstract block whose blocks have already been reordered
     should have the instruction range for this block.  If so, set the
     high/low attributes.  */
  if (!early_dwarf && TREE_ASM_WRITTEN (stmt))
    {
      gcc_assert (stmt_die);
      add_high_low_attributes (stmt, stmt_die);
    }

  decls_for_scope (stmt, stmt_die);
}

/* Generate a DIE for an inlined subprogram.  */

static void
gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die)
{
  tree decl = block_ultimate_origin (stmt);

  /* Make sure any inlined functions are known to be inlineable.  */
  gcc_checking_assert (DECL_ABSTRACT_P (decl)
		       || cgraph_function_possibly_inlined_p (decl));

  dw_die_ref subr_die = new_die (DW_TAG_inlined_subroutine, context_die, stmt);

  if (call_arg_locations || debug_inline_points)
    equate_block_to_die (stmt, subr_die);
  add_abstract_origin_attribute (subr_die, decl);
  if (TREE_ASM_WRITTEN (stmt))
    add_high_low_attributes (stmt, subr_die);
  add_call_src_coords_attributes (stmt, subr_die);

  /* The inliner creates an extra BLOCK for the parameter setup,
     we want to merge that with the actual outermost BLOCK of the
     inlined function to avoid duplicate locals in consumers.
     Do that by doing the recursion to subblocks on the single subblock
     of STMT.  */
  bool unwrap_one = false;
  if (BLOCK_SUBBLOCKS (stmt) && !BLOCK_CHAIN (BLOCK_SUBBLOCKS (stmt)))
    {
      tree origin = block_ultimate_origin (BLOCK_SUBBLOCKS (stmt));
      if (origin
	  && TREE_CODE (origin) == BLOCK
	  && BLOCK_SUPERCONTEXT (origin) == decl)
	unwrap_one = true;
    }
  decls_for_scope (stmt, subr_die, !unwrap_one);
  if (unwrap_one)
    decls_for_scope (BLOCK_SUBBLOCKS (stmt), subr_die);
}

/* Generate a DIE for a field in a record, or structure.  CTX is required: see
   the comment for VLR_CONTEXT.  */

static void
gen_field_die (tree decl, struct vlr_context *ctx, dw_die_ref context_die)
{
  dw_die_ref decl_die;

  if (TREE_TYPE (decl) == error_mark_node)
    return;

  decl_die = new_die (DW_TAG_member, context_die, decl);
  add_name_and_src_coords_attributes (decl_die, decl);
  add_type_attribute (decl_die, member_declared_type (decl), decl_quals (decl),
		      TYPE_REVERSE_STORAGE_ORDER (DECL_FIELD_CONTEXT (decl)),
		      context_die);

  if (DECL_BIT_FIELD_TYPE (decl))
    {
      add_byte_size_attribute (decl_die, decl);
      add_bit_size_attribute (decl_die, decl);
      add_bit_offset_attribute (decl_die, decl);
    }

  add_alignment_attribute (decl_die, decl);

  if (TREE_CODE (DECL_FIELD_CONTEXT (decl)) != UNION_TYPE)
    add_data_member_location_attribute (decl_die, decl, ctx);

  if (DECL_ARTIFICIAL (decl))
    add_AT_flag (decl_die, DW_AT_artificial, 1);

  add_accessibility_attribute (decl_die, decl);

  /* Equate decl number to die, so that we can look up this decl later on.  */
  equate_decl_number_to_die (decl, decl_die);
}

/* Generate a DIE for a pointer to a member type.  TYPE can be an
   OFFSET_TYPE, for a pointer to data member, or a RECORD_TYPE, for a
   pointer to member function.  */

static void
gen_ptr_to_mbr_type_die (tree type, dw_die_ref context_die)
{
  if (lookup_type_die (type))
    return;

  dw_die_ref ptr_die = new_die (DW_TAG_ptr_to_member_type,
				scope_die_for (type, context_die), type);

  equate_type_number_to_die (type, ptr_die);
  add_AT_die_ref (ptr_die, DW_AT_containing_type,
		  lookup_type_die (TYPE_OFFSET_BASETYPE (type)));
  add_type_attribute (ptr_die, TREE_TYPE (type), TYPE_UNQUALIFIED, false,
		      context_die);
  add_alignment_attribute (ptr_die, type);

  if (TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE
      && TREE_CODE (TREE_TYPE (type)) != METHOD_TYPE)
    {
      dw_loc_descr_ref op = new_loc_descr (DW_OP_plus, 0, 0);
      add_AT_loc (ptr_die, DW_AT_use_location, op);
    }
}

static char *producer_string;

/* Given a C and/or C++ language/version string return the "highest".
   C++ is assumed to be "higher" than C in this case.  Used for merging
   LTO translation unit languages.  */
static const char *
highest_c_language (const char *lang1, const char *lang2)
{
  if (strcmp ("GNU C++23", lang1) == 0 || strcmp ("GNU C++23", lang2) == 0)
    return "GNU C++23";
  if (strcmp ("GNU C++20", lang1) == 0 || strcmp ("GNU C++20", lang2) == 0)
    return "GNU C++20";
  if (strcmp ("GNU C++17", lang1) == 0 || strcmp ("GNU C++17", lang2) == 0)
    return "GNU C++17";
  if (strcmp ("GNU C++14", lang1) == 0 || strcmp ("GNU C++14", lang2) == 0)
    return "GNU C++14";
  if (strcmp ("GNU C++11", lang1) == 0 || strcmp ("GNU C++11", lang2) == 0)
    return "GNU C++11";
  if (strcmp ("GNU C++98", lang1) == 0 || strcmp ("GNU C++98", lang2) == 0)
    return "GNU C++98";

  if (strcmp ("GNU C2X", lang1) == 0 || strcmp ("GNU C2X", lang2) == 0)
    return "GNU C2X";
  if (strcmp ("GNU C17", lang1) == 0 || strcmp ("GNU C17", lang2) == 0)
    return "GNU C17";
  if (strcmp ("GNU C11", lang1) == 0 || strcmp ("GNU C11", lang2) == 0)
    return "GNU C11";
  if (strcmp ("GNU C99", lang1) == 0 || strcmp ("GNU C99", lang2) == 0)
    return "GNU C99";
  if (strcmp ("GNU C89", lang1) == 0 || strcmp ("GNU C89", lang2) == 0)
    return "GNU C89";

  gcc_unreachable ();
}


/* Generate the DIE for the compilation unit.  */

static dw_die_ref
gen_compile_unit_die (const char *filename)
{
  dw_die_ref die;
  const char *language_string = lang_hooks.name;
  int language;

  die = new_die (DW_TAG_compile_unit, NULL, NULL);

  if (filename)
    {
      add_filename_attribute (die, filename);
      /* Don't add cwd for <built-in>.  */
      if (filename[0] != '<')
	add_comp_dir_attribute (die);
    }

  add_AT_string (die, DW_AT_producer, producer_string ? producer_string : "");

  /* If our producer is LTO try to figure out a common language to use
     from the global list of translation units.  */
  if (strcmp (language_string, "GNU GIMPLE") == 0)
    {
      unsigned i;
      tree t;
      const char *common_lang = NULL;

      FOR_EACH_VEC_SAFE_ELT (all_translation_units, i, t)
	{
	  if (!TRANSLATION_UNIT_LANGUAGE (t))
	    continue;
	  if (!common_lang)
	    common_lang = TRANSLATION_UNIT_LANGUAGE (t);
	  else if (strcmp (common_lang, TRANSLATION_UNIT_LANGUAGE (t)) == 0)
	    ;
	  else if (startswith (common_lang, "GNU C")
		    && startswith (TRANSLATION_UNIT_LANGUAGE (t), "GNU C"))
	    /* Mixing C and C++ is ok, use C++ in that case.  */
	    common_lang = highest_c_language (common_lang,
					      TRANSLATION_UNIT_LANGUAGE (t));
	  else
	    {
	      /* Fall back to C.  */
	      common_lang = NULL;
	      break;
	    }
	}

      if (common_lang)
	language_string = common_lang;
    }

  language = DW_LANG_C;
  if (startswith (language_string, "GNU C")
      && ISDIGIT (language_string[5]))
    {
      language = DW_LANG_C89;
      if (dwarf_version >= 3 || !dwarf_strict)
	{
	  if (strcmp (language_string, "GNU C89") != 0)
	    language = DW_LANG_C99;

	  if (dwarf_version >= 5 /* || !dwarf_strict */)
	    if (strcmp (language_string, "GNU C11") == 0
		|| strcmp (language_string, "GNU C17") == 0
		|| strcmp (language_string, "GNU C2X") == 0)
	      language = DW_LANG_C11;
	}
    }
  else if (startswith (language_string, "GNU C++"))
    {
      language = DW_LANG_C_plus_plus;
      if (dwarf_version >= 5 /* || !dwarf_strict */)
	{
	  if (strcmp (language_string, "GNU C++11") == 0)
	    language = DW_LANG_C_plus_plus_11;
	  else if (strcmp (language_string, "GNU C++14") == 0)
	    language = DW_LANG_C_plus_plus_14;
	  else if (strcmp (language_string, "GNU C++17") == 0
		   || strcmp (language_string, "GNU C++20") == 0
		   || strcmp (language_string, "GNU C++23") == 0)
	    /* For now.  */
	    language = DW_LANG_C_plus_plus_14;
	}
    }
  else if (strcmp (language_string, "GNU F77") == 0)
    language = DW_LANG_Fortran77;
  else if (dwarf_version >= 3 || !dwarf_strict)
    {
      if (strcmp (language_string, "GNU Ada") == 0)
	language = DW_LANG_Ada95;
      else if (startswith (language_string, "GNU Fortran"))
	{
	  language = DW_LANG_Fortran95;
	  if (dwarf_version >= 5 /* || !dwarf_strict */)
	    {
	      if (strcmp (language_string, "GNU Fortran2003") == 0)
		language = DW_LANG_Fortran03;
	      else if (strcmp (language_string, "GNU Fortran2008") == 0)
		language = DW_LANG_Fortran08;
	    }
	}
      else if (strcmp (language_string, "GNU Objective-C") == 0)
	language = DW_LANG_ObjC;
      else if (strcmp (language_string, "GNU Objective-C++") == 0)
	language = DW_LANG_ObjC_plus_plus;
      else if (strcmp (language_string, "GNU D") == 0)
	language = DW_LANG_D;
      else if (dwarf_version >= 5 || !dwarf_strict)
	{
	  if (strcmp (language_string, "GNU Go") == 0)
	    language = DW_LANG_Go;
	}
    }
  /* Use a degraded Fortran setting in strict DWARF2 so is_fortran works.  */
  else if (startswith (language_string, "GNU Fortran"))
    language = DW_LANG_Fortran90;
  /* Likewise for Ada.  */
  else if (strcmp (language_string, "GNU Ada") == 0)
    language = DW_LANG_Ada83;

  add_AT_unsigned (die, DW_AT_language, language);

  switch (language)
    {
    case DW_LANG_Fortran77:
    case DW_LANG_Fortran90:
    case DW_LANG_Fortran95:
    case DW_LANG_Fortran03:
    case DW_LANG_Fortran08:
      /* Fortran has case insensitive identifiers and the front-end
	 lowercases everything.  */
      add_AT_unsigned (die, DW_AT_identifier_case, DW_ID_down_case);
      break;
    default:
      /* The default DW_ID_case_sensitive doesn't need to be specified.  */
      break;
    }
  return die;
}

/* Generate the DIE for a base class.  */

static void
gen_inheritance_die (tree binfo, tree access, tree type,
		     dw_die_ref context_die)
{
  dw_die_ref die = new_die (DW_TAG_inheritance, context_die, binfo);
  struct vlr_context ctx = { type, NULL };

  add_type_attribute (die, BINFO_TYPE (binfo), TYPE_UNQUALIFIED, false,
		      context_die);
  add_data_member_location_attribute (die, binfo, &ctx);

  if (BINFO_VIRTUAL_P (binfo))
    add_AT_unsigned (die, DW_AT_virtuality, DW_VIRTUALITY_virtual);

  /* In DWARF3+ the default is DW_ACCESS_private only in DW_TAG_class_type
     children, otherwise the default is DW_ACCESS_public.  In DWARF2
     the default has always been DW_ACCESS_private.  */
  if (access == access_public_node)
    {
      if (dwarf_version == 2
	  || context_die->die_tag == DW_TAG_class_type)
      add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_public);
    }
  else if (access == access_protected_node)
    add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_protected);
  else if (dwarf_version > 2
	   && context_die->die_tag != DW_TAG_class_type)
    add_AT_unsigned (die, DW_AT_accessibility, DW_ACCESS_private);
}

/* Return whether DECL is a FIELD_DECL that represents the variant part of a
   structure.  */

static bool
is_variant_part (tree decl)
{
  return (TREE_CODE (decl) == FIELD_DECL
	  && TREE_CODE (TREE_TYPE (decl)) == QUAL_UNION_TYPE);
}

/* Check that OPERAND is a reference to a field in STRUCT_TYPE.  If it is,
   return the FIELD_DECL.  Return NULL_TREE otherwise.  */

static tree
analyze_discr_in_predicate (tree operand, tree struct_type)
{
  while (CONVERT_EXPR_P (operand))
    operand = TREE_OPERAND (operand, 0);

  /* Match field access to members of struct_type only.  */
  if (TREE_CODE (operand) == COMPONENT_REF
      && TREE_CODE (TREE_OPERAND (operand, 0)) == PLACEHOLDER_EXPR
      && TREE_TYPE (TREE_OPERAND (operand, 0)) == struct_type
      && TREE_CODE (TREE_OPERAND (operand, 1)) == FIELD_DECL)
    return TREE_OPERAND (operand, 1);
  else
    return NULL_TREE;
}

/* Check that SRC is a constant integer that can be represented as a native
   integer constant (either signed or unsigned).  If so, store it into DEST and
   return true.  Return false otherwise. */

static bool
get_discr_value (tree src, dw_discr_value *dest)
{
  tree discr_type = TREE_TYPE (src);

  if (lang_hooks.types.get_debug_type)
    {
      tree debug_type = lang_hooks.types.get_debug_type (discr_type);
      if (debug_type != NULL)
	discr_type = debug_type;
    }

  if (TREE_CODE (src) != INTEGER_CST || !INTEGRAL_TYPE_P (discr_type))
    return false;

  /* Signedness can vary between the original type and the debug type. This
     can happen for character types in Ada for instance: the character type
     used for code generation can be signed, to be compatible with the C one,
     but from a debugger point of view, it must be unsigned.  */
  bool is_orig_unsigned = TYPE_UNSIGNED (TREE_TYPE (src));
  bool is_debug_unsigned = TYPE_UNSIGNED (discr_type);

  if (is_orig_unsigned != is_debug_unsigned)
    src = fold_convert (discr_type, src);

  if (!(is_debug_unsigned ? tree_fits_uhwi_p (src) : tree_fits_shwi_p (src)))
    return false;

  dest->pos = is_debug_unsigned;
  if (is_debug_unsigned)
    dest->v.uval = tree_to_uhwi (src);
  else
    dest->v.sval = tree_to_shwi (src);

  return true;
}

/* Try to extract synthetic properties out of VARIANT_PART_DECL, which is a
   FIELD_DECL in STRUCT_TYPE that represents a variant part.  If unsuccessful,
   store NULL_TREE in DISCR_DECL.  Otherwise:

     - store the discriminant field in STRUCT_TYPE that controls the variant
       part to *DISCR_DECL

     - put in *DISCR_LISTS_P an array where for each variant, the item
       represents the corresponding matching list of discriminant values.

     - put in *DISCR_LISTS_LENGTH the number of variants, which is the size of
       the above array.

   Note that when the array is allocated (i.e. when the analysis is
   successful), it is up to the caller to free the array.  */

static void
analyze_variants_discr (tree variant_part_decl,
			tree struct_type,
			tree *discr_decl,
			dw_discr_list_ref **discr_lists_p,
			unsigned *discr_lists_length)
{
  tree variant_part_type = TREE_TYPE (variant_part_decl);
  tree variant;
  dw_discr_list_ref *discr_lists;
  unsigned i;

  /* Compute how many variants there are in this variant part.  */
  *discr_lists_length = 0;
  for (variant = TYPE_FIELDS (variant_part_type);
       variant != NULL_TREE;
       variant = DECL_CHAIN (variant))
    ++*discr_lists_length;

  *discr_decl = NULL_TREE;
  *discr_lists_p
    = (dw_discr_list_ref *) xcalloc (*discr_lists_length,
				     sizeof (**discr_lists_p));
  discr_lists = *discr_lists_p;

  /* And then analyze all variants to extract discriminant information for all
     of them.  This analysis is conservative: as soon as we detect something we
     do not support, abort everything and pretend we found nothing.  */
  for (variant = TYPE_FIELDS (variant_part_type), i = 0;
       variant != NULL_TREE;
       variant = DECL_CHAIN (variant), ++i)
    {
      tree match_expr = DECL_QUALIFIER (variant);

      /* Now, try to analyze the predicate and deduce a discriminant for
	 it.  */
      if (match_expr == boolean_true_node)
	/* Typically happens for the default variant: it matches all cases that
	   previous variants rejected.  Don't output any matching value for
	   this one.  */
	continue;

      /* The following loop tries to iterate over each discriminant
	 possibility: single values or ranges.  */
      while (match_expr != NULL_TREE)
	{
	  tree next_round_match_expr;
	  tree candidate_discr = NULL_TREE;
	  dw_discr_list_ref new_node = NULL;

	  /* Possibilities are matched one after the other by nested
	     TRUTH_ORIF_EXPR expressions.  Process the current possibility and
	     continue with the rest at next iteration.  */
	  if (TREE_CODE (match_expr) == TRUTH_ORIF_EXPR)
	    {
	      next_round_match_expr = TREE_OPERAND (match_expr, 0);
	      match_expr = TREE_OPERAND (match_expr, 1);
	    }
	  else
	    next_round_match_expr = NULL_TREE;

	  if (match_expr == boolean_false_node)
	    /* This sub-expression matches nothing: just wait for the next
	       one.  */
	    ;

	  else if (TREE_CODE (match_expr) == EQ_EXPR)
	    {
	      /* We are matching:  <discr_field> == <integer_cst>
		 This sub-expression matches a single value.  */
	      tree integer_cst = TREE_OPERAND (match_expr, 1);

	      candidate_discr
	       = analyze_discr_in_predicate (TREE_OPERAND (match_expr, 0),
					     struct_type);

	      new_node = ggc_cleared_alloc<dw_discr_list_node> ();
	      if (!get_discr_value (integer_cst,
				    &new_node->dw_discr_lower_bound))
		goto abort;
	      new_node->dw_discr_range = false;
	    }

	  else if (TREE_CODE (match_expr) == TRUTH_ANDIF_EXPR)
	    {
	      /* We are matching:
		   <discr_field> > <integer_cst>
		   && <discr_field> < <integer_cst>.
		 This sub-expression matches the range of values between the
		 two matched integer constants.  Note that comparisons can be
		 inclusive or exclusive.  */
	      tree candidate_discr_1, candidate_discr_2;
	      tree lower_cst, upper_cst;
	      bool lower_cst_included, upper_cst_included;
	      tree lower_op = TREE_OPERAND (match_expr, 0);
	      tree upper_op = TREE_OPERAND (match_expr, 1);

	      /* When the comparison is exclusive, the integer constant is not
		 the discriminant range bound we are looking for: we will have
		 to increment or decrement it.  */
	      if (TREE_CODE (lower_op) == GE_EXPR)
		lower_cst_included = true;
	      else if (TREE_CODE (lower_op) == GT_EXPR)
		lower_cst_included = false;
	      else
		goto abort;

	      if (TREE_CODE (upper_op) == LE_EXPR)
		upper_cst_included = true;
	      else if (TREE_CODE (upper_op) == LT_EXPR)
		upper_cst_included = false;
	      else
		goto abort;

	      /* Extract the discriminant from the first operand and check it
		 is consistant with the same analysis in the second
		 operand.  */
	      candidate_discr_1
	        = analyze_discr_in_predicate (TREE_OPERAND (lower_op, 0),
					      struct_type);
	      candidate_discr_2
	        = analyze_discr_in_predicate (TREE_OPERAND (upper_op, 0),
					      struct_type);
	      if (candidate_discr_1 == candidate_discr_2)
		candidate_discr = candidate_discr_1;
	      else
		goto abort;

	      /* Extract bounds from both.  */
	      new_node = ggc_cleared_alloc<dw_discr_list_node> ();
	      lower_cst = TREE_OPERAND (lower_op, 1);
	      upper_cst = TREE_OPERAND (upper_op, 1);

	      if (!lower_cst_included)
		lower_cst
		  = fold_build2 (PLUS_EXPR, TREE_TYPE (lower_cst), lower_cst,
				 build_int_cst (TREE_TYPE (lower_cst), 1));
	      if (!upper_cst_included)
		upper_cst
		  = fold_build2 (MINUS_EXPR, TREE_TYPE (upper_cst), upper_cst,
				 build_int_cst (TREE_TYPE (upper_cst), 1));

	      if (!get_discr_value (lower_cst,
				    &new_node->dw_discr_lower_bound)
		  || !get_discr_value (upper_cst,
				       &new_node->dw_discr_upper_bound))
		goto abort;

	      new_node->dw_discr_range = true;
	    }

	  else if ((candidate_discr
		      = analyze_discr_in_predicate (match_expr, struct_type))
		   && (TREE_TYPE (candidate_discr) == boolean_type_node
		       || TREE_TYPE (TREE_TYPE (candidate_discr))
			  == boolean_type_node))
	    {
	      /* We are matching:  <discr_field> for a boolean discriminant.
		 This sub-expression matches boolean_true_node.  */
	      new_node = ggc_cleared_alloc<dw_discr_list_node> ();
	      if (!get_discr_value (boolean_true_node,
				    &new_node->dw_discr_lower_bound))
		goto abort;
	      new_node->dw_discr_range = false;
	    }

	  else
	    /* Unsupported sub-expression: we cannot determine the set of
	       matching discriminant values.  Abort everything.  */
	    goto abort;

	  /* If the discriminant info is not consistant with what we saw so
	     far, consider the analysis failed and abort everything.  */
	  if (candidate_discr == NULL_TREE
	      || (*discr_decl != NULL_TREE && candidate_discr != *discr_decl))
	    goto abort;
	  else
	    *discr_decl = candidate_discr;

	  if (new_node != NULL)
	    {
	      new_node->dw_discr_next = discr_lists[i];
	      discr_lists[i] = new_node;
	    }
	  match_expr = next_round_match_expr;
	}
    }

  /* If we reach this point, we could match everything we were interested
     in.  */
  return;

abort:
  /* Clean all data structure and return no result.  */
  free (*discr_lists_p);
  *discr_lists_p = NULL;
  *discr_decl = NULL_TREE;
}

/* Generate a DIE to represent VARIANT_PART_DECL, a variant part that is part
   of STRUCT_TYPE, a record type.  This new DIE is emitted as the next child
   under CONTEXT_DIE.

   Variant parts are supposed to be implemented as a FIELD_DECL whose type is a
   QUAL_UNION_TYPE: this is the VARIANT_PART_DECL parameter.  The members for
   this type, which are record types, represent the available variants and each
   has a DECL_QUALIFIER attribute.  The discriminant and the discriminant
   values are inferred from these attributes.

   In trees, the offsets for the fields inside these sub-records are relative
   to the variant part itself, whereas the corresponding DIEs should have
   offset attributes that are relative to the embedding record base address.
   This is why the caller must provide a VARIANT_PART_OFFSET expression: it
   must be an expression that computes the offset of the variant part to
   describe in DWARF.  */

static void
gen_variant_part (tree variant_part_decl, struct vlr_context *vlr_ctx,
		  dw_die_ref context_die)
{
  const tree variant_part_type = TREE_TYPE (variant_part_decl);
  tree variant_part_offset = vlr_ctx->variant_part_offset;

  /* The FIELD_DECL node in STRUCT_TYPE that acts as the discriminant, or
     NULL_TREE if there is no such field.  */
  tree discr_decl = NULL_TREE;
  dw_discr_list_ref *discr_lists;
  unsigned discr_lists_length = 0;
  unsigned i;

  dw_die_ref dwarf_proc_die = NULL;
  dw_die_ref variant_part_die
    = new_die (DW_TAG_variant_part, context_die, variant_part_type);

  equate_decl_number_to_die (variant_part_decl, variant_part_die);

  analyze_variants_discr (variant_part_decl, vlr_ctx->struct_type,
			  &discr_decl, &discr_lists, &discr_lists_length);

  if (discr_decl != NULL_TREE)
    {
      dw_die_ref discr_die = lookup_decl_die (discr_decl);

      if (discr_die)
	add_AT_die_ref (variant_part_die, DW_AT_discr, discr_die);
      else
	/* We have no DIE for the discriminant, so just discard all
	   discrimimant information in the output.  */
	discr_decl = NULL_TREE;
    }

  /* If the offset for this variant part is more complex than a constant,
     create a DWARF procedure for it so that we will not have to generate
     DWARF expressions for it for each member.  */
  if (TREE_CODE (variant_part_offset) != INTEGER_CST
      && (dwarf_version >= 3 || !dwarf_strict))
    {
      struct loc_descr_context ctx = {
	vlr_ctx->struct_type,	/* context_type */
	NULL_TREE,		/* base_decl */
	NULL,		  	/* dpi */
	false,		  	/* placeholder_arg */
	false,		  	/* placeholder_seen */
	false		  	/* strict_signedness */
      };
      const tree dwarf_proc_fndecl
        = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, NULL_TREE,
		      build_function_type (TREE_TYPE (variant_part_offset),
					   NULL_TREE));
      const tree dwarf_proc_call = build_call_expr (dwarf_proc_fndecl, 0);
      const dw_loc_descr_ref dwarf_proc_body
        = loc_descriptor_from_tree (variant_part_offset, 0, &ctx);

      dwarf_proc_die = new_dwarf_proc_die (dwarf_proc_body,
					   dwarf_proc_fndecl, context_die);
      if (dwarf_proc_die != NULL)
	variant_part_offset = dwarf_proc_call;
    }

  /* Output DIEs for all variants.  */
  i = 0;
  for (tree variant = TYPE_FIELDS (variant_part_type);
       variant != NULL_TREE;
       variant = DECL_CHAIN (variant), ++i)
    {
      tree variant_type = TREE_TYPE (variant);
      dw_die_ref variant_die;

      /* All variants (i.e. members of a variant part) are supposed to be
	 encoded as structures.  Sub-variant parts are QUAL_UNION_TYPE fields
	 under these records.  */
      gcc_assert (TREE_CODE (variant_type) == RECORD_TYPE);

      variant_die = new_die (DW_TAG_variant, variant_part_die, variant_type);
      equate_decl_number_to_die (variant, variant_die);

      /* Output discriminant values this variant matches, if any.  */
      if (discr_decl == NULL || discr_lists[i] == NULL)
	/* In the case we have discriminant information at all, this is
	   probably the default variant: as the standard says, don't
	   output any discriminant value/list attribute.  */
	;
      else if (discr_lists[i]->dw_discr_next == NULL
	       && !discr_lists[i]->dw_discr_range)
	/* If there is only one accepted value, don't bother outputting a
	   list.  */
	add_discr_value (variant_die, &discr_lists[i]->dw_discr_lower_bound);
      else
	add_discr_list (variant_die, discr_lists[i]);

      for (tree member = TYPE_FIELDS (variant_type);
	   member != NULL_TREE;
	   member = DECL_CHAIN (member))
	{
	  struct vlr_context vlr_sub_ctx = {
	    vlr_ctx->struct_type, /* struct_type */
	    NULL		  /* variant_part_offset */
	  };
	  if (is_variant_part (member))
	    {
	      /* All offsets for fields inside variant parts are relative to
		 the top-level embedding RECORD_TYPE's base address.  On the
		 other hand, offsets in GCC's types are relative to the
		 nested-most variant part.  So we have to sum offsets each time
		 we recurse.  */

	      vlr_sub_ctx.variant_part_offset
		= fold_build2 (PLUS_EXPR, TREE_TYPE (variant_part_offset),
			       variant_part_offset, byte_position (member));
	      gen_variant_part (member, &vlr_sub_ctx, variant_die);
	    }
	  else
	    {
	      vlr_sub_ctx.variant_part_offset = variant_part_offset;
	      gen_decl_die (member, NULL, &vlr_sub_ctx, variant_die);
	    }
	}
    }

  free (discr_lists);
}

/* Generate a DIE for a class member.  */

static void
gen_member_die (tree type, dw_die_ref context_die)
{
  tree member;
  tree binfo = TYPE_BINFO (type);

  gcc_assert (TYPE_MAIN_VARIANT (type) == type);

  /* If this is not an incomplete type, output descriptions of each of its
     members. Note that as we output the DIEs necessary to represent the
     members of this record or union type, we will also be trying to output
     DIEs to represent the *types* of those members. However the `type'
     function (above) will specifically avoid generating type DIEs for member
     types *within* the list of member DIEs for this (containing) type except
     for those types (of members) which are explicitly marked as also being
     members of this (containing) type themselves.  The g++ front- end can
     force any given type to be treated as a member of some other (containing)
     type by setting the TYPE_CONTEXT of the given (member) type to point to
     the TREE node representing the appropriate (containing) type.  */

  /* First output info about the base classes.  */
  if (binfo && early_dwarf)
    {
      vec<tree, va_gc> *accesses = BINFO_BASE_ACCESSES (binfo);
      int i;
      tree base;

      for (i = 0; BINFO_BASE_ITERATE (binfo, i, base); i++)
	gen_inheritance_die (base,
			     (accesses ? (*accesses)[i] : access_public_node),
			     type,
			     context_die);
    }

  /* Now output info about the members. */
  for (member = TYPE_FIELDS (type); member; member = DECL_CHAIN (member))
    {
      /* Ignore clones.  */
      if (DECL_ABSTRACT_ORIGIN (member))
	continue;

      struct vlr_context vlr_ctx = { type, NULL_TREE };
      bool static_inline_p
	= (VAR_P (member)
	   && TREE_STATIC (member)
	   && (lang_hooks.decls.decl_dwarf_attribute (member, DW_AT_inline)
	       != -1));

      /* If we thought we were generating minimal debug info for TYPE
	 and then changed our minds, some of the member declarations
	 may have already been defined.  Don't define them again, but
	 do put them in the right order.  */

      if (dw_die_ref child = lookup_decl_die (member))
	{
	  /* Handle inline static data members, which only have in-class
	     declarations.  */
	  bool splice = true;

	  dw_die_ref ref = NULL;
	  if (child->die_tag == DW_TAG_variable
	      && child->die_parent == comp_unit_die ())
	    {
	      ref = get_AT_ref (child, DW_AT_specification);

	      /* For C++17 inline static data members followed by redundant
		 out of class redeclaration, we might get here with
		 child being the DIE created for the out of class
		 redeclaration and with its DW_AT_specification being
		 the DIE created for in-class definition.  We want to
		 reparent the latter, and don't want to create another
		 DIE with DW_AT_specification in that case, because
		 we already have one.  */
	      if (ref
		  && static_inline_p
		  && ref->die_tag == DW_TAG_variable
		  && ref->die_parent == comp_unit_die ()
		  && get_AT (ref, DW_AT_specification) == NULL)
		{
		  child = ref;
		  ref = NULL;
		  static_inline_p = false;
		}

	      if (!ref)
		{
		  reparent_child (child, context_die);
		  if (dwarf_version < 5)
		    child->die_tag = DW_TAG_member;
		  splice = false;
		}
	    }
	  else if (child->die_tag == DW_TAG_enumerator)
	    /* Enumerators remain under their enumeration even if
	       their names are introduced in the enclosing scope.  */
	    splice = false;

	  if (splice)
	    splice_child_die (context_die, child);
	}

      /* Do not generate DWARF for variant parts if we are generating the
	 corresponding GNAT encodings: DIEs generated for the two schemes
	 would conflict in our mappings.  */
      else if (is_variant_part (member)
	       && gnat_encodings != DWARF_GNAT_ENCODINGS_ALL)
	{
	  vlr_ctx.variant_part_offset = byte_position (member);
	  gen_variant_part (member, &vlr_ctx, context_die);
	}
      else
	{
	  vlr_ctx.variant_part_offset = NULL_TREE;
	  gen_decl_die (member, NULL, &vlr_ctx, context_die);
	}

      /* For C++ inline static data members emit immediately a DW_TAG_variable
	 DIE that will refer to that DW_TAG_member/DW_TAG_variable through
	 DW_AT_specification.  */
      if (static_inline_p)
	{
	  int old_extern = DECL_EXTERNAL (member);
	  DECL_EXTERNAL (member) = 0;
	  gen_decl_die (member, NULL, NULL, comp_unit_die ());
	  DECL_EXTERNAL (member) = old_extern;
	}
    }
}

/* Generate a DIE for a structure or union type.  If TYPE_DECL_SUPPRESS_DEBUG
   is set, we pretend that the type was never defined, so we only get the
   member DIEs needed by later specification DIEs.  */

static void
gen_struct_or_union_type_die (tree type, dw_die_ref context_die,
				enum debug_info_usage usage)
{
  if (TREE_ASM_WRITTEN (type))
    {
      /* Fill in the bound of variable-length fields in late dwarf if
	 still incomplete.  */
      if (!early_dwarf && variably_modified_type_p (type, NULL))
	for (tree member = TYPE_FIELDS (type);
	     member;
	     member = DECL_CHAIN (member))
	  fill_variable_array_bounds (TREE_TYPE (member));
      return;
    }

  dw_die_ref type_die = lookup_type_die (type);
  dw_die_ref scope_die = 0;
  int nested = 0;
  int complete = (TYPE_SIZE (type)
		  && (! TYPE_STUB_DECL (type)
		      || ! TYPE_DECL_SUPPRESS_DEBUG (TYPE_STUB_DECL (type))));
  int ns_decl = (context_die && context_die->die_tag == DW_TAG_namespace);
  complete = complete && should_emit_struct_debug (type, usage);

  if (type_die && ! complete)
    return;

  if (TYPE_CONTEXT (type) != NULL_TREE
      && (AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
	  || TREE_CODE (TYPE_CONTEXT (type)) == NAMESPACE_DECL))
    nested = 1;

  scope_die = scope_die_for (type, context_die);

  /* Generate child dies for template parameters.  */
  if (!type_die && debug_info_level > DINFO_LEVEL_TERSE)
    schedule_generic_params_dies_gen (type);

  if (! type_die || (nested && is_cu_die (scope_die)))
    /* First occurrence of type or toplevel definition of nested class.  */
    {
      dw_die_ref old_die = type_die;

      type_die = new_die (TREE_CODE (type) == RECORD_TYPE
			  ? record_type_tag (type) : DW_TAG_union_type,
			  scope_die, type);
      equate_type_number_to_die (type, type_die);
      if (old_die)
	add_AT_specification (type_die, old_die);
      else
	add_name_attribute (type_die, type_tag (type));
    }
  else
    remove_AT (type_die, DW_AT_declaration);

  /* If this type has been completed, then give it a byte_size attribute and
     then give a list of members.  */
  if (complete && !ns_decl)
    {
      /* Prevent infinite recursion in cases where the type of some member of
	 this type is expressed in terms of this type itself.  */
      TREE_ASM_WRITTEN (type) = 1;
      add_byte_size_attribute (type_die, type);
      add_alignment_attribute (type_die, type);
      if (TYPE_STUB_DECL (type) != NULL_TREE)
	{
	  add_src_coords_attributes (type_die, TYPE_STUB_DECL (type));
	  add_accessibility_attribute (type_die, TYPE_STUB_DECL (type));
	}

      /* If the first reference to this type was as the return type of an
	 inline function, then it may not have a parent.  Fix this now.  */
      if (type_die->die_parent == NULL)
	add_child_die (scope_die, type_die);

      gen_member_die (type, type_die);

      add_gnat_descriptive_type_attribute (type_die, type, context_die);
      if (TYPE_ARTIFICIAL (type))
	add_AT_flag (type_die, DW_AT_artificial, 1);

      /* GNU extension: Record what type our vtable lives in.  */
      if (TYPE_VFIELD (type))
	{
	  tree vtype = DECL_FCONTEXT (TYPE_VFIELD (type));

	  gen_type_die (vtype, context_die);
	  add_AT_die_ref (type_die, DW_AT_containing_type,
			  lookup_type_die (vtype));
	}
    }
  else
    {
      add_AT_flag (type_die, DW_AT_declaration, 1);

      /* We don't need to do this for function-local types.  */
      if (TYPE_STUB_DECL (type)
	  && ! decl_function_context (TYPE_STUB_DECL (type)))
	vec_safe_push (incomplete_types, type);
    }

  if (get_AT (type_die, DW_AT_name))
    add_pubtype (type, type_die);
}

/* Generate a DIE for a subroutine _type_.  */

static void
gen_subroutine_type_die (tree type, dw_die_ref context_die)
{
  tree return_type = TREE_TYPE (type);
  dw_die_ref subr_die
    = new_die (DW_TAG_subroutine_type,
	       scope_die_for (type, context_die), type);

  equate_type_number_to_die (type, subr_die);
  add_prototyped_attribute (subr_die, type);
  add_type_attribute (subr_die, return_type, TYPE_UNQUALIFIED, false,
		      context_die);
  add_alignment_attribute (subr_die, type);
  gen_formal_types_die (type, subr_die);

  if (get_AT (subr_die, DW_AT_name))
    add_pubtype (type, subr_die);
  if ((dwarf_version >= 5 || !dwarf_strict)
      && lang_hooks.types.type_dwarf_attribute (type, DW_AT_reference) != -1)
    add_AT_flag (subr_die, DW_AT_reference, 1);
  if ((dwarf_version >= 5 || !dwarf_strict)
      && lang_hooks.types.type_dwarf_attribute (type,
						DW_AT_rvalue_reference) != -1)
    add_AT_flag (subr_die, DW_AT_rvalue_reference, 1);
}

/* Generate a DIE for a type definition.  */

static void
gen_typedef_die (tree decl, dw_die_ref context_die)
{
  dw_die_ref type_die;
  tree type;

  if (TREE_ASM_WRITTEN (decl))
    {
      if (DECL_ORIGINAL_TYPE (decl))
	fill_variable_array_bounds (DECL_ORIGINAL_TYPE (decl));
      return;
    }

  /* As we avoid creating DIEs for local typedefs (see decl_ultimate_origin
     checks in process_scope_var and modified_type_die), this should be called
     only for original types.  */
  gcc_assert (decl_ultimate_origin (decl) == NULL
	      || decl_ultimate_origin (decl) == decl);

  TREE_ASM_WRITTEN (decl) = 1;
  type_die = new_die (DW_TAG_typedef, context_die, decl);

  add_name_and_src_coords_attributes (type_die, decl);
  if (DECL_ORIGINAL_TYPE (decl))
    {
      type = DECL_ORIGINAL_TYPE (decl);
      if (type == error_mark_node)
	return;

      gcc_assert (type != TREE_TYPE (decl));
      equate_type_number_to_die (TREE_TYPE (decl), type_die);
    }
  else
    {
      type = TREE_TYPE (decl);
      if (type == error_mark_node)
	return;

      if (is_naming_typedef_decl (TYPE_NAME (type)))
	{
	  /* Here, we are in the case of decl being a typedef naming
	     an anonymous type, e.g:
		 typedef struct {...} foo;
	     In that case TREE_TYPE (decl) is not a typedef variant
	     type and TYPE_NAME of the anonymous type is set to the
	     TYPE_DECL of the typedef. This construct is emitted by
	     the C++ FE.

	     TYPE is the anonymous struct named by the typedef
	     DECL. As we need the DW_AT_type attribute of the
	     DW_TAG_typedef to point to the DIE of TYPE, let's
	     generate that DIE right away. add_type_attribute
	     called below will then pick (via lookup_type_die) that
	     anonymous struct DIE.  */
	  if (!TREE_ASM_WRITTEN (type))
	    gen_tagged_type_die (type, context_die, DINFO_USAGE_DIR_USE);

	  /* This is a GNU Extension.  We are adding a
	     DW_AT_linkage_name attribute to the DIE of the
	     anonymous struct TYPE.  The value of that attribute
	     is the name of the typedef decl naming the anonymous
	     struct.  This greatly eases the work of consumers of
	     this debug info.  */
	  add_linkage_name_raw (lookup_type_die (type), decl);
	}
    }

  add_type_attribute (type_die, type, decl_quals (decl), false,
		      context_die);

  if (is_naming_typedef_decl (decl))
    /* We want that all subsequent calls to lookup_type_die with
       TYPE in argument yield the DW_TAG_typedef we have just
       created.  */
    equate_type_number_to_die (type, type_die);

  add_alignment_attribute (type_die, TREE_TYPE (decl));

  add_accessibility_attribute (type_die, decl);

  if (DECL_ABSTRACT_P (decl))
    equate_decl_number_to_die (decl, type_die);

  if (get_AT (type_die, DW_AT_name))
    add_pubtype (decl, type_die);
}

/* Generate a DIE for a struct, class, enum or union type.  */

static void
gen_tagged_type_die (tree type,
		     dw_die_ref context_die,
		     enum debug_info_usage usage)
{
  if (type == NULL_TREE
      || !is_tagged_type (type))
    return;

  if (TREE_ASM_WRITTEN (type))
    ;
  /* If this is a nested type whose containing class hasn't been written
     out yet, writing it out will cover this one, too.  This does not apply
     to instantiations of member class templates; they need to be added to
     the containing class as they are generated.  FIXME: This hurts the
     idea of combining type decls from multiple TUs, since we can't predict
     what set of template instantiations we'll get.  */
  else if (TYPE_CONTEXT (type)
      && AGGREGATE_TYPE_P (TYPE_CONTEXT (type))
      && ! TREE_ASM_WRITTEN (TYPE_CONTEXT (type)))
    {
      gen_type_die_with_usage (TYPE_CONTEXT (type), context_die, usage);

      if (TREE_ASM_WRITTEN (type))
	return;

      /* If that failed, attach ourselves to the stub.  */
      context_die = lookup_type_die (TYPE_CONTEXT (type));
    }
  else if (TYPE_CONTEXT (type) != NULL_TREE
	   && (TREE_CODE (TYPE_CONTEXT (type)) == FUNCTION_DECL))
    {
      /* If this type is local to a function that hasn't been written
	 out yet, use a NULL context for now; it will be fixed up in
	 decls_for_scope.  */
      context_die = lookup_decl_die (TYPE_CONTEXT (type));
      /* A declaration DIE doesn't count; nested types need to go in the
	 specification.  */
      if (context_die && is_declaration_die (context_die))
	context_die = NULL;
    }
  else
    context_die = declare_in_namespace (type, context_die);

  if (TREE_CODE (type) == ENUMERAL_TYPE)
    {
      /* This might have been written out by the call to
	 declare_in_namespace.  */
      if (!TREE_ASM_WRITTEN (type))
	gen_enumeration_type_die (type, context_die);
    }
  else
    gen_struct_or_union_type_die (type, context_die, usage);

  /* Don't set TREE_ASM_WRITTEN on an incomplete struct; we want to fix
     it up if it is ever completed.  gen_*_type_die will set it for us
     when appropriate.  */
}

/* Generate a type description DIE.  */

static void
gen_type_die_with_usage (tree type, dw_die_ref context_die,
			 enum debug_info_usage usage)
{
  struct array_descr_info info;

  if (type == NULL_TREE || type == error_mark_node)
    return;

  if (flag_checking && type)
     verify_type (type);

  if (TYPE_NAME (type) != NULL_TREE
      && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
      && is_redundant_typedef (TYPE_NAME (type))
      && DECL_ORIGINAL_TYPE (TYPE_NAME (type)))
    /* The DECL of this type is a typedef we don't want to emit debug
       info for but we want debug info for its underlying typedef.
       This can happen for e.g, the injected-class-name of a C++
       type.  */
    type = DECL_ORIGINAL_TYPE (TYPE_NAME (type));

  /* If TYPE is a typedef type variant, let's generate debug info
     for the parent typedef which TYPE is a type of.  */
  if (typedef_variant_p (type))
    {
      if (TREE_ASM_WRITTEN (type))
	return;

      tree name = TYPE_NAME (type);
      tree origin = decl_ultimate_origin (name);
      if (origin != NULL && origin != name)
	{
	  gen_decl_die (origin, NULL, NULL, context_die);
	  return;
	}

      /* Prevent broken recursion; we can't hand off to the same type.  */
      gcc_assert (DECL_ORIGINAL_TYPE (name) != type);

      /* Give typedefs the right scope.  */
      context_die = scope_die_for (type, context_die);

      TREE_ASM_WRITTEN (type) = 1;

      gen_decl_die (name, NULL, NULL, context_die);
      return;
    }

  /* If type is an anonymous tagged type named by a typedef, let's
     generate debug info for the typedef.  */
  if (is_naming_typedef_decl (TYPE_NAME (type)))
    {
      /* Give typedefs the right scope.  */
      context_die = scope_die_for (type, context_die);

      gen_decl_die (TYPE_NAME (type), NULL, NULL, context_die);
      return;
    }

  if (lang_hooks.types.get_debug_type)
    {
      tree debug_type = lang_hooks.types.get_debug_type (type);

      if (debug_type != NULL_TREE && debug_type != type)
	{
	  gen_type_die_with_usage (debug_type, context_die, usage);
	  return;
	}
    }

  /* We are going to output a DIE to represent the unqualified version
     of this type (i.e. without any const or volatile qualifiers) so
     get the main variant (i.e. the unqualified version) of this type
     now.  (Vectors and arrays are special because the debugging info is in the
     cloned type itself.  Similarly function/method types can contain extra
     ref-qualification).  */
  if (TREE_CODE (type) == FUNCTION_TYPE
      || TREE_CODE (type) == METHOD_TYPE)
    {
      /* For function/method types, can't use type_main_variant here,
	 because that can have different ref-qualifiers for C++,
	 but try to canonicalize.  */
      tree main = TYPE_MAIN_VARIANT (type);
      for (tree t = main; t; t = TYPE_NEXT_VARIANT (t))
	if (TYPE_QUALS_NO_ADDR_SPACE (t) == 0
	    && check_base_type (t, main)
	    && check_lang_type (t, type))
	  {
	    type = t;
	    break;
	  }
    }
  else if (TREE_CODE (type) != VECTOR_TYPE
	   && TREE_CODE (type) != ARRAY_TYPE)
    type = type_main_variant (type);

  /* If this is an array type with hidden descriptor, handle it first.  */
  if (!TREE_ASM_WRITTEN (type)
      && lang_hooks.types.get_array_descr_info)
    {
      memset (&info, 0, sizeof (info));
      if (lang_hooks.types.get_array_descr_info (type, &info))
	{
	  /* Fortran sometimes emits array types with no dimension.  */
	  gcc_assert (info.ndimensions >= 0
		      && (info.ndimensions
			  <= DWARF2OUT_ARRAY_DESCR_INFO_MAX_DIMEN));
	  gen_descr_array_type_die (type, &info, context_die);
	  TREE_ASM_WRITTEN (type) = 1;
	  return;
	}
    }

  if (TREE_ASM_WRITTEN (type))
    {
      /* Variable-length types may be incomplete even if
	 TREE_ASM_WRITTEN.  For such types, fall through to
	 gen_array_type_die() and possibly fill in
	 DW_AT_{upper,lower}_bound attributes.  */
      if ((TREE_CODE (type) != ARRAY_TYPE
	   && TREE_CODE (type) != RECORD_TYPE
	   && TREE_CODE (type) != UNION_TYPE
	   && TREE_CODE (type) != QUAL_UNION_TYPE)
	  || !variably_modified_type_p (type, NULL))
	return;
    }

  switch (TREE_CODE (type))
    {
    case ERROR_MARK:
      break;

    case POINTER_TYPE:
    case REFERENCE_TYPE:
      /* We must set TREE_ASM_WRITTEN in case this is a recursive type.  This
	 ensures that the gen_type_die recursion will terminate even if the
	 type is recursive.  Recursive types are possible in Ada.  */
      /* ??? We could perhaps do this for all types before the switch
	 statement.  */
      TREE_ASM_WRITTEN (type) = 1;

      /* For these types, all that is required is that we output a DIE (or a
	 set of DIEs) to represent the "basis" type.  */
      gen_type_die_with_usage (TREE_TYPE (type), context_die,
			       DINFO_USAGE_IND_USE);
      break;

    case OFFSET_TYPE:
      /* This code is used for C++ pointer-to-data-member types.
	 Output a description of the relevant class type.  */
      gen_type_die_with_usage (TYPE_OFFSET_BASETYPE (type), context_die,
			       DINFO_USAGE_IND_USE);

      /* Output a description of the type of the object pointed to.  */
      gen_type_die_with_usage (TREE_TYPE (type), context_die,
			       DINFO_USAGE_IND_USE);

      /* Now output a DIE to represent this pointer-to-data-member type
	 itself.  */
      gen_ptr_to_mbr_type_die (type, context_die);
      break;

    case FUNCTION_TYPE:
      /* Force out return type (in case it wasn't forced out already).  */
      gen_type_die_with_usage (TREE_TYPE (type), context_die,
			       DINFO_USAGE_DIR_USE);
      gen_subroutine_type_die (type, context_die);
      break;

    case METHOD_TYPE:
      /* Force out return type (in case it wasn't forced out already).  */
      gen_type_die_with_usage (TREE_TYPE (type), context_die,
			       DINFO_USAGE_DIR_USE);
      gen_subroutine_type_die (type, context_die);
      break;

    case ARRAY_TYPE:
    case VECTOR_TYPE:
      gen_array_type_die (type, context_die);
      break;

    case ENUMERAL_TYPE:
    case RECORD_TYPE:
    case UNION_TYPE:
    case QUAL_UNION_TYPE:
      gen_tagged_type_die (type, context_die, usage);
      return;

    case VOID_TYPE:
    case OPAQUE_TYPE:
    case INTEGER_TYPE:
    case REAL_TYPE:
    case FIXED_POINT_TYPE:
    case COMPLEX_TYPE:
    case BOOLEAN_TYPE:
      /* No DIEs needed for fundamental types.  */
      break;

    case NULLPTR_TYPE:
    case LANG_TYPE:
      /* Just use DW_TAG_unspecified_type.  */
      {
        dw_die_ref type_die = lookup_type_die (type);
        if (type_die == NULL)
          {
	    tree name = TYPE_IDENTIFIER (type);
            type_die = new_die (DW_TAG_unspecified_type, comp_unit_die (),
				type);
            add_name_attribute (type_die, IDENTIFIER_POINTER (name));
            equate_type_number_to_die (type, type_die);
          }
      }
      break;

    default:
      if (is_cxx_auto (type))
	{
	  tree name = TYPE_IDENTIFIER (type);
	  dw_die_ref *die = (name == get_identifier ("auto")
			     ? &auto_die : &decltype_auto_die);
	  if (!*die)
	    {
	      *die = new_die (DW_TAG_unspecified_type,
			      comp_unit_die (), NULL_TREE);
	      add_name_attribute (*die, IDENTIFIER_POINTER (name));
	    }
	  equate_type_number_to_die (type, *die);
	  break;
	}
      gcc_unreachable ();
    }

  TREE_ASM_WRITTEN (type) = 1;
}

static void
gen_type_die (tree type, dw_die_ref context_die)
{
  if (type != error_mark_node)
    {
      gen_type_die_with_usage (type, context_die, DINFO_USAGE_DIR_USE);
      if (flag_checking)
	{
	  dw_die_ref die = lookup_type_die (type);
	  if (die)
	    check_die (die);
	}
    }
}

/* Generate a DW_TAG_lexical_block DIE followed by DIEs to represent all of the
   things which are local to the given block.  */

static void
gen_block_die (tree stmt, dw_die_ref context_die)
{
  int must_output_die = 0;
  bool inlined_func;

  /* Ignore blocks that are NULL.  */
  if (stmt == NULL_TREE)
    return;

  inlined_func = inlined_function_outer_scope_p (stmt);

  /* If the block is one fragment of a non-contiguous block, do not
     process the variables, since they will have been done by the
     origin block.  Do process subblocks.  */
  if (BLOCK_FRAGMENT_ORIGIN (stmt))
    {
      tree sub;

      for (sub = BLOCK_SUBBLOCKS (stmt); sub; sub = BLOCK_CHAIN (sub))
	gen_block_die (sub, context_die);

      return;
    }

  /* Determine if we need to output any Dwarf DIEs at all to represent this
     block.  */
  if (inlined_func)
    /* The outer scopes for inlinings *must* always be represented.  We
       generate DW_TAG_inlined_subroutine DIEs for them.  (See below.) */
    must_output_die = 1;
  else if (lookup_block_die (stmt))
    /* If we already have a DIE then it was filled early.  Meanwhile
       we might have pruned all BLOCK_VARS as optimized out but we
       still want to generate high/low PC attributes so output it.  */
    must_output_die = 1;
  else if (TREE_USED (stmt)
	   || TREE_ASM_WRITTEN (stmt))
    {
      /* Determine if this block directly contains any "significant"
	 local declarations which we will need to output DIEs for.  */
      if (debug_info_level > DINFO_LEVEL_TERSE)
	{
	  /* We are not in terse mode so any local declaration that
	     is not ignored for debug purposes counts as being a
	     "significant" one.  */
	  if (BLOCK_NUM_NONLOCALIZED_VARS (stmt))
	    must_output_die = 1;
	  else
	    for (tree var = BLOCK_VARS (stmt); var; var = DECL_CHAIN (var))
	      if (!DECL_IGNORED_P (var))
		{
		  must_output_die = 1;
		  break;
		}
	}
      else if (!dwarf2out_ignore_block (stmt))
	must_output_die = 1;
    }

  /* It would be a waste of space to generate a Dwarf DW_TAG_lexical_block
     DIE for any block which contains no significant local declarations at
     all.  Rather, in such cases we just call `decls_for_scope' so that any
     needed Dwarf info for any sub-blocks will get properly generated. Note
     that in terse mode, our definition of what constitutes a "significant"
     local declaration gets restricted to include only inlined function
     instances and local (nested) function definitions.  */
  if (must_output_die)
    {
      if (inlined_func)
	gen_inlined_subroutine_die (stmt, context_die);
      else
	gen_lexical_block_die (stmt, context_die);
    }
  else
    decls_for_scope (stmt, context_die);
}

/* Process variable DECL (or variable with origin ORIGIN) within
   block STMT and add it to CONTEXT_DIE.  */
static void
process_scope_var (tree stmt, tree decl, tree origin, dw_die_ref context_die)
{
  dw_die_ref die;
  tree decl_or_origin = decl ? decl : origin;

  if (TREE_CODE (decl_or_origin) == FUNCTION_DECL)
    die = lookup_decl_die (decl_or_origin);
  else if (TREE_CODE (decl_or_origin) == TYPE_DECL)
    {
      if (TYPE_DECL_IS_STUB (decl_or_origin))
	die = lookup_type_die (TREE_TYPE (decl_or_origin));
      else
	die = lookup_decl_die (decl_or_origin);
      /* Avoid re-creating the DIE late if it was optimized as unused early.  */
      if (! die && ! early_dwarf)
	return;
    }
  else
    die = NULL;

  /* Avoid creating DIEs for local typedefs and concrete static variables that
     will only be pruned later.  */
  if ((origin || decl_ultimate_origin (decl))
      && (TREE_CODE (decl_or_origin) == TYPE_DECL
	  || (VAR_P (decl_or_origin) && TREE_STATIC (decl_or_origin))))
    {
      origin = decl_ultimate_origin (decl_or_origin);
      if (decl && VAR_P (decl) && die != NULL)
	{
	  die = lookup_decl_die (origin);
	  if (die != NULL)
	    equate_decl_number_to_die (decl, die);
	}
      return;
    }

  if (die != NULL && die->die_parent == NULL)
    add_child_die (context_die, die);
  else if (TREE_CODE (decl_or_origin) == IMPORTED_DECL)
    {
      if (early_dwarf)
	dwarf2out_imported_module_or_decl_1 (decl_or_origin, DECL_NAME (decl_or_origin),
					     stmt, context_die);
    }
  else
    {
      if (decl && DECL_P (decl))
	{
	  die = lookup_decl_die (decl);

	  /* Early created DIEs do not have a parent as the decls refer
	     to the function as DECL_CONTEXT rather than the BLOCK.  */
	  if (die && die->die_parent == NULL)
	    {
	      gcc_assert (in_lto_p);
	      add_child_die (context_die, die);
	    }
	}

      gen_decl_die (decl, origin, NULL, context_die);
    }
}

/* Generate all of the decls declared within a given scope and (recursively)
   all of its sub-blocks.  */

static void
decls_for_scope (tree stmt, dw_die_ref context_die, bool recurse)
{
  tree decl;
  unsigned int i;
  tree subblocks;

  /* Ignore NULL blocks.  */
  if (stmt == NULL_TREE)
    return;

  /* Output the DIEs to represent all of the data objects and typedefs
     declared directly within this block but not within any nested
     sub-blocks.  Also, nested function and tag DIEs have been
     generated with a parent of NULL; fix that up now.  We don't
     have to do this if we're at -g1.  */
  if (debug_info_level > DINFO_LEVEL_TERSE)
    {
      for (decl = BLOCK_VARS (stmt); decl != NULL; decl = DECL_CHAIN (decl))
	process_scope_var (stmt, decl, NULL_TREE, context_die);
      /* BLOCK_NONLOCALIZED_VARs simply generate DIE stubs with abstract
	 origin - avoid doing this twice as we have no good way to see
	 if we've done it once already.  */
      if (! early_dwarf)
	for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++)
	  {
	    decl = BLOCK_NONLOCALIZED_VAR (stmt, i);
	    if (decl == current_function_decl)
	      /* Ignore declarations of the current function, while they
		 are declarations, gen_subprogram_die would treat them
		 as definitions again, because they are equal to
		 current_function_decl and endlessly recurse.  */;
	    else if (TREE_CODE (decl) == FUNCTION_DECL)
	      process_scope_var (stmt, decl, NULL_TREE, context_die);
	    else
	      process_scope_var (stmt, NULL_TREE, decl, context_die);
	  }
    }

  /* Even if we're at -g1, we need to process the subblocks in order to get
     inlined call information.  */

  /* Output the DIEs to represent all sub-blocks (and the items declared
     therein) of this block.  */
  if (recurse)
    for (subblocks = BLOCK_SUBBLOCKS (stmt);
	 subblocks != NULL;
	 subblocks = BLOCK_CHAIN (subblocks))
      gen_block_die (subblocks, context_die);
}

/* Is this a typedef we can avoid emitting?  */

static bool
is_redundant_typedef (const_tree decl)
{
  if (TYPE_DECL_IS_STUB (decl))
    return true;

  if (DECL_ARTIFICIAL (decl)
      && DECL_CONTEXT (decl)
      && is_tagged_type (DECL_CONTEXT (decl))
      && TREE_CODE (TYPE_NAME (DECL_CONTEXT (decl))) == TYPE_DECL
      && DECL_NAME (decl) == DECL_NAME (TYPE_NAME (DECL_CONTEXT (decl))))
    /* Also ignore the artificial member typedef for the class name.  */
    return true;

  return false;
}

/* Return TRUE if TYPE is a typedef that names a type for linkage
   purposes. This kind of typedefs is produced by the C++ FE for
   constructs like:

   typedef struct {...} foo;

   In that case, there is no typedef variant type produced for foo.
   Rather, the TREE_TYPE of the TYPE_DECL of foo is the anonymous
   struct type.  */

static bool
is_naming_typedef_decl (const_tree decl)
{
  if (decl == NULL_TREE
      || TREE_CODE (decl) != TYPE_DECL
      || DECL_NAMELESS (decl)
      || !is_tagged_type (TREE_TYPE (decl))
      || DECL_IS_UNDECLARED_BUILTIN (decl)
      || is_redundant_typedef (decl)
      /* It looks like Ada produces TYPE_DECLs that are very similar
         to C++ naming typedefs but that have different
         semantics. Let's be specific to c++ for now.  */
      || !is_cxx (decl))
    return FALSE;

  return (DECL_ORIGINAL_TYPE (decl) == NULL_TREE
	  && TYPE_NAME (TREE_TYPE (decl)) == decl
	  && (TYPE_STUB_DECL (TREE_TYPE (decl))
	      != TYPE_NAME (TREE_TYPE (decl))));
}

/* Looks up the DIE for a context.  */

static inline dw_die_ref
lookup_context_die (tree context)
{
  if (context)
    {
      /* Find die that represents this context.  */
      if (TYPE_P (context))
	{
	  context = TYPE_MAIN_VARIANT (context);
	  dw_die_ref ctx = lookup_type_die (context);
	  if (!ctx)
	    return NULL;
	  return strip_naming_typedef (context, ctx);
	}
      else
	return lookup_decl_die (context);
    }
  return comp_unit_die ();
}

/* Returns the DIE for a context.  */

static inline dw_die_ref
get_context_die (tree context)
{
  if (context)
    {
      /* Find die that represents this context.  */
      if (TYPE_P (context))
	{
	  context = TYPE_MAIN_VARIANT (context);
	  return strip_naming_typedef (context, force_type_die (context));
	}
      else
	return force_decl_die (context);
    }
  return comp_unit_die ();
}

/* Returns the DIE for decl.  A DIE will always be returned.  */

static dw_die_ref
force_decl_die (tree decl)
{
  dw_die_ref decl_die;
  unsigned saved_external_flag;
  tree save_fn = NULL_TREE;
  decl_die = lookup_decl_die (decl);
  if (!decl_die)
    {
      dw_die_ref context_die = get_context_die (DECL_CONTEXT (decl));

      decl_die = lookup_decl_die (decl);
      if (decl_die)
	return decl_die;

      switch (TREE_CODE (decl))
	{
	case FUNCTION_DECL:
	  /* Clear current_function_decl, so that gen_subprogram_die thinks
	     that this is a declaration. At this point, we just want to force
	     declaration die.  */
	  save_fn = current_function_decl;
	  current_function_decl = NULL_TREE;
	  gen_subprogram_die (decl, context_die);
	  current_function_decl = save_fn;
	  break;

	case VAR_DECL:
	  /* Set external flag to force declaration die. Restore it after
	   gen_decl_die() call.  */
	  saved_external_flag = DECL_EXTERNAL (decl);
	  DECL_EXTERNAL (decl) = 1;
	  gen_decl_die (decl, NULL, NULL, context_die);
	  DECL_EXTERNAL (decl) = saved_external_flag;
	  break;

	case NAMESPACE_DECL:
	  if (dwarf_version >= 3 || !dwarf_strict)
	    dwarf2out_decl (decl);
	  else
	    /* DWARF2 has neither DW_TAG_module, nor DW_TAG_namespace.  */
	    decl_die = comp_unit_die ();
	  break;

	case CONST_DECL:
	  /* Enumerators shouldn't need force_decl_die.  */
	  gcc_assert (DECL_CONTEXT (decl) == NULL_TREE
		      || TREE_CODE (DECL_CONTEXT (decl)) != ENUMERAL_TYPE);
	  gen_decl_die (decl, NULL, NULL, context_die);
	  break;

	case TRANSLATION_UNIT_DECL:
	  decl_die = comp_unit_die ();
	  break;

	default:
	  gcc_unreachable ();
	}

      /* We should be able to find the DIE now.  */
      if (!decl_die)
	decl_die = lookup_decl_die (decl);
      gcc_assert (decl_die);
    }

  return decl_die;
}

/* Returns the DIE for TYPE, that must not be a base type.  A DIE is
   always returned.  */

static dw_die_ref
force_type_die (tree type)
{
  dw_die_ref type_die;

  type_die = lookup_type_die (type);
  if (!type_die)
    {
      dw_die_ref context_die = get_context_die (TYPE_CONTEXT (type));

      type_die = modified_type_die (type, TYPE_QUALS_NO_ADDR_SPACE (type),
				    false, context_die);
      gcc_assert (type_die);
    }
  return type_die;
}

/* Force out any required namespaces to be able to output DECL,
   and return the new context_die for it, if it's changed.  */

static dw_die_ref
setup_namespace_context (tree thing, dw_die_ref context_die)
{
  tree context = (DECL_P (thing)
		  ? DECL_CONTEXT (thing) : TYPE_CONTEXT (thing));
  if (context && TREE_CODE (context) == NAMESPACE_DECL)
    /* Force out the namespace.  */
    context_die = force_decl_die (context);

  return context_die;
}

/* Emit a declaration DIE for THING (which is either a DECL or a tagged
   type) within its namespace, if appropriate.

   For compatibility with older debuggers, namespace DIEs only contain
   declarations; all definitions are emitted at CU scope, with
   DW_AT_specification pointing to the declaration (like with class
   members).  */

static dw_die_ref
declare_in_namespace (tree thing, dw_die_ref context_die)
{
  dw_die_ref ns_context;

  if (debug_info_level <= DINFO_LEVEL_TERSE)
    return context_die;

  /* External declarations in the local scope only need to be emitted
     once, not once in the namespace and once in the scope.

     This avoids declaring the `extern' below in the
     namespace DIE as well as in the innermost scope:

          namespace S
	  {
            int i=5;
            int foo()
	    {
              int i=8;
              extern int i;
     	      return i;
	    }
          }
  */
  if (DECL_P (thing) && DECL_EXTERNAL (thing) && local_scope_p (context_die))
    return context_die;

  /* If this decl is from an inlined function, then don't try to emit it in its
     namespace, as we will get confused.  It would have already been emitted
     when the abstract instance of the inline function was emitted anyways.  */
  if (DECL_P (thing) && DECL_ABSTRACT_ORIGIN (thing))
    return context_die;

  ns_context = setup_namespace_context (thing, context_die);

  if (ns_context != context_die)
    {
      if (is_fortran () || is_dlang ())
	return ns_context;
      if (DECL_P (thing))
	gen_decl_die (thing, NULL, NULL, ns_context);
      else
	gen_type_die (thing, ns_context);
    }
  return context_die;
}

/* Generate a DIE for a namespace or namespace alias.  */

static void
gen_namespace_die (tree decl, dw_die_ref context_die)
{
  dw_die_ref namespace_die;

  /* Namespace aliases have a DECL_ABSTRACT_ORIGIN of the namespace
     they are an alias of.  */
  if (DECL_ABSTRACT_ORIGIN (decl) == NULL)
    {
      /* Output a real namespace or module.  */
      context_die = setup_namespace_context (decl, comp_unit_die ());
      namespace_die = new_die (is_fortran () || is_dlang ()
			       ? DW_TAG_module : DW_TAG_namespace,
			       context_die, decl);
      /* For Fortran modules defined in different CU don't add src coords.  */
      if (namespace_die->die_tag == DW_TAG_module && DECL_EXTERNAL (decl))
	{
	  const char *name = dwarf2_name (decl, 0);
	  if (name)
	    add_name_attribute (namespace_die, name);
	}
      else
	add_name_and_src_coords_attributes (namespace_die, decl);
      if (DECL_EXTERNAL (decl))
	add_AT_flag (namespace_die, DW_AT_declaration, 1);
      equate_decl_number_to_die (decl, namespace_die);
    }
  else
    {
      /* Output a namespace alias.  */

      /* Force out the namespace we are an alias of, if necessary.  */
      dw_die_ref origin_die
	= force_decl_die (DECL_ABSTRACT_ORIGIN (decl));

      if (DECL_FILE_SCOPE_P (decl)
	  || TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL)
	context_die = setup_namespace_context (decl, comp_unit_die ());
      /* Now create the namespace alias DIE.  */
      namespace_die = new_die (DW_TAG_imported_declaration, context_die, decl);
      add_name_and_src_coords_attributes (namespace_die, decl);
      add_AT_die_ref (namespace_die, DW_AT_import, origin_die);
      equate_decl_number_to_die (decl, namespace_die);
    }
  if ((dwarf_version >= 5 || !dwarf_strict)
      && lang_hooks.decls.decl_dwarf_attribute (decl,
						DW_AT_export_symbols) == 1)
    add_AT_flag (namespace_die, DW_AT_export_symbols, 1);

  /* Bypass dwarf2_name's check for DECL_NAMELESS.  */
  if (want_pubnames ())
    add_pubname_string (lang_hooks.dwarf_name (decl, 1), namespace_die);
}

/* Generate Dwarf debug information for a decl described by DECL.
   The return value is currently only meaningful for PARM_DECLs,
   for all other decls it returns NULL.

   If DECL is a FIELD_DECL, CTX is required: see the comment for VLR_CONTEXT.
   It can be NULL otherwise.  */

static dw_die_ref
gen_decl_die (tree decl, tree origin, struct vlr_context *ctx,
	      dw_die_ref context_die)
{
  tree decl_or_origin = decl ? decl : origin;
  tree class_origin = NULL, ultimate_origin;

  if (DECL_P (decl_or_origin) && DECL_IGNORED_P (decl_or_origin))
    return NULL;

  switch (TREE_CODE (decl_or_origin))
    {
    case ERROR_MARK:
      break;

    case CONST_DECL:
      if (!is_fortran () && !is_ada () && !is_dlang ())
	{
	  /* The individual enumerators of an enum type get output when we output
	     the Dwarf representation of the relevant enum type itself.  */
	  break;
	}

      /* Emit its type.  */
      gen_type_die (TREE_TYPE (decl), context_die);

      /* And its containing namespace.  */
      context_die = declare_in_namespace (decl, context_die);

      gen_const_die (decl, context_die);
      break;

    case FUNCTION_DECL:
#if 0
      /* FIXME */
      /* This doesn't work because the C frontend sets DECL_ABSTRACT_ORIGIN
	 on local redeclarations of global functions.  That seems broken.  */
      if (current_function_decl != decl)
	/* This is only a declaration.  */;
#endif

      /* We should have abstract copies already and should not generate
	 stray type DIEs in late LTO dumping.  */
      if (! early_dwarf)
	;

      /* If we're emitting a clone, emit info for the abstract instance.  */
      else if (origin || DECL_ORIGIN (decl) != decl)
	dwarf2out_abstract_function (origin
				     ? DECL_ORIGIN (origin)
				     : DECL_ABSTRACT_ORIGIN (decl));

      /* If we're emitting a possibly inlined function emit it as
         abstract instance.  */
      else if (cgraph_function_possibly_inlined_p (decl)
	       && ! DECL_ABSTRACT_P (decl)
	       && ! class_or_namespace_scope_p (context_die)
	       /* dwarf2out_abstract_function won't emit a die if this is just
		  a declaration.  We must avoid setting DECL_ABSTRACT_ORIGIN in
		  that case, because that works only if we have a die.  */
	       && DECL_INITIAL (decl) != NULL_TREE)
	dwarf2out_abstract_function (decl);

      /* Otherwise we're emitting the primary DIE for this decl.  */
      else if (debug_info_level > DINFO_LEVEL_TERSE)
	{
	  /* Before we describe the FUNCTION_DECL itself, make sure that we
	     have its containing type.  */
	  if (!origin)
	    origin = decl_class_context (decl);
	  if (origin != NULL_TREE)
	    gen_type_die (origin, context_die);

	  /* And its return type.  */
	  gen_type_die (TREE_TYPE (TREE_TYPE (decl)), context_die);

	  /* And its virtual context.  */
	  if (DECL_VINDEX (decl) != NULL_TREE)
	    gen_type_die (DECL_CONTEXT (decl), context_die);

	  /* Make sure we have a member DIE for decl.  */
	  if (origin != NULL_TREE)
	    gen_type_die_for_member (origin, decl, context_die);

	  /* And its containing namespace.  */
	  context_die = declare_in_namespace (decl, context_die);
	}

      /* Now output a DIE to represent the function itself.  */
      if (decl)
        gen_subprogram_die (decl, context_die);
      break;

    case TYPE_DECL:
      /* If we are in terse mode, don't generate any DIEs to represent any
	 actual typedefs.  */
      if (debug_info_level <= DINFO_LEVEL_TERSE)
	break;

      /* In the special case of a TYPE_DECL node representing the declaration
	 of some type tag, if the given TYPE_DECL is marked as having been
	 instantiated from some other (original) TYPE_DECL node (e.g. one which
	 was generated within the original definition of an inline function) we
	 used to generate a special (abbreviated) DW_TAG_structure_type,
	 DW_TAG_union_type, or DW_TAG_enumeration_type DIE here.  But nothing
	 should be actually referencing those DIEs, as variable DIEs with that
	 type would be emitted already in the abstract origin, so it was always
	 removed during unused type prunning.  Don't add anything in this
	 case.  */
      if (TYPE_DECL_IS_STUB (decl) && decl_ultimate_origin (decl) != NULL_TREE)
	break;

      if (is_redundant_typedef (decl))
	gen_type_die (TREE_TYPE (decl), context_die);
      else
	/* Output a DIE to represent the typedef itself.  */
	gen_typedef_die (decl, context_die);
      break;

    case LABEL_DECL:
      if (debug_info_level >= DINFO_LEVEL_NORMAL)
	gen_label_die (decl, context_die);
      break;

    case VAR_DECL:
    case RESULT_DECL:
      /* If we are in terse mode, don't generate any DIEs to represent any
	 variable declarations or definitions unless it is external.  */
      if (debug_info_level < DINFO_LEVEL_TERSE
	  || (debug_info_level == DINFO_LEVEL_TERSE
	      && !TREE_PUBLIC (decl_or_origin)))
	break;

      if (debug_info_level > DINFO_LEVEL_TERSE)
	{
	  /* Avoid generating stray type DIEs during late dwarf dumping.
	     All types have been dumped early.  */
	  if (early_dwarf
	      /* ???  But in LTRANS we cannot annotate early created variably
		 modified type DIEs without copying them and adjusting all
		 references to them.  Dump them again as happens for inlining
		 which copies both the decl and the types.  */
	      /* ???  And even non-LTO needs to re-visit type DIEs to fill
		 in VLA bound information for example.  */
	      || (decl && variably_modified_type_p (TREE_TYPE (decl),
						    current_function_decl)))
	    {
	      /* Output any DIEs that are needed to specify the type of this data
		 object.  */
	      if (decl_by_reference_p (decl_or_origin))
		gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
	      else
		gen_type_die (TREE_TYPE (decl_or_origin), context_die);
	    }

	  if (early_dwarf)
	    {
	      /* And its containing type.  */
	      class_origin = decl_class_context (decl_or_origin);
	      if (class_origin != NULL_TREE)
		gen_type_die_for_member (class_origin, decl_or_origin, context_die);

	      /* And its containing namespace.  */
	      context_die = declare_in_namespace (decl_or_origin, context_die);
	    }
	}

      /* Now output the DIE to represent the data object itself.  This gets
	 complicated because of the possibility that the VAR_DECL really
	 represents an inlined instance of a formal parameter for an inline
	 function.  */
      ultimate_origin = decl_ultimate_origin (decl_or_origin);
      if (ultimate_origin != NULL_TREE
	  && TREE_CODE (ultimate_origin) == PARM_DECL)
	gen_formal_parameter_die (decl, origin,
				  true /* Emit name attribute.  */,
				  context_die);
      else
	gen_variable_die (decl, origin, context_die);
      break;

    case FIELD_DECL:
      gcc_assert (ctx != NULL && ctx->struct_type != NULL);
      /* Ignore the nameless fields that are used to skip bits but handle C++
	 anonymous unions and structs.  */
      if (DECL_NAME (decl) != NULL_TREE
	  || TREE_CODE (TREE_TYPE (decl)) == UNION_TYPE
	  || TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
	{
	  gen_type_die (member_declared_type (decl), context_die);
	  gen_field_die (decl, ctx, context_die);
	}
      break;

    case PARM_DECL:
      /* Avoid generating stray type DIEs during late dwarf dumping.
         All types have been dumped early.  */
      if (early_dwarf
	  /* ???  But in LTRANS we cannot annotate early created variably
	     modified type DIEs without copying them and adjusting all
	     references to them.  Dump them again as happens for inlining
	     which copies both the decl and the types.  */
	  /* ???  And even non-LTO needs to re-visit type DIEs to fill
	     in VLA bound information for example.  */
	  || (decl && variably_modified_type_p (TREE_TYPE (decl),
						current_function_decl)))
	{
	  if (DECL_BY_REFERENCE (decl_or_origin))
	    gen_type_die (TREE_TYPE (TREE_TYPE (decl_or_origin)), context_die);
	  else
	    gen_type_die (TREE_TYPE (decl_or_origin), context_die);
	}
      return gen_formal_parameter_die (decl, origin,
				       true /* Emit name attribute.  */,
				       context_die);

    case NAMESPACE_DECL:
      if (dwarf_version >= 3 || !dwarf_strict)
	gen_namespace_die (decl, context_die);
      break;

    case IMPORTED_DECL:
      dwarf2out_imported_module_or_decl_1 (decl, DECL_NAME (decl),
					   DECL_CONTEXT (decl), context_die);
      break;

    case NAMELIST_DECL:
      gen_namelist_decl (DECL_NAME (decl), context_die,
			 NAMELIST_DECL_ASSOCIATED_DECL (decl));
      break;

    default:
      /* Probably some frontend-internal decl.  Assume we don't care.  */
      gcc_assert ((int)TREE_CODE (decl) > NUM_TREE_CODES);
      break;
    }

  return NULL;
}

/* Output initial debug information for global DECL.  Called at the
   end of the parsing process.

   This is the initial debug generation process.  As such, the DIEs
   generated may be incomplete.  A later debug generation pass
   (dwarf2out_late_global_decl) will augment the information generated
   in this pass (e.g., with complete location info).  */

static void
dwarf2out_early_global_decl (tree decl)
{
  set_early_dwarf s;

  /* gen_decl_die() will set DECL_ABSTRACT because
     cgraph_function_possibly_inlined_p() returns true.  This is in
     turn will cause DW_AT_inline attributes to be set.

     This happens because at early dwarf generation, there is no
     cgraph information, causing cgraph_function_possibly_inlined_p()
     to return true.  Trick cgraph_function_possibly_inlined_p()
     while we generate dwarf early.  */
  bool save = symtab->global_info_ready;
  symtab->global_info_ready = true;

  /* We don't handle TYPE_DECLs.  If required, they'll be reached via
     other DECLs and they can point to template types or other things
     that dwarf2out can't handle when done via dwarf2out_decl.  */
  if (TREE_CODE (decl) != TYPE_DECL
      && TREE_CODE (decl) != PARM_DECL)
    {
      if (TREE_CODE (decl) == FUNCTION_DECL)
	{
	  tree save_fndecl = current_function_decl;

	  /* For nested functions, make sure we have DIEs for the parents first
	     so that all nested DIEs are generated at the proper scope in the
	     first shot.  */
	  tree context = decl_function_context (decl);
	  if (context != NULL)
	    {
	      dw_die_ref context_die = lookup_decl_die (context);
	      current_function_decl = context;

	      /* Avoid emitting DIEs multiple times, but still process CONTEXT
		 enough so that it lands in its own context.  This avoids type
		 pruning issues later on.  */
	      if (context_die == NULL || is_declaration_die (context_die))
		dwarf2out_early_global_decl (context);
	    }

	  /* Emit an abstract origin of a function first.  This happens
	     with C++ constructor clones for example and makes
	     dwarf2out_abstract_function happy which requires the early
	     DIE of the abstract instance to be present.  */
	  tree origin = DECL_ABSTRACT_ORIGIN (decl);
	  dw_die_ref origin_die;
	  if (origin != NULL
	      /* Do not emit the DIE multiple times but make sure to
	         process it fully here in case we just saw a declaration.  */
	      && ((origin_die = lookup_decl_die (origin)) == NULL
		  || is_declaration_die (origin_die)))
	    {
	      current_function_decl = origin;
	      dwarf2out_decl (origin);
	    }

	  /* Emit the DIE for decl but avoid doing that multiple times.  */
	  dw_die_ref old_die;
	  if ((old_die = lookup_decl_die (decl)) == NULL
	      || is_declaration_die (old_die))
	    {
	      current_function_decl = decl;
	      dwarf2out_decl (decl);
	    }

	  current_function_decl = save_fndecl;
	}
      else
	dwarf2out_decl (decl);
    }
  symtab->global_info_ready = save;
}

/* Return whether EXPR is an expression with the following pattern:
   INDIRECT_REF (NOP_EXPR (INTEGER_CST)).  */

static bool
is_trivial_indirect_ref (tree expr)
{
  if (expr == NULL_TREE || TREE_CODE (expr) != INDIRECT_REF)
    return false;

  tree nop = TREE_OPERAND (expr, 0);
  if (nop == NULL_TREE || TREE_CODE (nop) != NOP_EXPR)
    return false;

  tree int_cst = TREE_OPERAND (nop, 0);
  return int_cst != NULL_TREE && TREE_CODE (int_cst) == INTEGER_CST;
}

/* Output debug information for global decl DECL.  Called from
   toplev.c after compilation proper has finished.  */

static void
dwarf2out_late_global_decl (tree decl)
{
  /* Fill-in any location information we were unable to determine
     on the first pass.  */
  if (VAR_P (decl))
    {
      dw_die_ref die = lookup_decl_die (decl);

      /* We may have to generate full debug late for LTO in case debug
         was not enabled at compile-time or the target doesn't support
	 the LTO early debug scheme.  */
      if (! die && in_lto_p)
	dwarf2out_decl (decl);
      else if (die)
	{
	  /* We get called via the symtab code invoking late_global_decl
	     for symbols that are optimized out.

	     Do not add locations for those, except if they have a
	     DECL_VALUE_EXPR, in which case they are relevant for debuggers.
	     Still don't add a location if the DECL_VALUE_EXPR is not a trivial
	     INDIRECT_REF expression, as this could generate relocations to
	     text symbols in LTO object files, which is invalid.  */
	  varpool_node *node = varpool_node::get (decl);
	  if ((! node || ! node->definition)
	      && ! (DECL_HAS_VALUE_EXPR_P (decl)
		    && is_trivial_indirect_ref (DECL_VALUE_EXPR (decl))))
	    tree_add_const_value_attribute_for_decl (die, decl);
	  else
	    add_location_or_const_value_attribute (die, decl, false);
	}
    }
}

/* Output debug information for type decl DECL.  Called from toplev.c
   and from language front ends (to record built-in types).  */
static void
dwarf2out_type_decl (tree decl, int local)
{
  if (!local)
    {
      set_early_dwarf s;
      dwarf2out_decl (decl);
    }
}

/* Output debug information for imported module or decl DECL.
   NAME is non-NULL name in the lexical block if the decl has been renamed.
   LEXICAL_BLOCK is the lexical block (which TREE_CODE is a BLOCK)
   that DECL belongs to.
   LEXICAL_BLOCK_DIE is the DIE of LEXICAL_BLOCK.  */
static void
dwarf2out_imported_module_or_decl_1 (tree decl,
				     tree name,
				     tree lexical_block,
				     dw_die_ref lexical_block_die)
{
  expanded_location xloc;
  dw_die_ref imported_die = NULL;
  dw_die_ref at_import_die;

  if (TREE_CODE (decl) == IMPORTED_DECL)
    {
      xloc = expand_location (DECL_SOURCE_LOCATION (decl));
      decl = IMPORTED_DECL_ASSOCIATED_DECL (decl);
      gcc_assert (decl);
    }
  else
    xloc = expand_location (input_location);

  if (TREE_CODE (decl) == TYPE_DECL)
    {
      at_import_die = force_type_die (TREE_TYPE (decl));
      /* For namespace N { typedef void T; } using N::T; base_type_die
	 returns NULL, but DW_TAG_imported_declaration requires
	 the DW_AT_import tag.  Force creation of DW_TAG_typedef.  */
      if (!at_import_die)
	{
	  gcc_assert (TREE_CODE (decl) == TYPE_DECL);
	  gen_typedef_die (decl, get_context_die (DECL_CONTEXT (decl)));
	  at_import_die = lookup_type_die (TREE_TYPE (decl));
	  gcc_assert (at_import_die);
	}
    }
  else
    {
      at_import_die = lookup_decl_die (decl);
      if (!at_import_die)
	{
	  /* If we're trying to avoid duplicate debug info, we may not have
	     emitted the member decl for this field.  Emit it now.  */
	  if (TREE_CODE (decl) == FIELD_DECL)
	    {
	      tree type = DECL_CONTEXT (decl);

	      if (TYPE_CONTEXT (type)
		  && TYPE_P (TYPE_CONTEXT (type))
		  && !should_emit_struct_debug (TYPE_CONTEXT (type),
						DINFO_USAGE_DIR_USE))
		return;
	      gen_type_die_for_member (type, decl,
				       get_context_die (TYPE_CONTEXT (type)));
	    }
	  if (TREE_CODE (decl) == CONST_DECL)
	    {
	      /* Individual enumerators of an enum type do not get output here
		 (see gen_decl_die), so we cannot call force_decl_die.  */
	      if (!is_fortran () && !is_ada () && !is_dlang ())
		return;
	    }
	  if (TREE_CODE (decl) == NAMELIST_DECL)
	    at_import_die = gen_namelist_decl (DECL_NAME (decl),
					 get_context_die (DECL_CONTEXT (decl)),
					 NULL_TREE);
	  else
	    at_import_die = force_decl_die (decl);
	}
    }

  if (TREE_CODE (decl) == NAMESPACE_DECL)
    {
      if (dwarf_version >= 3 || !dwarf_strict)
	imported_die = new_die (DW_TAG_imported_module,
				lexical_block_die,
				lexical_block);
      else
	return;
    }
  else
    imported_die = new_die (DW_TAG_imported_declaration,
			    lexical_block_die,
			    lexical_block);

  add_AT_file (imported_die, DW_AT_decl_file, lookup_filename (xloc.file));
  add_AT_unsigned (imported_die, DW_AT_decl_line, xloc.line);
  if (debug_column_info && xloc.column)
    add_AT_unsigned (imported_die, DW_AT_decl_column, xloc.column);
  if (name)
    add_AT_string (imported_die, DW_AT_name,
		   IDENTIFIER_POINTER (name));
  add_AT_die_ref (imported_die, DW_AT_import, at_import_die);
}

/* Output debug information for imported module or decl DECL.
   NAME is non-NULL name in context if the decl has been renamed.
   CHILD is true if decl is one of the renamed decls as part of
   importing whole module.
   IMPLICIT is set if this hook is called for an implicit import
   such as inline namespace.  */

static void
dwarf2out_imported_module_or_decl (tree decl, tree name, tree context,
				   bool child, bool implicit)
{
  /* dw_die_ref at_import_die;  */
  dw_die_ref scope_die;

  if (debug_info_level <= DINFO_LEVEL_TERSE)
    return;

  gcc_assert (decl);

  /* For DWARF5, just DW_AT_export_symbols on the DW_TAG_namespace
     should be enough, for DWARF4 and older even if we emit as extension
     DW_AT_export_symbols add the implicit DW_TAG_imported_module anyway
     for the benefit of consumers unaware of DW_AT_export_symbols.  */
  if (implicit
      && dwarf_version >= 5
      && lang_hooks.decls.decl_dwarf_attribute (decl,
						DW_AT_export_symbols) == 1)
    return;

  set_early_dwarf s;

  /* To emit DW_TAG_imported_module or DW_TAG_imported_decl, we need two DIEs.
     We need decl DIE for reference and scope die. First, get DIE for the decl
     itself.  */

  /* Get the scope die for decl context. Use comp_unit_die for global module
     or decl. If die is not found for non globals, force new die.  */
  if (context
      && TYPE_P (context)
      && !should_emit_struct_debug (context, DINFO_USAGE_DIR_USE))
    return;

  scope_die = get_context_die (context);

  if (child)
    {
      /* DW_TAG_imported_module was introduced in the DWARFv3 specification, so
	 there is nothing we can do, here.  */
      if (dwarf_version < 3 && dwarf_strict)
	return;

      gcc_assert (scope_die->die_child);
      gcc_assert (scope_die->die_child->die_tag == DW_TAG_imported_module);
      gcc_assert (TREE_CODE (decl) != NAMESPACE_DECL);
      scope_die = scope_die->die_child;
    }

  /* OK, now we have DIEs for decl as well as scope. Emit imported die.  */
  dwarf2out_imported_module_or_decl_1 (decl, name, context, scope_die);
}

/* Output debug information for namelists.   */

static dw_die_ref
gen_namelist_decl (tree name, dw_die_ref scope_die, tree item_decls)
{
  dw_die_ref nml_die, nml_item_die, nml_item_ref_die;
  tree value;
  unsigned i;

  if (debug_info_level <= DINFO_LEVEL_TERSE)
    return NULL;

  gcc_assert (scope_die != NULL);
  nml_die = new_die (DW_TAG_namelist, scope_die, NULL);
  add_AT_string (nml_die, DW_AT_name, IDENTIFIER_POINTER (name));

  /* If there are no item_decls, we have a nondefining namelist, e.g.
     with USE association; hence, set DW_AT_declaration.  */
  if (item_decls == NULL_TREE)
    {
      add_AT_flag (nml_die, DW_AT_declaration, 1);
      return nml_die;
    }

  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (item_decls), i, value)
    {
      nml_item_ref_die = lookup_decl_die (value);
      if (!nml_item_ref_die)
	nml_item_ref_die = force_decl_die (value);

      nml_item_die = new_die (DW_TAG_namelist_item, nml_die, NULL);
      add_AT_die_ref (nml_item_die, DW_AT_namelist_items, nml_item_ref_die);
    }
  return nml_die;
}


/* Write the debugging output for DECL and return the DIE.  */

static void
dwarf2out_decl (tree decl)
{
  dw_die_ref context_die = comp_unit_die ();

  switch (TREE_CODE (decl))
    {
    case ERROR_MARK:
      return;

    case FUNCTION_DECL:
      /* If we're a nested function, initially use a parent of NULL; if we're
	 a plain function, this will be fixed up in decls_for_scope.  If
	 we're a method, it will be ignored, since we already have a DIE.
	 Avoid doing this late though since clones of class methods may
	 otherwise end up in limbo and create type DIEs late.  */
      if (early_dwarf
	  && decl_function_context (decl)
	  /* But if we're in terse mode, we don't care about scope.  */
	  && debug_info_level > DINFO_LEVEL_TERSE)
	context_die = NULL;
      break;

    case VAR_DECL:
      /* For local statics lookup proper context die.  */
      if (local_function_static (decl))
	context_die = lookup_decl_die (DECL_CONTEXT (decl));

      /* If we are in terse mode, don't generate any DIEs to represent any
	 variable declarations or definitions unless it is external.  */
      if (debug_info_level < DINFO_LEVEL_TERSE
	  || (debug_info_level == DINFO_LEVEL_TERSE
	      && !TREE_PUBLIC (decl)))
	return;
      break;

    case CONST_DECL:
      if (debug_info_level <= DINFO_LEVEL_TERSE)
	return;
      if (!is_fortran () && !is_ada () && !is_dlang ())
	return;
      if (TREE_STATIC (decl) && decl_function_context (decl))
	context_die = lookup_decl_die (DECL_CONTEXT (decl));
      break;

    case NAMESPACE_DECL:
    case IMPORTED_DECL:
      if (debug_info_level <= DINFO_LEVEL_TERSE)
	return;
      if (lookup_decl_die (decl) != NULL)
	return;
      break;

    case TYPE_DECL:
      /* Don't emit stubs for types unless they are needed by other DIEs.  */
      if (TYPE_DECL_SUPPRESS_DEBUG (decl))
	return;

      /* Don't bother trying to generate any DIEs to represent any of the
	 normal built-in types for the language we are compiling.  */
      if (DECL_IS_UNDECLARED_BUILTIN (decl))
	return;

      /* If we are in terse mode, don't generate any DIEs for types.  */
      if (debug_info_level <= DINFO_LEVEL_TERSE)
	return;

      /* If we're a function-scope tag, initially use a parent of NULL;
	 this will be fixed up in decls_for_scope.  */
      if (decl_function_context (decl))
	context_die = NULL;

      break;

    case NAMELIST_DECL:
      break;

    default:
      return;
    }

  gen_decl_die (decl, NULL, NULL, context_die);

  if (flag_checking)
    {
      dw_die_ref die = lookup_decl_die (decl);
      if (die)
	check_die (die);
    }
}

/* Write the debugging output for DECL.  */

static void
dwarf2out_function_decl (tree decl)
{
  dwarf2out_decl (decl);
  call_arg_locations = NULL;
  call_arg_loc_last = NULL;
  call_site_count = -1;
  tail_call_site_count = -1;
  decl_loc_table->empty ();
  cached_dw_loc_list_table->empty ();
}

/* Output a marker (i.e. a label) for the beginning of the generated code for
   a lexical block.  */

static void
dwarf2out_begin_block (unsigned int line ATTRIBUTE_UNUSED,
		       unsigned int blocknum)
{
  switch_to_section (current_function_section ());
  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_BEGIN_LABEL, blocknum);
}

/* Output a marker (i.e. a label) for the end of the generated code for a
   lexical block.  */

static void
dwarf2out_end_block (unsigned int line ATTRIBUTE_UNUSED, unsigned int blocknum)
{
  switch_to_section (current_function_section ());
  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_END_LABEL, blocknum);
}

/* Returns nonzero if it is appropriate not to emit any debugging
   information for BLOCK, because it doesn't contain any instructions.

   Don't allow this for blocks with nested functions or local classes
   as we would end up with orphans, and in the presence of scheduling
   we may end up calling them anyway.  */

static bool
dwarf2out_ignore_block (const_tree block)
{
  tree decl;
  unsigned int i;

  for (decl = BLOCK_VARS (block); decl; decl = DECL_CHAIN (decl))
    if (TREE_CODE (decl) == FUNCTION_DECL
	|| (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
      return 0;
  for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (block); i++)
    {
      decl = BLOCK_NONLOCALIZED_VAR (block, i);
      if (TREE_CODE (decl) == FUNCTION_DECL
	  || (TREE_CODE (decl) == TYPE_DECL && TYPE_DECL_IS_STUB (decl)))
      return 0;
    }

  return 1;
}

/* Hash table routines for file_hash.  */

bool
dwarf_file_hasher::equal (dwarf_file_data *p1, const char *p2)
{
  return filename_cmp (p1->key, p2) == 0;
}

hashval_t
dwarf_file_hasher::hash (dwarf_file_data *p)
{
  return htab_hash_string (p->key);
}

/* Lookup FILE_NAME (in the list of filenames that we know about here in
   dwarf2out.c) and return its "index".  The index of each (known) filename is
   just a unique number which is associated with only that one filename.  We
   need such numbers for the sake of generating labels (in the .debug_sfnames
   section) and references to those files numbers (in the .debug_srcinfo
   and .debug_macinfo sections).  If the filename given as an argument is not
   found in our current list, add it to the list and assign it the next
   available unique index number.  */

static struct dwarf_file_data *
lookup_filename (const char *file_name)
{
  struct dwarf_file_data * created;

  if (!file_name)
    return NULL;

  if (!file_name[0])
    file_name = "<stdin>";

  dwarf_file_data **slot
    = file_table->find_slot_with_hash (file_name, htab_hash_string (file_name),
				       INSERT);
  if (*slot)
    return *slot;

  created = ggc_alloc<dwarf_file_data> ();
  created->key = file_name;
  created->filename = remap_debug_filename (file_name);
  created->emitted_number = 0;
  *slot = created;
  return created;
}

/* If the assembler will construct the file table, then translate the compiler
   internal file table number into the assembler file table number, and emit
   a .file directive if we haven't already emitted one yet.  The file table
   numbers are different because we prune debug info for unused variables and
   types, which may include filenames.  */

static int
maybe_emit_file (struct dwarf_file_data * fd)
{
  if (! fd->emitted_number)
    {
      if (last_emitted_file)
	fd->emitted_number = last_emitted_file->emitted_number + 1;
      else
	fd->emitted_number = 1;
      last_emitted_file = fd;

      if (output_asm_line_debug_info ())
	{
	  fprintf (asm_out_file, "\t.file %u ", fd->emitted_number);
	  output_quoted_string (asm_out_file, fd->filename);
	  fputc ('\n', asm_out_file);
	}
    }

  return fd->emitted_number;
}

/* Schedule generation of a DW_AT_const_value attribute to DIE.
   That generation should happen after function debug info has been
   generated. The value of the attribute is the constant value of ARG.  */

static void
append_entry_to_tmpl_value_parm_die_table (dw_die_ref die, tree arg)
{
  die_arg_entry entry;

  if (!die || !arg)
    return;

  gcc_assert (early_dwarf);

  if (!tmpl_value_parm_die_table)
    vec_alloc (tmpl_value_parm_die_table, 32);

  entry.die = die;
  entry.arg = arg;
  vec_safe_push (tmpl_value_parm_die_table, entry);
}

/* Return TRUE if T is an instance of generic type, FALSE
   otherwise.  */

static bool
generic_type_p (tree t)
{
  if (t == NULL_TREE || !TYPE_P (t))
    return false;
  return lang_hooks.get_innermost_generic_parms (t) != NULL_TREE;
}

/* Schedule the generation of the generic parameter dies for the
  instance of generic type T. The proper generation itself is later
  done by gen_scheduled_generic_parms_dies. */

static void
schedule_generic_params_dies_gen (tree t)
{
  if (!generic_type_p (t))
    return;

  gcc_assert (early_dwarf);

  if (!generic_type_instances)
    vec_alloc (generic_type_instances, 256);

  vec_safe_push (generic_type_instances, t);
}

/* Add a DW_AT_const_value attribute to DIEs that were scheduled
   by append_entry_to_tmpl_value_parm_die_table. This function must
   be called after function DIEs have been generated.  */

static void
gen_remaining_tmpl_value_param_die_attribute (void)
{
  if (tmpl_value_parm_die_table)
    {
      unsigned i, j;
      die_arg_entry *e;

      /* We do this in two phases - first get the cases we can
	 handle during early-finish, preserving those we cannot
	 (containing symbolic constants where we don't yet know
	 whether we are going to output the referenced symbols).
	 For those we try again at late-finish.  */
      j = 0;
      FOR_EACH_VEC_ELT (*tmpl_value_parm_die_table, i, e)
	{
	  if (!e->die->removed
	      && !tree_add_const_value_attribute (e->die, e->arg))
	    {
	      dw_loc_descr_ref loc = NULL;
	      if (! early_dwarf
		  && (dwarf_version >= 5 || !dwarf_strict))
		loc = loc_descriptor_from_tree (e->arg, 2, NULL);
	      if (loc)
		add_AT_loc (e->die, DW_AT_location, loc);
	      else
		(*tmpl_value_parm_die_table)[j++] = *e;
	    }
	}
      tmpl_value_parm_die_table->truncate (j);
    }
}

/* Generate generic parameters DIEs for instances of generic types
   that have been previously scheduled by
   schedule_generic_params_dies_gen. This function must be called
   after all the types of the CU have been laid out.  */

static void
gen_scheduled_generic_parms_dies (void)
{
  unsigned i;
  tree t;

  if (!generic_type_instances)
    return;
  
  FOR_EACH_VEC_ELT (*generic_type_instances, i, t)
    if (COMPLETE_TYPE_P (t))
      gen_generic_params_dies (t);

  generic_type_instances = NULL;
}


/* Replace DW_AT_name for the decl with name.  */

static void
dwarf2out_set_name (tree decl, tree name)
{
  dw_die_ref die;
  dw_attr_node *attr;
  const char *dname;

  die = TYPE_SYMTAB_DIE (decl);
  if (!die)
    return;

  dname = dwarf2_name (name, 0);
  if (!dname)
    return;

  attr = get_AT (die, DW_AT_name);
  if (attr)
    {
      struct indirect_string_node *node;

      node = find_AT_string (dname);
      /* replace the string.  */
      attr->dw_attr_val.v.val_str = node;
    }

  else
    add_name_attribute (die, dname);
}

/* True if before or during processing of the first function being emitted.  */
static bool in_first_function_p = true;
/* True if loc_note during dwarf2out_var_location call might still be
   before first real instruction at address equal to .Ltext0.  */
static bool maybe_at_text_label_p = true;
/* One above highest N where .LVLN label might be equal to .Ltext0 label.  */
static unsigned int first_loclabel_num_not_at_text_label;

/* Look ahead for a real insn.  */

static rtx_insn *
dwarf2out_next_real_insn (rtx_insn *loc_note)
{
  rtx_insn *next_real = NEXT_INSN (loc_note);

  while (next_real)
    if (INSN_P (next_real))
      break;
    else
      next_real = NEXT_INSN (next_real);

  return next_real;
}

/* Called by the final INSN scan whenever we see a var location.  We
   use it to drop labels in the right places, and throw the location in
   our lookup table.  */

static void
dwarf2out_var_location (rtx_insn *loc_note)
{
  char loclabel[MAX_ARTIFICIAL_LABEL_BYTES + 2];
  struct var_loc_node *newloc;
  rtx_insn *next_real;
  rtx_insn *call_insn = NULL;
  static const char *last_label;
  static const char *last_postcall_label;
  static bool last_in_cold_section_p;
  static rtx_insn *expected_next_loc_note;
  tree decl;
  bool var_loc_p;
  var_loc_view view = 0;

  if (!NOTE_P (loc_note))
    {
      if (CALL_P (loc_note))
	{
	  maybe_reset_location_view (loc_note, cur_line_info_table);
	  call_site_count++;
	  if (SIBLING_CALL_P (loc_note))
	    tail_call_site_count++;
	  if (find_reg_note (loc_note, REG_CALL_ARG_LOCATION, NULL_RTX))
	    {
	      call_insn = loc_note;
	      loc_note = NULL;
	      var_loc_p = false;

	      next_real = dwarf2out_next_real_insn (call_insn);
	      cached_next_real_insn = NULL;
	      goto create_label;
	    }
	  if (optimize == 0 && !flag_var_tracking)
	    {
	      /* When the var-tracking pass is not running, there is no note
		 for indirect calls whose target is compile-time known. In this
		 case, process such calls specifically so that we generate call
		 sites for them anyway.  */
	      rtx x = PATTERN (loc_note);
	      if (GET_CODE (x) == PARALLEL)
		x = XVECEXP (x, 0, 0);
	      if (GET_CODE (x) == SET)
		x = SET_SRC (x);
	      if (GET_CODE (x) == CALL)
		x = XEXP (x, 0);
	      if (!MEM_P (x)
		  || GET_CODE (XEXP (x, 0)) != SYMBOL_REF
		  || !SYMBOL_REF_DECL (XEXP (x, 0))
		  || (TREE_CODE (SYMBOL_REF_DECL (XEXP (x, 0)))
		      != FUNCTION_DECL))
		{
		  call_insn = loc_note;
		  loc_note = NULL;
		  var_loc_p = false;

		  next_real = dwarf2out_next_real_insn (call_insn);
		  cached_next_real_insn = NULL;
		  goto create_label;
		}
	    }
	}
      else if (!debug_variable_location_views)
	gcc_unreachable ();
      else
	maybe_reset_location_view (loc_note, cur_line_info_table);

      return;
    }

  var_loc_p = NOTE_KIND (loc_note) == NOTE_INSN_VAR_LOCATION;
  if (var_loc_p && !DECL_P (NOTE_VAR_LOCATION_DECL (loc_note)))
    return;

  /* Optimize processing a large consecutive sequence of location
     notes so we don't spend too much time in next_real_insn.  If the
     next insn is another location note, remember the next_real_insn
     calculation for next time.  */
  next_real = cached_next_real_insn;
  if (next_real)
    {
      if (expected_next_loc_note != loc_note)
	next_real = NULL;
    }

  if (! next_real)
    next_real = dwarf2out_next_real_insn (loc_note);

  if (next_real)
    {
      rtx_insn *next_note = NEXT_INSN (loc_note);
      while (next_note != next_real)
	{
	  if (! next_note->deleted ()
	      && NOTE_P (next_note)
	      && NOTE_KIND (next_note) == NOTE_INSN_VAR_LOCATION)
	    break;
	  next_note = NEXT_INSN (next_note);
	}

      if (next_note == next_real)
	cached_next_real_insn = NULL;
      else
	{
	  expected_next_loc_note = next_note;
	  cached_next_real_insn = next_real;
	}
    }
  else
    cached_next_real_insn = NULL;

  /* If there are no instructions which would be affected by this note,
     don't do anything.  */
  if (var_loc_p
      && next_real == NULL_RTX
      && !NOTE_DURING_CALL_P (loc_note))
    return;

create_label:

  if (next_real == NULL_RTX)
    next_real = get_last_insn ();

  /* If there were any real insns between note we processed last time
     and this note (or if it is the first note), clear
     last_{,postcall_}label so that they are not reused this time.  */
  if (last_var_location_insn == NULL_RTX
      || last_var_location_insn != next_real
      || last_in_cold_section_p != in_cold_section_p)
    {
      last_label = NULL;
      last_postcall_label = NULL;
    }

  if (var_loc_p)
    {
      const char *label
	= NOTE_DURING_CALL_P (loc_note) ? last_postcall_label : last_label;
      view = cur_line_info_table->view;
      decl = NOTE_VAR_LOCATION_DECL (loc_note);
      newloc = add_var_loc_to_decl (decl, loc_note, label, view);
      if (newloc == NULL)
	return;
    }
  else
    {
      decl = NULL_TREE;
      newloc = NULL;
    }

  /* If there were no real insns between note we processed last time
     and this note, use the label we emitted last time.  Otherwise
     create a new label and emit it.  */
  if (last_label == NULL)
    {
      ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", loclabel_num);
      ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LVL", loclabel_num);
      loclabel_num++;
      last_label = ggc_strdup (loclabel);
      /* See if loclabel might be equal to .Ltext0.  If yes,
	 bump first_loclabel_num_not_at_text_label.  */
      if (!have_multiple_function_sections
	  && in_first_function_p
	  && maybe_at_text_label_p)
	{
	  static rtx_insn *last_start;
	  rtx_insn *insn;
	  for (insn = loc_note; insn; insn = previous_insn (insn))
	    if (insn == last_start)
	      break;
	    else if (!NONDEBUG_INSN_P (insn))
	      continue;
	    else
	      {
		rtx body = PATTERN (insn);
		if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER)
		  continue;
		/* Inline asm could occupy zero bytes.  */
		else if (GET_CODE (body) == ASM_INPUT
			 || asm_noperands (body) >= 0)
		  continue;
#ifdef HAVE_ATTR_length /* ??? We don't include insn-attr.h.  */
		else if (HAVE_ATTR_length && get_attr_min_length (insn) == 0)
		  continue;
#endif
		else
		  {
		    /* Assume insn has non-zero length.  */
		    maybe_at_text_label_p = false;
		    break;
		  }
	      }
	  if (maybe_at_text_label_p)
	    {
	      last_start = loc_note;
	      first_loclabel_num_not_at_text_label = loclabel_num;
	    }
	}
    }

  gcc_assert ((loc_note == NULL_RTX && call_insn != NULL_RTX)
	      || (loc_note != NULL_RTX && call_insn == NULL_RTX));

  if (!var_loc_p)
    {
      struct call_arg_loc_node *ca_loc
	= ggc_cleared_alloc<call_arg_loc_node> ();
      rtx_insn *prev = call_insn;

      ca_loc->call_arg_loc_note
	= find_reg_note (call_insn, REG_CALL_ARG_LOCATION, NULL_RTX);
      ca_loc->next = NULL;
      ca_loc->label = last_label;
      gcc_assert (prev
		  && (CALL_P (prev)
		      || (NONJUMP_INSN_P (prev)
			  && GET_CODE (PATTERN (prev)) == SEQUENCE
			  && CALL_P (XVECEXP (PATTERN (prev), 0, 0)))));
      if (!CALL_P (prev))
	prev = as_a <rtx_sequence *> (PATTERN (prev))->insn (0);
      ca_loc->tail_call_p = SIBLING_CALL_P (prev);

      /* Look for a SYMBOL_REF in the "prev" instruction.  */
      rtx x = get_call_rtx_from (prev);
      if (x)
	{
	  /* Try to get the call symbol, if any.  */
	  if (MEM_P (XEXP (x, 0)))
	    x = XEXP (x, 0);
	  /* First, look for a memory access to a symbol_ref.  */
	  if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
	      && SYMBOL_REF_DECL (XEXP (x, 0))
	      && TREE_CODE (SYMBOL_REF_DECL (XEXP (x, 0))) == FUNCTION_DECL)
	    ca_loc->symbol_ref = XEXP (x, 0);
	  /* Otherwise, look at a compile-time known user-level function
	     declaration.  */
	  else if (MEM_P (x)
		   && MEM_EXPR (x)
		   && TREE_CODE (MEM_EXPR (x)) == FUNCTION_DECL)
	    ca_loc->symbol_ref = XEXP (DECL_RTL (MEM_EXPR (x)), 0);
	}

      ca_loc->block = insn_scope (prev);
      if (call_arg_locations)
	call_arg_loc_last->next = ca_loc;
      else
	call_arg_locations = ca_loc;
      call_arg_loc_last = ca_loc;
    }
  else if (loc_note != NULL_RTX && !NOTE_DURING_CALL_P (loc_note))
    {
      newloc->label = last_label;
      newloc->view = view;
    }
  else
    {
      if (!last_postcall_label)
	{
	  sprintf (loclabel, "%s-1", last_label);
	  last_postcall_label = ggc_strdup (loclabel);
	}
      newloc->label = last_postcall_label;
      /* ??? This view is at last_label, not last_label-1, but we
	 could only assume view at last_label-1 is zero if we could
	 assume calls always have length greater than one.  This is
	 probably true in general, though there might be a rare
	 exception to this rule, e.g. if a call insn is optimized out
	 by target magic.  Then, even the -1 in the label will be
	 wrong, which might invalidate the range.  Anyway, using view,
	 though technically possibly incorrect, will work as far as
	 ranges go: since L-1 is in the middle of the call insn,
	 (L-1).0 and (L-1).V shouldn't make any difference, and having
	 the loclist entry refer to the .loc entry might be useful, so
	 leave it like this.  */
      newloc->view = view;
    }

  if (var_loc_p && flag_debug_asm)
    {
      const char *name, *sep, *patstr;
      if (decl && DECL_NAME (decl))
	name = IDENTIFIER_POINTER (DECL_NAME (decl));
      else
	name = "";
      if (NOTE_VAR_LOCATION_LOC (loc_note))
	{
	  sep = " => ";
	  patstr = str_pattern_slim (NOTE_VAR_LOCATION_LOC (loc_note));
	}
      else
	{
	  sep = " ";
	  patstr = "RESET";
	}
      fprintf (asm_out_file, "\t%s DEBUG %s%s%s\n", ASM_COMMENT_START,
	       name, sep, patstr);
    }

  last_var_location_insn = next_real;
  last_in_cold_section_p = in_cold_section_p;
}

/* Check whether BLOCK, a lexical block, is nested within OUTER, or is
   OUTER itself.  If BOTHWAYS, check not only that BLOCK can reach
   OUTER through BLOCK_SUPERCONTEXT links, but also that there is a
   path from OUTER to BLOCK through BLOCK_SUBBLOCKs and
   BLOCK_FRAGMENT_ORIGIN links.  */
static bool
block_within_block_p (tree block, tree outer, bool bothways)
{
  if (block == outer)
    return true;

  /* Quickly check that OUTER is up BLOCK's supercontext chain.  */
  for (tree context = BLOCK_SUPERCONTEXT (block);
       context != outer;
       context = BLOCK_SUPERCONTEXT (context))
    if (!context || TREE_CODE (context) != BLOCK)
      return false;

  if (!bothways)
    return true;

  /* Now check that each block is actually referenced by its
     parent.  */
  for (tree context = BLOCK_SUPERCONTEXT (block); ;
       context = BLOCK_SUPERCONTEXT (context))
    {
      if (BLOCK_FRAGMENT_ORIGIN (context))
	{
	  gcc_assert (!BLOCK_SUBBLOCKS (context));
	  context = BLOCK_FRAGMENT_ORIGIN (context);
	}
      for (tree sub = BLOCK_SUBBLOCKS (context);
	   sub != block;
	   sub = BLOCK_CHAIN (sub))
	if (!sub)
	  return false;
      if (context == outer)
	return true;
      else
	block = context;
    }
}

/* Called during final while assembling the marker of the entry point
   for an inlined function.  */

static void
dwarf2out_inline_entry (tree block)
{
  gcc_assert (debug_inline_points);

  /* If we can't represent it, don't bother.  */
  if (!(dwarf_version >= 3 || !dwarf_strict))
    return;

  gcc_assert (DECL_P (block_ultimate_origin (block)));

  /* Sanity check the block tree.  This would catch a case in which
     BLOCK got removed from the tree reachable from the outermost
     lexical block, but got retained in markers.  It would still link
     back to its parents, but some ancestor would be missing a link
     down the path to the sub BLOCK.  If the block got removed, its
     BLOCK_NUMBER will not be a usable value.  */
  if (flag_checking)
    gcc_assert (block_within_block_p (block,
				      DECL_INITIAL (current_function_decl),
				      true));

  gcc_assert (inlined_function_outer_scope_p (block));
  gcc_assert (!lookup_block_die (block));

  if (BLOCK_FRAGMENT_ORIGIN (block))
    block = BLOCK_FRAGMENT_ORIGIN (block);
  /* Can the entry point ever not be at the beginning of an
     unfragmented lexical block?  */
  else if (!(BLOCK_FRAGMENT_CHAIN (block)
	     || (cur_line_info_table
		 && !ZERO_VIEW_P (cur_line_info_table->view))))
    return;

  if (!inline_entry_data_table)
    inline_entry_data_table
      = hash_table<inline_entry_data_hasher>::create_ggc (10);


  inline_entry_data **iedp
    = inline_entry_data_table->find_slot_with_hash (block,
						    htab_hash_pointer (block),
						    INSERT);
  if (*iedp)
    /* ??? Ideally, we'd record all entry points for the same inlined
       function (some may have been duplicated by e.g. unrolling), but
       we have no way to represent that ATM.  */
    return;

  inline_entry_data *ied = *iedp = ggc_cleared_alloc<inline_entry_data> ();
  ied->block = block;
  ied->label_pfx = BLOCK_INLINE_ENTRY_LABEL;
  ied->label_num = BLOCK_NUMBER (block);
  if (cur_line_info_table)
    ied->view = cur_line_info_table->view;

  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, BLOCK_INLINE_ENTRY_LABEL,
			  BLOCK_NUMBER (block));
}

/* Called from finalize_size_functions for size functions so that their body
   can be encoded in the debug info to describe the layout of variable-length
   structures.  */

static void
dwarf2out_size_function (tree decl)
{
  set_early_dwarf s;
  function_to_dwarf_procedure (decl);
}

/* Note in one location list that text section has changed.  */

int
var_location_switch_text_section_1 (var_loc_list **slot, void *)
{
  var_loc_list *list = *slot;
  if (list->first)
    list->last_before_switch
      = list->last->next ? list->last->next : list->last;
  return 1;
}

/* Note in all location lists that text section has changed.  */

static void
var_location_switch_text_section (void)
{
  if (decl_loc_table == NULL)
    return;

  decl_loc_table->traverse<void *, var_location_switch_text_section_1> (NULL);
}

/* Create a new line number table.  */

static dw_line_info_table *
new_line_info_table (void)
{
  dw_line_info_table *table;

  table = ggc_cleared_alloc<dw_line_info_table> ();
  table->file_num = 1;
  table->line_num = 1;
  table->is_stmt = DWARF_LINE_DEFAULT_IS_STMT_START;
  FORCE_RESET_NEXT_VIEW (table->view);
  table->symviews_since_reset = 0;

  return table;
}

/* Lookup the "current" table into which we emit line info, so
   that we don't have to do it for every source line.  */

static void
set_cur_line_info_table (section *sec)
{
  dw_line_info_table *table;

  if (sec == text_section)
    table = text_section_line_info;
  else if (sec == cold_text_section)
    {
      table = cold_text_section_line_info;
      if (!table)
	{
	  cold_text_section_line_info = table = new_line_info_table ();
	  table->end_label = cold_end_label;
	}
    }
  else
    {
      const char *end_label;

      if (crtl->has_bb_partition)
	{
	  if (in_cold_section_p)
	    end_label = crtl->subsections.cold_section_end_label;
	  else
	    end_label = crtl->subsections.hot_section_end_label;
	}
      else
	{
	  char label[MAX_ARTIFICIAL_LABEL_BYTES];
	  ASM_GENERATE_INTERNAL_LABEL (label, FUNC_END_LABEL,
				       current_function_funcdef_no);
	  end_label = ggc_strdup (label);
	}

      table = new_line_info_table ();
      table->end_label = end_label;

      vec_safe_push (separate_line_info, table);
    }

  if (output_asm_line_debug_info ())
    table->is_stmt = (cur_line_info_table
		      ? cur_line_info_table->is_stmt
		      : DWARF_LINE_DEFAULT_IS_STMT_START);
  cur_line_info_table = table;
}


/* We need to reset the locations at the beginning of each
   function. We can't do this in the end_function hook, because the
   declarations that use the locations won't have been output when
   that hook is called.  Also compute have_multiple_function_sections here.  */

static void
dwarf2out_begin_function (tree fun)
{
  section *sec = function_section (fun);

  if (sec != text_section)
    have_multiple_function_sections = true;

  if (crtl->has_bb_partition && !cold_text_section)
    {
      gcc_assert (current_function_decl == fun);
      cold_text_section = unlikely_text_section ();
      switch_to_section (cold_text_section);
      ASM_OUTPUT_LABEL (asm_out_file, cold_text_section_label);
      switch_to_section (sec);
    }

  call_site_count = 0;
  tail_call_site_count = 0;

  set_cur_line_info_table (sec);
  FORCE_RESET_NEXT_VIEW (cur_line_info_table->view);
}

/* Helper function of dwarf2out_end_function, called only after emitting
   the very first function into assembly.  Check if some .debug_loc range
   might end with a .LVL* label that could be equal to .Ltext0.
   In that case we must force using absolute addresses in .debug_loc ranges,
   because this range could be .LVLN-.Ltext0 .. .LVLM-.Ltext0 for
   .LVLN == .LVLM == .Ltext0, thus 0 .. 0, which is a .debug_loc
   list terminator.
   Set have_multiple_function_sections to true in that case and
   terminate htab traversal.  */

int
find_empty_loc_ranges_at_text_label (var_loc_list **slot, int)
{
  var_loc_list *entry = *slot;
  struct var_loc_node *node;

  node = entry->first;
  if (node && node->next && node->next->label)
    {
      unsigned int i;
      const char *label = node->next->label;
      char loclabel[MAX_ARTIFICIAL_LABEL_BYTES];

      for (i = 0; i < first_loclabel_num_not_at_text_label; i++)
	{
	  ASM_GENERATE_INTERNAL_LABEL (loclabel, "LVL", i);
	  if (strcmp (label, loclabel) == 0)
	    {
	      have_multiple_function_sections = true;
	      return 0;
	    }
	}
    }
  return 1;
}

/* Hook called after emitting a function into assembly.
   This does something only for the very first function emitted.  */

static void
dwarf2out_end_function (unsigned int)
{
  if (in_first_function_p
      && !have_multiple_function_sections
      && first_loclabel_num_not_at_text_label
      && decl_loc_table)
    decl_loc_table->traverse<int, find_empty_loc_ranges_at_text_label> (0);
  in_first_function_p = false;
  maybe_at_text_label_p = false;
}

/* Temporary holder for dwarf2out_register_main_translation_unit.  Used to let
   front-ends register a translation unit even before dwarf2out_init is
   called.  */
static tree main_translation_unit = NULL_TREE;

/* Hook called by front-ends after they built their main translation unit.
   Associate comp_unit_die to UNIT.  */

static void
dwarf2out_register_main_translation_unit (tree unit)
{
  gcc_assert (TREE_CODE (unit) == TRANSLATION_UNIT_DECL
	      && main_translation_unit == NULL_TREE);
  main_translation_unit = unit;
  /* If dwarf2out_init has not been called yet, it will perform the association
     itself looking at main_translation_unit.  */
  if (decl_die_table != NULL)
    equate_decl_number_to_die (unit, comp_unit_die ());
}

/* Add OPCODE+VAL as an entry at the end of the opcode array in TABLE.  */

static void
push_dw_line_info_entry (dw_line_info_table *table,
			 enum dw_line_info_opcode opcode, unsigned int val)
{
  dw_line_info_entry e;
  e.opcode = opcode;
  e.val = val;
  vec_safe_push (table->entries, e);
}

/* Output a label to mark the beginning of a source code line entry
   and record information relating to this source line, in
   'line_info_table' for later output of the .debug_line section.  */
/* ??? The discriminator parameter ought to be unsigned.  */

static void
dwarf2out_source_line (unsigned int line, unsigned int column,
		       const char *filename,
                       int discriminator, bool is_stmt)
{
  unsigned int file_num;
  dw_line_info_table *table;
  static var_loc_view lvugid;

  /* 'line_info_table' information gathering is not needed when the debug
     info level is set to the lowest value.  Also, the current DWARF-based
     debug formats do not use this info.  */
  if (debug_info_level < DINFO_LEVEL_TERSE || !dwarf_debuginfo_p ())
    return;

  table = cur_line_info_table;

  if (line == 0)
    {
      if (debug_variable_location_views
	  && output_asm_line_debug_info ()
	  && table && !RESETTING_VIEW_P (table->view))
	{
	  /* If we're using the assembler to compute view numbers, we
	     can't issue a .loc directive for line zero, so we can't
	     get a view number at this point.  We might attempt to
	     compute it from the previous view, or equate it to a
	     subsequent view (though it might not be there!), but
	     since we're omitting the line number entry, we might as
	     well omit the view number as well.  That means pretending
	     it's a view number zero, which might very well turn out
	     to be correct.  ??? Extend the assembler so that the
	     compiler could emit e.g. ".locview .LVU#", to output a
	     view without changing line number information.  We'd then
	     have to count it in symviews_since_reset; when it's omitted,
	     it doesn't count.  */
	  if (!zero_view_p)
	    zero_view_p = BITMAP_GGC_ALLOC ();
	  bitmap_set_bit (zero_view_p, table->view);
	  if (flag_debug_asm)
	    {
	      char label[MAX_ARTIFICIAL_LABEL_BYTES];
	      ASM_GENERATE_INTERNAL_LABEL (label, "LVU", table->view);
	      fprintf (asm_out_file, "\t%s line 0, omitted view ",
		       ASM_COMMENT_START);
	      assemble_name (asm_out_file, label);
	      putc ('\n', asm_out_file);
	    }
	  table->view = ++lvugid;
	}
      return;
    }

  /* The discriminator column was added in dwarf4.  Simplify the below
     by simply removing it if we're not supposed to output it.  */
  if (dwarf_version < 4 && dwarf_strict)
    discriminator = 0;

  if (!debug_column_info)
    column = 0;

  file_num = maybe_emit_file (lookup_filename (filename));

  /* ??? TODO: Elide duplicate line number entries.  Traditionally,
     the debugger has used the second (possibly duplicate) line number
     at the beginning of the function to mark the end of the prologue.
     We could eliminate any other duplicates within the function.  For
     Dwarf3, we ought to include the DW_LNS_set_prologue_end mark in
     that second line number entry.  */
  /* Recall that this end-of-prologue indication is *not* the same thing
     as the end_prologue debug hook.  The NOTE_INSN_PROLOGUE_END note,
     to which the hook corresponds, follows the last insn that was 
     emitted by gen_prologue.  What we need is to precede the first insn
     that had been emitted after NOTE_INSN_FUNCTION_BEG, i.e. the first
     insn that corresponds to something the user wrote.  These may be
     very different locations once scheduling is enabled.  */

  if (0 && file_num == table->file_num
      && line == table->line_num
      && column == table->column_num
      && discriminator == table->discrim_num
      && is_stmt == table->is_stmt)
    return;

  switch_to_section (current_function_section ());

  /* If requested, emit something human-readable.  */
  if (flag_debug_asm)
    {
      if (debug_column_info)
	fprintf (asm_out_file, "\t%s %s:%d:%d\n", ASM_COMMENT_START,
		 filename, line, column);
      else
	fprintf (asm_out_file, "\t%s %s:%d\n", ASM_COMMENT_START,
		 filename, line);
    }

  if (output_asm_line_debug_info ())
    {
      /* Emit the .loc directive understood by GNU as.  */
      /* "\t.loc %u %u 0 is_stmt %u discriminator %u",
	 file_num, line, is_stmt, discriminator */
      fputs ("\t.loc ", asm_out_file);
      fprint_ul (asm_out_file, file_num);
      putc (' ', asm_out_file);
      fprint_ul (asm_out_file, line);
      putc (' ', asm_out_file);
      fprint_ul (asm_out_file, column);

      if (is_stmt != table->is_stmt)
	{
#if HAVE_GAS_LOC_STMT
	  fputs (" is_stmt ", asm_out_file);
	  putc (is_stmt ? '1' : '0', asm_out_file);
#endif
	}
      if (SUPPORTS_DISCRIMINATOR && discriminator != 0)
	{
	  gcc_assert (discriminator > 0);
	  fputs (" discriminator ", asm_out_file);
	  fprint_ul (asm_out_file, (unsigned long) discriminator);
	}
      if (debug_variable_location_views)
	{
	  if (!RESETTING_VIEW_P (table->view))
	    {
	      table->symviews_since_reset++;
	      if (table->symviews_since_reset > symview_upper_bound)
		symview_upper_bound = table->symviews_since_reset;
	      /* When we're using the assembler to compute view
		 numbers, we output symbolic labels after "view" in
		 .loc directives, and the assembler will set them for
		 us, so that we can refer to the view numbers in
		 location lists.  The only exceptions are when we know
		 a view will be zero: "-0" is a forced reset, used
		 e.g. in the beginning of functions, whereas "0" tells
		 the assembler to check that there was a PC change
		 since the previous view, in a way that implicitly
		 resets the next view.  */
	      fputs (" view ", asm_out_file);
	      char label[MAX_ARTIFICIAL_LABEL_BYTES];
	      ASM_GENERATE_INTERNAL_LABEL (label, "LVU", table->view);
	      assemble_name (asm_out_file, label);
	      table->view = ++lvugid;
	    }
	  else
	    {
	      table->symviews_since_reset = 0;
	      if (FORCE_RESETTING_VIEW_P (table->view))
		fputs (" view -0", asm_out_file);
	      else
		fputs (" view 0", asm_out_file);
	      /* Mark the present view as a zero view.  Earlier debug
		 binds may have already added its id to loclists to be
		 emitted later, so we can't reuse the id for something
		 else.  However, it's good to know whether a view is
		 known to be zero, because then we may be able to
		 optimize out locviews that are all zeros, so take
		 note of it in zero_view_p.  */
	      if (!zero_view_p)
		zero_view_p = BITMAP_GGC_ALLOC ();
	      bitmap_set_bit (zero_view_p, lvugid);
	      table->view = ++lvugid;
	    }
	}
      putc ('\n', asm_out_file);
    }
  else
    {
      unsigned int label_num = ++line_info_label_num;

      targetm.asm_out.internal_label (asm_out_file, LINE_CODE_LABEL, label_num);

      if (debug_variable_location_views && !RESETTING_VIEW_P (table->view))
	push_dw_line_info_entry (table, LI_adv_address, label_num);
      else
	push_dw_line_info_entry (table, LI_set_address, label_num);
      if (debug_variable_location_views)
	{
	  bool resetting = FORCE_RESETTING_VIEW_P (table->view);
	  if (resetting)
	    table->view = 0;

	  if (flag_debug_asm)
	    fprintf (asm_out_file, "\t%s view %s%d\n",
		     ASM_COMMENT_START,
		     resetting ? "-" : "",
		     table->view);

	  table->view++;
	}
      if (file_num != table->file_num)
	push_dw_line_info_entry (table, LI_set_file, file_num);
      if (discriminator != table->discrim_num)
	push_dw_line_info_entry (table, LI_set_discriminator, discriminator);
      if (is_stmt != table->is_stmt)
	push_dw_line_info_entry (table, LI_negate_stmt, 0);
      push_dw_line_info_entry (table, LI_set_line, line);
      if (debug_column_info)
	push_dw_line_info_entry (table, LI_set_column, column);
    }

  table->file_num = file_num;
  table->line_num = line;
  table->column_num = column;
  table->discrim_num = discriminator;
  table->is_stmt = is_stmt;
  table->in_use = true;
}

/* Record a source file location for a DECL_IGNORED_P function.  */

static void
dwarf2out_set_ignored_loc (unsigned int line, unsigned int column,
			   const char *filename)
{
  dw_fde_ref fde = cfun->fde;

  fde->ignored_debug = false;
  set_cur_line_info_table (function_section (fde->decl));

  dwarf2out_source_line (line, column, filename, 0, true);
}

/* Record the beginning of a new source file.  */

static void
dwarf2out_start_source_file (unsigned int lineno, const char *filename)
{
  if (debug_info_level >= DINFO_LEVEL_VERBOSE)
    {
      macinfo_entry e;
      e.code = DW_MACINFO_start_file;
      e.lineno = lineno;
      e.info = ggc_strdup (filename);
      vec_safe_push (macinfo_table, e);
    }
}

/* Record the end of a source file.  */

static void
dwarf2out_end_source_file (unsigned int lineno ATTRIBUTE_UNUSED)
{
  if (debug_info_level >= DINFO_LEVEL_VERBOSE)
    {
      macinfo_entry e;
      e.code = DW_MACINFO_end_file;
      e.lineno = lineno;
      e.info = NULL;
      vec_safe_push (macinfo_table, e);
    }
}

/* Called from debug_define in toplev.c.  The `buffer' parameter contains
   the tail part of the directive line, i.e. the part which is past the
   initial whitespace, #, whitespace, directive-name, whitespace part.  */

static void
dwarf2out_define (unsigned int lineno ATTRIBUTE_UNUSED,
		  const char *buffer ATTRIBUTE_UNUSED)
{
  if (debug_info_level >= DINFO_LEVEL_VERBOSE)
    {
      macinfo_entry e;
      /* Insert a dummy first entry to be able to optimize the whole
	 predefined macro block using DW_MACRO_import.  */
      if (macinfo_table->is_empty () && lineno <= 1)
	{
	  e.code = 0;
	  e.lineno = 0;
	  e.info = NULL;
	  vec_safe_push (macinfo_table, e);
	}
      e.code = DW_MACINFO_define;
      e.lineno = lineno;
      e.info = ggc_strdup (buffer);
      vec_safe_push (macinfo_table, e);
    }
}

/* Called from debug_undef in toplev.c.  The `buffer' parameter contains
   the tail part of the directive line, i.e. the part which is past the
   initial whitespace, #, whitespace, directive-name, whitespace part.  */

static void
dwarf2out_undef (unsigned int lineno ATTRIBUTE_UNUSED,
		 const char *buffer ATTRIBUTE_UNUSED)
{
  if (debug_info_level >= DINFO_LEVEL_VERBOSE)
    {
      macinfo_entry e;
      /* Insert a dummy first entry to be able to optimize the whole
	 predefined macro block using DW_MACRO_import.  */
      if (macinfo_table->is_empty () && lineno <= 1)
	{
	  e.code = 0;
	  e.lineno = 0;
	  e.info = NULL;
	  vec_safe_push (macinfo_table, e);
	}
      e.code = DW_MACINFO_undef;
      e.lineno = lineno;
      e.info = ggc_strdup (buffer);
      vec_safe_push (macinfo_table, e);
    }
}

/* Helpers to manipulate hash table of CUs.  */

struct macinfo_entry_hasher : nofree_ptr_hash <macinfo_entry>
{
  static inline hashval_t hash (const macinfo_entry *);
  static inline bool equal (const macinfo_entry *, const macinfo_entry *);
};

inline hashval_t
macinfo_entry_hasher::hash (const macinfo_entry *entry)
{
  return htab_hash_string (entry->info);
}

inline bool
macinfo_entry_hasher::equal (const macinfo_entry *entry1,
			     const macinfo_entry *entry2)
{
  return !strcmp (entry1->info, entry2->info);
}

typedef hash_table<macinfo_entry_hasher> macinfo_hash_type;

/* Output a single .debug_macinfo entry.  */

static void
output_macinfo_op (macinfo_entry *ref)
{
  int file_num;
  size_t len;
  struct indirect_string_node *node;
  char label[MAX_ARTIFICIAL_LABEL_BYTES];
  struct dwarf_file_data *fd;

  switch (ref->code)
    {
    case DW_MACINFO_start_file:
      fd = lookup_filename (ref->info);
      file_num = maybe_emit_file (fd);
      dw2_asm_output_data (1, DW_MACINFO_start_file, "Start new file");
      dw2_asm_output_data_uleb128 (ref->lineno,
				   "Included from line number %lu", 
				   (unsigned long) ref->lineno);
      dw2_asm_output_data_uleb128 (file_num, "file %s", ref->info);
      break;
    case DW_MACINFO_end_file:
      dw2_asm_output_data (1, DW_MACINFO_end_file, "End file");
      break;
    case DW_MACINFO_define:
    case DW_MACINFO_undef:
      len = strlen (ref->info) + 1;
      if ((!dwarf_strict || dwarf_version >= 5)
	  && len > (size_t) dwarf_offset_size
	  && !DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET
	  && (debug_str_section->common.flags & SECTION_MERGE) != 0)
	{
	  if (dwarf_split_debug_info && dwarf_version >= 5)
	    ref->code = ref->code == DW_MACINFO_define
			? DW_MACRO_define_strx : DW_MACRO_undef_strx;
	  else
	    ref->code = ref->code == DW_MACINFO_define
			? DW_MACRO_define_strp : DW_MACRO_undef_strp;
	  output_macinfo_op (ref);
	  return;
	}
      dw2_asm_output_data (1, ref->code,
			   ref->code == DW_MACINFO_define
			   ? "Define macro" : "Undefine macro");
      dw2_asm_output_data_uleb128 (ref->lineno, "At line number %lu", 
				   (unsigned long) ref->lineno);
      dw2_asm_output_nstring (ref->info, -1, "The macro");
      break;
    case DW_MACRO_define_strp:
      dw2_asm_output_data (1, ref->code, "Define macro strp");
      goto do_DW_MACRO_define_strpx;
    case DW_MACRO_undef_strp:
      dw2_asm_output_data (1, ref->code, "Undefine macro strp");
      goto do_DW_MACRO_define_strpx;
    case DW_MACRO_define_strx:
      dw2_asm_output_data (1, ref->code, "Define macro strx");
      goto do_DW_MACRO_define_strpx;
    case DW_MACRO_undef_strx:
      dw2_asm_output_data (1, ref->code, "Undefine macro strx");
      /* FALLTHRU */
    do_DW_MACRO_define_strpx:
      /* NB: dwarf2out_finish performs:
	   1. save_macinfo_strings
	   2. hash table traverse of index_string
	   3. output_macinfo -> output_macinfo_op
	   4. output_indirect_strings
		-> hash table traverse of output_index_string

	 When output_macinfo_op is called, all index strings have been
	 added to hash table by save_macinfo_strings and we can't pass
	 INSERT to find_slot_with_hash which may expand hash table, even
	 if no insertion is needed, and change hash table traverse order
	 between index_string and output_index_string.  */
      node = find_AT_string (ref->info, NO_INSERT);
      gcc_assert (node
		  && (node->form == DW_FORM_strp
		      || node->form == dwarf_FORM (DW_FORM_strx)));
      dw2_asm_output_data_uleb128 (ref->lineno, "At line number %lu",
				   (unsigned long) ref->lineno);
      if (node->form == DW_FORM_strp)
        dw2_asm_output_offset (dwarf_offset_size, node->label,
                               debug_str_section, "The macro: \"%s\"",
                               ref->info);
      else
        dw2_asm_output_data_uleb128 (node->index, "The macro: \"%s\"",
                                     ref->info);
      break;
    case DW_MACRO_import:
      dw2_asm_output_data (1, ref->code, "Import");
      ASM_GENERATE_INTERNAL_LABEL (label,
				   DEBUG_MACRO_SECTION_LABEL,
				   ref->lineno + macinfo_label_base);
      dw2_asm_output_offset (dwarf_offset_size, label, NULL, NULL);
      break;
    default:
      fprintf (asm_out_file, "%s unrecognized macinfo code %lu\n",
	       ASM_COMMENT_START, (unsigned long) ref->code);
      break;
    }
}

/* Attempt to make a sequence of define/undef macinfo ops shareable with
   other compilation unit .debug_macinfo sections.  IDX is the first
   index of a define/undef, return the number of ops that should be
   emitted in a comdat .debug_macinfo section and emit
   a DW_MACRO_import entry referencing it.
   If the define/undef entry should be emitted normally, return 0.  */

static unsigned
optimize_macinfo_range (unsigned int idx, vec<macinfo_entry, va_gc> *files,
			macinfo_hash_type **macinfo_htab)
{
  macinfo_entry *first, *second, *cur, *inc;
  char linebuf[sizeof (HOST_WIDE_INT) * 3 + 1];
  unsigned char checksum[16];
  struct md5_ctx ctx;
  char *grp_name, *tail;
  const char *base;
  unsigned int i, count, encoded_filename_len, linebuf_len;
  macinfo_entry **slot;

  first = &(*macinfo_table)[idx];
  second = &(*macinfo_table)[idx + 1];

  /* Optimize only if there are at least two consecutive define/undef ops,
     and either all of them are before first DW_MACINFO_start_file
     with lineno {0,1} (i.e. predefined macro block), or all of them are
     in some included header file.  */
  if (second->code != DW_MACINFO_define && second->code != DW_MACINFO_undef)
    return 0;
  if (vec_safe_is_empty (files))
    {
      if (first->lineno > 1 || second->lineno > 1)
	return 0;
    }
  else if (first->lineno == 0)
    return 0;

  /* Find the last define/undef entry that can be grouped together
     with first and at the same time compute md5 checksum of their
     codes, linenumbers and strings.  */
  md5_init_ctx (&ctx);
  for (i = idx; macinfo_table->iterate (i, &cur); i++)
    if (cur->code != DW_MACINFO_define && cur->code != DW_MACINFO_undef)
      break;
    else if (vec_safe_is_empty (files) && cur->lineno > 1)
      break;
    else
      {
	unsigned char code = cur->code;
	md5_process_bytes (&code, 1, &ctx);
	checksum_uleb128 (cur->lineno, &ctx);
	md5_process_bytes (cur->info, strlen (cur->info) + 1, &ctx);
      }
  md5_finish_ctx (&ctx, checksum);
  count = i - idx;

  /* From the containing include filename (if any) pick up just
     usable characters from its basename.  */
  if (vec_safe_is_empty (files))
    base = "";
  else
    base = lbasename (files->last ().info);
  for (encoded_filename_len = 0, i = 0; base[i]; i++)
    if (ISIDNUM (base[i]) || base[i] == '.')
      encoded_filename_len++;
  /* Count . at the end.  */
  if (encoded_filename_len)
    encoded_filename_len++;

  sprintf (linebuf, HOST_WIDE_INT_PRINT_UNSIGNED, first->lineno);
  linebuf_len = strlen (linebuf);

  /* The group name format is: wmN.[<encoded filename>.]<lineno>.<md5sum>  */
  grp_name = XALLOCAVEC (char, 4 + encoded_filename_len + linebuf_len + 1
			 + 16 * 2 + 1);
  memcpy (grp_name, dwarf_offset_size == 4 ? "wm4." : "wm8.", 4);
  tail = grp_name + 4;
  if (encoded_filename_len)
    {
      for (i = 0; base[i]; i++)
	if (ISIDNUM (base[i]) || base[i] == '.')
	  *tail++ = base[i];
      *tail++ = '.';
    }
  memcpy (tail, linebuf, linebuf_len);
  tail += linebuf_len;
  *tail++ = '.';
  for (i = 0; i < 16; i++)
    sprintf (tail + i * 2, "%02x", checksum[i] & 0xff);

  /* Construct a macinfo_entry for DW_MACRO_import
     in the empty vector entry before the first define/undef.  */
  inc = &(*macinfo_table)[idx - 1];
  inc->code = DW_MACRO_import;
  inc->lineno = 0;
  inc->info = ggc_strdup (grp_name);
  if (!*macinfo_htab)
    *macinfo_htab = new macinfo_hash_type (10);
  /* Avoid emitting duplicates.  */
  slot = (*macinfo_htab)->find_slot (inc, INSERT);
  if (*slot != NULL)
    {
      inc->code = 0;
      inc->info = NULL;
      /* If such an entry has been used before, just emit
	 a DW_MACRO_import op.  */
      inc = *slot;
      output_macinfo_op (inc);
      /* And clear all macinfo_entry in the range to avoid emitting them
	 in the second pass.  */
      for (i = idx; macinfo_table->iterate (i, &cur) && i < idx + count; i++)
	{
	  cur->code = 0;
	  cur->info = NULL;
	}
    }
  else
    {
      *slot = inc;
      inc->lineno = (*macinfo_htab)->elements ();
      output_macinfo_op (inc);
    }
  return count;
}

/* Save any strings needed by the macinfo table in the debug str
   table.  All strings must be collected into the table by the time
   index_string is called.  */

static void
save_macinfo_strings (void)
{
  unsigned len;
  unsigned i;
  macinfo_entry *ref;

  for (i = 0; macinfo_table && macinfo_table->iterate (i, &ref); i++)
    {
      switch (ref->code)
        {
          /* Match the logic in output_macinfo_op to decide on
             indirect strings.  */
          case DW_MACINFO_define:
          case DW_MACINFO_undef:
            len = strlen (ref->info) + 1;
	    if ((!dwarf_strict || dwarf_version >= 5)
                && len > (unsigned) dwarf_offset_size
                && !DWARF2_INDIRECT_STRING_SUPPORT_MISSING_ON_TARGET
                && (debug_str_section->common.flags & SECTION_MERGE) != 0)
              set_indirect_string (find_AT_string (ref->info));
            break;
	  case DW_MACINFO_start_file:
	    /* -gsplit-dwarf -g3 will also output filename as indirect
	       string.  */
	    if (!dwarf_split_debug_info)
	      break;
	    /* Fall through. */
	  case DW_MACRO_define_strp:
	  case DW_MACRO_undef_strp:
	  case DW_MACRO_define_strx:
	  case DW_MACRO_undef_strx:
            set_indirect_string (find_AT_string (ref->info));
            break;
          default:
            break;
        }
    }
}

/* Output macinfo section(s).  */

static void
output_macinfo (const char *debug_line_label, bool early_lto_debug)
{
  unsigned i;
  unsigned long length = vec_safe_length (macinfo_table);
  macinfo_entry *ref;
  vec<macinfo_entry, va_gc> *files = NULL;
  macinfo_hash_type *macinfo_htab = NULL;
  char dl_section_ref[MAX_ARTIFICIAL_LABEL_BYTES];

  if (! length)
    return;

  /* output_macinfo* uses these interchangeably.  */
  gcc_assert ((int) DW_MACINFO_define == (int) DW_MACRO_define
	      && (int) DW_MACINFO_undef == (int) DW_MACRO_undef
	      && (int) DW_MACINFO_start_file == (int) DW_MACRO_start_file
	      && (int) DW_MACINFO_end_file == (int) DW_MACRO_end_file);

  /* AIX Assembler inserts the length, so adjust the reference to match the
     offset expected by debuggers.  */
  strcpy (dl_section_ref, debug_line_label);
  if (XCOFF_DEBUGGING_INFO)
    strcat (dl_section_ref, DWARF_INITIAL_LENGTH_SIZE_STR);

  /* For .debug_macro emit the section header.  */
  if (!dwarf_strict || dwarf_version >= 5)
    {
      dw2_asm_output_data (2, dwarf_version >= 5 ? 5 : 4,
			   "DWARF macro version number");
      if (dwarf_offset_size == 8)
	dw2_asm_output_data (1, 3, "Flags: 64-bit, lineptr present");
      else
	dw2_asm_output_data (1, 2, "Flags: 32-bit, lineptr present");
      dw2_asm_output_offset (dwarf_offset_size, debug_line_label,
                             debug_line_section, NULL);
    }

  /* In the first loop, it emits the primary .debug_macinfo section
     and after each emitted op the macinfo_entry is cleared.
     If a longer range of define/undef ops can be optimized using
     DW_MACRO_import, the DW_MACRO_import op is emitted and kept in
     the vector before the first define/undef in the range and the
     whole range of define/undef ops is not emitted and kept.  */
  for (i = 0; macinfo_table->iterate (i, &ref); i++)
    {
      switch (ref->code)
	{
	case DW_MACINFO_start_file:
	  vec_safe_push (files, *ref);
	  break;
	case DW_MACINFO_end_file:
	  if (!vec_safe_is_empty (files))
	    files->pop ();
	  break;
	case DW_MACINFO_define:
	case DW_MACINFO_undef:
	  if ((!dwarf_strict || dwarf_version >= 5)
	      && HAVE_COMDAT_GROUP
	      && vec_safe_length (files) != 1
	      && i > 0
	      && i + 1 < length
	      && (*macinfo_table)[i - 1].code == 0)
	    {
	      unsigned count = optimize_macinfo_range (i, files, &macinfo_htab);
	      if (count)
		{
		  i += count - 1;
		  continue;
		}
	    }
	  break;
	case 0:
	  /* A dummy entry may be inserted at the beginning to be able
	     to optimize the whole block of predefined macros.  */
	  if (i == 0)
	    continue;
	default:
	  break;
	}
      output_macinfo_op (ref);
      ref->info = NULL;
      ref->code = 0;
    }

  if (!macinfo_htab)
    return;

  /* Save the number of transparent includes so we can adjust the
     label number for the fat LTO object DWARF.  */
  unsigned macinfo_label_base_adj = macinfo_htab->elements ();

  delete macinfo_htab;
  macinfo_htab = NULL;

  /* If any DW_MACRO_import were used, on those DW_MACRO_import entries
     terminate the current chain and switch to a new comdat .debug_macinfo
     section and emit the define/undef entries within it.  */
  for (i = 0; macinfo_table->iterate (i, &ref); i++)
    switch (ref->code)
      {
      case 0:
	continue;
      case DW_MACRO_import:
	{
	  char label[MAX_ARTIFICIAL_LABEL_BYTES];
	  tree comdat_key = get_identifier (ref->info);
	  /* Terminate the previous .debug_macinfo section.  */
	  dw2_asm_output_data (1, 0, "End compilation unit");
	  targetm.asm_out.named_section (debug_macinfo_section_name,
					 SECTION_DEBUG
					 | SECTION_LINKONCE
					 | (early_lto_debug
					    ? SECTION_EXCLUDE : 0),
					 comdat_key);
	  ASM_GENERATE_INTERNAL_LABEL (label,
				       DEBUG_MACRO_SECTION_LABEL,
				       ref->lineno + macinfo_label_base);
	  ASM_OUTPUT_LABEL (asm_out_file, label);
	  ref->code = 0;
	  ref->info = NULL;
	  dw2_asm_output_data (2, dwarf_version >= 5 ? 5 : 4,
			       "DWARF macro version number");
	  if (dwarf_offset_size == 8)
	    dw2_asm_output_data (1, 1, "Flags: 64-bit");
	  else
	    dw2_asm_output_data (1, 0, "Flags: 32-bit");
	}
	break;
      case DW_MACINFO_define:
      case DW_MACINFO_undef:
	output_macinfo_op (ref);
	ref->code = 0;
	ref->info = NULL;
	break;
      default:
	gcc_unreachable ();
      }

  macinfo_label_base += macinfo_label_base_adj;
}

/* As init_sections_and_labels may get called multiple times, have a
   generation count for labels.  */
static unsigned init_sections_and_labels_generation;

/* Initialize the various sections and labels for dwarf output and prefix
   them with PREFIX if non-NULL.  Returns the generation (zero based
   number of times function was called).  */

static unsigned
init_sections_and_labels (bool early_lto_debug)
{
  if (early_lto_debug)
    {
      if (!dwarf_split_debug_info)
	{
	  debug_info_section = get_section (DEBUG_LTO_INFO_SECTION,
					    SECTION_DEBUG | SECTION_EXCLUDE,
					    NULL);
	  debug_abbrev_section = get_section (DEBUG_LTO_ABBREV_SECTION,
					      SECTION_DEBUG | SECTION_EXCLUDE,
					      NULL);
	  debug_macinfo_section_name
	    = ((dwarf_strict && dwarf_version < 5)
	       ? DEBUG_LTO_MACINFO_SECTION : DEBUG_LTO_MACRO_SECTION);
	  debug_macinfo_section = get_section (debug_macinfo_section_name,
					       SECTION_DEBUG
					       | SECTION_EXCLUDE, NULL);
	}
      else
	{
	  /* ???  Which of the following do we need early?  */
	  debug_info_section = get_section (DEBUG_LTO_DWO_INFO_SECTION,
					    SECTION_DEBUG | SECTION_EXCLUDE,
					    NULL);
	  debug_abbrev_section = get_section (DEBUG_LTO_DWO_ABBREV_SECTION,
					      SECTION_DEBUG | SECTION_EXCLUDE,
					      NULL);
	  debug_skeleton_info_section = get_section (DEBUG_LTO_INFO_SECTION,
						     SECTION_DEBUG
						     | SECTION_EXCLUDE, NULL);
	  debug_skeleton_abbrev_section
	    = get_section (DEBUG_LTO_ABBREV_SECTION,
			   SECTION_DEBUG | SECTION_EXCLUDE, NULL);
	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label,
				       DEBUG_SKELETON_ABBREV_SECTION_LABEL,
				       init_sections_and_labels_generation);

	  /* Somewhat confusing detail: The skeleton_[abbrev|info] sections
	     stay in the main .o, but the skeleton_line goes into the split
	     off dwo.  */
	  debug_skeleton_line_section
	    = get_section (DEBUG_LTO_LINE_SECTION,
			   SECTION_DEBUG | SECTION_EXCLUDE, NULL);
	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_line_section_label,
				       DEBUG_SKELETON_LINE_SECTION_LABEL,
				       init_sections_and_labels_generation);
	  debug_str_offsets_section
	    = get_section (DEBUG_LTO_DWO_STR_OFFSETS_SECTION,
			   SECTION_DEBUG | SECTION_EXCLUDE,
			   NULL);
	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label,
				       DEBUG_SKELETON_INFO_SECTION_LABEL,
				       init_sections_and_labels_generation);
	  debug_str_dwo_section = get_section (DEBUG_LTO_STR_DWO_SECTION,
					       DEBUG_STR_DWO_SECTION_FLAGS,
					       NULL);
	  debug_macinfo_section_name
	    = ((dwarf_strict && dwarf_version < 5)
	       ? DEBUG_LTO_DWO_MACINFO_SECTION : DEBUG_LTO_DWO_MACRO_SECTION);
	  debug_macinfo_section = get_section (debug_macinfo_section_name,
					       SECTION_DEBUG | SECTION_EXCLUDE,
					       NULL);
	}
      /* For macro info and the file table we have to refer to a
	 debug_line section.  */
      debug_line_section = get_section (DEBUG_LTO_LINE_SECTION,
					SECTION_DEBUG | SECTION_EXCLUDE, NULL);
      ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
				   DEBUG_LINE_SECTION_LABEL,
				   init_sections_and_labels_generation);

      debug_str_section = get_section (DEBUG_LTO_STR_SECTION,
				       DEBUG_STR_SECTION_FLAGS
				       | SECTION_EXCLUDE, NULL);
      if (!dwarf_split_debug_info)
	debug_line_str_section
	  = get_section (DEBUG_LTO_LINE_STR_SECTION,
			 DEBUG_STR_SECTION_FLAGS | SECTION_EXCLUDE, NULL);
    }
  else
    {
      if (!dwarf_split_debug_info)
	{
	  debug_info_section = get_section (DEBUG_INFO_SECTION,
					    SECTION_DEBUG, NULL);
	  debug_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
					      SECTION_DEBUG, NULL);
	  debug_loc_section = get_section (dwarf_version >= 5
					   ? DEBUG_LOCLISTS_SECTION
					   : DEBUG_LOC_SECTION,
					   SECTION_DEBUG, NULL);
	  debug_macinfo_section_name
	    = ((dwarf_strict && dwarf_version < 5)
	       ? DEBUG_MACINFO_SECTION : DEBUG_MACRO_SECTION);
	  debug_macinfo_section = get_section (debug_macinfo_section_name,
					       SECTION_DEBUG, NULL);
	}
      else
	{
	  debug_info_section = get_section (DEBUG_DWO_INFO_SECTION,
					    SECTION_DEBUG | SECTION_EXCLUDE,
					    NULL);
	  debug_abbrev_section = get_section (DEBUG_DWO_ABBREV_SECTION,
					      SECTION_DEBUG | SECTION_EXCLUDE,
					      NULL);
	  debug_addr_section = get_section (DEBUG_ADDR_SECTION,
					    SECTION_DEBUG, NULL);
	  debug_skeleton_info_section = get_section (DEBUG_INFO_SECTION,
						     SECTION_DEBUG, NULL);
	  debug_skeleton_abbrev_section = get_section (DEBUG_ABBREV_SECTION,
						       SECTION_DEBUG, NULL);
	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_abbrev_section_label,
				       DEBUG_SKELETON_ABBREV_SECTION_LABEL,
				       init_sections_and_labels_generation);

	  /* Somewhat confusing detail: The skeleton_[abbrev|info] sections
	     stay in the main .o, but the skeleton_line goes into the
	     split off dwo.  */
	  debug_skeleton_line_section
	      = get_section (DEBUG_DWO_LINE_SECTION,
			     SECTION_DEBUG | SECTION_EXCLUDE, NULL);
	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_line_section_label,
				       DEBUG_SKELETON_LINE_SECTION_LABEL,
				       init_sections_and_labels_generation);
	  debug_str_offsets_section
	    = get_section (DEBUG_DWO_STR_OFFSETS_SECTION,
			   SECTION_DEBUG | SECTION_EXCLUDE, NULL);
	  ASM_GENERATE_INTERNAL_LABEL (debug_skeleton_info_section_label,
				       DEBUG_SKELETON_INFO_SECTION_LABEL,
				       init_sections_and_labels_generation);
	  debug_loc_section = get_section (dwarf_version >= 5
					   ? DEBUG_DWO_LOCLISTS_SECTION
					   : DEBUG_DWO_LOC_SECTION,
					   SECTION_DEBUG | SECTION_EXCLUDE,
					   NULL);
	  debug_str_dwo_section = get_section (DEBUG_STR_DWO_SECTION,
					       DEBUG_STR_DWO_SECTION_FLAGS,
					       NULL);
	  debug_macinfo_section_name
	    = ((dwarf_strict && dwarf_version < 5)
	       ? DEBUG_DWO_MACINFO_SECTION : DEBUG_DWO_MACRO_SECTION);
	  debug_macinfo_section = get_section (debug_macinfo_section_name,
					       SECTION_DEBUG | SECTION_EXCLUDE,
					       NULL);
	  if (dwarf_version >= 5)
	    debug_ranges_dwo_section
	      = get_section (DEBUG_DWO_RNGLISTS_SECTION,
			     SECTION_DEBUG | SECTION_EXCLUDE, NULL);
	}
      debug_aranges_section = get_section (DEBUG_ARANGES_SECTION,
					   SECTION_DEBUG, NULL);
      debug_line_section = get_section (DEBUG_LINE_SECTION,
					SECTION_DEBUG, NULL);
      debug_pubnames_section = get_section (DEBUG_PUBNAMES_SECTION,
					    SECTION_DEBUG, NULL);
      debug_pubtypes_section = get_section (DEBUG_PUBTYPES_SECTION,
					    SECTION_DEBUG, NULL);
      debug_str_section = get_section (DEBUG_STR_SECTION,
				       DEBUG_STR_SECTION_FLAGS, NULL);
      if ((!dwarf_split_debug_info && !output_asm_line_debug_info ())
	  || asm_outputs_debug_line_str ())
	debug_line_str_section = get_section (DEBUG_LINE_STR_SECTION,
					      DEBUG_STR_SECTION_FLAGS, NULL);

      debug_ranges_section = get_section (dwarf_version >= 5
					  ? DEBUG_RNGLISTS_SECTION
					  : DEBUG_RANGES_SECTION,
					  SECTION_DEBUG, NULL);
      debug_frame_section = get_section (DEBUG_FRAME_SECTION,
					 SECTION_DEBUG, NULL);
    }

  ASM_GENERATE_INTERNAL_LABEL (abbrev_section_label,
			       DEBUG_ABBREV_SECTION_LABEL,
			       init_sections_and_labels_generation);
  ASM_GENERATE_INTERNAL_LABEL (debug_info_section_label,
			       DEBUG_INFO_SECTION_LABEL,
			       init_sections_and_labels_generation);
  info_section_emitted = false;
  ASM_GENERATE_INTERNAL_LABEL (debug_line_section_label,
			       DEBUG_LINE_SECTION_LABEL,
			       init_sections_and_labels_generation);
  /* There are up to 6 unique ranges labels per generation.
     See also output_rnglists.  */
  ASM_GENERATE_INTERNAL_LABEL (ranges_section_label,
			       DEBUG_RANGES_SECTION_LABEL,
			       init_sections_and_labels_generation * 6);
  if (dwarf_version >= 5 && dwarf_split_debug_info)
    ASM_GENERATE_INTERNAL_LABEL (ranges_base_label,
				 DEBUG_RANGES_SECTION_LABEL,
				 1 + init_sections_and_labels_generation * 6);
  ASM_GENERATE_INTERNAL_LABEL (debug_addr_section_label,
			       DEBUG_ADDR_SECTION_LABEL,
			       init_sections_and_labels_generation);
  ASM_GENERATE_INTERNAL_LABEL (macinfo_section_label,
			       (dwarf_strict && dwarf_version < 5)
			       ? DEBUG_MACINFO_SECTION_LABEL
			       : DEBUG_MACRO_SECTION_LABEL,
			       init_sections_and_labels_generation);
  ASM_GENERATE_INTERNAL_LABEL (loc_section_label, DEBUG_LOC_SECTION_LABEL,
			       init_sections_and_labels_generation);

  ++init_sections_and_labels_generation;
  return init_sections_and_labels_generation - 1;
}

/* Set up for Dwarf output at the start of compilation.  */

static void
dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
{
  /* Allocate the file_table.  */
  file_table = hash_table<dwarf_file_hasher>::create_ggc (50);

#ifndef DWARF2_LINENO_DEBUGGING_INFO
  /* Allocate the decl_die_table.  */
  decl_die_table = hash_table<decl_die_hasher>::create_ggc (10);

  /* Allocate the decl_loc_table.  */
  decl_loc_table = hash_table<decl_loc_hasher>::create_ggc (10);

  /* Allocate the cached_dw_loc_list_table.  */
  cached_dw_loc_list_table = hash_table<dw_loc_list_hasher>::create_ggc (10);

  /* Allocate the initial hunk of the abbrev_die_table.  */
  vec_alloc (abbrev_die_table, 256);
  /* Zero-th entry is allocated, but unused.  */
  abbrev_die_table->quick_push (NULL);

  /* Allocate the dwarf_proc_stack_usage_map.  */
  dwarf_proc_stack_usage_map = new hash_map<dw_die_ref, int>;

  /* Allocate the pubtypes and pubnames vectors.  */
  vec_alloc (pubname_table, 32);
  vec_alloc (pubtype_table, 32);

  vec_alloc (incomplete_types, 64);

  vec_alloc (used_rtx_array, 32);

  if (debug_info_level >= DINFO_LEVEL_VERBOSE)
    vec_alloc (macinfo_table, 64);
#endif

  /* If front-ends already registered a main translation unit but we were not
     ready to perform the association, do this now.  */
  if (main_translation_unit != NULL_TREE)
    equate_decl_number_to_die (main_translation_unit, comp_unit_die ());
}

/* Called before compile () starts outputtting functions, variables
   and toplevel asms into assembly.  */

static void
dwarf2out_assembly_start (void)
{
  if (text_section_line_info)
    return;

#ifndef DWARF2_LINENO_DEBUGGING_INFO
  ASM_GENERATE_INTERNAL_LABEL (text_section_label, TEXT_SECTION_LABEL, 0);
  ASM_GENERATE_INTERNAL_LABEL (text_end_label, TEXT_END_LABEL, 0);
  ASM_GENERATE_INTERNAL_LABEL (cold_text_section_label,
			       COLD_TEXT_SECTION_LABEL, 0);
  ASM_GENERATE_INTERNAL_LABEL (cold_end_label, COLD_END_LABEL, 0);

  switch_to_section (text_section);
  ASM_OUTPUT_LABEL (asm_out_file, text_section_label);
#endif

  /* Make sure the line number table for .text always exists.  */
  text_section_line_info = new_line_info_table ();
  text_section_line_info->end_label = text_end_label;

#ifdef DWARF2_LINENO_DEBUGGING_INFO
  cur_line_info_table = text_section_line_info;
#endif

  if (HAVE_GAS_CFI_SECTIONS_DIRECTIVE
      && dwarf2out_do_cfi_asm ()
      && !dwarf2out_do_eh_frame ())
    fprintf (asm_out_file, "\t.cfi_sections\t.debug_frame\n");

#if defined(HAVE_AS_GDWARF_5_DEBUG_FLAG) && defined(HAVE_AS_WORKING_DWARF_N_FLAG)
  if (output_asm_line_debug_info () && dwarf_version >= 5)
    {
      /* When gas outputs DWARF5 .debug_line[_str] then we have to
	 tell it the comp_dir and main file name for the zero entry
	 line table.  */
      const char *comp_dir, *filename0;

      comp_dir = comp_dir_string ();
      if (comp_dir == NULL)
	comp_dir = "";

      filename0 = get_AT_string (comp_unit_die (), DW_AT_name);
      if (filename0 == NULL)
	filename0 = "";

      fprintf (asm_out_file, "\t.file 0 ");
      output_quoted_string (asm_out_file, remap_debug_filename (comp_dir));
      fputc (' ', asm_out_file);
      output_quoted_string (asm_out_file, remap_debug_filename (filename0));
      fputc ('\n', asm_out_file);
    }
  else
#endif
  /* Work around for PR101575: output a dummy .file directive.  */
  if (!last_emitted_file && dwarf_debuginfo_p ()
      && debug_info_level >= DINFO_LEVEL_TERSE)
    {
      const char *filename0 = get_AT_string (comp_unit_die (), DW_AT_name);

      if (filename0 == NULL)
	filename0 = "<dummy>";
      maybe_emit_file (lookup_filename (filename0));
    }
}

/* A helper function for dwarf2out_finish called through
   htab_traverse.  Assign a string its index.  All strings must be
   collected into the table by the time index_string is called,
   because the indexing code relies on htab_traverse to traverse nodes
   in the same order for each run. */

int
index_string (indirect_string_node **h, unsigned int *index)
{
  indirect_string_node *node = *h;

  find_string_form (node);
  if (node->form == dwarf_FORM (DW_FORM_strx) && node->refcount > 0)
    {
      gcc_assert (node->index == NO_INDEX_ASSIGNED);
      node->index = *index;
      *index += 1;
    }
  return 1;
}

/* A helper function for output_indirect_strings called through
   htab_traverse.  Output the offset to a string and update the
   current offset.  */

int
output_index_string_offset (indirect_string_node **h, unsigned int *offset)
{
  indirect_string_node *node = *h;

  if (node->form == dwarf_FORM (DW_FORM_strx) && node->refcount > 0)
    {
      /* Assert that this node has been assigned an index.  */
      gcc_assert (node->index != NO_INDEX_ASSIGNED
                  && node->index != NOT_INDEXED);
      dw2_asm_output_data (dwarf_offset_size, *offset,
                           "indexed string 0x%x: %s", node->index, node->str);
      *offset += strlen (node->str) + 1;
    }
  return 1;
}

/* A helper function for dwarf2out_finish called through
   htab_traverse.  Output the indexed string.  */

int
output_index_string (indirect_string_node **h, unsigned int *cur_idx)
{
  struct indirect_string_node *node = *h;

  if (node->form == dwarf_FORM (DW_FORM_strx) && node->refcount > 0)
    {
      /* Assert that the strings are output in the same order as their
         indexes were assigned.  */
      gcc_assert (*cur_idx == node->index);
      assemble_string (node->str, strlen (node->str) + 1);
      *cur_idx += 1;
    }
  return 1;
}

/* A helper function for output_indirect_strings.  Counts the number
   of index strings offsets.  Must match the logic of the functions
   output_index_string[_offsets] above.  */
int
count_index_strings (indirect_string_node **h, unsigned int *last_idx)
{
  struct indirect_string_node *node = *h;

  if (node->form == dwarf_FORM (DW_FORM_strx) && node->refcount > 0)
    *last_idx += 1;
  return 1;
}

/* A helper function for dwarf2out_finish called through
   htab_traverse.  Emit one queued .debug_str string.  */

int
output_indirect_string (indirect_string_node **h, enum dwarf_form form)
{
  struct indirect_string_node *node = *h;

  node->form = find_string_form (node);
  if (node->form == form && node->refcount > 0)
    {
      ASM_OUTPUT_LABEL (asm_out_file, node->label);
      assemble_string (node->str, strlen (node->str) + 1);
    }

  return 1;
}

/* Output the indexed string table.  */

static void
output_indirect_strings (void)
{
  switch_to_section (debug_str_section);
  if (!dwarf_split_debug_info)
    debug_str_hash->traverse<enum dwarf_form,
			     output_indirect_string> (DW_FORM_strp);
  else
    {
      unsigned int offset = 0;
      unsigned int cur_idx = 0;

      if (skeleton_debug_str_hash)
        skeleton_debug_str_hash->traverse<enum dwarf_form,
					  output_indirect_string> (DW_FORM_strp);

      switch_to_section (debug_str_offsets_section);
      /* For DWARF5 the .debug_str_offsets[.dwo] section needs a unit
	 header.  Note that we don't need to generate a label to the
	 actual index table following the header here, because this is
	 for the split dwarf case only.  In an .dwo file there is only
	 one string offsets table (and one debug info section).  But
	 if we would start using string offset tables for the main (or
	 skeleton) unit, then we have to add a DW_AT_str_offsets_base
	 pointing to the actual index after the header.  Split dwarf
	 units will never have a string offsets base attribute.  When
	 a split unit is moved into a .dwp file the string offsets can
	 be found through the .debug_cu_index section table.  */
      if (dwarf_version >= 5)
	{
	  unsigned int last_idx = 0;
	  unsigned long str_offsets_length;

	  debug_str_hash->traverse_noresize
	    <unsigned int *, count_index_strings> (&last_idx);
	  str_offsets_length = last_idx * dwarf_offset_size + 4;
	  if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
	    dw2_asm_output_data (4, 0xffffffff,
				 "Escape value for 64-bit DWARF extension");
	  dw2_asm_output_data (dwarf_offset_size, str_offsets_length,
			       "Length of string offsets unit");
	  dw2_asm_output_data (2, 5, "DWARF string offsets version");
	  dw2_asm_output_data (2, 0, "Header zero padding");
	}
      debug_str_hash->traverse_noresize
	<unsigned int *, output_index_string_offset> (&offset);
      switch_to_section (debug_str_dwo_section);
      debug_str_hash->traverse_noresize<unsigned int *, output_index_string>
	(&cur_idx);
    }
}

/* Callback for htab_traverse to assign an index to an entry in the
   table, and to write that entry to the .debug_addr section.  */

int
output_addr_table_entry (addr_table_entry **slot, unsigned int *cur_index)
{
  addr_table_entry *entry = *slot;

  if (entry->refcount == 0)
    {
      gcc_assert (entry->index == NO_INDEX_ASSIGNED
                  || entry->index == NOT_INDEXED);
      return 1;
    }

  gcc_assert (entry->index == *cur_index);
  (*cur_index)++;

  switch (entry->kind)
    {
      case ate_kind_rtx:
        dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, entry->addr.rtl,
                                 "0x%x", entry->index);
        break;
      case ate_kind_rtx_dtprel:
        gcc_assert (targetm.asm_out.output_dwarf_dtprel);
        targetm.asm_out.output_dwarf_dtprel (asm_out_file,
                                             DWARF2_ADDR_SIZE,
                                             entry->addr.rtl);
        fputc ('\n', asm_out_file);
        break;
      case ate_kind_label:
        dw2_asm_output_addr (DWARF2_ADDR_SIZE, entry->addr.label,
                                 "0x%x", entry->index);
        break;
      default:
        gcc_unreachable ();
    }
  return 1;
}

/* A helper function for dwarf2out_finish.  Counts the number
   of indexed addresses.  Must match the logic of the functions
   output_addr_table_entry above.  */
int
count_index_addrs (addr_table_entry **slot, unsigned int *last_idx)
{
  addr_table_entry *entry = *slot;

  if (entry->refcount > 0)
    *last_idx += 1;
  return 1;
}

/* Produce the .debug_addr section.  */

static void
output_addr_table (void)
{
  unsigned int index = 0;
  if (addr_index_table == NULL || addr_index_table->size () == 0)
    return;

  switch_to_section (debug_addr_section);
  /* GNU DebugFission https://gcc.gnu.org/wiki/DebugFission
     which GCC uses to implement -gsplit-dwarf as DWARF GNU extension
     before DWARF5, didn't have a header for .debug_addr units.
     DWARF5 specifies a small header when address tables are used.  */
  if (dwarf_version >= 5)
    {
      unsigned int last_idx = 0;
      unsigned long addrs_length;

      addr_index_table->traverse_noresize
	<unsigned int *, count_index_addrs> (&last_idx);
      addrs_length = last_idx * DWARF2_ADDR_SIZE + 4;

      if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
	dw2_asm_output_data (4, 0xffffffff,
			     "Escape value for 64-bit DWARF extension");
      dw2_asm_output_data (dwarf_offset_size, addrs_length,
			   "Length of Address Unit");
      dw2_asm_output_data (2, 5, "DWARF addr version");
      dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Size of Address");
      dw2_asm_output_data (1, 0, "Size of Segment Descriptor");
    }
  ASM_OUTPUT_LABEL (asm_out_file, debug_addr_section_label);

  addr_index_table
    ->traverse_noresize<unsigned int *, output_addr_table_entry> (&index);
}

#if ENABLE_ASSERT_CHECKING
/* Verify that all marks are clear.  */

static void
verify_marks_clear (dw_die_ref die)
{
  dw_die_ref c;

  gcc_assert (! die->die_mark);
  FOR_EACH_CHILD (die, c, verify_marks_clear (c));
}
#endif /* ENABLE_ASSERT_CHECKING */

/* Clear the marks for a die and its children.
   Be cool if the mark isn't set.  */

static void
prune_unmark_dies (dw_die_ref die)
{
  dw_die_ref c;

  if (die->die_mark)
    die->die_mark = 0;
  FOR_EACH_CHILD (die, c, prune_unmark_dies (c));
}

/* Given LOC that is referenced by a DIE we're marking as used, find all
   referenced DWARF procedures it references and mark them as used.  */

static void
prune_unused_types_walk_loc_descr (dw_loc_descr_ref loc)
{
  for (; loc != NULL; loc = loc->dw_loc_next)
    switch (loc->dw_loc_opc)
      {
      case DW_OP_implicit_pointer:
      case DW_OP_convert:
      case DW_OP_reinterpret:
      case DW_OP_GNU_implicit_pointer:
      case DW_OP_GNU_convert:
      case DW_OP_GNU_reinterpret:
	if (loc->dw_loc_oprnd1.val_class == dw_val_class_die_ref)
	  prune_unused_types_mark (loc->dw_loc_oprnd1.v.val_die_ref.die, 1);
	break;
      case DW_OP_GNU_variable_value:
	if (loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
	  {
	    dw_die_ref ref
	      = lookup_decl_die (loc->dw_loc_oprnd1.v.val_decl_ref);
	    if (ref == NULL)
	      break;
	    loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	    loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
	    loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  }
	/* FALLTHRU */
      case DW_OP_call2:
      case DW_OP_call4:
      case DW_OP_call_ref:
      case DW_OP_const_type:
      case DW_OP_GNU_const_type:
      case DW_OP_GNU_parameter_ref:
	gcc_assert (loc->dw_loc_oprnd1.val_class == dw_val_class_die_ref);
	prune_unused_types_mark (loc->dw_loc_oprnd1.v.val_die_ref.die, 1);
	break;
      case DW_OP_regval_type:
      case DW_OP_deref_type:
      case DW_OP_GNU_regval_type:
      case DW_OP_GNU_deref_type:
	gcc_assert (loc->dw_loc_oprnd2.val_class == dw_val_class_die_ref);
	prune_unused_types_mark (loc->dw_loc_oprnd2.v.val_die_ref.die, 1);
	break;
      case DW_OP_entry_value:
      case DW_OP_GNU_entry_value:
	gcc_assert (loc->dw_loc_oprnd1.val_class == dw_val_class_loc);
	prune_unused_types_walk_loc_descr (loc->dw_loc_oprnd1.v.val_loc);
	break;
      default:
	break;
      }
}

/* Given DIE that we're marking as used, find any other dies
   it references as attributes and mark them as used.  */

static void
prune_unused_types_walk_attribs (dw_die_ref die)
{
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    {
      switch (AT_class (a))
	{
	/* Make sure DWARF procedures referenced by location descriptions will
	   get emitted.  */
	case dw_val_class_loc:
	  prune_unused_types_walk_loc_descr (AT_loc (a));
	  break;
	case dw_val_class_loc_list:
	  for (dw_loc_list_ref list = AT_loc_list (a);
	       list != NULL;
	       list = list->dw_loc_next)
	    prune_unused_types_walk_loc_descr (list->expr);
	  break;

	case dw_val_class_view_list:
	  /* This points to a loc_list in another attribute, so it's
	     already covered.  */
	  break;

	case dw_val_class_die_ref:
	  /* A reference to another DIE.
	     Make sure that it will get emitted.
	     If it was broken out into a comdat group, don't follow it.  */
          if (! AT_ref (a)->comdat_type_p
              || a->dw_attr == DW_AT_specification)
	    prune_unused_types_mark (a->dw_attr_val.v.val_die_ref.die, 1);
	  break;

	case dw_val_class_str:
	  /* Set the string's refcount to 0 so that prune_unused_types_mark
	     accounts properly for it.  */
	  a->dw_attr_val.v.val_str->refcount = 0;
	  break;

	default:
	  break;
	}
    }
}

/* Mark the generic parameters and arguments children DIEs of DIE.  */

static void
prune_unused_types_mark_generic_parms_dies (dw_die_ref die)
{
  dw_die_ref c;

  if (die == NULL || die->die_child == NULL)
    return;
  c = die->die_child;
  do
    {
      if (is_template_parameter (c))
	prune_unused_types_mark (c, 1);
      c = c->die_sib;
    } while (c && c != die->die_child);
}

/* Mark DIE as being used.  If DOKIDS is true, then walk down
   to DIE's children.  */

static void
prune_unused_types_mark (dw_die_ref die, int dokids)
{
  dw_die_ref c;

  if (die->die_mark == 0)
    {
      /* We haven't done this node yet.  Mark it as used.  */
      die->die_mark = 1;
      /* If this is the DIE of a generic type instantiation,
	 mark the children DIEs that describe its generic parms and
	 args.  */
      prune_unused_types_mark_generic_parms_dies (die);

      /* We also have to mark its parents as used.
	 (But we don't want to mark our parent's kids due to this,
	 unless it is a class.)  */
      if (die->die_parent)
	prune_unused_types_mark (die->die_parent,
				 class_scope_p (die->die_parent));

      /* Mark any referenced nodes.  */
      prune_unused_types_walk_attribs (die);

      /* If this node is a specification,
	 also mark the definition, if it exists.  */
      if (get_AT_flag (die, DW_AT_declaration) && die->die_definition)
	prune_unused_types_mark (die->die_definition, 1);
    }

  if (dokids && die->die_mark != 2)
    {
      /* We need to walk the children, but haven't done so yet.
	 Remember that we've walked the kids.  */
      die->die_mark = 2;

      /* If this is an array type, we need to make sure our
	 kids get marked, even if they're types.  If we're
	 breaking out types into comdat sections, do this
	 for all type definitions.  */
      if (die->die_tag == DW_TAG_array_type
          || (use_debug_types
              && is_type_die (die) && ! is_declaration_die (die)))
	FOR_EACH_CHILD (die, c, prune_unused_types_mark (c, 1));
      else
	FOR_EACH_CHILD (die, c, prune_unused_types_walk (c));
    }
}

/* For local classes, look if any static member functions were emitted
   and if so, mark them.  */

static void
prune_unused_types_walk_local_classes (dw_die_ref die)
{
  dw_die_ref c;

  if (die->die_mark == 2)
    return;

  switch (die->die_tag)
    {
    case DW_TAG_structure_type:
    case DW_TAG_union_type:
    case DW_TAG_class_type:
    case DW_TAG_interface_type:
      break;

    case DW_TAG_subprogram:
      if (!get_AT_flag (die, DW_AT_declaration)
	  || die->die_definition != NULL)
	prune_unused_types_mark (die, 1);
      return;

    default:
      return;
    }

  /* Mark children.  */
  FOR_EACH_CHILD (die, c, prune_unused_types_walk_local_classes (c));
}

/* Walk the tree DIE and mark types that we actually use.  */

static void
prune_unused_types_walk (dw_die_ref die)
{
  dw_die_ref c;

  /* Don't do anything if this node is already marked and
     children have been marked as well.  */
  if (die->die_mark == 2)
    return;

  switch (die->die_tag)
    {
    case DW_TAG_structure_type:
    case DW_TAG_union_type:
    case DW_TAG_class_type:
    case DW_TAG_interface_type:
      if (die->die_perennial_p)
	break;

      for (c = die->die_parent; c; c = c->die_parent)
	if (c->die_tag == DW_TAG_subprogram)
	  break;

      /* Finding used static member functions inside of classes
	 is needed just for local classes, because for other classes
	 static member function DIEs with DW_AT_specification
	 are emitted outside of the DW_TAG_*_type.  If we ever change
	 it, we'd need to call this even for non-local classes.  */
      if (c)
	prune_unused_types_walk_local_classes (die);

      /* It's a type node --- don't mark it.  */
      return;

    case DW_TAG_const_type:
    case DW_TAG_packed_type:
    case DW_TAG_pointer_type:
    case DW_TAG_reference_type:
    case DW_TAG_rvalue_reference_type:
    case DW_TAG_volatile_type:
    case DW_TAG_typedef:
    case DW_TAG_array_type:
    case DW_TAG_friend:
    case DW_TAG_enumeration_type:
    case DW_TAG_subroutine_type:
    case DW_TAG_string_type:
    case DW_TAG_set_type:
    case DW_TAG_subrange_type:
    case DW_TAG_ptr_to_member_type:
    case DW_TAG_file_type:
      /* Type nodes are useful only when other DIEs reference them --- don't
	 mark them.  */
      /* FALLTHROUGH */

    case DW_TAG_dwarf_procedure:
      /* Likewise for DWARF procedures.  */

      if (die->die_perennial_p)
	break;

      return;

    case DW_TAG_variable:
      if (flag_debug_only_used_symbols)
	{
	  if (die->die_perennial_p)
	    break;

	  /* For static data members, the declaration in the class is supposed
	     to have DW_TAG_member tag in DWARF{3,4} but DW_TAG_variable in
	     DWARF5.  DW_TAG_member will be marked, so mark even such
	     DW_TAG_variables in DWARF5, as long as it has DW_AT_const_value
	     attribute.  */
	  if (dwarf_version >= 5
	      && class_scope_p (die->die_parent)
	      && get_AT (die, DW_AT_const_value))
	    break;

	  /* premark_used_variables marks external variables --- don't mark
	     them here.  But function-local externals are always considered
	     used.  */
	  if (get_AT (die, DW_AT_external))
	    {
	      for (c = die->die_parent; c; c = c->die_parent)
		if (c->die_tag == DW_TAG_subprogram)
		  break;
	      if (!c)
		return;
	    }
	}
      /* FALLTHROUGH */

    default:
      /* Mark everything else.  */
      break;
  }

  if (die->die_mark == 0)
    {
      die->die_mark = 1;

      /* Now, mark any dies referenced from here.  */
      prune_unused_types_walk_attribs (die);
    }

  die->die_mark = 2;

  /* Mark children.  */
  FOR_EACH_CHILD (die, c, prune_unused_types_walk (c));
}

/* Increment the string counts on strings referred to from DIE's
   attributes.  */

static void
prune_unused_types_update_strings (dw_die_ref die)
{
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_str)
      {
	struct indirect_string_node *s = a->dw_attr_val.v.val_str;
	s->refcount++;
	/* Avoid unnecessarily putting strings that are used less than
	   twice in the hash table.  */
	if (s->form != DW_FORM_line_strp
	    && (s->refcount
		== ((DEBUG_STR_SECTION_FLAGS & SECTION_MERGE) ? 1 : 2)))
	  {
	    indirect_string_node **slot
	      = debug_str_hash->find_slot_with_hash (s->str,
						     htab_hash_string (s->str),
						     INSERT);
	    gcc_assert (*slot == NULL);
	    *slot = s;
	  }
      }
}

/* Mark DIE and its children as removed.  */

static void
mark_removed (dw_die_ref die)
{
  dw_die_ref c;
  die->removed = true;
  FOR_EACH_CHILD (die, c, mark_removed (c));
}

/* Remove from the tree DIE any dies that aren't marked.  */

static void
prune_unused_types_prune (dw_die_ref die)
{
  dw_die_ref c;

  gcc_assert (die->die_mark);
  prune_unused_types_update_strings (die);

  if (! die->die_child)
    return;

  c = die->die_child;
  do {
    dw_die_ref prev = c, next;
    for (c = c->die_sib; ! c->die_mark; c = next)
      if (c == die->die_child)
	{
	  /* No marked children between 'prev' and the end of the list.  */
	  if (prev == c)
	    /* No marked children at all.  */
	    die->die_child = NULL;
	  else
	    {
	      prev->die_sib = c->die_sib;
	      die->die_child = prev;
	    }
	  c->die_sib = NULL;
	  mark_removed (c);
	  return;
	}
      else
	{
	  next = c->die_sib;
	  c->die_sib = NULL;
	  mark_removed (c);
	}

    if (c != prev->die_sib)
      prev->die_sib = c;
    prune_unused_types_prune (c);
  } while (c != die->die_child);
}

/* Remove dies representing declarations that we never use.  */

static void
prune_unused_types (void)
{
  unsigned int i;
  limbo_die_node *node;
  comdat_type_node *ctnode;
  pubname_entry *pub;
  dw_die_ref base_type;

#if ENABLE_ASSERT_CHECKING
  /* All the marks should already be clear.  */
  verify_marks_clear (comp_unit_die ());
  for (node = limbo_die_list; node; node = node->next)
    verify_marks_clear (node->die);
  for (ctnode = comdat_type_list; ctnode; ctnode = ctnode->next)
    verify_marks_clear (ctnode->root_die);
#endif /* ENABLE_ASSERT_CHECKING */

  /* Mark types that are used in global variables.  */
  premark_types_used_by_global_vars ();

  /* Mark variables used in the symtab.  */
  if (flag_debug_only_used_symbols)
    premark_used_variables ();

  /* Set the mark on nodes that are actually used.  */
  prune_unused_types_walk (comp_unit_die ());
  for (node = limbo_die_list; node; node = node->next)
    prune_unused_types_walk (node->die);
  for (ctnode = comdat_type_list; ctnode; ctnode = ctnode->next)
    {
      prune_unused_types_walk (ctnode->root_die);
      prune_unused_types_mark (ctnode->type_die, 1);
    }

  /* Also set the mark on nodes referenced from the pubname_table.  Enumerators
     are unusual in that they are pubnames that are the children of pubtypes.
     They should only be marked via their parent DW_TAG_enumeration_type die,
     not as roots in themselves.  */
  FOR_EACH_VEC_ELT (*pubname_table, i, pub)
    if (pub->die->die_tag != DW_TAG_enumerator)
      prune_unused_types_mark (pub->die, 1);
  for (i = 0; base_types.iterate (i, &base_type); i++)
    prune_unused_types_mark (base_type, 1);

  /* Also set the mark on nodes that could be referenced by
     DW_TAG_call_site DW_AT_call_origin (i.e. direct call callees) or
     by DW_TAG_inlined_subroutine origins.  */
  cgraph_node *cnode;
  FOR_EACH_FUNCTION (cnode)
    if (cnode->referred_to_p (false))
      {
	dw_die_ref die = lookup_decl_die (cnode->decl);
	if (die == NULL || die->die_mark)
	  continue;
	for (cgraph_edge *e = cnode->callers; e; e = e->next_caller)
	  if (e->caller != cnode)
	    {
	      prune_unused_types_mark (die, 1);
	      break;
	    }
      }

  if (debug_str_hash)
    debug_str_hash->empty ();
  if (skeleton_debug_str_hash)
    skeleton_debug_str_hash->empty ();
  prune_unused_types_prune (comp_unit_die ());
  for (limbo_die_node **pnode = &limbo_die_list; *pnode; )
    {
      node = *pnode;
      if (!node->die->die_mark)
	*pnode = node->next;
      else
	{
	  prune_unused_types_prune (node->die);
	  pnode = &node->next;
	}
    }
  for (ctnode = comdat_type_list; ctnode; ctnode = ctnode->next)
    prune_unused_types_prune (ctnode->root_die);

  /* Leave the marks clear.  */
  prune_unmark_dies (comp_unit_die ());
  for (node = limbo_die_list; node; node = node->next)
    prune_unmark_dies (node->die);
  for (ctnode = comdat_type_list; ctnode; ctnode = ctnode->next)
    prune_unmark_dies (ctnode->root_die);
}

/* Helpers to manipulate hash table of comdat type units.  */

struct comdat_type_hasher : nofree_ptr_hash <comdat_type_node>
{
  static inline hashval_t hash (const comdat_type_node *);
  static inline bool equal (const comdat_type_node *, const comdat_type_node *);
};

inline hashval_t
comdat_type_hasher::hash (const comdat_type_node *type_node)
{
  hashval_t h;
  memcpy (&h, type_node->signature, sizeof (h));
  return h;
}

inline bool
comdat_type_hasher::equal (const comdat_type_node *type_node_1,
			   const comdat_type_node *type_node_2)
{
  return (! memcmp (type_node_1->signature, type_node_2->signature,
                    DWARF_TYPE_SIGNATURE_SIZE));
}

/* Move a DW_AT_{,MIPS_}linkage_name attribute just added to dw_die_ref
   to the location it would have been added, should we know its
   DECL_ASSEMBLER_NAME when we added other attributes.  This will
   probably improve compactness of debug info, removing equivalent
   abbrevs, and hide any differences caused by deferring the
   computation of the assembler name, triggered by e.g. PCH.  */

static inline void
move_linkage_attr (dw_die_ref die)
{
  unsigned ix = vec_safe_length (die->die_attr);
  dw_attr_node linkage = (*die->die_attr)[ix - 1];

  gcc_assert (linkage.dw_attr == DW_AT_linkage_name
	      || linkage.dw_attr == DW_AT_MIPS_linkage_name);

  while (--ix > 0)
    {
      dw_attr_node *prev = &(*die->die_attr)[ix - 1];

      if (prev->dw_attr == DW_AT_decl_line
	  || prev->dw_attr == DW_AT_decl_column
	  || prev->dw_attr == DW_AT_name)
	break;
    }

  if (ix != vec_safe_length (die->die_attr) - 1)
    {
      die->die_attr->pop ();
      die->die_attr->quick_insert (ix, linkage);
    }
}

/* Helper function for resolve_addr, mark DW_TAG_base_type nodes
   referenced from typed stack ops and count how often they are used.  */

static void
mark_base_types (dw_loc_descr_ref loc)
{
  dw_die_ref base_type = NULL;

  for (; loc; loc = loc->dw_loc_next)
    {
      switch (loc->dw_loc_opc)
	{
	case DW_OP_regval_type:
	case DW_OP_deref_type:
	case DW_OP_GNU_regval_type:
	case DW_OP_GNU_deref_type:
	  base_type = loc->dw_loc_oprnd2.v.val_die_ref.die;
	  break;
	case DW_OP_convert:
	case DW_OP_reinterpret:
	case DW_OP_GNU_convert:
	case DW_OP_GNU_reinterpret:
	  if (loc->dw_loc_oprnd1.val_class == dw_val_class_unsigned_const)
	    continue;
	  /* FALLTHRU */
	case DW_OP_const_type:
	case DW_OP_GNU_const_type:
	  base_type = loc->dw_loc_oprnd1.v.val_die_ref.die;
	  break;
	case DW_OP_entry_value:
	case DW_OP_GNU_entry_value:
	  mark_base_types (loc->dw_loc_oprnd1.v.val_loc);
	  continue;
	default:
	  continue;
	}
      gcc_assert (base_type->die_parent == comp_unit_die ());
      if (base_type->die_mark)
	base_type->die_mark++;
      else
	{
	  base_types.safe_push (base_type);
	  base_type->die_mark = 1;
	}
    }
}

/* Stripped-down variant of resolve_addr, mark DW_TAG_base_type nodes
   referenced from typed stack ops and count how often they are used.  */

static void
mark_base_types (dw_die_ref die)
{
  dw_die_ref c;
  dw_attr_node *a;
  dw_loc_list_ref *curr;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    switch (AT_class (a))
      {
      case dw_val_class_loc_list:
	curr = AT_loc_list_ptr (a);
	while (*curr)
	  {
	    mark_base_types ((*curr)->expr);
	    curr = &(*curr)->dw_loc_next;
	  }
	break;

      case dw_val_class_loc:
	mark_base_types (AT_loc (a));
	break;

      default:
	break;
      }

  FOR_EACH_CHILD (die, c, mark_base_types (c));
}

/* Comparison function for sorting marked base types.  */

static int
base_type_cmp (const void *x, const void *y)
{
  dw_die_ref dx = *(const dw_die_ref *) x;
  dw_die_ref dy = *(const dw_die_ref *) y;
  unsigned int byte_size1, byte_size2;
  unsigned int encoding1, encoding2;
  unsigned int align1, align2;
  if (dx->die_mark > dy->die_mark)
    return -1;
  if (dx->die_mark < dy->die_mark)
    return 1;
  byte_size1 = get_AT_unsigned (dx, DW_AT_byte_size);
  byte_size2 = get_AT_unsigned (dy, DW_AT_byte_size);
  if (byte_size1 < byte_size2)
    return 1;
  if (byte_size1 > byte_size2)
    return -1;
  encoding1 = get_AT_unsigned (dx, DW_AT_encoding);
  encoding2 = get_AT_unsigned (dy, DW_AT_encoding);
  if (encoding1 < encoding2)
    return 1;
  if (encoding1 > encoding2)
    return -1;
  align1 = get_AT_unsigned (dx, DW_AT_alignment);
  align2 = get_AT_unsigned (dy, DW_AT_alignment);
  if (align1 < align2)
    return 1;
  if (align1 > align2)
    return -1;
  return 0;
}

/* Move base types marked by mark_base_types as early as possible
   in the CU, sorted by decreasing usage count both to make the
   uleb128 references as small as possible and to make sure they
   will have die_offset already computed by calc_die_sizes when
   sizes of typed stack loc ops is computed.  */

static void
move_marked_base_types (void)
{
  unsigned int i;
  dw_die_ref base_type, die, c;

  if (base_types.is_empty ())
    return;

  /* Sort by decreasing usage count, they will be added again in that
     order later on.  */
  base_types.qsort (base_type_cmp);
  die = comp_unit_die ();
  c = die->die_child;
  do
    {
      dw_die_ref prev = c;
      c = c->die_sib;
      while (c->die_mark)
	{
	  remove_child_with_prev (c, prev);
	  /* As base types got marked, there must be at least
	     one node other than DW_TAG_base_type.  */
	  gcc_assert (die->die_child != NULL);
	  c = prev->die_sib;
	}
    }
  while (c != die->die_child);
  gcc_assert (die->die_child);
  c = die->die_child;
  for (i = 0; base_types.iterate (i, &base_type); i++)
    {
      base_type->die_mark = 0;
      base_type->die_sib = c->die_sib;
      c->die_sib = base_type;
      c = base_type;
    }
}

/* Helper function for resolve_addr, attempt to resolve
   one CONST_STRING, return true if successful.  Similarly verify that
   SYMBOL_REFs refer to variables emitted in the current CU.  */

static bool
resolve_one_addr (rtx *addr)
{
  rtx rtl = *addr;

  if (GET_CODE (rtl) == CONST_STRING)
    {
      size_t len = strlen (XSTR (rtl, 0)) + 1;
      tree t = build_string (len, XSTR (rtl, 0));
      tree tlen = size_int (len - 1);
      TREE_TYPE (t)
	= build_array_type (char_type_node, build_index_type (tlen));
      rtl = lookup_constant_def (t);
      if (!rtl || !MEM_P (rtl))
	return false;
      rtl = XEXP (rtl, 0);
      if (GET_CODE (rtl) == SYMBOL_REF
	  && SYMBOL_REF_DECL (rtl)
	  && !TREE_ASM_WRITTEN (SYMBOL_REF_DECL (rtl)))
	return false;
      vec_safe_push (used_rtx_array, rtl);
      *addr = rtl;
      return true;
    }

  if (GET_CODE (rtl) == SYMBOL_REF
      && SYMBOL_REF_DECL (rtl))
    {
      if (TREE_CONSTANT_POOL_ADDRESS_P (rtl))
	{
	  if (!TREE_ASM_WRITTEN (DECL_INITIAL (SYMBOL_REF_DECL (rtl))))
	    return false;
	}
      else if (!TREE_ASM_WRITTEN (SYMBOL_REF_DECL (rtl)))
	return false;
    }

  if (GET_CODE (rtl) == CONST)
    {
      subrtx_ptr_iterator::array_type array;
      FOR_EACH_SUBRTX_PTR (iter, array, &XEXP (rtl, 0), ALL)
	if (!resolve_one_addr (*iter))
	  return false;
    }

  return true;
}

/* For STRING_CST, return SYMBOL_REF of its constant pool entry,
   if possible, and create DW_TAG_dwarf_procedure that can be referenced
   from DW_OP_implicit_pointer if the string hasn't been seen yet.  */

static rtx
string_cst_pool_decl (tree t)
{
  rtx rtl = output_constant_def (t, 1);
  unsigned char *array;
  dw_loc_descr_ref l;
  tree decl;
  size_t len;
  dw_die_ref ref;

  if (!rtl || !MEM_P (rtl))
    return NULL_RTX;
  rtl = XEXP (rtl, 0);
  if (GET_CODE (rtl) != SYMBOL_REF
      || SYMBOL_REF_DECL (rtl) == NULL_TREE)
    return NULL_RTX;

  decl = SYMBOL_REF_DECL (rtl);
  if (!lookup_decl_die (decl))
    {
      len = TREE_STRING_LENGTH (t);
      vec_safe_push (used_rtx_array, rtl);
      ref = new_die (DW_TAG_dwarf_procedure, comp_unit_die (), decl);
      array = ggc_vec_alloc<unsigned char> (len);
      memcpy (array, TREE_STRING_POINTER (t), len);
      l = new_loc_descr (DW_OP_implicit_value, len, 0);
      l->dw_loc_oprnd2.val_class = dw_val_class_vec;
      l->dw_loc_oprnd2.v.val_vec.length = len;
      l->dw_loc_oprnd2.v.val_vec.elt_size = 1;
      l->dw_loc_oprnd2.v.val_vec.array = array;
      add_AT_loc (ref, DW_AT_location, l);
      equate_decl_number_to_die (decl, ref);
    }
  return rtl;
}

/* Helper function of resolve_addr_in_expr.  LOC is
   a DW_OP_addr followed by DW_OP_stack_value, either at the start
   of exprloc or after DW_OP_{,bit_}piece, and val_addr can't be
   resolved.  Replace it (both DW_OP_addr and DW_OP_stack_value)
   with DW_OP_implicit_pointer if possible
   and return true, if unsuccessful, return false.  */

static bool
optimize_one_addr_into_implicit_ptr (dw_loc_descr_ref loc)
{
  rtx rtl = loc->dw_loc_oprnd1.v.val_addr;
  HOST_WIDE_INT offset = 0;
  dw_die_ref ref = NULL;
  tree decl;

  if (GET_CODE (rtl) == CONST
      && GET_CODE (XEXP (rtl, 0)) == PLUS
      && CONST_INT_P (XEXP (XEXP (rtl, 0), 1)))
    {
      offset = INTVAL (XEXP (XEXP (rtl, 0), 1));
      rtl = XEXP (XEXP (rtl, 0), 0);
    }
  if (GET_CODE (rtl) == CONST_STRING)
    {
      size_t len = strlen (XSTR (rtl, 0)) + 1;
      tree t = build_string (len, XSTR (rtl, 0));
      tree tlen = size_int (len - 1);

      TREE_TYPE (t)
	= build_array_type (char_type_node, build_index_type (tlen));
      rtl = string_cst_pool_decl (t);
      if (!rtl)
	return false;
    }
  if (GET_CODE (rtl) == SYMBOL_REF && SYMBOL_REF_DECL (rtl))
    {
      decl = SYMBOL_REF_DECL (rtl);
      if (VAR_P (decl) && !DECL_EXTERNAL (decl))
	{
	  ref = lookup_decl_die (decl);
	  if (ref && (get_AT (ref, DW_AT_location)
		      || get_AT (ref, DW_AT_const_value)))
	    {
	      loc->dw_loc_opc = dwarf_OP (DW_OP_implicit_pointer);
	      loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	      loc->dw_loc_oprnd1.val_entry = NULL;
	      loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
	      loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
	      loc->dw_loc_next = loc->dw_loc_next->dw_loc_next;
	      loc->dw_loc_oprnd2.v.val_int = offset;
	      return true;
	    }
	}
    }
  return false;
}

/* Helper function for resolve_addr, handle one location
   expression, return false if at least one CONST_STRING or SYMBOL_REF in
   the location list couldn't be resolved.  */

static bool
resolve_addr_in_expr (dw_attr_node *a, dw_loc_descr_ref loc)
{
  dw_loc_descr_ref keep = NULL;
  for (dw_loc_descr_ref prev = NULL; loc; prev = loc, loc = loc->dw_loc_next)
    switch (loc->dw_loc_opc)
      {
      case DW_OP_addr:
	if (!resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr))
	  {
	    if ((prev == NULL
		 || prev->dw_loc_opc == DW_OP_piece
		 || prev->dw_loc_opc == DW_OP_bit_piece)
		&& loc->dw_loc_next
		&& loc->dw_loc_next->dw_loc_opc == DW_OP_stack_value
		&& (!dwarf_strict || dwarf_version >= 5)
		&& optimize_one_addr_into_implicit_ptr (loc))
	      break;
	    return false;
	  }
	break;
      case DW_OP_GNU_addr_index:
      case DW_OP_addrx:
      case DW_OP_GNU_const_index:
      case DW_OP_constx:
	if ((loc->dw_loc_opc == DW_OP_GNU_addr_index
	     || loc->dw_loc_opc == DW_OP_addrx)
	    || ((loc->dw_loc_opc == DW_OP_GNU_const_index
		 || loc->dw_loc_opc == DW_OP_constx)
		&& loc->dtprel))
          {
            rtx rtl = loc->dw_loc_oprnd1.val_entry->addr.rtl;
            if (!resolve_one_addr (&rtl))
              return false;
            remove_addr_table_entry (loc->dw_loc_oprnd1.val_entry);
	    loc->dw_loc_oprnd1.val_entry
	      = add_addr_table_entry (rtl, ate_kind_rtx);
          }
	break;
      case DW_OP_const4u:
      case DW_OP_const8u:
	if (loc->dtprel
	    && !resolve_one_addr (&loc->dw_loc_oprnd1.v.val_addr))
	  return false;
	break;
      case DW_OP_plus_uconst:
	if (size_of_loc_descr (loc)
	    > size_of_int_loc_descriptor (loc->dw_loc_oprnd1.v.val_unsigned)
	      + 1
	    && loc->dw_loc_oprnd1.v.val_unsigned > 0)
	  {
	    dw_loc_descr_ref repl
	      = int_loc_descriptor (loc->dw_loc_oprnd1.v.val_unsigned);
	    add_loc_descr (&repl, new_loc_descr (DW_OP_plus, 0, 0));
	    add_loc_descr (&repl, loc->dw_loc_next);
	    *loc = *repl;
	  }
	break;
      case DW_OP_implicit_value:
	if (loc->dw_loc_oprnd2.val_class == dw_val_class_addr
	    && !resolve_one_addr (&loc->dw_loc_oprnd2.v.val_addr))
	  return false;
	break;
      case DW_OP_implicit_pointer:
      case DW_OP_GNU_implicit_pointer:
      case DW_OP_GNU_parameter_ref:
      case DW_OP_GNU_variable_value:
	if (loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
	  {
	    dw_die_ref ref
	      = lookup_decl_die (loc->dw_loc_oprnd1.v.val_decl_ref);
	    if (ref == NULL)
	      return false;
	    loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	    loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
	    loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  }
	if (loc->dw_loc_opc == DW_OP_GNU_variable_value)
	  {
	    if (prev == NULL
		&& loc->dw_loc_next == NULL
		&& AT_class (a) == dw_val_class_loc)
	      switch (a->dw_attr)
		{
		  /* Following attributes allow both exprloc and reference,
		     so if the whole expression is DW_OP_GNU_variable_value
		     alone we could transform it into reference.  */
		case DW_AT_byte_size:
		case DW_AT_bit_size:
		case DW_AT_lower_bound:
		case DW_AT_upper_bound:
		case DW_AT_bit_stride:
		case DW_AT_count:
		case DW_AT_allocated:
		case DW_AT_associated:
		case DW_AT_byte_stride:
		  a->dw_attr_val.val_class = dw_val_class_die_ref;
		  a->dw_attr_val.val_entry = NULL;
		  a->dw_attr_val.v.val_die_ref.die
		    = loc->dw_loc_oprnd1.v.val_die_ref.die;
		  a->dw_attr_val.v.val_die_ref.external = 0;
		  return true;
		default:
		  break;
		}
	    if (dwarf_strict)
	      return false;
	  }
	break;
      case DW_OP_const_type:
      case DW_OP_regval_type:
      case DW_OP_deref_type:
      case DW_OP_convert:
      case DW_OP_reinterpret:
      case DW_OP_GNU_const_type:
      case DW_OP_GNU_regval_type:
      case DW_OP_GNU_deref_type:
      case DW_OP_GNU_convert:
      case DW_OP_GNU_reinterpret:
	while (loc->dw_loc_next
	       && (loc->dw_loc_next->dw_loc_opc == DW_OP_convert
		   || loc->dw_loc_next->dw_loc_opc == DW_OP_GNU_convert))
	  {
	    dw_die_ref base1, base2;
	    unsigned enc1, enc2, size1, size2;
	    if (loc->dw_loc_opc == DW_OP_regval_type
		|| loc->dw_loc_opc == DW_OP_deref_type
		|| loc->dw_loc_opc == DW_OP_GNU_regval_type
		|| loc->dw_loc_opc == DW_OP_GNU_deref_type)
	      base1 = loc->dw_loc_oprnd2.v.val_die_ref.die;
	    else if (loc->dw_loc_oprnd1.val_class
		     == dw_val_class_unsigned_const)
	      break;
	    else
	      base1 = loc->dw_loc_oprnd1.v.val_die_ref.die;
	    if (loc->dw_loc_next->dw_loc_oprnd1.val_class
		== dw_val_class_unsigned_const)
	      break;
	    base2 = loc->dw_loc_next->dw_loc_oprnd1.v.val_die_ref.die;
	    gcc_assert (base1->die_tag == DW_TAG_base_type
			&& base2->die_tag == DW_TAG_base_type);
	    enc1 = get_AT_unsigned (base1, DW_AT_encoding);
	    enc2 = get_AT_unsigned (base2, DW_AT_encoding);
	    size1 = get_AT_unsigned (base1, DW_AT_byte_size);
	    size2 = get_AT_unsigned (base2, DW_AT_byte_size);
	    if (size1 == size2
		&& (((enc1 == DW_ATE_unsigned || enc1 == DW_ATE_signed)
		     && (enc2 == DW_ATE_unsigned || enc2 == DW_ATE_signed)
		     && loc != keep)
		    || enc1 == enc2))
	      {
		/* Optimize away next DW_OP_convert after
		   adjusting LOC's base type die reference.  */
		if (loc->dw_loc_opc == DW_OP_regval_type
		    || loc->dw_loc_opc == DW_OP_deref_type
		    || loc->dw_loc_opc == DW_OP_GNU_regval_type
		    || loc->dw_loc_opc == DW_OP_GNU_deref_type)
		  loc->dw_loc_oprnd2.v.val_die_ref.die = base2;
		else
		  loc->dw_loc_oprnd1.v.val_die_ref.die = base2;
		loc->dw_loc_next = loc->dw_loc_next->dw_loc_next;
		continue;
	      }
	    /* Don't change integer DW_OP_convert after e.g. floating
	       point typed stack entry.  */
	    else if (enc1 != DW_ATE_unsigned && enc1 != DW_ATE_signed)
	      keep = loc->dw_loc_next;
	    break;
	  }
	break;
      default:
	break;
      }
  return true;
}

/* Helper function of resolve_addr.  DIE had DW_AT_location of
   DW_OP_addr alone, which referred to DECL in DW_OP_addr's operand
   and DW_OP_addr couldn't be resolved.  resolve_addr has already
   removed the DW_AT_location attribute.  This function attempts to
   add a new DW_AT_location attribute with DW_OP_implicit_pointer
   to it or DW_AT_const_value attribute, if possible.  */

static void
optimize_location_into_implicit_ptr (dw_die_ref die, tree decl)
{
  if (!VAR_P (decl)
      || lookup_decl_die (decl) != die
      || DECL_EXTERNAL (decl)
      || !TREE_STATIC (decl)
      || DECL_INITIAL (decl) == NULL_TREE
      || DECL_P (DECL_INITIAL (decl))
      || get_AT (die, DW_AT_const_value))
    return;

  tree init = DECL_INITIAL (decl);
  HOST_WIDE_INT offset = 0;
  /* For variables that have been optimized away and thus
     don't have a memory location, see if we can emit
     DW_AT_const_value instead.  */
  if (tree_add_const_value_attribute (die, init))
    return;
  if (dwarf_strict && dwarf_version < 5)
    return;
  /* If init is ADDR_EXPR or POINTER_PLUS_EXPR of ADDR_EXPR,
     and ADDR_EXPR refers to a decl that has DW_AT_location or
     DW_AT_const_value (but isn't addressable, otherwise
     resolving the original DW_OP_addr wouldn't fail), see if
     we can add DW_OP_implicit_pointer.  */
  STRIP_NOPS (init);
  if (TREE_CODE (init) == POINTER_PLUS_EXPR
      && tree_fits_shwi_p (TREE_OPERAND (init, 1)))
    {
      offset = tree_to_shwi (TREE_OPERAND (init, 1));
      init = TREE_OPERAND (init, 0);
      STRIP_NOPS (init);
    }
  if (TREE_CODE (init) != ADDR_EXPR)
    return;
  if ((TREE_CODE (TREE_OPERAND (init, 0)) == STRING_CST
       && !TREE_ASM_WRITTEN (TREE_OPERAND (init, 0)))
      || (TREE_CODE (TREE_OPERAND (init, 0)) == VAR_DECL
	  && !DECL_EXTERNAL (TREE_OPERAND (init, 0))
	  && TREE_OPERAND (init, 0) != decl))
    {
      dw_die_ref ref;
      dw_loc_descr_ref l;

      if (TREE_CODE (TREE_OPERAND (init, 0)) == STRING_CST)
	{
	  rtx rtl = string_cst_pool_decl (TREE_OPERAND (init, 0));
	  if (!rtl)
	    return;
	  decl = SYMBOL_REF_DECL (rtl);
	}
      else
	decl = TREE_OPERAND (init, 0);
      ref = lookup_decl_die (decl);
      if (ref == NULL
	  || (!get_AT (ref, DW_AT_location)
	      && !get_AT (ref, DW_AT_const_value)))
	return;
      l = new_loc_descr (dwarf_OP (DW_OP_implicit_pointer), 0, offset);
      l->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
      l->dw_loc_oprnd1.v.val_die_ref.die = ref;
      l->dw_loc_oprnd1.v.val_die_ref.external = 0;
      add_AT_loc (die, DW_AT_location, l);
    }
}

/* Return NULL if l is a DWARF expression, or first op that is not
   valid DWARF expression.  */

static dw_loc_descr_ref
non_dwarf_expression (dw_loc_descr_ref l)
{
  while (l)
    {
      if (l->dw_loc_opc >= DW_OP_reg0 && l->dw_loc_opc <= DW_OP_reg31)
	return l;
      switch (l->dw_loc_opc)
	{
	case DW_OP_regx:
	case DW_OP_implicit_value:
	case DW_OP_stack_value:
	case DW_OP_implicit_pointer:
	case DW_OP_GNU_implicit_pointer:
	case DW_OP_GNU_parameter_ref:
	case DW_OP_piece:
	case DW_OP_bit_piece:
	  return l;
	default:
	  break;
	}
      l = l->dw_loc_next;
    }
  return NULL;
}

/* Return adjusted copy of EXPR:
   If it is empty DWARF expression, return it.
   If it is valid non-empty DWARF expression,
   return copy of EXPR with DW_OP_deref appended to it.
   If it is DWARF expression followed by DW_OP_reg{N,x}, return
   copy of the DWARF expression with DW_OP_breg{N,x} <0> appended.
   If it is DWARF expression followed by DW_OP_stack_value, return
   copy of the DWARF expression without anything appended.
   Otherwise, return NULL.  */

static dw_loc_descr_ref
copy_deref_exprloc (dw_loc_descr_ref expr)
{
  dw_loc_descr_ref tail = NULL;

  if (expr == NULL)
    return NULL;

  dw_loc_descr_ref l = non_dwarf_expression (expr);
  if (l && l->dw_loc_next)
    return NULL;

  if (l)
    {
      if (l->dw_loc_opc >= DW_OP_reg0 && l->dw_loc_opc <= DW_OP_reg31)
	tail = new_loc_descr ((enum dwarf_location_atom)
			      (DW_OP_breg0 + (l->dw_loc_opc - DW_OP_reg0)),
			      0, 0);
      else
	switch (l->dw_loc_opc)
	  {
	  case DW_OP_regx:
	    tail = new_loc_descr (DW_OP_bregx,
				  l->dw_loc_oprnd1.v.val_unsigned, 0);
	    break;
	  case DW_OP_stack_value:
	    break;
	  default:
	    return NULL;
	  }
    }
  else
    tail = new_loc_descr (DW_OP_deref, 0, 0);

  dw_loc_descr_ref ret = NULL, *p = &ret;
  while (expr != l)
    {
      *p = new_loc_descr (expr->dw_loc_opc, 0, 0);
      (*p)->dw_loc_oprnd1 = expr->dw_loc_oprnd1;
      (*p)->dw_loc_oprnd2 = expr->dw_loc_oprnd2;
      p = &(*p)->dw_loc_next;
      expr = expr->dw_loc_next;
    }
  *p = tail;
  return ret;
}

/* For DW_AT_string_length attribute with DW_OP_GNU_variable_value
   reference to a variable or argument, adjust it if needed and return:
   -1 if the DW_AT_string_length attribute and DW_AT_{string_length_,}byte_size
      attribute if present should be removed
   0 keep the attribute perhaps with minor modifications, no need to rescan
   1 if the attribute has been successfully adjusted.  */

static int
optimize_string_length (dw_attr_node *a)
{
  dw_loc_descr_ref l = AT_loc (a), lv;
  dw_die_ref die;
  if (l->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
    {
      tree decl = l->dw_loc_oprnd1.v.val_decl_ref;
      die = lookup_decl_die (decl);
      if (die)
	{
	  l->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  l->dw_loc_oprnd1.v.val_die_ref.die = die;
	  l->dw_loc_oprnd1.v.val_die_ref.external = 0;
	}
      else
	return -1;
    }
  else
    die = l->dw_loc_oprnd1.v.val_die_ref.die;

  /* DWARF5 allows reference class, so we can then reference the DIE.
     Only do this for DW_OP_GNU_variable_value DW_OP_stack_value.  */
  if (l->dw_loc_next != NULL && dwarf_version >= 5)
    {
      a->dw_attr_val.val_class = dw_val_class_die_ref;
      a->dw_attr_val.val_entry = NULL;
      a->dw_attr_val.v.val_die_ref.die = die;
      a->dw_attr_val.v.val_die_ref.external = 0;
      return 0;
    }

  dw_attr_node *av = get_AT (die, DW_AT_location);
  dw_loc_list_ref d;
  bool non_dwarf_expr = false;

  if (av == NULL)
    return dwarf_strict ? -1 : 0;
  switch (AT_class (av))
    {
    case dw_val_class_loc_list:
      for (d = AT_loc_list (av); d != NULL; d = d->dw_loc_next)
	if (d->expr && non_dwarf_expression (d->expr))
	  non_dwarf_expr = true;
      break;
    case dw_val_class_view_list:
      gcc_unreachable ();
    case dw_val_class_loc:
      lv = AT_loc (av);
      if (lv == NULL)
	return dwarf_strict ? -1 : 0;
      if (non_dwarf_expression (lv))
	non_dwarf_expr = true;
      break;
    default:
      return dwarf_strict ? -1 : 0;
    }

  /* If it is safe to transform DW_OP_GNU_variable_value DW_OP_stack_value
     into DW_OP_call4  or DW_OP_GNU_variable_value into
     DW_OP_call4 DW_OP_deref, do so.  */
  if (!non_dwarf_expr
      && (l->dw_loc_next != NULL || AT_class (av) == dw_val_class_loc))
    {
      l->dw_loc_opc = DW_OP_call4;
      if (l->dw_loc_next)
	l->dw_loc_next = NULL;
      else
	l->dw_loc_next = new_loc_descr (DW_OP_deref, 0, 0);
      return 0;
    }

  /* For DW_OP_GNU_variable_value DW_OP_stack_value, we can just
     copy over the DW_AT_location attribute from die to a.  */
  if (l->dw_loc_next != NULL)
    {
      a->dw_attr_val = av->dw_attr_val;
      return 1;
    }

  dw_loc_list_ref list, *p;
  switch (AT_class (av))
    {
    case dw_val_class_loc_list:
      p = &list;
      list = NULL;
      for (d = AT_loc_list (av); d != NULL; d = d->dw_loc_next)
	{
	  lv = copy_deref_exprloc (d->expr);
	  if (lv)
	    {
	      *p = new_loc_list (lv, d->begin, d->vbegin, d->end, d->vend, d->section);
	      p = &(*p)->dw_loc_next;
	    }
	  else if (!dwarf_strict && d->expr)
	    return 0;
	}
      if (list == NULL)
	return dwarf_strict ? -1 : 0;
      a->dw_attr_val.val_class = dw_val_class_loc_list;
      gen_llsym (list);
      *AT_loc_list_ptr (a) = list;
      return 1;
    case dw_val_class_loc:
      lv = copy_deref_exprloc (AT_loc (av));
      if (lv == NULL)
	return dwarf_strict ? -1 : 0;
      a->dw_attr_val.v.val_loc = lv;
      return 1;
    default:
      gcc_unreachable ();
    }
}

/* Resolve DW_OP_addr and DW_AT_const_value CONST_STRING arguments to
   an address in .rodata section if the string literal is emitted there,
   or remove the containing location list or replace DW_AT_const_value
   with DW_AT_location and empty location expression, if it isn't found
   in .rodata.  Similarly for SYMBOL_REFs, keep only those that refer
   to something that has been emitted in the current CU.  */

static void
resolve_addr (dw_die_ref die)
{
  dw_die_ref c;
  dw_attr_node *a;
  dw_loc_list_ref *curr, *start, loc;
  unsigned ix;
  bool remove_AT_byte_size = false;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    switch (AT_class (a))
      {
      case dw_val_class_loc_list:
	start = curr = AT_loc_list_ptr (a);
	loc = *curr;
	gcc_assert (loc);
	/* The same list can be referenced more than once.  See if we have
	   already recorded the result from a previous pass.  */
	if (loc->replaced)
	  *curr = loc->dw_loc_next;
	else if (!loc->resolved_addr)
	  {
	    /* As things stand, we do not expect or allow one die to
	       reference a suffix of another die's location list chain.
	       References must be identical or completely separate.
	       There is therefore no need to cache the result of this
	       pass on any list other than the first; doing so
	       would lead to unnecessary writes.  */
	    while (*curr)
	      {
		gcc_assert (!(*curr)->replaced && !(*curr)->resolved_addr);
		if (!resolve_addr_in_expr (a, (*curr)->expr))
		  {
		    dw_loc_list_ref next = (*curr)->dw_loc_next;
                    dw_loc_descr_ref l = (*curr)->expr;

		    if (next && (*curr)->ll_symbol)
		      {
			gcc_assert (!next->ll_symbol);
			next->ll_symbol = (*curr)->ll_symbol;
			next->vl_symbol = (*curr)->vl_symbol;
		      }
                    if (dwarf_split_debug_info)
                      remove_loc_list_addr_table_entries (l);
		    *curr = next;
		  }
		else
		  {
		    mark_base_types ((*curr)->expr);
		    curr = &(*curr)->dw_loc_next;
		  }
	      }
	    if (loc == *start)
	      loc->resolved_addr = 1;
	    else
	      {
		loc->replaced = 1;
		loc->dw_loc_next = *start;
	      }
	  }
	if (!*start)
	  {
	    remove_AT (die, a->dw_attr);
	    ix--;
	  }
	break;
      case dw_val_class_view_list:
	{
	  gcc_checking_assert (a->dw_attr == DW_AT_GNU_locviews);
	  gcc_checking_assert (dwarf2out_locviews_in_attribute ());
	  dw_val_node *llnode
	    = view_list_to_loc_list_val_node (&a->dw_attr_val);
	  /* If we no longer have a loclist, or it no longer needs
	     views, drop this attribute.  */
	  if (!llnode || !llnode->v.val_loc_list->vl_symbol)
	    {
	      remove_AT (die, a->dw_attr);
	      ix--;
	    }
	  break;
	}
      case dw_val_class_loc:
	{
	  dw_loc_descr_ref l = AT_loc (a);
	  /* DW_OP_GNU_variable_value DW_OP_stack_value or
	     DW_OP_GNU_variable_value in DW_AT_string_length can be converted
	     into DW_OP_call4 or DW_OP_call4 DW_OP_deref, which is standard
	     DWARF4 unlike DW_OP_GNU_variable_value.  Or for DWARF5
	     DW_OP_GNU_variable_value DW_OP_stack_value can be replaced
	     with DW_FORM_ref referencing the same DIE as
	     DW_OP_GNU_variable_value used to reference.  */
	  if (a->dw_attr == DW_AT_string_length
	      && l
	      && l->dw_loc_opc == DW_OP_GNU_variable_value
	      && (l->dw_loc_next == NULL
		  || (l->dw_loc_next->dw_loc_next == NULL
		      && l->dw_loc_next->dw_loc_opc == DW_OP_stack_value)))
	    {
	      switch (optimize_string_length (a))
		{
		case -1:
		  remove_AT (die, a->dw_attr);
		  ix--;
		  /* If we drop DW_AT_string_length, we need to drop also
		     DW_AT_{string_length_,}byte_size.  */
		  remove_AT_byte_size = true;
		  continue;
		default:
		  break;
		case 1:
		  /* Even if we keep the optimized DW_AT_string_length,
		     it might have changed AT_class, so process it again.  */
		  ix--;
		  continue;
		}
	    }
	  /* For -gdwarf-2 don't attempt to optimize
	     DW_AT_data_member_location containing
	     DW_OP_plus_uconst - older consumers might
	     rely on it being that op instead of a more complex,
	     but shorter, location description.  */
	  if ((dwarf_version > 2
	       || a->dw_attr != DW_AT_data_member_location
	       || l == NULL
	       || l->dw_loc_opc != DW_OP_plus_uconst
	       || l->dw_loc_next != NULL)
	      && !resolve_addr_in_expr (a, l))
	    {
	      if (dwarf_split_debug_info)
		remove_loc_list_addr_table_entries (l);
	      if (l != NULL
		  && l->dw_loc_next == NULL
		  && l->dw_loc_opc == DW_OP_addr
		  && GET_CODE (l->dw_loc_oprnd1.v.val_addr) == SYMBOL_REF
		  && SYMBOL_REF_DECL (l->dw_loc_oprnd1.v.val_addr)
		  && a->dw_attr == DW_AT_location)
		{
		  tree decl = SYMBOL_REF_DECL (l->dw_loc_oprnd1.v.val_addr);
		  remove_AT (die, a->dw_attr);
		  ix--;
		  optimize_location_into_implicit_ptr (die, decl);
		  break;
		}
	      if (a->dw_attr == DW_AT_string_length)
		/* If we drop DW_AT_string_length, we need to drop also
		   DW_AT_{string_length_,}byte_size.  */
		remove_AT_byte_size = true;
	      remove_AT (die, a->dw_attr);
	      ix--;
	    }
	  else
	    mark_base_types (l);
	}
	break;
      case dw_val_class_addr:
	if (a->dw_attr == DW_AT_const_value
	    && !resolve_one_addr (&a->dw_attr_val.v.val_addr))
	  {
            if (AT_index (a) != NOT_INDEXED)
              remove_addr_table_entry (a->dw_attr_val.val_entry);
	    remove_AT (die, a->dw_attr);
	    ix--;
	  }
	if ((die->die_tag == DW_TAG_call_site
	     && a->dw_attr == DW_AT_call_origin)
	    || (die->die_tag == DW_TAG_GNU_call_site
		&& a->dw_attr == DW_AT_abstract_origin))
	  {
	    tree tdecl = SYMBOL_REF_DECL (a->dw_attr_val.v.val_addr);
	    dw_die_ref tdie = lookup_decl_die (tdecl);
	    dw_die_ref cdie;
	    if (tdie == NULL
		&& DECL_EXTERNAL (tdecl)
		&& DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE
		&& (cdie = lookup_context_die (DECL_CONTEXT (tdecl))))
	      {
		dw_die_ref pdie = cdie;
		/* Make sure we don't add these DIEs into type units.
		   We could emit skeleton DIEs for context (namespaces,
		   outer structs/classes) and a skeleton DIE for the
		   innermost context with DW_AT_signature pointing to the
		   type unit.  See PR78835.  */
		while (pdie && pdie->die_tag != DW_TAG_type_unit)
		  pdie = pdie->die_parent;
		if (pdie == NULL)
		  {
		    /* Creating a full DIE for tdecl is overly expensive and
		       at this point even wrong when in the LTO phase
		       as it can end up generating new type DIEs we didn't
		       output and thus optimize_external_refs will crash.  */
		    tdie = new_die (DW_TAG_subprogram, cdie, NULL_TREE);
		    add_AT_flag (tdie, DW_AT_external, 1);
		    add_AT_flag (tdie, DW_AT_declaration, 1);
		    add_linkage_attr (tdie, tdecl);
		    add_name_and_src_coords_attributes (tdie, tdecl, true);
		    equate_decl_number_to_die (tdecl, tdie);
		  }
	      }
	    if (tdie)
	      {
		a->dw_attr_val.val_class = dw_val_class_die_ref;
		a->dw_attr_val.v.val_die_ref.die = tdie;
		a->dw_attr_val.v.val_die_ref.external = 0;
	      }
	    else
	      {
                if (AT_index (a) != NOT_INDEXED)
                  remove_addr_table_entry (a->dw_attr_val.val_entry);
		remove_AT (die, a->dw_attr);
		ix--;
	      }
	  }
	break;
      default:
	break;
      }

  if (remove_AT_byte_size)
    remove_AT (die, dwarf_version >= 5
		    ? DW_AT_string_length_byte_size
		    : DW_AT_byte_size);

  FOR_EACH_CHILD (die, c, resolve_addr (c));
}

/* Helper routines for optimize_location_lists.
   This pass tries to share identical local lists in .debug_loc
   section.  */

/* Iteratively hash operands of LOC opcode into HSTATE.  */

static void
hash_loc_operands (dw_loc_descr_ref loc, inchash::hash &hstate)
{
  dw_val_ref val1 = &loc->dw_loc_oprnd1;
  dw_val_ref val2 = &loc->dw_loc_oprnd2;

  switch (loc->dw_loc_opc)
    {
    case DW_OP_const4u:
    case DW_OP_const8u:
      if (loc->dtprel)
	goto hash_addr;
      /* FALLTHRU */
    case DW_OP_const1u:
    case DW_OP_const1s:
    case DW_OP_const2u:
    case DW_OP_const2s:
    case DW_OP_const4s:
    case DW_OP_const8s:
    case DW_OP_constu:
    case DW_OP_consts:
    case DW_OP_pick:
    case DW_OP_plus_uconst:
    case DW_OP_breg0:
    case DW_OP_breg1:
    case DW_OP_breg2:
    case DW_OP_breg3:
    case DW_OP_breg4:
    case DW_OP_breg5:
    case DW_OP_breg6:
    case DW_OP_breg7:
    case DW_OP_breg8:
    case DW_OP_breg9:
    case DW_OP_breg10:
    case DW_OP_breg11:
    case DW_OP_breg12:
    case DW_OP_breg13:
    case DW_OP_breg14:
    case DW_OP_breg15:
    case DW_OP_breg16:
    case DW_OP_breg17:
    case DW_OP_breg18:
    case DW_OP_breg19:
    case DW_OP_breg20:
    case DW_OP_breg21:
    case DW_OP_breg22:
    case DW_OP_breg23:
    case DW_OP_breg24:
    case DW_OP_breg25:
    case DW_OP_breg26:
    case DW_OP_breg27:
    case DW_OP_breg28:
    case DW_OP_breg29:
    case DW_OP_breg30:
    case DW_OP_breg31:
    case DW_OP_regx:
    case DW_OP_fbreg:
    case DW_OP_piece:
    case DW_OP_deref_size:
    case DW_OP_xderef_size:
      hstate.add_object (val1->v.val_int);
      break;
    case DW_OP_skip:
    case DW_OP_bra:
      {
	int offset;

	gcc_assert (val1->val_class == dw_val_class_loc);
	offset = val1->v.val_loc->dw_loc_addr - (loc->dw_loc_addr + 3);
	hstate.add_object (offset);
      }
      break;
    case DW_OP_implicit_value:
      hstate.add_object (val1->v.val_unsigned);
      switch (val2->val_class)
	{
	case dw_val_class_const:
	  hstate.add_object (val2->v.val_int);
	  break;
	case dw_val_class_vec:
	  {
	    unsigned int elt_size = val2->v.val_vec.elt_size;
	    unsigned int len = val2->v.val_vec.length;

	    hstate.add_int (elt_size);
	    hstate.add_int (len);
	    hstate.add (val2->v.val_vec.array, len * elt_size);
	  }
	  break;
	case dw_val_class_const_double:
	  hstate.add_object (val2->v.val_double.low);
	  hstate.add_object (val2->v.val_double.high);
	  break;
	case dw_val_class_wide_int:
	  hstate.add (val2->v.val_wide->get_val (),
		      get_full_len (*val2->v.val_wide)
		      * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
	  break;
	case dw_val_class_addr:	
	  inchash::add_rtx (val2->v.val_addr, hstate);
	  break;
	default:
	  gcc_unreachable ();
	}
      break;
    case DW_OP_bregx:
    case DW_OP_bit_piece:
      hstate.add_object (val1->v.val_int);
      hstate.add_object (val2->v.val_int);
      break;
    case DW_OP_addr:
    hash_addr:
      if (loc->dtprel)
	{
	  unsigned char dtprel = 0xd1;
	  hstate.add_object (dtprel);
	}
      inchash::add_rtx (val1->v.val_addr, hstate);
      break;
    case DW_OP_GNU_addr_index:
    case DW_OP_addrx:
    case DW_OP_GNU_const_index:
    case DW_OP_constx:
      {
        if (loc->dtprel)
          {
            unsigned char dtprel = 0xd1;
	    hstate.add_object (dtprel);
          }
        inchash::add_rtx (val1->val_entry->addr.rtl, hstate);
      }
      break;
    case DW_OP_implicit_pointer:
    case DW_OP_GNU_implicit_pointer:
      hstate.add_int (val2->v.val_int);
      break;
    case DW_OP_entry_value:
    case DW_OP_GNU_entry_value:
      hstate.add_object (val1->v.val_loc);
      break;
    case DW_OP_regval_type:
    case DW_OP_deref_type:
    case DW_OP_GNU_regval_type:
    case DW_OP_GNU_deref_type:
      {
	unsigned int byte_size
	  = get_AT_unsigned (val2->v.val_die_ref.die, DW_AT_byte_size);
	unsigned int encoding
	  = get_AT_unsigned (val2->v.val_die_ref.die, DW_AT_encoding);
	hstate.add_object (val1->v.val_int);
	hstate.add_object (byte_size);
	hstate.add_object (encoding);
      }
      break;
    case DW_OP_convert:
    case DW_OP_reinterpret:
    case DW_OP_GNU_convert:
    case DW_OP_GNU_reinterpret:
      if (val1->val_class == dw_val_class_unsigned_const)
	{
	  hstate.add_object (val1->v.val_unsigned);
	  break;
	}
      /* FALLTHRU */
    case DW_OP_const_type:
    case DW_OP_GNU_const_type:
      {
	unsigned int byte_size
	  = get_AT_unsigned (val1->v.val_die_ref.die, DW_AT_byte_size);
	unsigned int encoding
	  = get_AT_unsigned (val1->v.val_die_ref.die, DW_AT_encoding);
	hstate.add_object (byte_size);
	hstate.add_object (encoding);
	if (loc->dw_loc_opc != DW_OP_const_type
	    && loc->dw_loc_opc != DW_OP_GNU_const_type)
	  break;
	hstate.add_object (val2->val_class);
	switch (val2->val_class)
	  {
	  case dw_val_class_const:
	    hstate.add_object (val2->v.val_int);
	    break;
	  case dw_val_class_vec:
	    {
	      unsigned int elt_size = val2->v.val_vec.elt_size;
	      unsigned int len = val2->v.val_vec.length;

	      hstate.add_object (elt_size);
	      hstate.add_object (len);
	      hstate.add (val2->v.val_vec.array, len * elt_size);
	    }
	    break;
	  case dw_val_class_const_double:
	    hstate.add_object (val2->v.val_double.low);
	    hstate.add_object (val2->v.val_double.high);
	    break;
	  case dw_val_class_wide_int:
	    hstate.add (val2->v.val_wide->get_val (),
			get_full_len (*val2->v.val_wide)
			* HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR);
	    break;
	  default:
	    gcc_unreachable ();
	  }
      }
      break;

    default:
      /* Other codes have no operands.  */
      break;
    }
}

/* Iteratively hash the whole DWARF location expression LOC into HSTATE.  */

static inline void
hash_locs (dw_loc_descr_ref loc, inchash::hash &hstate)
{
  dw_loc_descr_ref l;
  bool sizes_computed = false;
  /* Compute sizes, so that DW_OP_skip/DW_OP_bra can be checksummed.  */
  size_of_locs (loc);

  for (l = loc; l != NULL; l = l->dw_loc_next)
    {
      enum dwarf_location_atom opc = l->dw_loc_opc;
      hstate.add_object (opc);
      if ((opc == DW_OP_skip || opc == DW_OP_bra) && !sizes_computed)
	{
	  size_of_locs (loc);
	  sizes_computed = true;
	}
      hash_loc_operands (l, hstate);
    }
}

/* Compute hash of the whole location list LIST_HEAD.  */

static inline void
hash_loc_list (dw_loc_list_ref list_head)
{
  dw_loc_list_ref curr = list_head;
  inchash::hash hstate;

  for (curr = list_head; curr != NULL; curr = curr->dw_loc_next)
    {
      hstate.add (curr->begin, strlen (curr->begin) + 1);
      hstate.add (curr->end, strlen (curr->end) + 1);
      hstate.add_object (curr->vbegin);
      hstate.add_object (curr->vend);
      if (curr->section)
	hstate.add (curr->section, strlen (curr->section) + 1);
      hash_locs (curr->expr, hstate);
    }
  list_head->hash = hstate.end ();
}

/* Return true if X and Y opcodes have the same operands.  */

static inline bool
compare_loc_operands (dw_loc_descr_ref x, dw_loc_descr_ref y)
{
  dw_val_ref valx1 = &x->dw_loc_oprnd1;
  dw_val_ref valx2 = &x->dw_loc_oprnd2;
  dw_val_ref valy1 = &y->dw_loc_oprnd1;
  dw_val_ref valy2 = &y->dw_loc_oprnd2;

  switch (x->dw_loc_opc)
    {
    case DW_OP_const4u:
    case DW_OP_const8u:
      if (x->dtprel)
	goto hash_addr;
      /* FALLTHRU */
    case DW_OP_const1u:
    case DW_OP_const1s:
    case DW_OP_const2u:
    case DW_OP_const2s:
    case DW_OP_const4s:
    case DW_OP_const8s:
    case DW_OP_constu:
    case DW_OP_consts:
    case DW_OP_pick:
    case DW_OP_plus_uconst:
    case DW_OP_breg0:
    case DW_OP_breg1:
    case DW_OP_breg2:
    case DW_OP_breg3:
    case DW_OP_breg4:
    case DW_OP_breg5:
    case DW_OP_breg6:
    case DW_OP_breg7:
    case DW_OP_breg8:
    case DW_OP_breg9:
    case DW_OP_breg10:
    case DW_OP_breg11:
    case DW_OP_breg12:
    case DW_OP_breg13:
    case DW_OP_breg14:
    case DW_OP_breg15:
    case DW_OP_breg16:
    case DW_OP_breg17:
    case DW_OP_breg18:
    case DW_OP_breg19:
    case DW_OP_breg20:
    case DW_OP_breg21:
    case DW_OP_breg22:
    case DW_OP_breg23:
    case DW_OP_breg24:
    case DW_OP_breg25:
    case DW_OP_breg26:
    case DW_OP_breg27:
    case DW_OP_breg28:
    case DW_OP_breg29:
    case DW_OP_breg30:
    case DW_OP_breg31:
    case DW_OP_regx:
    case DW_OP_fbreg:
    case DW_OP_piece:
    case DW_OP_deref_size:
    case DW_OP_xderef_size:
      return valx1->v.val_int == valy1->v.val_int;
    case DW_OP_skip:
    case DW_OP_bra:
      /* If splitting debug info, the use of DW_OP_GNU_addr_index
        can cause irrelevant differences in dw_loc_addr.  */
      gcc_assert (valx1->val_class == dw_val_class_loc
		  && valy1->val_class == dw_val_class_loc
                  && (dwarf_split_debug_info
                      || x->dw_loc_addr == y->dw_loc_addr));
      return valx1->v.val_loc->dw_loc_addr == valy1->v.val_loc->dw_loc_addr;
    case DW_OP_implicit_value:
      if (valx1->v.val_unsigned != valy1->v.val_unsigned
	  || valx2->val_class != valy2->val_class)
	return false;
      switch (valx2->val_class)
	{
	case dw_val_class_const:
	  return valx2->v.val_int == valy2->v.val_int;
	case dw_val_class_vec:
	  return valx2->v.val_vec.elt_size == valy2->v.val_vec.elt_size
		 && valx2->v.val_vec.length == valy2->v.val_vec.length
		 && memcmp (valx2->v.val_vec.array, valy2->v.val_vec.array,
			    valx2->v.val_vec.elt_size
			    * valx2->v.val_vec.length) == 0;
	case dw_val_class_const_double:
	  return valx2->v.val_double.low == valy2->v.val_double.low
		 && valx2->v.val_double.high == valy2->v.val_double.high;
	case dw_val_class_wide_int:
	  return *valx2->v.val_wide == *valy2->v.val_wide;
	case dw_val_class_addr:
	  return rtx_equal_p (valx2->v.val_addr, valy2->v.val_addr);
	default:
	  gcc_unreachable ();
	}
    case DW_OP_bregx:
    case DW_OP_bit_piece:
      return valx1->v.val_int == valy1->v.val_int
	     && valx2->v.val_int == valy2->v.val_int;
    case DW_OP_addr:
    hash_addr:
      return rtx_equal_p (valx1->v.val_addr, valy1->v.val_addr);
    case DW_OP_GNU_addr_index:
    case DW_OP_addrx:
    case DW_OP_GNU_const_index:
    case DW_OP_constx:
      {
        rtx ax1 = valx1->val_entry->addr.rtl;
        rtx ay1 = valy1->val_entry->addr.rtl;
        return rtx_equal_p (ax1, ay1);
      }
    case DW_OP_implicit_pointer:
    case DW_OP_GNU_implicit_pointer:
      return valx1->val_class == dw_val_class_die_ref
	     && valx1->val_class == valy1->val_class
	     && valx1->v.val_die_ref.die == valy1->v.val_die_ref.die
	     && valx2->v.val_int == valy2->v.val_int;
    case DW_OP_entry_value:
    case DW_OP_GNU_entry_value:
      return compare_loc_operands (valx1->v.val_loc, valy1->v.val_loc);
    case DW_OP_const_type:
    case DW_OP_GNU_const_type:
      if (valx1->v.val_die_ref.die != valy1->v.val_die_ref.die
	  || valx2->val_class != valy2->val_class)
	return false;
      switch (valx2->val_class)
	{
	case dw_val_class_const:
	  return valx2->v.val_int == valy2->v.val_int;
	case dw_val_class_vec:
	  return valx2->v.val_vec.elt_size == valy2->v.val_vec.elt_size
		 && valx2->v.val_vec.length == valy2->v.val_vec.length
		 && memcmp (valx2->v.val_vec.array, valy2->v.val_vec.array,
			    valx2->v.val_vec.elt_size
			    * valx2->v.val_vec.length) == 0;
	case dw_val_class_const_double:
	  return valx2->v.val_double.low == valy2->v.val_double.low
		 && valx2->v.val_double.high == valy2->v.val_double.high;
	case dw_val_class_wide_int:
	  return *valx2->v.val_wide == *valy2->v.val_wide;
	default:
	  gcc_unreachable ();
	}
    case DW_OP_regval_type:
    case DW_OP_deref_type:
    case DW_OP_GNU_regval_type:
    case DW_OP_GNU_deref_type:
      return valx1->v.val_int == valy1->v.val_int
	     && valx2->v.val_die_ref.die == valy2->v.val_die_ref.die;
    case DW_OP_convert:
    case DW_OP_reinterpret:
    case DW_OP_GNU_convert:
    case DW_OP_GNU_reinterpret:
      if (valx1->val_class != valy1->val_class)
	return false;
      if (valx1->val_class == dw_val_class_unsigned_const)
	return valx1->v.val_unsigned == valy1->v.val_unsigned;
      return valx1->v.val_die_ref.die == valy1->v.val_die_ref.die;
    case DW_OP_GNU_parameter_ref:
      return valx1->val_class == dw_val_class_die_ref
	     && valx1->val_class == valy1->val_class
	     && valx1->v.val_die_ref.die == valy1->v.val_die_ref.die;
    default:
      /* Other codes have no operands.  */
      return true;
    }
}

/* Return true if DWARF location expressions X and Y are the same.  */

static inline bool
compare_locs (dw_loc_descr_ref x, dw_loc_descr_ref y)
{
  for (; x != NULL && y != NULL; x = x->dw_loc_next, y = y->dw_loc_next)
    if (x->dw_loc_opc != y->dw_loc_opc
	|| x->dtprel != y->dtprel
	|| !compare_loc_operands (x, y))
      break;
  return x == NULL && y == NULL;
}

/* Hashtable helpers.  */

struct loc_list_hasher : nofree_ptr_hash <dw_loc_list_struct>
{
  static inline hashval_t hash (const dw_loc_list_struct *);
  static inline bool equal (const dw_loc_list_struct *,
			    const dw_loc_list_struct *);
};

/* Return precomputed hash of location list X.  */

inline hashval_t
loc_list_hasher::hash (const dw_loc_list_struct *x)
{
  return x->hash;
}

/* Return true if location lists A and B are the same.  */

inline bool
loc_list_hasher::equal (const dw_loc_list_struct *a,
			const dw_loc_list_struct *b)
{
  if (a == b)
    return 1;
  if (a->hash != b->hash)
    return 0;
  for (; a != NULL && b != NULL; a = a->dw_loc_next, b = b->dw_loc_next)
    if (strcmp (a->begin, b->begin) != 0
	|| strcmp (a->end, b->end) != 0
	|| (a->section == NULL) != (b->section == NULL)
	|| (a->section && strcmp (a->section, b->section) != 0)
	|| a->vbegin != b->vbegin || a->vend != b->vend
	|| !compare_locs (a->expr, b->expr))
      break;
  return a == NULL && b == NULL;
}

typedef hash_table<loc_list_hasher> loc_list_hash_type;


/* Recursively optimize location lists referenced from DIE
   children and share them whenever possible.  */

static void
optimize_location_lists_1 (dw_die_ref die, loc_list_hash_type *htab)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;
  dw_loc_list_struct **slot;
  bool drop_locviews = false;
  bool has_locviews = false;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_loc_list)
      {
	dw_loc_list_ref list = AT_loc_list (a);
	/* TODO: perform some optimizations here, before hashing
	   it and storing into the hash table.  */
	hash_loc_list (list);
	slot = htab->find_slot_with_hash (list, list->hash, INSERT);
	if (*slot == NULL)
	  {
	    *slot = list;
	    if (loc_list_has_views (list))
	      gcc_assert (list->vl_symbol);
	    else if (list->vl_symbol)
	      {
		drop_locviews = true;
		list->vl_symbol = NULL;
	      }
	  }
	else
	  {
	    if (list->vl_symbol && !(*slot)->vl_symbol)
	      drop_locviews = true;
	    a->dw_attr_val.v.val_loc_list = *slot;
	  }
      }
    else if (AT_class (a) == dw_val_class_view_list)
      {
	gcc_checking_assert (a->dw_attr == DW_AT_GNU_locviews);
	has_locviews = true;
      }


  if (drop_locviews && has_locviews)
    remove_AT (die, DW_AT_GNU_locviews);

  FOR_EACH_CHILD (die, c, optimize_location_lists_1 (c, htab));
}


/* Recursively assign each location list a unique index into the debug_addr
   section.  */

static void
index_location_lists (dw_die_ref die)
{
  dw_die_ref c;
  dw_attr_node *a;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    if (AT_class (a) == dw_val_class_loc_list)
      {
        dw_loc_list_ref list = AT_loc_list (a);
        dw_loc_list_ref curr;
        for (curr = list; curr != NULL; curr = curr->dw_loc_next)
          {
            /* Don't index an entry that has already been indexed
	       or won't be output.  Make sure skip_loc_list_entry doesn't
	       call size_of_locs, because that might cause circular dependency,
	       index_location_lists requiring address table indexes to be
	       computed, but adding new indexes through add_addr_table_entry
	       and address table index computation requiring no new additions
	       to the hash table.  In the rare case of DWARF[234] >= 64KB
	       location expression, we'll just waste unused address table entry
	       for it.  */
	    if (curr->begin_entry != NULL || skip_loc_list_entry (curr))
              continue;

            curr->begin_entry
	      = add_addr_table_entry (xstrdup (curr->begin), ate_kind_label);
	    if (dwarf_version >= 5 && !HAVE_AS_LEB128)
	      curr->end_entry
		= add_addr_table_entry (xstrdup (curr->end), ate_kind_label);
          }
      }

  FOR_EACH_CHILD (die, c, index_location_lists (c));
}

/* Optimize location lists referenced from DIE
   children and share them whenever possible.  */

static void
optimize_location_lists (dw_die_ref die)
{
  loc_list_hash_type htab (500);
  optimize_location_lists_1 (die, &htab);
}

/* Traverse the limbo die list, and add parent/child links.  The only
   dies without parents that should be here are concrete instances of
   inline functions, and the comp_unit_die.  We can ignore the comp_unit_die.
   For concrete instances, we can get the parent die from the abstract
   instance.  */

static void
flush_limbo_die_list (void)
{
  limbo_die_node *node;

  /* get_context_die calls force_decl_die, which can put new DIEs on the
     limbo list in LTO mode when nested functions are put in a different
     partition than that of their parent function.  */
  while ((node = limbo_die_list))
    {
      dw_die_ref die = node->die;
      limbo_die_list = node->next;

      if (die->die_parent == NULL)
	{
	  dw_die_ref origin = get_AT_ref (die, DW_AT_abstract_origin);

	  if (origin && origin->die_parent)
	    add_child_die (origin->die_parent, die);
	  else if (is_cu_die (die))
	    ;
	  else if (seen_error ())
	    /* It's OK to be confused by errors in the input.  */
	    add_child_die (comp_unit_die (), die);
	  else
	    {
	      /* In certain situations, the lexical block containing a
		 nested function can be optimized away, which results
		 in the nested function die being orphaned.  Likewise
		 with the return type of that nested function.  Force
		 this to be a child of the containing function.

		 It may happen that even the containing function got fully
		 inlined and optimized out.  In that case we are lost and
		 assign the empty child.  This should not be big issue as
		 the function is likely unreachable too.  */
	      gcc_assert (node->created_for);

	      if (DECL_P (node->created_for))
		origin = get_context_die (DECL_CONTEXT (node->created_for));
	      else if (TYPE_P (node->created_for))
		origin = scope_die_for (node->created_for, comp_unit_die ());
	      else
		origin = comp_unit_die ();

	      add_child_die (origin, die);
	    }
	}
    }
}

/* Reset DIEs so we can output them again.  */

static void
reset_dies (dw_die_ref die)
{
  dw_die_ref c;

  /* Remove stuff we re-generate.  */
  die->die_mark = 0;
  die->die_offset = 0;
  die->die_abbrev = 0;
  remove_AT (die, DW_AT_sibling);

  FOR_EACH_CHILD (die, c, reset_dies (c));
}

/* reset_indirect_string removed the references coming from DW_AT_name
   and DW_AT_comp_dir attributes on compilation unit DIEs.  Readd them as
   .debug_line_str strings again.  */

static void
adjust_name_comp_dir (dw_die_ref die)
{
  for (int i = 0; i < 2; i++)
    {
      dwarf_attribute attr_kind = i ? DW_AT_comp_dir : DW_AT_name;
      dw_attr_node *a = get_AT (die, attr_kind);
      if (a == NULL || a->dw_attr_val.val_class != dw_val_class_str)
	continue;

      if (!debug_line_str_hash)
	debug_line_str_hash
	  = hash_table<indirect_string_hasher>::create_ggc (10);

      struct indirect_string_node *node
	= find_AT_string_in_table (a->dw_attr_val.v.val_str->str,
				   debug_line_str_hash);
      set_indirect_string (node);
      node->form = DW_FORM_line_strp;
      a->dw_attr_val.v.val_str = node;
    }
}

/* Output stuff that dwarf requires at the end of every file,
   and generate the DWARF-2 debugging info.  */

static void
dwarf2out_finish (const char *filename)
{
  comdat_type_node *ctnode;
  dw_die_ref main_comp_unit_die;
  unsigned char checksum[16];
  char dl_section_ref[MAX_ARTIFICIAL_LABEL_BYTES];

  /* Generate CTF/BTF debug info.  */
  if ((ctf_debug_info_level > CTFINFO_LEVEL_NONE
       || btf_debuginfo_p ()) && lang_GNU_C ())
    ctf_debug_finish (filename);

  /* Skip emitting DWARF if not required.  */
  if (!dwarf_debuginfo_p ())
    return;

  /* Flush out any latecomers to the limbo party.  */
  flush_limbo_die_list ();

  if (inline_entry_data_table)
    gcc_assert (inline_entry_data_table->is_empty ());

  if (flag_checking)
    {
      verify_die (comp_unit_die ());
      for (limbo_die_node *node = cu_die_list; node; node = node->next)
	verify_die (node->die);
    }

  /* We shouldn't have any symbols with delayed asm names for
     DIEs generated after early finish.  */
  gcc_assert (deferred_asm_name == NULL);

  gen_remaining_tmpl_value_param_die_attribute ();

  if (flag_generate_lto || flag_generate_offload)
    {
      gcc_assert (flag_fat_lto_objects || flag_generate_offload);

      /* Prune stuff so that dwarf2out_finish runs successfully
	 for the fat part of the object.  */
      reset_dies (comp_unit_die ());
      for (limbo_die_node *node = cu_die_list; node; node = node->next)
	reset_dies (node->die);

      hash_table<comdat_type_hasher> comdat_type_table (100);
      for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
	{
	  comdat_type_node **slot
	      = comdat_type_table.find_slot (ctnode, INSERT);

	  /* Don't reset types twice.  */
	  if (*slot != HTAB_EMPTY_ENTRY)
	    continue;

	  /* Remove the pointer to the line table.  */
	  remove_AT (ctnode->root_die, DW_AT_stmt_list);

	  if (debug_info_level >= DINFO_LEVEL_TERSE)
	    reset_dies (ctnode->root_die);

	  *slot = ctnode;
	}

      /* Reset die CU symbol so we don't output it twice.  */
      comp_unit_die ()->die_id.die_symbol = NULL;

      /* Remove DW_AT_macro and DW_AT_stmt_list from the early output.  */
      remove_AT (comp_unit_die (), DW_AT_stmt_list);
      if (have_macinfo)
	remove_AT (comp_unit_die (), DEBUG_MACRO_ATTRIBUTE);

      /* Remove indirect string decisions.  */
      debug_str_hash->traverse<void *, reset_indirect_string> (NULL);
      if (debug_line_str_hash)
	{
	  debug_line_str_hash->traverse<void *, reset_indirect_string> (NULL);
	  debug_line_str_hash = NULL;
	  if (asm_outputs_debug_line_str ())
	    {
	      adjust_name_comp_dir (comp_unit_die ());
	      for (limbo_die_node *node = cu_die_list; node; node = node->next)
		adjust_name_comp_dir (node->die);
	    }
	}
    }

#if ENABLE_ASSERT_CHECKING
  {
    dw_die_ref die = comp_unit_die (), c;
    FOR_EACH_CHILD (die, c, gcc_assert (! c->die_mark));
  }
#endif
  for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
    resolve_addr (ctnode->root_die);
  resolve_addr (comp_unit_die ());
  move_marked_base_types ();

  if (dump_file)
    {
      fprintf (dump_file, "DWARF for %s\n", filename);
      print_die (comp_unit_die (), dump_file);
    }

  /* Initialize sections and labels used for actual assembler output.  */
  unsigned generation = init_sections_and_labels (false);

  /* Traverse the DIE's and add sibling attributes to those DIE's that
     have children.  */
  add_sibling_attributes (comp_unit_die ());
  limbo_die_node *node;
  for (node = cu_die_list; node; node = node->next)
    add_sibling_attributes (node->die);
  for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
    add_sibling_attributes (ctnode->root_die);

  /* When splitting DWARF info, we put some attributes in the
     skeleton compile_unit DIE that remains in the .o, while
     most attributes go in the DWO compile_unit_die.  */
  if (dwarf_split_debug_info)
    {
      limbo_die_node *cu;
      main_comp_unit_die = gen_compile_unit_die (NULL);
      if (dwarf_version >= 5)
	main_comp_unit_die->die_tag = DW_TAG_skeleton_unit;
      cu = limbo_die_list;
      gcc_assert (cu->die == main_comp_unit_die);
      limbo_die_list = limbo_die_list->next;
      cu->next = cu_die_list;
      cu_die_list = cu;
    }
  else
    main_comp_unit_die = comp_unit_die ();

  /* Output a terminator label for the .text section.  */
  switch_to_section (text_section);
  targetm.asm_out.internal_label (asm_out_file, TEXT_END_LABEL, 0);
  if (cold_text_section)
    {
      switch_to_section (cold_text_section);
      targetm.asm_out.internal_label (asm_out_file, COLD_END_LABEL, 0);
    }

  /* We can only use the low/high_pc attributes if all of the code was
     in .text.  */
  if ((!have_multiple_function_sections
       && vec_safe_length (switch_text_ranges) < 2)
      || (dwarf_version < 3 && dwarf_strict))
    {
      const char *end_label = text_end_label;
      if (vec_safe_length (switch_text_ranges) == 1)
	end_label = (*switch_text_ranges)[0];
      /* Don't add if the CU has no associated code.  */
      if (switch_text_ranges)
	add_AT_low_high_pc (main_comp_unit_die, text_section_label,
			    end_label, true);
    }
  else
    {
      unsigned fde_idx;
      dw_fde_ref fde;
      bool range_list_added = false;
      if (switch_text_ranges)
	{
	  const char *prev_loc = text_section_label;
	  const char *loc;
	  unsigned idx;

	  FOR_EACH_VEC_ELT (*switch_text_ranges, idx, loc)
	    if (prev_loc)
	      {
		add_ranges_by_labels (main_comp_unit_die, prev_loc,
				      loc, &range_list_added, true);
		prev_loc = NULL;
	      }
	    else
	      prev_loc = loc;

	  if (prev_loc)
	    add_ranges_by_labels (main_comp_unit_die, prev_loc,
				  text_end_label, &range_list_added, true);
	}

      if (switch_cold_ranges)
	{
	  const char *prev_loc = cold_text_section_label;
	  const char *loc;
	  unsigned idx;

	  FOR_EACH_VEC_ELT (*switch_cold_ranges, idx, loc)
	    if (prev_loc)
	      {
		add_ranges_by_labels (main_comp_unit_die, prev_loc,
				      loc, &range_list_added, true);
		prev_loc = NULL;
	      }
	    else
	      prev_loc = loc;

	  if (prev_loc)
	    add_ranges_by_labels (main_comp_unit_die, prev_loc,
				  cold_end_label, &range_list_added, true);
	}

      FOR_EACH_VEC_ELT (*fde_vec, fde_idx, fde)
	{
	  if (fde->ignored_debug)
	    continue;
	  if (!fde->in_std_section)
            add_ranges_by_labels (main_comp_unit_die, fde->dw_fde_begin,
                                  fde->dw_fde_end, &range_list_added,
                                  true);
	  if (fde->dw_fde_second_begin && !fde->second_in_std_section)
            add_ranges_by_labels (main_comp_unit_die, fde->dw_fde_second_begin,
                                  fde->dw_fde_second_end, &range_list_added,
                                  true);
	}

      if (range_list_added)
	{
	  /* We need to give .debug_loc and .debug_ranges an appropriate
	     "base address".  Use zero so that these addresses become
	     absolute.  Historically, we've emitted the unexpected
	     DW_AT_entry_pc instead of DW_AT_low_pc for this purpose.
	     Emit both to give time for other tools to adapt.  */
          add_AT_addr (main_comp_unit_die, DW_AT_low_pc, const0_rtx, true);
	  if (! dwarf_strict && dwarf_version < 4)
            add_AT_addr (main_comp_unit_die, DW_AT_entry_pc, const0_rtx, true);

	  add_ranges (NULL);
	  have_multiple_function_sections = true;
	}
    }

  /* AIX Assembler inserts the length, so adjust the reference to match the
     offset expected by debuggers.  */
  strcpy (dl_section_ref, debug_line_section_label);
  if (XCOFF_DEBUGGING_INFO)
    strcat (dl_section_ref, DWARF_INITIAL_LENGTH_SIZE_STR);

  if (debug_info_level >= DINFO_LEVEL_TERSE)
    add_AT_lineptr (main_comp_unit_die, DW_AT_stmt_list,
		    dl_section_ref);

  if (have_macinfo)
    add_AT_macptr (comp_unit_die (), DEBUG_MACRO_ATTRIBUTE,
		   macinfo_section_label);

  if (dwarf_split_debug_info)
    {
      if (have_location_lists)
	{
	  /* Since we generate the loclists in the split DWARF .dwo
	     file itself, we don't need to generate a loclists_base
	     attribute for the split compile unit DIE.  That attribute
	     (and using relocatable sec_offset FORMs) isn't allowed
	     for a split compile unit.  Only if the .debug_loclists
	     section was in the main file, would we need to generate a
	     loclists_base attribute here (for the full or skeleton
	     unit DIE).  */

	  /* optimize_location_lists calculates the size of the lists,
	     so index them first, and assign indices to the entries.
	     Although optimize_location_lists will remove entries from
	     the table, it only does so for duplicates, and therefore
	     only reduces ref_counts to 1.  */
	  index_location_lists (comp_unit_die ());
	}

      if (dwarf_version >= 5 && !vec_safe_is_empty (ranges_table))
	index_rnglists ();

      if (addr_index_table != NULL)
        {
          unsigned int index = 0;
          addr_index_table
	    ->traverse_noresize<unsigned int *, index_addr_table_entry>
	    (&index);
        }
    }

  loc_list_idx = 0;
  if (have_location_lists)
    {
      optimize_location_lists (comp_unit_die ());
      /* And finally assign indexes to the entries for -gsplit-dwarf.  */
      if (dwarf_version >= 5 && dwarf_split_debug_info)
	assign_location_list_indexes (comp_unit_die ());
    }

  save_macinfo_strings ();

  if (dwarf_split_debug_info)
    {
      unsigned int index = 0;

      /* Add attributes common to skeleton compile_units and
         type_units.  Because these attributes include strings, it
         must be done before freezing the string table.  Top-level
         skeleton die attrs are added when the skeleton type unit is
         created, so ensure it is created by this point.  */
      add_top_level_skeleton_die_attrs (main_comp_unit_die);
      debug_str_hash->traverse_noresize<unsigned int *, index_string> (&index);
    }

  /* Output all of the compilation units.  We put the main one last so that
     the offsets are available to output_pubnames.  */
  for (node = cu_die_list; node; node = node->next)
    output_comp_unit (node->die, 0, NULL);

  hash_table<comdat_type_hasher> comdat_type_table (100);
  for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
    {
      comdat_type_node **slot = comdat_type_table.find_slot (ctnode, INSERT);

      /* Don't output duplicate types.  */
      if (*slot != HTAB_EMPTY_ENTRY)
        continue;

      /* Add a pointer to the line table for the main compilation unit
         so that the debugger can make sense of DW_AT_decl_file
         attributes.  */
      if (debug_info_level >= DINFO_LEVEL_TERSE)
        add_AT_lineptr (ctnode->root_die, DW_AT_stmt_list,
                        (!dwarf_split_debug_info
                         ? dl_section_ref
                         : debug_skeleton_line_section_label));

      output_comdat_type_unit (ctnode, false);
      *slot = ctnode;
    }

  if (dwarf_split_debug_info)
    {
      int mark;
      struct md5_ctx ctx;

      /* Compute a checksum of the comp_unit to use as the dwo_id.  */
      md5_init_ctx (&ctx);
      mark = 0;
      die_checksum (comp_unit_die (), &ctx, &mark);
      unmark_all_dies (comp_unit_die ());
      md5_finish_ctx (&ctx, checksum);

      if (dwarf_version < 5)
	{
	  /* Use the first 8 bytes of the checksum as the dwo_id,
	     and add it to both comp-unit DIEs.  */
	  add_AT_data8 (main_comp_unit_die, DW_AT_GNU_dwo_id, checksum);
	  add_AT_data8 (comp_unit_die (), DW_AT_GNU_dwo_id, checksum);
	}

      /* Add the base offset of the ranges table to the skeleton
        comp-unit DIE.  */
      if (!vec_safe_is_empty (ranges_table))
	{
	  if (dwarf_version < 5)
	    add_AT_lineptr (main_comp_unit_die, DW_AT_GNU_ranges_base,
			    ranges_section_label);
	}

      output_addr_table ();
    }

  /* Output the main compilation unit if non-empty or if .debug_macinfo
     or .debug_macro will be emitted.  */
  output_comp_unit (comp_unit_die (), have_macinfo,
		    dwarf_split_debug_info ? checksum : NULL);

  if (dwarf_split_debug_info && info_section_emitted)
    output_skeleton_debug_sections (main_comp_unit_die, checksum);

  /* Output the abbreviation table.  */
  if (vec_safe_length (abbrev_die_table) != 1)
    {
      switch_to_section (debug_abbrev_section);
      ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
      output_abbrev_section ();
    }

  /* Output location list section if necessary.  */
  if (have_location_lists)
    {
      char l1[MAX_ARTIFICIAL_LABEL_BYTES];
      char l2[MAX_ARTIFICIAL_LABEL_BYTES];
      /* Output the location lists info.  */
      switch_to_section (debug_loc_section);
      if (dwarf_version >= 5)
	{
	  ASM_GENERATE_INTERNAL_LABEL (l1, DEBUG_LOC_SECTION_LABEL, 2);
	  ASM_GENERATE_INTERNAL_LABEL (l2, DEBUG_LOC_SECTION_LABEL, 3);
	  if (DWARF_INITIAL_LENGTH_SIZE - dwarf_offset_size == 4)
	    dw2_asm_output_data (4, 0xffffffff,
				 "Initial length escape value indicating "
				 "64-bit DWARF extension");
	  dw2_asm_output_delta (dwarf_offset_size, l2, l1,
			    "Length of Location Lists");
	  ASM_OUTPUT_LABEL (asm_out_file, l1);
	  output_dwarf_version ();
	  dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size");
	  dw2_asm_output_data (1, 0, "Segment Size");
	  dw2_asm_output_data (4, dwarf_split_debug_info ? loc_list_idx : 0,
			       "Offset Entry Count");
	}
      ASM_OUTPUT_LABEL (asm_out_file, loc_section_label);
      if (dwarf_version >= 5 && dwarf_split_debug_info)
	{
	  unsigned int save_loc_list_idx = loc_list_idx;
	  loc_list_idx = 0;
	  output_loclists_offsets (comp_unit_die ());
	  gcc_assert (save_loc_list_idx == loc_list_idx);
	}
      output_location_lists (comp_unit_die ());
      if (dwarf_version >= 5)
	ASM_OUTPUT_LABEL (asm_out_file, l2);
    }

  output_pubtables ();

  /* Output the address range information if a CU (.debug_info section)
     was emitted.  We output an empty table even if we had no functions
     to put in it.  This because the consumer has no way to tell the
     difference between an empty table that we omitted and failure to
     generate a table that would have contained data.  */
  if (info_section_emitted)
    {
      switch_to_section (debug_aranges_section);
      output_aranges ();
    }

  /* Output ranges section if necessary.  */
  if (!vec_safe_is_empty (ranges_table))
    {
      if (dwarf_version >= 5)
	{
	  if (dwarf_split_debug_info)
	    {
	      /* We don't know right now whether there are any
		 ranges for .debug_rnglists and any for .debug_rnglists.dwo.
		 Depending on into which of those two belongs the first
		 ranges_table entry, emit that section first and that
		 output_rnglists call will return true if the other kind of
		 ranges needs to be emitted as well.  */
	      bool dwo = (*ranges_table)[0].idx != DW_RANGES_IDX_SKELETON;
	      if (output_rnglists (generation, dwo))
		output_rnglists (generation, !dwo);
	    }
	  else
	    output_rnglists (generation, false);
	}
      else
	output_ranges ();
    }

  /* Have to end the macro section.  */
  if (have_macinfo)
    {
      switch_to_section (debug_macinfo_section);
      ASM_OUTPUT_LABEL (asm_out_file, macinfo_section_label);
      output_macinfo (!dwarf_split_debug_info ? debug_line_section_label
		      : debug_skeleton_line_section_label, false);
      dw2_asm_output_data (1, 0, "End compilation unit");
    }

  /* Output the source line correspondence table.  We must do this
     even if there is no line information.  Otherwise, on an empty
     translation unit, we will generate a present, but empty,
     .debug_info section.  IRIX 6.5 `nm' will then complain when
     examining the file.  This is done late so that any filenames
     used by the debug_info section are marked as 'used'.  */
  switch_to_section (debug_line_section);
  ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label);
  if (! output_asm_line_debug_info ())
    output_line_info (false);

  if (dwarf_split_debug_info && info_section_emitted)
    {
      switch_to_section (debug_skeleton_line_section);
      ASM_OUTPUT_LABEL (asm_out_file, debug_skeleton_line_section_label);
      output_line_info (true);
    }

  /* If we emitted any indirect strings, output the string table too.  */
  if (debug_str_hash || skeleton_debug_str_hash)
    output_indirect_strings ();
  if (debug_line_str_hash)
    {
      switch_to_section (debug_line_str_section);
      const enum dwarf_form form = DW_FORM_line_strp;
      debug_line_str_hash->traverse<enum dwarf_form,
				    output_indirect_string> (form);
    }

  /* ??? Move lvugid out of dwarf2out_source_line and reset it too?  */
  symview_upper_bound = 0;
  if (zero_view_p)
    bitmap_clear (zero_view_p);
}

/* Returns a hash value for X (which really is a variable_value_struct).  */

inline hashval_t
variable_value_hasher::hash (variable_value_struct *x)
{
  return (hashval_t) x->decl_id;
}

/* Return nonzero if decl_id of variable_value_struct X is the same as
   UID of decl Y.  */

inline bool
variable_value_hasher::equal (variable_value_struct *x, tree y)
{
  return x->decl_id == DECL_UID (y);
}

/* Helper function for resolve_variable_value, handle
   DW_OP_GNU_variable_value in one location expression.
   Return true if exprloc has been changed into loclist.  */

static bool
resolve_variable_value_in_expr (dw_attr_node *a, dw_loc_descr_ref loc)
{
  dw_loc_descr_ref next;
  for (dw_loc_descr_ref prev = NULL; loc; prev = loc, loc = next)
    {
      next = loc->dw_loc_next;
      if (loc->dw_loc_opc != DW_OP_GNU_variable_value
	  || loc->dw_loc_oprnd1.val_class != dw_val_class_decl_ref)
	continue;

      tree decl = loc->dw_loc_oprnd1.v.val_decl_ref;
      if (DECL_CONTEXT (decl) != current_function_decl)
	continue;

      dw_die_ref ref = lookup_decl_die (decl);
      if (ref)
	{
	  loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	  loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
	  loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
	  continue;
	}
      dw_loc_list_ref l = loc_list_from_tree (decl, 0, NULL);
      if (l == NULL)
	continue;
      if (l->dw_loc_next)
	{
	  if (AT_class (a) != dw_val_class_loc)
	    continue;
	  switch (a->dw_attr)
	    {
	    /* Following attributes allow both exprloc and loclist
	       classes, so we can change them into a loclist.  */
	    case DW_AT_location:
	    case DW_AT_string_length:
	    case DW_AT_return_addr:
	    case DW_AT_data_member_location:
	    case DW_AT_frame_base:
	    case DW_AT_segment:
	    case DW_AT_static_link:
	    case DW_AT_use_location:
	    case DW_AT_vtable_elem_location:
	      if (prev)
		{
		  prev->dw_loc_next = NULL;
		  prepend_loc_descr_to_each (l, AT_loc (a));
		}
	      if (next)
		add_loc_descr_to_each (l, next);
	      a->dw_attr_val.val_class = dw_val_class_loc_list;
	      a->dw_attr_val.val_entry = NULL;
	      a->dw_attr_val.v.val_loc_list = l;
	      have_location_lists = true;
	      return true;
	    /* Following attributes allow both exprloc and reference,
	       so if the whole expression is DW_OP_GNU_variable_value alone
	       we could transform it into reference.  */
	    case DW_AT_byte_size:
	    case DW_AT_bit_size:
	    case DW_AT_lower_bound:
	    case DW_AT_upper_bound:
	    case DW_AT_bit_stride:
	    case DW_AT_count:
	    case DW_AT_allocated:
	    case DW_AT_associated:
	    case DW_AT_byte_stride:
	      if (prev == NULL && next == NULL)
		break;
	      /* FALLTHRU */
	    default:
	      if (dwarf_strict)
		continue;
	      break;
	    }
	  /* Create DW_TAG_variable that we can refer to.  */
	  gen_decl_die (decl, NULL_TREE, NULL,
			lookup_decl_die (current_function_decl));
	  ref = lookup_decl_die (decl);
	  if (ref)
	    {
	      loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	      loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
	      loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
	    }
	  continue;
	}
      if (prev)
	{
	  prev->dw_loc_next = l->expr;
	  add_loc_descr (&prev->dw_loc_next, next);
	  free_loc_descr (loc, NULL);
	  next = prev->dw_loc_next;
	}
      else
	{
	  memcpy (loc, l->expr, sizeof (dw_loc_descr_node));
	  add_loc_descr (&loc, next);
	  next = loc;
	}
      loc = prev;
    }
  return false;
}

/* Attempt to resolve DW_OP_GNU_variable_value using loc_list_from_tree.  */

static void
resolve_variable_value (dw_die_ref die)
{
  dw_attr_node *a;
  dw_loc_list_ref loc;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    switch (AT_class (a))
      {
      case dw_val_class_loc:
	if (!resolve_variable_value_in_expr (a, AT_loc (a)))
	  break;
	/* FALLTHRU */
      case dw_val_class_loc_list:
	loc = AT_loc_list (a);
	gcc_assert (loc);
	for (; loc; loc = loc->dw_loc_next)
	  resolve_variable_value_in_expr (a, loc->expr);
	break;
      default:
	break;
      }
}

/* Attempt to optimize DW_OP_GNU_variable_value refering to
   temporaries in the current function.  */

static void
resolve_variable_values (void)
{
  if (!variable_value_hash || !current_function_decl)
    return;

  struct variable_value_struct *node
    = variable_value_hash->find_with_hash (current_function_decl,
					   DECL_UID (current_function_decl));

  if (node == NULL)
    return;

  unsigned int i;
  dw_die_ref die;
  FOR_EACH_VEC_SAFE_ELT (node->dies, i, die)
    resolve_variable_value (die);
}

/* Helper function for note_variable_value, handle one location
   expression.  */

static void
note_variable_value_in_expr (dw_die_ref die, dw_loc_descr_ref loc)
{
  for (; loc; loc = loc->dw_loc_next)
    if (loc->dw_loc_opc == DW_OP_GNU_variable_value
	&& loc->dw_loc_oprnd1.val_class == dw_val_class_decl_ref)
      {
	tree decl = loc->dw_loc_oprnd1.v.val_decl_ref;
	dw_die_ref ref = lookup_decl_die (decl);
	if (! ref && (flag_generate_lto || flag_generate_offload))
	  {
	    /* ???  This is somewhat a hack because we do not create DIEs
	       for variables not in BLOCK trees early but when generating
	       early LTO output we need the dw_val_class_decl_ref to be
	       fully resolved.  For fat LTO objects we'd also like to
	       undo this after LTO dwarf output.  */
	    gcc_assert (DECL_CONTEXT (decl));
	    dw_die_ref ctx = lookup_decl_die (DECL_CONTEXT (decl));
	    gcc_assert (ctx != NULL);
	    gen_decl_die (decl, NULL_TREE, NULL, ctx);
	    ref = lookup_decl_die (decl);
	    gcc_assert (ref != NULL);
	  }
	if (ref)
	  {
	    loc->dw_loc_oprnd1.val_class = dw_val_class_die_ref;
	    loc->dw_loc_oprnd1.v.val_die_ref.die = ref;
	    loc->dw_loc_oprnd1.v.val_die_ref.external = 0;
	    continue;
	  }
	if (VAR_P (decl)
	    && DECL_CONTEXT (decl)
	    && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL
	    && lookup_decl_die (DECL_CONTEXT (decl)))
	  {
	    if (!variable_value_hash)
	      variable_value_hash
		= hash_table<variable_value_hasher>::create_ggc (10);

	    tree fndecl = DECL_CONTEXT (decl);
	    struct variable_value_struct *node;
	    struct variable_value_struct **slot
	      = variable_value_hash->find_slot_with_hash (fndecl,
							  DECL_UID (fndecl),
							  INSERT);
	    if (*slot == NULL)
	      {
		node = ggc_cleared_alloc<variable_value_struct> ();
		node->decl_id = DECL_UID (fndecl);
		*slot = node;
	      }
	    else
	      node = *slot;

	    vec_safe_push (node->dies, die);
	  }
      }
}

/* Walk the tree DIE and note DIEs with DW_OP_GNU_variable_value still
   with dw_val_class_decl_ref operand.  */

static void
note_variable_value (dw_die_ref die)
{
  dw_die_ref c;
  dw_attr_node *a;
  dw_loc_list_ref loc;
  unsigned ix;

  FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a)
    switch (AT_class (a))
      {
      case dw_val_class_loc_list:
	loc = AT_loc_list (a);
	gcc_assert (loc);
	if (!loc->noted_variable_value)
	  {
	    loc->noted_variable_value = 1;
	    for (; loc; loc = loc->dw_loc_next)
	      note_variable_value_in_expr (die, loc->expr);
	  }
	break;
      case dw_val_class_loc:
	note_variable_value_in_expr (die, AT_loc (a));
	break;
      default:
	break;
      }

  /* Mark children.  */
  FOR_EACH_CHILD (die, c, note_variable_value (c));
}

/* Process DWARF dies for CTF generation.  */

static void
ctf_debug_do_cu (dw_die_ref die)
{
  dw_die_ref c;

  if (!ctf_do_die (die))
    return;

  FOR_EACH_CHILD (die, c, ctf_do_die (c));
}

/* Perform any cleanups needed after the early debug generation pass
   has run.  */

static void
dwarf2out_early_finish (const char *filename)
{
  comdat_type_node *ctnode;
  set_early_dwarf s;
  char dl_section_ref[MAX_ARTIFICIAL_LABEL_BYTES];

  /* PCH might result in DW_AT_producer string being restored from the
     header compilation, so always fill it with empty string initially
     and overwrite only here.  */
  dw_attr_node *producer = get_AT (comp_unit_die (), DW_AT_producer);

  if (dwarf_record_gcc_switches)
    producer_string = gen_producer_string (lang_hooks.name,
					   save_decoded_options,
					   save_decoded_options_count);
  else
    producer_string = concat (lang_hooks.name, " ", version_string, NULL);

  producer->dw_attr_val.v.val_str->refcount--;
  producer->dw_attr_val.v.val_str = find_AT_string (producer_string);

  /* Add the name for the main input file now.  We delayed this from
     dwarf2out_init to avoid complications with PCH.  */
  add_filename_attribute (comp_unit_die (), remap_debug_filename (filename));
  add_comp_dir_attribute (comp_unit_die ());

  /* With LTO early dwarf was really finished at compile-time, so make
     sure to adjust the phase after annotating the LTRANS CU DIE.  */
  if (in_lto_p)
    {
      early_dwarf_finished = true;
      if (dump_file)
	{
	  fprintf (dump_file, "LTO EARLY DWARF for %s\n", filename);
	  print_die (comp_unit_die (), dump_file);
	}
      return;
    }

  /* Walk through the list of incomplete types again, trying once more to
     emit full debugging info for them.  */
  retry_incomplete_types ();

  gen_scheduled_generic_parms_dies ();
  gen_remaining_tmpl_value_param_die_attribute ();

  /* The point here is to flush out the limbo list so that it is empty
     and we don't need to stream it for LTO.  */
  flush_limbo_die_list ();

  /* Add DW_AT_linkage_name for all deferred DIEs.  */
  for (limbo_die_node *node = deferred_asm_name; node; node = node->next)
    {
      tree decl = node->created_for;
      if (DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl)
	  /* A missing DECL_ASSEMBLER_NAME can be a constant DIE that
	     ended up in deferred_asm_name before we knew it was
	     constant and never written to disk.  */
	  && DECL_ASSEMBLER_NAME (decl))
	{
	  add_linkage_attr (node->die, decl);
	  move_linkage_attr (node->die);
	}
    }
  deferred_asm_name = NULL;

  if (flag_eliminate_unused_debug_types)
    prune_unused_types ();

  /* Generate separate COMDAT sections for type DIEs. */
  if (use_debug_types)
    {
      break_out_comdat_types (comp_unit_die ());

      /* Each new type_unit DIE was added to the limbo die list when created.
         Since these have all been added to comdat_type_list, clear the
         limbo die list.  */
      limbo_die_list = NULL;

      /* For each new comdat type unit, copy declarations for incomplete
         types to make the new unit self-contained (i.e., no direct
         references to the main compile unit).  */
      for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
        copy_decls_for_unworthy_types (ctnode->root_die);
      copy_decls_for_unworthy_types (comp_unit_die ());

      /* In the process of copying declarations from one unit to another,
         we may have left some declarations behind that are no longer
         referenced.  Prune them.  */
      prune_unused_types ();
    }

  /* Traverse the DIE's and note DIEs with DW_OP_GNU_variable_value still
     with dw_val_class_decl_ref operand.  */
  note_variable_value (comp_unit_die ());
  for (limbo_die_node *node = cu_die_list; node; node = node->next)
    note_variable_value (node->die);
  for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
    note_variable_value (ctnode->root_die);
  for (limbo_die_node *node = limbo_die_list; node; node = node->next)
    note_variable_value (node->die);

  /* The AT_pubnames attribute needs to go in all skeleton dies, including
     both the main_cu and all skeleton TUs.  Making this call unconditional
     would end up either adding a second copy of the AT_pubnames attribute, or
     requiring a special case in add_top_level_skeleton_die_attrs.  */
  if (!dwarf_split_debug_info)
    add_AT_pubnames (comp_unit_die ());

  /* The early debug phase is now finished.  */
  early_dwarf_finished = true;
  if (dump_file)
    {
      fprintf (dump_file, "EARLY DWARF for %s\n", filename);
      print_die (comp_unit_die (), dump_file);
    }

  /* Generate CTF/BTF debug info.  */
  if ((ctf_debug_info_level > CTFINFO_LEVEL_NONE
       || btf_debuginfo_p ()) && lang_GNU_C ())
    {
      ctf_debug_init ();
      ctf_debug_do_cu (comp_unit_die ());
      for (limbo_die_node *node = limbo_die_list; node; node = node->next)
	ctf_debug_do_cu (node->die);
      /* Post process the debug data in the CTF container if necessary.  */
      ctf_debug_init_postprocess (btf_debuginfo_p ());

      ctf_debug_early_finish (filename);
    }

  /* Do not generate DWARF assembler now when not producing LTO bytecode.  */
  if ((!flag_generate_lto && !flag_generate_offload)
      /* FIXME: Disable debug info generation for (PE-)COFF targets since the
	 copy_lto_debug_sections operation of the simple object support in
	 libiberty is not implemented for them yet.  */
      || TARGET_PECOFF || TARGET_COFF)
    return;

  /* Now as we are going to output for LTO initialize sections and labels
     to the LTO variants.  We don't need a random-seed postfix as other
     LTO sections as linking the LTO debug sections into one in a partial
     link is fine.  */
  init_sections_and_labels (true);

  /* The output below is modeled after dwarf2out_finish with all
     location related output removed and some LTO specific changes.
     Some refactoring might make both smaller and easier to match up.  */

  for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
    mark_base_types (ctnode->root_die);
  mark_base_types (comp_unit_die ());
  move_marked_base_types ();

  /* Traverse the DIE's and add sibling attributes to those DIE's
     that have children.  */
  add_sibling_attributes (comp_unit_die ());
  for (limbo_die_node *node = limbo_die_list; node; node = node->next)
    add_sibling_attributes (node->die);
  for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
    add_sibling_attributes (ctnode->root_die);

  /* AIX Assembler inserts the length, so adjust the reference to match the
     offset expected by debuggers.  */
  strcpy (dl_section_ref, debug_line_section_label);
  if (XCOFF_DEBUGGING_INFO)
    strcat (dl_section_ref, DWARF_INITIAL_LENGTH_SIZE_STR);

  if (debug_info_level >= DINFO_LEVEL_TERSE)
    add_AT_lineptr (comp_unit_die (), DW_AT_stmt_list, dl_section_ref);

  if (have_macinfo)
    add_AT_macptr (comp_unit_die (), DEBUG_MACRO_ATTRIBUTE,
		   macinfo_section_label);

  save_macinfo_strings ();

  if (dwarf_split_debug_info)
    {
      unsigned int index = 0;
      debug_str_hash->traverse_noresize<unsigned int *, index_string> (&index);
    }

  /* Output all of the compilation units.  We put the main one last so that
     the offsets are available to output_pubnames.  */
  for (limbo_die_node *node = limbo_die_list; node; node = node->next)
    output_comp_unit (node->die, 0, NULL);

  hash_table<comdat_type_hasher> comdat_type_table (100);
  for (ctnode = comdat_type_list; ctnode != NULL; ctnode = ctnode->next)
    {
      comdat_type_node **slot = comdat_type_table.find_slot (ctnode, INSERT);

      /* Don't output duplicate types.  */
      if (*slot != HTAB_EMPTY_ENTRY)
        continue;

      /* Add a pointer to the line table for the main compilation unit
         so that the debugger can make sense of DW_AT_decl_file
         attributes.  */
      if (debug_info_level >= DINFO_LEVEL_TERSE)
        add_AT_lineptr (ctnode->root_die, DW_AT_stmt_list,
                        (!dwarf_split_debug_info
                         ? debug_line_section_label
                         : debug_skeleton_line_section_label));

      output_comdat_type_unit (ctnode, true);
      *slot = ctnode;
    }

  /* Stick a unique symbol to the main debuginfo section.  */
  compute_comp_unit_symbol (comp_unit_die ());

  /* Output the main compilation unit.  We always need it if only for
     the CU symbol.  */
  output_comp_unit (comp_unit_die (), true, NULL);

  /* Output the abbreviation table.  */
  if (vec_safe_length (abbrev_die_table) != 1)
    {
      switch_to_section (debug_abbrev_section);
      ASM_OUTPUT_LABEL (asm_out_file, abbrev_section_label);
      output_abbrev_section ();
    }

  /* Have to end the macro section.  */
  if (have_macinfo)
    {
      /* We have to save macinfo state if we need to output it again
	 for the FAT part of the object.  */
      vec<macinfo_entry, va_gc> *saved_macinfo_table = macinfo_table;
      if (flag_fat_lto_objects)
	macinfo_table = macinfo_table->copy ();

      switch_to_section (debug_macinfo_section);
      ASM_OUTPUT_LABEL (asm_out_file, macinfo_section_label);
      output_macinfo (debug_line_section_label, true);
      dw2_asm_output_data (1, 0, "End compilation unit");

      if (flag_fat_lto_objects)
	{
	  vec_free (macinfo_table);
	  macinfo_table = saved_macinfo_table;
	}
    }

  /* Emit a skeleton debug_line section.  */
  switch_to_section (debug_line_section);
  ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label);
  output_line_info (true);

  /* If we emitted any indirect strings, output the string table too.  */
  if (debug_str_hash || skeleton_debug_str_hash)
    output_indirect_strings ();
  if (debug_line_str_hash)
    {
      switch_to_section (debug_line_str_section);
      const enum dwarf_form form = DW_FORM_line_strp;
      debug_line_str_hash->traverse<enum dwarf_form,
				    output_indirect_string> (form);
    }

  /* Switch back to the text section.  */
  switch_to_section (text_section);
}

/* Reset all state within dwarf2out.c so that we can rerun the compiler
   within the same process.  For use by toplev::finalize.  */

void
dwarf2out_c_finalize (void)
{
  last_var_location_insn = NULL;
  cached_next_real_insn = NULL;
  used_rtx_array = NULL;
  incomplete_types = NULL;
  debug_info_section = NULL;
  debug_skeleton_info_section = NULL;
  debug_abbrev_section = NULL;
  debug_skeleton_abbrev_section = NULL;
  debug_aranges_section = NULL;
  debug_addr_section = NULL;
  debug_macinfo_section = NULL;
  debug_line_section = NULL;
  debug_skeleton_line_section = NULL;
  debug_loc_section = NULL;
  debug_pubnames_section = NULL;
  debug_pubtypes_section = NULL;
  debug_str_section = NULL;
  debug_line_str_section = NULL;
  debug_str_dwo_section = NULL;
  debug_str_offsets_section = NULL;
  debug_ranges_section = NULL;
  debug_ranges_dwo_section = NULL;
  debug_frame_section = NULL;
  fde_vec = NULL;
  debug_str_hash = NULL;
  debug_line_str_hash = NULL;
  skeleton_debug_str_hash = NULL;
  dw2_string_counter = 0;
  have_multiple_function_sections = false;
  in_text_section_p = false;
  cold_text_section = NULL;
  last_text_label = NULL;
  last_cold_label = NULL;
  switch_text_ranges = NULL;
  switch_cold_ranges = NULL;
  current_unit_personality = NULL;

  early_dwarf = false;
  early_dwarf_finished = false;

  next_die_offset = 0;
  single_comp_unit_die = NULL;
  comdat_type_list = NULL;
  limbo_die_list = NULL;
  file_table = NULL;
  decl_die_table = NULL;
  common_block_die_table = NULL;
  decl_loc_table = NULL;
  call_arg_locations = NULL;
  call_arg_loc_last = NULL;
  call_site_count = -1;
  tail_call_site_count = -1;
  cached_dw_loc_list_table = NULL;
  abbrev_die_table = NULL;
  delete dwarf_proc_stack_usage_map;
  dwarf_proc_stack_usage_map = NULL;
  line_info_label_num = 0;
  cur_line_info_table = NULL;
  text_section_line_info = NULL;
  cold_text_section_line_info = NULL;
  separate_line_info = NULL;
  info_section_emitted = false;
  pubname_table = NULL;
  pubtype_table = NULL;
  macinfo_table = NULL;
  ranges_table = NULL;
  ranges_by_label = NULL;
  rnglist_idx = 0;
  have_location_lists = false;
  loclabel_num = 0;
  poc_label_num = 0;
  last_emitted_file = NULL;
  label_num = 0;
  tmpl_value_parm_die_table = NULL;
  generic_type_instances = NULL;
  frame_pointer_fb_offset = 0;
  frame_pointer_fb_offset_valid = false;
  base_types.release ();
  XDELETEVEC (producer_string);
  producer_string = NULL;
  output_line_info_generation = 0;
  init_sections_and_labels_generation = 0;
}

#include "gt-dwarf2out.h"
