1 /* RTL specific diagnostic subroutines for GCC 2 Copyright (C) 2001-2013 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 "insn-attr.h" 27 #include "insn-config.h" 28 #include "input.h" 29 #include "intl.h" 30 #include "diagnostic.h" 31 32 static location_t location_for_asm (const_rtx); 33 static void diagnostic_for_asm (const_rtx, const char *, va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0); 34 35 /* Figure the location of the given INSN. */ 36 static location_t 37 location_for_asm (const_rtx insn) 38 { 39 rtx body = PATTERN (insn); 40 rtx asmop; 41 location_t loc; 42 43 /* Find the (or one of the) ASM_OPERANDS in the insn. */ 44 if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) 45 asmop = SET_SRC (body); 46 else if (GET_CODE (body) == ASM_OPERANDS) 47 asmop = body; 48 else if (GET_CODE (body) == PARALLEL 49 && GET_CODE (XVECEXP (body, 0, 0)) == SET) 50 asmop = SET_SRC (XVECEXP (body, 0, 0)); 51 else if (GET_CODE (body) == PARALLEL 52 && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) 53 asmop = XVECEXP (body, 0, 0); 54 else 55 asmop = NULL; 56 57 if (asmop) 58 loc = ASM_OPERANDS_SOURCE_LOCATION (asmop); 59 else 60 loc = input_location; 61 return loc; 62 } 63 64 /* Report a diagnostic MESSAGE (an error or a WARNING) at the line number 65 of the insn INSN. This is used only when INSN is an `asm' with operands, 66 and each ASM_OPERANDS records its own source file and line. */ 67 static void 68 diagnostic_for_asm (const_rtx insn, const char *msg, va_list *args_ptr, 69 diagnostic_t kind) 70 { 71 diagnostic_info diagnostic; 72 73 diagnostic_set_info (&diagnostic, msg, args_ptr, 74 location_for_asm (insn), kind); 75 report_diagnostic (&diagnostic); 76 } 77 78 void 79 error_for_asm (const_rtx insn, const char *gmsgid, ...) 80 { 81 va_list ap; 82 83 va_start (ap, gmsgid); 84 diagnostic_for_asm (insn, gmsgid, &ap, DK_ERROR); 85 va_end (ap); 86 } 87 88 void 89 warning_for_asm (const_rtx insn, const char *gmsgid, ...) 90 { 91 va_list ap; 92 93 va_start (ap, gmsgid); 94 diagnostic_for_asm (insn, gmsgid, &ap, DK_WARNING); 95 va_end (ap); 96 } 97 98 void 99 _fatal_insn (const char *msgid, const_rtx insn, const char *file, int line, 100 const char *function) 101 { 102 error ("%s", _(msgid)); 103 104 /* The above incremented error_count, but isn't an error that we want to 105 count, so reset it here. */ 106 errorcount--; 107 108 debug_rtx (insn); 109 fancy_abort (file, line, function); 110 } 111 112 void 113 _fatal_insn_not_found (const_rtx insn, const char *file, int line, 114 const char *function) 115 { 116 if (INSN_CODE (insn) < 0) 117 _fatal_insn ("unrecognizable insn:", insn, file, line, function); 118 else 119 _fatal_insn ("insn does not satisfy its constraints:", 120 insn, file, line, function); 121 } 122