1132718Skan/* RTL specific diagnostic subroutines for GCC 2169689Skan Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc. 390075Sobrien Contributed by Gabriel Dos Reis <gdr@codesourcery.com> 490075Sobrien 590075SobrienThis file is part of GCC. 690075Sobrien 790075SobrienGCC is free software; you can redistribute it and/or modify 890075Sobrienit under the terms of the GNU General Public License as published by 990075Sobrienthe Free Software Foundation; either version 2, or (at your option) 1090075Sobrienany later version. 1190075Sobrien 1290075SobrienGCC is distributed in the hope that it will be useful, 1390075Sobrienbut WITHOUT ANY WARRANTY; without even the implied warranty of 1490075SobrienMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1590075SobrienGNU General Public License for more details. 1690075Sobrien 1790075SobrienYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to 19169689Skanthe Free Software Foundation, 51 Franklin Street, Fifth Floor, 20169689SkanBoston, MA 02110-1301, USA. */ 2190075Sobrien 2290075Sobrien#include "config.h" 2390075Sobrien#undef FLOAT /* This is for hpux. They should change hpux. */ 2490075Sobrien#undef FFS /* Some systems define this in param.h. */ 2590075Sobrien#include "system.h" 26132718Skan#include "coretypes.h" 27132718Skan#include "tm.h" 2890075Sobrien#include "rtl.h" 2990075Sobrien#include "insn-attr.h" 3090075Sobrien#include "insn-config.h" 3190075Sobrien#include "input.h" 3290075Sobrien#include "toplev.h" 3390075Sobrien#include "intl.h" 3490075Sobrien#include "diagnostic.h" 3590075Sobrien 36132718Skanstatic location_t location_for_asm (rtx); 37169689Skanstatic void diagnostic_for_asm (rtx, const char *, va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0); 3890075Sobrien 39132718Skan/* Figure the location of the given INSN. */ 40132718Skanstatic location_t 41132718Skanlocation_for_asm (rtx insn) 4290075Sobrien{ 4390075Sobrien rtx body = PATTERN (insn); 4490075Sobrien rtx asmop; 45132718Skan location_t loc; 4690075Sobrien 4790075Sobrien /* Find the (or one of the) ASM_OPERANDS in the insn. */ 4890075Sobrien if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS) 4990075Sobrien asmop = SET_SRC (body); 5090075Sobrien else if (GET_CODE (body) == ASM_OPERANDS) 5190075Sobrien asmop = body; 5290075Sobrien else if (GET_CODE (body) == PARALLEL 5390075Sobrien && GET_CODE (XVECEXP (body, 0, 0)) == SET) 5490075Sobrien asmop = SET_SRC (XVECEXP (body, 0, 0)); 5590075Sobrien else if (GET_CODE (body) == PARALLEL 5690075Sobrien && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS) 5790075Sobrien asmop = XVECEXP (body, 0, 0); 5890075Sobrien else 5990075Sobrien asmop = NULL; 6090075Sobrien 6190075Sobrien if (asmop) 62169689Skan#ifdef USE_MAPPED_LOCATION 63169689Skan loc = ASM_OPERANDS_SOURCE_LOCATION (asmop); 64169689Skan#else 6590075Sobrien { 66132718Skan loc.file = ASM_OPERANDS_SOURCE_FILE (asmop); 67132718Skan loc.line = ASM_OPERANDS_SOURCE_LINE (asmop); 6890075Sobrien } 69169689Skan#endif 7090075Sobrien else 71132718Skan loc = input_location; 72132718Skan return loc; 7390075Sobrien} 7490075Sobrien 7590075Sobrien/* Report a diagnostic MESSAGE (an errror or a WARNING) at the line number 7690075Sobrien of the insn INSN. This is used only when INSN is an `asm' with operands, 7790075Sobrien and each ASM_OPERANDS records its own source file and line. */ 7890075Sobrienstatic void 79132718Skandiagnostic_for_asm (rtx insn, const char *msg, va_list *args_ptr, 80132718Skan diagnostic_t kind) 8190075Sobrien{ 82117395Skan diagnostic_info diagnostic; 8390075Sobrien 84132718Skan diagnostic_set_info (&diagnostic, msg, args_ptr, 85132718Skan location_for_asm (insn), kind); 86117395Skan report_diagnostic (&diagnostic); 8790075Sobrien} 8890075Sobrien 8990075Sobrienvoid 90169689Skanerror_for_asm (rtx insn, const char *gmsgid, ...) 9190075Sobrien{ 92132718Skan va_list ap; 9390075Sobrien 94169689Skan va_start (ap, gmsgid); 95169689Skan diagnostic_for_asm (insn, gmsgid, &ap, DK_ERROR); 96132718Skan va_end (ap); 9790075Sobrien} 9890075Sobrien 9990075Sobrienvoid 100169689Skanwarning_for_asm (rtx insn, const char *gmsgid, ...) 10190075Sobrien{ 102132718Skan va_list ap; 10390075Sobrien 104169689Skan va_start (ap, gmsgid); 105169689Skan diagnostic_for_asm (insn, gmsgid, &ap, DK_WARNING); 106132718Skan va_end (ap); 10790075Sobrien} 10890075Sobrien 10990075Sobrienvoid 110132718Skan_fatal_insn (const char *msgid, rtx insn, const char *file, int line, 111132718Skan const char *function) 11290075Sobrien{ 11390075Sobrien error ("%s", _(msgid)); 11490075Sobrien 11590075Sobrien /* The above incremented error_count, but isn't an error that we want to 11690075Sobrien count, so reset it here. */ 11790075Sobrien errorcount--; 11890075Sobrien 11990075Sobrien debug_rtx (insn); 12090075Sobrien fancy_abort (file, line, function); 12190075Sobrien} 12290075Sobrien 12390075Sobrienvoid 124132718Skan_fatal_insn_not_found (rtx insn, const char *file, int line, 125132718Skan const char *function) 12690075Sobrien{ 12790075Sobrien if (INSN_CODE (insn) < 0) 12890075Sobrien _fatal_insn ("unrecognizable insn:", insn, file, line, function); 12990075Sobrien else 13090075Sobrien _fatal_insn ("insn does not satisfy its constraints:", 13190075Sobrien insn, file, line, function); 13290075Sobrien} 133