11debfc3dSmrg /* RTL specific diagnostic subroutines for GCC
2*8feb0f0bSmrg Copyright (C) 2001-2020 Free Software Foundation, Inc.
31debfc3dSmrg Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
41debfc3dSmrg
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify
81debfc3dSmrg it under the terms of the GNU General Public License as published by
91debfc3dSmrg the Free Software Foundation; either version 3, or (at your option)
101debfc3dSmrg any later version.
111debfc3dSmrg
121debfc3dSmrg GCC is distributed in the hope that it will be useful,
131debfc3dSmrg but WITHOUT ANY WARRANTY; without even the implied warranty of
141debfc3dSmrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
151debfc3dSmrg GNU General Public License for more details.
161debfc3dSmrg
171debfc3dSmrg You should have received a copy of the GNU General Public License
181debfc3dSmrg along with GCC; see the file COPYING3. If not see
191debfc3dSmrg <http://www.gnu.org/licenses/>. */
201debfc3dSmrg
211debfc3dSmrg #include "config.h"
221debfc3dSmrg #include "system.h"
231debfc3dSmrg #include "coretypes.h"
241debfc3dSmrg #include "tm.h"
251debfc3dSmrg #include "rtl-error.h"
261debfc3dSmrg #include "diagnostic.h"
271debfc3dSmrg #include "intl.h"
281debfc3dSmrg
291debfc3dSmrg static location_t location_for_asm (const rtx_insn *);
301debfc3dSmrg static void diagnostic_for_asm (const rtx_insn *, const char *, va_list *,
311debfc3dSmrg diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0);
321debfc3dSmrg
331debfc3dSmrg /* Figure the location of the given INSN. */
341debfc3dSmrg static location_t
location_for_asm(const rtx_insn * insn)351debfc3dSmrg location_for_asm (const rtx_insn *insn)
361debfc3dSmrg {
371debfc3dSmrg rtx body = PATTERN (insn);
381debfc3dSmrg rtx asmop;
391debfc3dSmrg location_t loc;
401debfc3dSmrg
411debfc3dSmrg /* Find the (or one of the) ASM_OPERANDS in the insn. */
421debfc3dSmrg if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
431debfc3dSmrg asmop = SET_SRC (body);
441debfc3dSmrg else if (GET_CODE (body) == ASM_OPERANDS)
451debfc3dSmrg asmop = body;
461debfc3dSmrg else if (GET_CODE (body) == PARALLEL
471debfc3dSmrg && GET_CODE (XVECEXP (body, 0, 0)) == SET)
481debfc3dSmrg asmop = SET_SRC (XVECEXP (body, 0, 0));
491debfc3dSmrg else if (GET_CODE (body) == PARALLEL
501debfc3dSmrg && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
511debfc3dSmrg asmop = XVECEXP (body, 0, 0);
521debfc3dSmrg else
531debfc3dSmrg asmop = NULL;
541debfc3dSmrg
551debfc3dSmrg if (asmop)
561debfc3dSmrg loc = ASM_OPERANDS_SOURCE_LOCATION (asmop);
571debfc3dSmrg else
581debfc3dSmrg loc = input_location;
591debfc3dSmrg return loc;
601debfc3dSmrg }
611debfc3dSmrg
621debfc3dSmrg /* Report a diagnostic MESSAGE (an error or a WARNING) at the line number
631debfc3dSmrg of the insn INSN. This is used only when INSN is an `asm' with operands,
641debfc3dSmrg and each ASM_OPERANDS records its own source file and line. */
651debfc3dSmrg static void
diagnostic_for_asm(const rtx_insn * insn,const char * msg,va_list * args_ptr,diagnostic_t kind)661debfc3dSmrg diagnostic_for_asm (const rtx_insn *insn, const char *msg, va_list *args_ptr,
671debfc3dSmrg diagnostic_t kind)
681debfc3dSmrg {
691debfc3dSmrg diagnostic_info diagnostic;
701debfc3dSmrg rich_location richloc (line_table, location_for_asm (insn));
711debfc3dSmrg
721debfc3dSmrg diagnostic_set_info (&diagnostic, msg, args_ptr,
731debfc3dSmrg &richloc, kind);
74a2dc1f3fSmrg diagnostic_report_diagnostic (global_dc, &diagnostic);
751debfc3dSmrg }
761debfc3dSmrg
771debfc3dSmrg void
error_for_asm(const rtx_insn * insn,const char * gmsgid,...)781debfc3dSmrg error_for_asm (const rtx_insn *insn, const char *gmsgid, ...)
791debfc3dSmrg {
801debfc3dSmrg va_list ap;
811debfc3dSmrg
821debfc3dSmrg va_start (ap, gmsgid);
831debfc3dSmrg diagnostic_for_asm (insn, gmsgid, &ap, DK_ERROR);
841debfc3dSmrg va_end (ap);
851debfc3dSmrg }
861debfc3dSmrg
871debfc3dSmrg void
warning_for_asm(const rtx_insn * insn,const char * gmsgid,...)881debfc3dSmrg warning_for_asm (const rtx_insn *insn, const char *gmsgid, ...)
891debfc3dSmrg {
901debfc3dSmrg va_list ap;
911debfc3dSmrg
921debfc3dSmrg va_start (ap, gmsgid);
931debfc3dSmrg diagnostic_for_asm (insn, gmsgid, &ap, DK_WARNING);
941debfc3dSmrg va_end (ap);
951debfc3dSmrg }
961debfc3dSmrg
971debfc3dSmrg void
_fatal_insn(const char * msgid,const_rtx insn,const char * file,int line,const char * function)981debfc3dSmrg _fatal_insn (const char *msgid, const_rtx insn, const char *file, int line,
991debfc3dSmrg const char *function)
1001debfc3dSmrg {
1011debfc3dSmrg error ("%s", _(msgid));
1021debfc3dSmrg
1031debfc3dSmrg /* The above incremented error_count, but isn't an error that we want to
1041debfc3dSmrg count, so reset it here. */
1051debfc3dSmrg errorcount--;
1061debfc3dSmrg
1071debfc3dSmrg debug_rtx (insn);
1081debfc3dSmrg fancy_abort (file, line, function);
1091debfc3dSmrg }
1101debfc3dSmrg
1111debfc3dSmrg void
_fatal_insn_not_found(const_rtx insn,const char * file,int line,const char * function)1121debfc3dSmrg _fatal_insn_not_found (const_rtx insn, const char *file, int line,
1131debfc3dSmrg const char *function)
1141debfc3dSmrg {
1151debfc3dSmrg if (INSN_CODE (insn) < 0)
1161debfc3dSmrg _fatal_insn ("unrecognizable insn:", insn, file, line, function);
1171debfc3dSmrg else
1181debfc3dSmrg _fatal_insn ("insn does not satisfy its constraints:",
1191debfc3dSmrg insn, file, line, function);
1201debfc3dSmrg }
121