/* Output Dwarf2 format symbol table information from GCC.
   Copyright (C) 1992-2022 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.cc 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);
    }
}

static void
build_breg_loc (struct dw_loc_descr_node **head, unsigned int regno)
{
  if (regno <= 31)
    add_loc_descr (head, new_loc_descr ((enum dwarf_location_atom)
					(DW_OP_breg0 + regno),  0, 0));
  else
    add_loc_descr (head, new_loc_descr (DW_OP_bregx, regno, 0));
}

/* Build a dwarf location for a cfa_reg spanning multiple
   consecutive registers.  */

struct dw_loc_descr_node *
build_span_loc (struct cfa_reg reg)
{
  struct dw_loc_descr_node *head = NULL;

  gcc_assert (reg.span_width > 0);
  gcc_assert (reg.span > 1);

  /* Start from the highest number register as it goes in the upper bits.  */
  unsigned int regno = reg.reg + reg.span - 1;
  build_breg_loc (&head, regno);

  /* Deal with the remaining registers in the span.  */
  for (int i = reg.span - 2; i >= 0; i--)
    {
      add_loc_descr (&head, int_loc_descriptor (reg.span_width * 8));
      add_loc_descr (&head, new_loc_descr (DW_OP_shl, 0, 0));
      regno--;
      build_breg_loc (&head, regno);
      add_loc_descr (&head, new_loc_descr (DW_OP_plus, 0, 0));
    }
  return head;
}

/* 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->reg.span > 1)
    {
      head = build_span_loc (cfa->reg);

      if (maybe_ne (offset, 0))
	  loc_descr_plus_const (&head, offset);
    }
  else if (cfa->indirect)
    {
      head = new_reg_loc_descr (cfa->reg.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.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.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, machine_mode, 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

/* 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++;

      int block_num = r->num;
      if ((HAVE_AS_LEB128 || block_num < 0)
	  && !have_multiple_function_sections)
	continue;
      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 = NULL;
  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 ();
    }
}

/* 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 = ARRAY_SIZE (dwarf_qual_info);

/* 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;
}

/* If TYPE is long double or complex long double that
   should be emitted as artificial typedef to _Float128 or
   complex _Float128, return the type it should be emitted as.
   This is done in case the target already supports 16-byte
   composite floating point type (ibm_extended_format).  */

static tree
long_double_as_float128 (tree type)
{
  if (type != long_double_type_node
      && type != complex_long_double_type_node)
    return NULL_TREE;

  machine_mode mode, fmode;
  if (TREE_CODE (type) == COMPLEX_TYPE)
    mode = TYPE_MODE (TREE_TYPE (type));
  else
    mode = TYPE_MODE (type);
  if (known_eq (GET_MODE_SIZE (mode), 16) && !MODE_COMPOSITE_P (mode))
    FOR_EACH_MODE_IN_CLASS (fmode, MODE_FLOAT)
      if (known_eq (GET_MODE_SIZE (fmode), 16)
          && MODE_COMPOSITE_P (fmode))
	{
	  if (type == long_double_type_node)
	    {
	      if (float128_type_node
		  && (TYPE_MODE (float128_type_node)
		      == TYPE_MODE (type)))
		return float128_type_node;
	      return NULL_TREE;
	    }
	  for (int i = 0; i < NUM_FLOATN_NX_TYPES; i++)
	    if (COMPLEX_FLOATN_NX_TYPE_NODE (i) != NULL_TREE
		&& (TYPE_MODE (COMPLEX_FLOATN_NX_TYPE_NODE (i))
		    == TYPE_MODE (type)))
	      return COMPLEX_FLOATN_NX_TYPE_NODE (i);
	}

  return NULL_TREE;
}

