Path: blob/main/contrib/llvm-project/llvm/lib/TableGen/Error.cpp
35232 views
//===- Error.cpp - tblgen error handling helper routines --------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains error handling helper routines to pretty-print diagnostic9// messages from tblgen.10//11//===----------------------------------------------------------------------===//1213#include "llvm/ADT/Twine.h"14#include "llvm/Support/raw_ostream.h"15#include "llvm/Support/Signals.h"16#include "llvm/Support/WithColor.h"17#include "llvm/TableGen/Error.h"18#include "llvm/TableGen/Record.h"19#include <cstdlib>2021namespace llvm {2223SourceMgr SrcMgr;24unsigned ErrorsPrinted = 0;2526static void PrintMessage(ArrayRef<SMLoc> Loc, SourceMgr::DiagKind Kind,27const Twine &Msg) {28// Count the total number of errors printed.29// This is used to exit with an error code if there were any errors.30if (Kind == SourceMgr::DK_Error)31++ErrorsPrinted;3233SMLoc NullLoc;34if (Loc.empty())35Loc = NullLoc;36SrcMgr.PrintMessage(Loc.front(), Kind, Msg);37for (unsigned i = 1; i < Loc.size(); ++i)38SrcMgr.PrintMessage(Loc[i], SourceMgr::DK_Note,39"instantiated from multiclass");40}4142// Functions to print notes.4344void PrintNote(const Twine &Msg) {45WithColor::note() << Msg << "\n";46}4748void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {49PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg);50}5152// Functions to print fatal notes.5354void PrintFatalNote(const Twine &Msg) {55PrintNote(Msg);56// The following call runs the file cleanup handlers.57sys::RunInterruptHandlers();58std::exit(1);59}6061void PrintFatalNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {62PrintNote(NoteLoc, Msg);63// The following call runs the file cleanup handlers.64sys::RunInterruptHandlers();65std::exit(1);66}6768// This method takes a Record and uses the source location69// stored in it.70void PrintFatalNote(const Record *Rec, const Twine &Msg) {71PrintNote(Rec->getLoc(), Msg);72// The following call runs the file cleanup handlers.73sys::RunInterruptHandlers();74std::exit(1);75}7677// This method takes a RecordVal and uses the source location78// stored in it.79void PrintFatalNote(const RecordVal *RecVal, const Twine &Msg) {80PrintNote(RecVal->getLoc(), Msg);81// The following call runs the file cleanup handlers.82sys::RunInterruptHandlers();83std::exit(1);84}8586// Functions to print warnings.8788void PrintWarning(const Twine &Msg) { WithColor::warning() << Msg << "\n"; }8990void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg) {91PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);92}9394void PrintWarning(const char *Loc, const Twine &Msg) {95SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg);96}9798// Functions to print errors.99100void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; }101102void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {103PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg);104}105106void PrintError(const char *Loc, const Twine &Msg) {107SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);108}109110// This method takes a Record and uses the source location111// stored in it.112void PrintError(const Record *Rec, const Twine &Msg) {113PrintMessage(Rec->getLoc(), SourceMgr::DK_Error, Msg);114}115116// This method takes a RecordVal and uses the source location117// stored in it.118void PrintError(const RecordVal *RecVal, const Twine &Msg) {119PrintMessage(RecVal->getLoc(), SourceMgr::DK_Error, Msg);120}121122// Functions to print fatal errors.123124void PrintFatalError(const Twine &Msg) {125PrintError(Msg);126// The following call runs the file cleanup handlers.127sys::RunInterruptHandlers();128std::exit(1);129}130131void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {132PrintError(ErrorLoc, Msg);133// The following call runs the file cleanup handlers.134sys::RunInterruptHandlers();135std::exit(1);136}137138// This method takes a Record and uses the source location139// stored in it.140void PrintFatalError(const Record *Rec, const Twine &Msg) {141PrintError(Rec->getLoc(), Msg);142// The following call runs the file cleanup handlers.143sys::RunInterruptHandlers();144std::exit(1);145}146147// This method takes a RecordVal and uses the source location148// stored in it.149void PrintFatalError(const RecordVal *RecVal, const Twine &Msg) {150PrintError(RecVal->getLoc(), Msg);151// The following call runs the file cleanup handlers.152sys::RunInterruptHandlers();153std::exit(1);154}155156// Check an assertion: Obtain the condition value and be sure it is true.157// If not, print a nonfatal error along with the message.158void CheckAssert(SMLoc Loc, Init *Condition, Init *Message) {159auto *CondValue = dyn_cast_or_null<IntInit>(Condition->convertInitializerTo(160IntRecTy::get(Condition->getRecordKeeper())));161if (!CondValue)162PrintError(Loc, "assert condition must of type bit, bits, or int.");163else if (!CondValue->getValue()) {164PrintError(Loc, "assertion failed");165if (auto *MessageInit = dyn_cast<StringInit>(Message))166PrintNote(MessageInit->getValue());167else168PrintNote("(assert message is not a string)");169}170}171172// Dump a message to stderr.173void dumpMessage(SMLoc Loc, Init *Message) {174auto *MessageInit = dyn_cast<StringInit>(Message);175assert(MessageInit && "no debug message to print");176PrintNote(Loc, MessageInit->getValue());177}178179} // end namespace llvm180181182