1 /* RTL specific diagnostic subroutines for GCC 2 Copyright (C) 2001-2018 Free Software Foundation, Inc. 3 Contributed by Gabriel Dos Reis <gdr@codesourcery.com> 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 3, or (at your option) 10 any later version. 11 12 GCC is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING3. If not see 19 <http://www.gnu.org/licenses/>. */ 20 21 #include "config.h" 22 #include "system.h" 23 #include "coretypes.h" 24 #include "tm.h" 25 #include "rtl-error.h" 26 #include "diagnostic.h" 27 #include "intl.h" 28 29 static location_t location_for_asm (const rtx_insn *); 30 static void diagnostic_for_asm (const rtx_insn *, const char *, va_list *, 31 diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0); 32 33 /* Figure the location of the given INSN. */ 34 static location_t 35 location_for_asm (const rtx_insn *insn) 36 { 37 rtx body = PATTERN (insn); 38 rtx asmop; 39 location_t loc; 40 41 /* Find the (or one of the) ASM_OPERANDS in the insn. */ 42 if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) 43 asmop = SET_SRC (body); 44 else if (GET_CODE (body) == ASM_OPERANDS) 45 asmop = body; 46 else if (GET_CODE (body) == PARALLEL 47 && GET_CODE (XVECEXP (body, 0, 0)) == SET) 48 asmop = SET_SRC (XVECEXP (body, 0, 0)); 49 else if (GET_CODE (body) == PARALLEL 50 && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) 51 asmop = XVECEXP (body, 0, 0); 52 else 53 asmop = NULL; 54 55 if (asmop) 56 loc = ASM_OPERANDS_SOURCE_LOCATION (asmop); 57 else 58 loc = input_location; 59 return loc; 60 } 61 62 /* Report a diagnostic MESSAGE (an error or a WARNING) at the line number 63 of the insn INSN. This is used only when INSN is an `asm' with operands, 64 and each ASM_OPERANDS records its own source file and line. */ 65 static void 66 diagnostic_for_asm (const rtx_insn *insn, const char *msg, va_list *args_ptr, 67 diagnostic_t kind) 68 { 69 diagnostic_info diagnostic; 70 rich_location richloc (line_table, location_for_asm (insn)); 71 72 diagnostic_set_info (&diagnostic, msg, args_ptr, 73 &richloc, kind); 74 diagnostic_report_diagnostic (global_dc, &diagnostic); 75 } 76 77 void 78 error_for_asm (const rtx_insn *insn, const char *gmsgid, ...) 79 { 80 va_list ap; 81 82 va_start (ap, gmsgid); 83 diagnostic_for_asm (insn, gmsgid, &ap, DK_ERROR); 84 va_end (ap); 85 } 86 87 void 88 warning_for_asm (const rtx_insn *insn, const char *gmsgid, ...) 89 { 90 va_list ap; 91 92 va_start (ap, gmsgid); 93 diagnostic_for_asm (insn, gmsgid, &ap, DK_WARNING); 94 va_end (ap); 95 } 96 97 void 98 _fatal_insn (const char *msgid, const_rtx insn, const char *file, int line, 99 const char *function) 100 { 101 error ("%s", _(msgid)); 102 103 /* The above incremented error_count, but isn't an error that we want to 104 count, so reset it here. */ 105 errorcount--; 106 107 debug_rtx (insn); 108 fancy_abort (file, line, function); 109 } 110 111 void 112 _fatal_insn_not_found (const_rtx insn, const char *file, int line, 113 const char *function) 114 { 115 if (INSN_CODE (insn) < 0) 116 _fatal_insn ("unrecognizable insn:", insn, file, line, function); 117 else 118 _fatal_insn ("insn does not satisfy its constraints:", 119 insn, file, line, function); 120 } 121