/* 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))
    {
      /* If a target supports long double as different floating point
	 modes with the same 16-byte size, use normal DW_TAG_base_type
	 only for the composite (ibm_extended_real_format) type and
	 for the other for the time being emit instead a "_Float128"
	 or "complex _Float128" DW_TAG_base_type and a "long double"
	 or "complex long double" typedef to it.  */
      if (tree other_type = long_double_as_float128 (type))
	{
	  dw_die_ref other_die;
	  if (TYPE_NAME (other_type))
	    other_die
	      = modified_type_die (other_type, TYPE_UNQUALIFIED, reverse,
				   context_die);
	  else
	    {
	      other_die = base_type_die (type, reverse);
	      add_child_die (comp_unit_die (), other_die);
	      add_name_attribute (other_die,
				  TREE_CODE (type) == COMPLEX_TYPE
				  ? "complex _Float128" : "_Float128");
	    }
	  mod_type_die = new_die_raw (DW_TAG_typedef);
	  add_AT_die_ref (mod_type_die, DW_AT_type, other_die);
	}
      else
	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);
      if (XEXP (rtl, 0) == XEXP (rtl, 1))
	{
	  if (op0 == 0)
	    break;
	  mem_loc_result = op0;
	  add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_dup, 0, 0));
	  add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
	  break;
	}
      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.cc, 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:
      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 (DW_OP_lit0, 0, 0));
      add_loc_descr_to_each (list_ret, new_loc_descr (DW_OP_eq, 0, 0));
      break;

    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);
	/* Likewise, swap the operands for a logically negated condition.  */
	else if (TREE_CODE (TREE_OPERAND (loc, 0)) == TRUTH_NOT_EXPR)
	  {
	    lhs = loc_descriptor_from_tree (TREE_OPERAND (loc, 2), 0, context);
	    rhs = loc_list_from_tree_1 (TREE_OPERAND (loc, 1), 0, context);
	    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
      && DECL_BIT_FIELD_TYPE (decl)
      && 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, machine_mode mode, rtx rtl)
{
  scalar_mode int_mode;

  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:
      if (is_int_mode (mode, &int_mode)
	  && (GET_MODE_PRECISION (int_mode)
	      & (HOST_BITS_PER_WIDE_INT - 1)) == 0)
	{
	  wide_int w = rtx_mode_t (rtl, int_mode);
	  add_AT_wide (die, DW_AT_const_value, w);
	  return true;
	}
      return false;

    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, mode, 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 ();
    }
}

/* 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!
     If this changes, please adjust tree_add_const_value_attribute
     so that for early_dwarf it will for such initializers mangle referenced
     decls.  */
  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.cc 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.cc 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, DECL_MODE (decl), 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, DECL_MODE (decl), 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);
}

/* Mangle referenced decls.  */
static tree
mangle_referenced_decls (tree *tp, int *walk_subtrees, void *)
{
  if (! EXPR_P (*tp) && ! CONSTANT_CLASS_P (*tp))
    *walk_subtrees = 0;

  if (VAR_OR_FUNCTION_DECL_P (*tp))
    assign_assembler_name_if_needed (*tp);

  return NULL_TREE;
}

/* 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);

  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;
	}
    }
  if (!early_dwarf)
    {
      rtx rtl = rtl_for_decl_init (init, type);
      if (rtl)
	return add_const_value_attribute (die, TYPE_MODE (type), rtl);
    }
  else
    {
      /* For early_dwarf force mangling of all referenced symbols.  */
      tree initializer = init;
      STRIP_NOPS (initializer);
      /* rtl_for_decl_init punts on other aggregates, and complex values.  */
      if (AGGREGATE_TYPE_P (type)
	  || (TREE_CODE (initializer) == VIEW_CONVERT_EXPR
	      && AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (initializer, 0))))
	  || TREE_CODE (type) == COMPLEX_TYPE)
	;
      else if (initializer_constant_valid_p (initializer, type))
	walk_tree (&initializer, mangle_referenced_decls, NULL, NULL);
    }
  /* 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.set_by_dwreg (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.cc 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.cc and cse.cc) 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.cc 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.cc
   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_item, 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.cc) 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.cc.  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.cc.  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
  base_types.truncate (0);
  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.  */

  base_types.truncate (0);
  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.cc so that we can rerun the compiler
   within the same process.  For use by toplev::finalize.  */

void
dwarf2out_cc_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"
