1*0b57cec5SDimitry Andric //===- Error.cpp - tblgen error handling helper routines --------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file contains error handling helper routines to pretty-print diagnostic 10*0b57cec5SDimitry Andric // messages from tblgen. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 15e8d8bef9SDimitry Andric #include "llvm/Support/raw_ostream.h" 16*0b57cec5SDimitry Andric #include "llvm/Support/Signals.h" 17*0b57cec5SDimitry Andric #include "llvm/Support/WithColor.h" 18e8d8bef9SDimitry Andric #include "llvm/TableGen/Error.h" 19e8d8bef9SDimitry Andric #include "llvm/TableGen/Record.h" 20*0b57cec5SDimitry Andric #include <cstdlib> 21*0b57cec5SDimitry Andric 22*0b57cec5SDimitry Andric namespace llvm { 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric SourceMgr SrcMgr; 25*0b57cec5SDimitry Andric unsigned ErrorsPrinted = 0; 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric static void PrintMessage(ArrayRef<SMLoc> Loc, SourceMgr::DiagKind Kind, 28*0b57cec5SDimitry Andric const Twine &Msg) { 29*0b57cec5SDimitry Andric // Count the total number of errors printed. 30*0b57cec5SDimitry Andric // This is used to exit with an error code if there were any errors. 31*0b57cec5SDimitry Andric if (Kind == SourceMgr::DK_Error) 32*0b57cec5SDimitry Andric ++ErrorsPrinted; 33*0b57cec5SDimitry Andric 34*0b57cec5SDimitry Andric SMLoc NullLoc; 35*0b57cec5SDimitry Andric if (Loc.empty()) 36*0b57cec5SDimitry Andric Loc = NullLoc; 37*0b57cec5SDimitry Andric SrcMgr.PrintMessage(Loc.front(), Kind, Msg); 38*0b57cec5SDimitry Andric for (unsigned i = 1; i < Loc.size(); ++i) 39*0b57cec5SDimitry Andric SrcMgr.PrintMessage(Loc[i], SourceMgr::DK_Note, 40*0b57cec5SDimitry Andric "instantiated from multiclass"); 41*0b57cec5SDimitry Andric } 42*0b57cec5SDimitry Andric 43e8d8bef9SDimitry Andric // Functions to print notes. 44e8d8bef9SDimitry Andric 45e8d8bef9SDimitry Andric void PrintNote(const Twine &Msg) { 46e8d8bef9SDimitry Andric WithColor::note() << Msg << "\n"; 47e8d8bef9SDimitry Andric } 488bcb0991SDimitry Andric 49*0b57cec5SDimitry Andric void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) { 50*0b57cec5SDimitry Andric PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg); 51*0b57cec5SDimitry Andric } 52*0b57cec5SDimitry Andric 53e8d8bef9SDimitry Andric // Functions to print fatal notes. 54e8d8bef9SDimitry Andric 55e8d8bef9SDimitry Andric void PrintFatalNote(const Twine &Msg) { 56e8d8bef9SDimitry Andric PrintNote(Msg); 57e8d8bef9SDimitry Andric // The following call runs the file cleanup handlers. 58e8d8bef9SDimitry Andric sys::RunInterruptHandlers(); 59e8d8bef9SDimitry Andric std::exit(1); 60e8d8bef9SDimitry Andric } 61e8d8bef9SDimitry Andric 62e8d8bef9SDimitry Andric void PrintFatalNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) { 63e8d8bef9SDimitry Andric PrintNote(NoteLoc, Msg); 64e8d8bef9SDimitry Andric // The following call runs the file cleanup handlers. 65e8d8bef9SDimitry Andric sys::RunInterruptHandlers(); 66e8d8bef9SDimitry Andric std::exit(1); 67e8d8bef9SDimitry Andric } 68e8d8bef9SDimitry Andric 69e8d8bef9SDimitry Andric // This method takes a Record and uses the source location 70e8d8bef9SDimitry Andric // stored in it. 71e8d8bef9SDimitry Andric void PrintFatalNote(const Record *Rec, const Twine &Msg) { 72e8d8bef9SDimitry Andric PrintNote(Rec->getLoc(), Msg); 73e8d8bef9SDimitry Andric // The following call runs the file cleanup handlers. 74e8d8bef9SDimitry Andric sys::RunInterruptHandlers(); 75e8d8bef9SDimitry Andric std::exit(1); 76e8d8bef9SDimitry Andric } 77e8d8bef9SDimitry Andric 78e8d8bef9SDimitry Andric // This method takes a RecordVal and uses the source location 79e8d8bef9SDimitry Andric // stored in it. 80e8d8bef9SDimitry Andric void PrintFatalNote(const RecordVal *RecVal, const Twine &Msg) { 81e8d8bef9SDimitry Andric PrintNote(RecVal->getLoc(), Msg); 82e8d8bef9SDimitry Andric // The following call runs the file cleanup handlers. 83e8d8bef9SDimitry Andric sys::RunInterruptHandlers(); 84e8d8bef9SDimitry Andric std::exit(1); 85e8d8bef9SDimitry Andric } 86e8d8bef9SDimitry Andric 87e8d8bef9SDimitry Andric // Functions to print warnings. 88e8d8bef9SDimitry Andric 89e8d8bef9SDimitry Andric void PrintWarning(const Twine &Msg) { WithColor::warning() << Msg << "\n"; } 90e8d8bef9SDimitry Andric 91*0b57cec5SDimitry Andric void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg) { 92*0b57cec5SDimitry Andric PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg); 93*0b57cec5SDimitry Andric } 94*0b57cec5SDimitry Andric 95*0b57cec5SDimitry Andric void PrintWarning(const char *Loc, const Twine &Msg) { 96*0b57cec5SDimitry Andric SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg); 97*0b57cec5SDimitry Andric } 98*0b57cec5SDimitry Andric 99e8d8bef9SDimitry Andric // Functions to print errors. 100e8d8bef9SDimitry Andric 101e8d8bef9SDimitry Andric void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; } 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) { 104*0b57cec5SDimitry Andric PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg); 105*0b57cec5SDimitry Andric } 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric void PrintError(const char *Loc, const Twine &Msg) { 108*0b57cec5SDimitry Andric SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg); 109*0b57cec5SDimitry Andric } 110*0b57cec5SDimitry Andric 111e8d8bef9SDimitry Andric // This method takes a Record and uses the source location 112e8d8bef9SDimitry Andric // stored in it. 113e8d8bef9SDimitry Andric void PrintError(const Record *Rec, const Twine &Msg) { 114e8d8bef9SDimitry Andric PrintMessage(Rec->getLoc(), SourceMgr::DK_Error, Msg); 115e8d8bef9SDimitry Andric } 116e8d8bef9SDimitry Andric 117e8d8bef9SDimitry Andric // This method takes a RecordVal and uses the source location 118e8d8bef9SDimitry Andric // stored in it. 119e8d8bef9SDimitry Andric void PrintError(const RecordVal *RecVal, const Twine &Msg) { 120e8d8bef9SDimitry Andric PrintMessage(RecVal->getLoc(), SourceMgr::DK_Error, Msg); 121e8d8bef9SDimitry Andric } 122e8d8bef9SDimitry Andric 123e8d8bef9SDimitry Andric // Functions to print fatal errors. 124*0b57cec5SDimitry Andric 125*0b57cec5SDimitry Andric void PrintFatalError(const Twine &Msg) { 126*0b57cec5SDimitry Andric PrintError(Msg); 127*0b57cec5SDimitry Andric // The following call runs the file cleanup handlers. 128*0b57cec5SDimitry Andric sys::RunInterruptHandlers(); 129*0b57cec5SDimitry Andric std::exit(1); 130*0b57cec5SDimitry Andric } 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) { 133*0b57cec5SDimitry Andric PrintError(ErrorLoc, Msg); 134*0b57cec5SDimitry Andric // The following call runs the file cleanup handlers. 135*0b57cec5SDimitry Andric sys::RunInterruptHandlers(); 136*0b57cec5SDimitry Andric std::exit(1); 137*0b57cec5SDimitry Andric } 138*0b57cec5SDimitry Andric 139e8d8bef9SDimitry Andric // This method takes a Record and uses the source location 140e8d8bef9SDimitry Andric // stored in it. 141e8d8bef9SDimitry Andric void PrintFatalError(const Record *Rec, const Twine &Msg) { 142e8d8bef9SDimitry Andric PrintError(Rec->getLoc(), Msg); 143e8d8bef9SDimitry Andric // The following call runs the file cleanup handlers. 144e8d8bef9SDimitry Andric sys::RunInterruptHandlers(); 145e8d8bef9SDimitry Andric std::exit(1); 146e8d8bef9SDimitry Andric } 147e8d8bef9SDimitry Andric 148e8d8bef9SDimitry Andric // This method takes a RecordVal and uses the source location 149e8d8bef9SDimitry Andric // stored in it. 150e8d8bef9SDimitry Andric void PrintFatalError(const RecordVal *RecVal, const Twine &Msg) { 151e8d8bef9SDimitry Andric PrintError(RecVal->getLoc(), Msg); 152e8d8bef9SDimitry Andric // The following call runs the file cleanup handlers. 153e8d8bef9SDimitry Andric sys::RunInterruptHandlers(); 154e8d8bef9SDimitry Andric std::exit(1); 155e8d8bef9SDimitry Andric } 156e8d8bef9SDimitry Andric 157*0b57cec5SDimitry Andric } // end namespace llvm 158