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