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