/* RTL specific diagnostic subroutines for GCC
   Copyright (C) 2001, 2002, 2003, 2004, 2007, 2008, 2010
   Free Software Foundation, Inc.
   Contributed by Gabriel Dos Reis <gdr@codesourcery.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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "rtl-error.h"
#include "insn-attr.h"
#include "insn-config.h"
#include "input.h"
#include "intl.h"
#include "diagnostic.h"

static location_t location_for_asm (const_rtx);
static void diagnostic_for_asm (const_rtx, const char *, va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);

/* Figure the location of the given INSN.  */
static location_t
location_for_asm (const_rtx insn)
{
  rtx body = PATTERN (insn);
  rtx asmop;
  location_t loc;

  /* Find the (or one of the) ASM_OPERANDS in the insn.  */
  if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
    asmop = SET_SRC (body);
  else if (GET_CODE (body) == ASM_OPERANDS)
    asmop = body;
  else if (GET_CODE (body) == PARALLEL
	   && GET_CODE (XVECEXP (body, 0, 0)) == SET)
    asmop = SET_SRC (XVECEXP (body, 0, 0));
  else if (GET_CODE (body) == PARALLEL
	   && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
    asmop = XVECEXP (body, 0, 0);
  else
    asmop = NULL;

  if (asmop)
    loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
  else
    loc = input_location;
  return loc;
}

/* Report a diagnostic MESSAGE (an error or a WARNING) at the line number
   of the insn INSN.  This is used only when INSN is an `asm' with operands,
   and each ASM_OPERANDS records its own source file and line.  */
static void
diagnostic_for_asm (const_rtx insn, const char *msg, va_list *args_ptr,
		    diagnostic_t kind)
{
  diagnostic_info diagnostic;

  diagnostic_set_info (&diagnostic, msg, args_ptr,
		       location_for_asm (insn), kind);
  report_diagnostic (&diagnostic);
}

void
error_for_asm (const_rtx insn, const char *gmsgid, ...)
{
  va_list ap;

  va_start (ap, gmsgid);
  diagnostic_for_asm (insn, gmsgid, &ap, DK_ERROR);
  va_end (ap);
}

void
warning_for_asm (const_rtx insn, const char *gmsgid, ...)
{
  va_list ap;

  va_start (ap, gmsgid);
  diagnostic_for_asm (insn, gmsgid, &ap, DK_WARNING);
  va_end (ap);
}

void
_fatal_insn (const char *msgid, const_rtx insn, const char *file, int line,
	     const char *function)
{
  error ("%s", _(msgid));

  /* The above incremented error_count, but isn't an error that we want to
     count, so reset it here.  */
  errorcount--;

  debug_rtx (insn);
  fancy_abort (file, line, function);
}

void
_fatal_insn_not_found (const_rtx insn, const char *file, int line,
		       const char *function)
{
  if (INSN_CODE (insn) < 0)
    _fatal_insn ("unrecognizable insn:", insn, file, line, function);
  else
    _fatal_insn ("insn does not satisfy its constraints:",
		insn, file, line, function);
}
