static void
compile_cplus_convert_struct_or_union_methods (compile_cplus_instance *instance,
					       struct type *type,
					       gcc_type class_type)
{
  for (int i = 0; i < TYPE_NFN_FIELDS (type); ++i)
    {
      struct fn_field *methods = TYPE_FN_FIELDLIST1 (type, i);
      gdb::unique_xmalloc_ptr<char> overloaded_name
	= compile_cplus_instance::decl_name (TYPE_FN_FIELDLIST_NAME (type, i));

      /* Loop through the fieldlist, adding decls to the compiler's
	 representation of the class.  */
      for (int j = 0; j < TYPE_FN_FIELDLIST_LENGTH (type, i); ++j)
	{
	  /* Skip artificial methods.  */
	  if (TYPE_FN_FIELD_ARTIFICIAL (methods, j))
	    continue;

	  gcc_cp_symbol_kind_flags sym_kind = GCC_CP_SYMBOL_FUNCTION;
	  gcc_type method_type;
	  struct block_symbol sym
	    = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (methods, j),
			     instance->block (), VAR_DOMAIN, nullptr);

	  if (sym.symbol == nullptr)
	    {
	      if (TYPE_FN_FIELD_VIRTUAL_P (methods, j))
		{
		  /* This is beyond hacky, and is really only a workaround for
		     detecting pure virtual methods.  */
		  method_type = compile_cplus_convert_method
		    (instance, type, TYPE_FN_FIELD_TYPE (methods, j));

		  instance->plugin ().build_decl
		    ("pure virtual method", overloaded_name.get (),
		     (sym_kind
		      | get_method_access_flag (type, i, j)
		      | GCC_CP_FLAG_VIRTUAL_FUNCTION
		      | GCC_CP_FLAG_PURE_VIRTUAL_FUNCTION),
		     method_type, nullptr, 0, nullptr, 0);
		  continue;
		}

	      /* This can happen if we have a DW_AT_declaration DIE
		 for the method, but no "definition"-type DIE (with
		 DW_AT_specification referencing the decl DIE), i.e.,
		 the compiler has probably optimized the method away.

		 In this case, all we can hope to do is issue a warning
		 to the user letting him know.  If the user has not actually
		 requested using this method, things should still work.  */
	      warning (_("Method %s appears to be optimized out.\n"
			 "All references to this method will be undefined."),
			 TYPE_FN_FIELD_PHYSNAME (methods, j));
	      continue;
	    }

	  const char *filename = symbol_symtab (sym.symbol)->filename;
	  unsigned int line = SYMBOL_LINE (sym.symbol);
	  CORE_ADDR address = BLOCK_START (SYMBOL_BLOCK_VALUE (sym.symbol));
	  const char *kind;

	  if (TYPE_FN_FIELD_STATIC_P (methods, j))
	    {
	      kind = "static method";
	      method_type = compile_cplus_convert_func
		(instance, TYPE_FN_FIELD_TYPE (methods, j), true);
	    }
	  else
	    {
	      kind = "method";
	      method_type = (compile_cplus_convert_method
			     (instance, type, TYPE_FN_FIELD_TYPE (methods, j)));
	    }

	  if (TYPE_FN_FIELD_VIRTUAL_P (methods, j))
	    sym_kind |= GCC_CP_FLAG_VIRTUAL_FUNCTION;

	  instance->plugin ().build_decl
	    (kind, overloaded_name.get (),
	     sym_kind | get_method_access_flag (type, i, j),
	     method_type, nullptr, address, filename, line);
	}
    }
}
static void
convert_one_symbol (struct compile_c_instance *context,
		    struct symbol *sym,
		    int is_global,
		    int is_local)
{
  gcc_type sym_type;
  const char *filename = symbol_symtab (sym)->filename;
  unsigned short line = SYMBOL_LINE (sym);

  error_symbol_once (context, sym);

  if (SYMBOL_CLASS (sym) == LOC_LABEL)
    sym_type = 0;
  else
    sym_type = convert_type (context, SYMBOL_TYPE (sym));

  if (SYMBOL_DOMAIN (sym) == STRUCT_DOMAIN)
    {
      /* Binding a tag, so we don't need to build a decl.  */
      C_CTX (context)->c_ops->tagbind (C_CTX (context),
				       SYMBOL_NATURAL_NAME (sym),
				       sym_type, filename, line);
    }
  else
    {
      gcc_decl decl;
      enum gcc_c_symbol_kind kind;
      CORE_ADDR addr = 0;
      char *symbol_name = NULL;

      switch (SYMBOL_CLASS (sym))
	{
	case LOC_TYPEDEF:
	  kind = GCC_C_SYMBOL_TYPEDEF;
	  break;

	case LOC_LABEL:
	  kind = GCC_C_SYMBOL_LABEL;
	  addr = SYMBOL_VALUE_ADDRESS (sym);
	  break;

	case LOC_BLOCK:
	  kind = GCC_C_SYMBOL_FUNCTION;
	  addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
	  if (is_global && TYPE_GNU_IFUNC (SYMBOL_TYPE (sym)))
	    addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr);
	  break;

	case LOC_CONST:
	  if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM)
	    {
	      /* Already handled by convert_enum.  */
	      return;
	    }
	  C_CTX (context)->c_ops->build_constant (C_CTX (context), sym_type,
						  SYMBOL_NATURAL_NAME (sym),
						  SYMBOL_VALUE (sym),
						  filename, line);
	  return;

	case LOC_CONST_BYTES:
	  error (_("Unsupported LOC_CONST_BYTES for symbol \"%s\"."),
		 SYMBOL_PRINT_NAME (sym));

	case LOC_UNDEF:
	  internal_error (__FILE__, __LINE__, _("LOC_UNDEF found for \"%s\"."),
			  SYMBOL_PRINT_NAME (sym));

	case LOC_COMMON_BLOCK:
	  error (_("Fortran common block is unsupported for compilation "
		   "evaluaton of symbol \"%s\"."),
		 SYMBOL_PRINT_NAME (sym));

	case LOC_OPTIMIZED_OUT:
	  error (_("Symbol \"%s\" cannot be used for compilation evaluation "
		   "as it is optimized out."),
		 SYMBOL_PRINT_NAME (sym));

	case LOC_COMPUTED:
	  if (is_local)
	    goto substitution;
	  /* Probably TLS here.  */
	  warning (_("Symbol \"%s\" is thread-local and currently can only "
		     "be referenced from the current thread in "
		     "compiled code."),
		   SYMBOL_PRINT_NAME (sym));
	  /* FALLTHROUGH */
	case LOC_UNRESOLVED:
	  /* 'symbol_name' cannot be used here as that one is used only for
	     local variables from compile_dwarf_expr_to_c.
	     Global variables can be accessed by GCC only by their address, not
	     by their name.  */
	  {
	    struct value *val;
	    struct frame_info *frame = NULL;

	    if (symbol_read_needs_frame (sym))
	      {
		frame = get_selected_frame (NULL);
		if (frame == NULL)
		  error (_("Symbol \"%s\" cannot be used because "
			   "there is no selected frame"),
			 SYMBOL_PRINT_NAME (sym));
	      }

	    val = read_var_value (sym, frame);
	    if (VALUE_LVAL (val) != lval_memory)
	      error (_("Symbol \"%s\" cannot be used for compilation "
		       "evaluation as its address has not been found."),
		     SYMBOL_PRINT_NAME (sym));

	    kind = GCC_C_SYMBOL_VARIABLE;
	    addr = value_address (val);
	  }
	  break;


	case LOC_REGISTER:
	case LOC_ARG:
	case LOC_REF_ARG:
	case LOC_REGPARM_ADDR:
	case LOC_LOCAL:
	substitution:
	  kind = GCC_C_SYMBOL_VARIABLE;
	  symbol_name = symbol_substitution_name (sym);
	  break;

	case LOC_STATIC:
	  kind = GCC_C_SYMBOL_VARIABLE;
	  addr = SYMBOL_VALUE_ADDRESS (sym);
	  break;

	case LOC_FINAL_VALUE:
	default:
	  gdb_assert_not_reached ("Unreachable case in convert_one_symbol.");

	}

      /* Don't emit local variable decls for a raw expression.  */
      if (context->base.scope != COMPILE_I_RAW_SCOPE
	  || symbol_name == NULL)
	{
	  decl = C_CTX (context)->c_ops->build_decl (C_CTX (context),
						     SYMBOL_NATURAL_NAME (sym),
						     kind,
						     sym_type,
						     symbol_name, addr,
						     filename, line);

	  C_CTX (context)->c_ops->bind (C_CTX (context), decl, is_global);
	}

      xfree (symbol_name);
    }
}
static void
compile_cplus_convert_struct_or_union_members
  (compile_cplus_instance *instance, struct type *type, gcc_type comp_type)
{
  for (int i = TYPE_N_BASECLASSES (type); i < TYPE_NFIELDS (type); ++i)
    {
      const char *field_name = TYPE_FIELD_NAME (type, i);

      if (TYPE_FIELD_IGNORE (type, i)
	  || TYPE_FIELD_ARTIFICIAL (type, i))
	continue;

      /* GDB records unnamed/anonymous fields with empty string names.  */
      if (*field_name == '\0')
	field_name = nullptr;

      gcc_type field_type
	= instance->convert_type (TYPE_FIELD_TYPE (type, i));

      if (field_is_static (&TYPE_FIELD (type, i)))
	{
	  CORE_ADDR physaddr;

	  switch (TYPE_FIELD_LOC_KIND (type, i))
	    {
	    case FIELD_LOC_KIND_PHYSADDR:
	      {
		physaddr = TYPE_FIELD_STATIC_PHYSADDR (type, i);

		instance->plugin ().build_decl
		  ("field physaddr", field_name,
		   (GCC_CP_SYMBOL_VARIABLE | get_field_access_flag (type, i)),
		   field_type, nullptr, physaddr, nullptr, 0);
	      }
	      break;

	    case FIELD_LOC_KIND_PHYSNAME:
	      {
		const char *physname = TYPE_FIELD_STATIC_PHYSNAME (type, i);
		struct block_symbol sym
		  = lookup_symbol (physname, instance->block (),
				   VAR_DOMAIN, nullptr);

		if (sym.symbol == nullptr)
		  {
		    /* We didn't actually find the symbol.  There's little
		       we can do but ignore this member.  */
		    continue;
		  }
		const char *filename = symbol_symtab (sym.symbol)->filename;
		unsigned int line = SYMBOL_LINE (sym.symbol);

		physaddr = SYMBOL_VALUE_ADDRESS (sym.symbol);
		instance->plugin ().build_decl
		  ("field physname", field_name,
		   (GCC_CP_SYMBOL_VARIABLE| get_field_access_flag (type, i)),
		   field_type, nullptr, physaddr, filename, line);
	      }
	      break;

	    default:
	      gdb_assert_not_reached
		("unexpected static field location kind");
	    }
	}
      else
	{
	  unsigned long bitsize = TYPE_FIELD_BITSIZE (type, i);
	  enum gcc_cp_symbol_kind field_flags = GCC_CP_SYMBOL_FIELD
	    | get_field_access_flag (type, i);

	  if (bitsize == 0)
	    bitsize = 8 * TYPE_LENGTH (TYPE_FIELD_TYPE (type, i));

	  instance->plugin ().build_field
	    (field_name, field_type, field_flags, bitsize,
	     TYPE_FIELD_BITPOS (type, i));
	}
    }
}