[TableGen] Add PrintError family overload that take a print function (#107333)
Add PrintError and family overload that accepts a print function. This avoids constructing potentially long strings for passing into these print functions.
This commit is contained in:
parent
6df1291296
commit
0ceffd362b
@ -14,12 +14,16 @@
|
||||
#ifndef LLVM_TABLEGEN_ERROR_H
|
||||
#define LLVM_TABLEGEN_ERROR_H
|
||||
|
||||
#include "llvm/ADT/STLFunctionalExtras.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/TableGen/Record.h"
|
||||
|
||||
namespace llvm {
|
||||
class Record;
|
||||
class RecordVal;
|
||||
class Init;
|
||||
|
||||
void PrintNote(const Twine &Msg);
|
||||
void PrintNote(function_ref<void(raw_ostream &OS)> PrintMsg);
|
||||
void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg);
|
||||
|
||||
[[noreturn]] void PrintFatalNote(const Twine &Msg);
|
||||
@ -32,6 +36,7 @@ void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg);
|
||||
void PrintWarning(const char *Loc, const Twine &Msg);
|
||||
|
||||
void PrintError(const Twine &Msg);
|
||||
void PrintError(function_ref<void(raw_ostream &OS)> PrintMsg);
|
||||
void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg);
|
||||
void PrintError(const char *Loc, const Twine &Msg);
|
||||
void PrintError(const Record *Rec, const Twine &Msg);
|
||||
@ -41,6 +46,7 @@ void PrintError(const RecordVal *RecVal, const Twine &Msg);
|
||||
[[noreturn]] void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg);
|
||||
[[noreturn]] void PrintFatalError(const Record *Rec, const Twine &Msg);
|
||||
[[noreturn]] void PrintFatalError(const RecordVal *RecVal, const Twine &Msg);
|
||||
[[noreturn]] void PrintFatalError(function_ref<void(raw_ostream &OS)> PrintMsg);
|
||||
|
||||
void CheckAssert(SMLoc Loc, Init *Condition, Init *Message);
|
||||
void dumpMessage(SMLoc Loc, Init *Message);
|
||||
|
||||
@ -40,12 +40,23 @@ static void PrintMessage(ArrayRef<SMLoc> Loc, SourceMgr::DiagKind Kind,
|
||||
"instantiated from multiclass");
|
||||
}
|
||||
|
||||
// Run file cleanup handlers and then exit fatally (with non-zero exit code).
|
||||
[[noreturn]] inline static void fatal_exit() {
|
||||
// The following call runs the file cleanup handlers.
|
||||
sys::RunInterruptHandlers();
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// Functions to print notes.
|
||||
|
||||
void PrintNote(const Twine &Msg) {
|
||||
WithColor::note() << Msg << "\n";
|
||||
}
|
||||
|
||||
void PrintNote(function_ref<void(raw_ostream &OS)> PrintMsg) {
|
||||
PrintMsg(WithColor::note());
|
||||
}
|
||||
|
||||
void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
|
||||
PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg);
|
||||
}
|
||||
@ -54,34 +65,26 @@ void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
|
||||
|
||||
void PrintFatalNote(const Twine &Msg) {
|
||||
PrintNote(Msg);
|
||||
// The following call runs the file cleanup handlers.
|
||||
sys::RunInterruptHandlers();
|
||||
std::exit(1);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
void PrintFatalNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
|
||||
PrintNote(NoteLoc, Msg);
|
||||
// The following call runs the file cleanup handlers.
|
||||
sys::RunInterruptHandlers();
|
||||
std::exit(1);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
// 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);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
// 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);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
// Functions to print warnings.
|
||||
@ -100,6 +103,10 @@ void PrintWarning(const char *Loc, const Twine &Msg) {
|
||||
|
||||
void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; }
|
||||
|
||||
void PrintError(function_ref<void(raw_ostream &OS)> PrintMsg) {
|
||||
PrintMsg(WithColor::error());
|
||||
}
|
||||
|
||||
void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
|
||||
PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
|
||||
}
|
||||
@ -124,34 +131,31 @@ void PrintError(const RecordVal *RecVal, const Twine &Msg) {
|
||||
|
||||
void PrintFatalError(const Twine &Msg) {
|
||||
PrintError(Msg);
|
||||
// The following call runs the file cleanup handlers.
|
||||
sys::RunInterruptHandlers();
|
||||
std::exit(1);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
void PrintFatalError(function_ref<void(raw_ostream &OS)> PrintMsg) {
|
||||
PrintError(PrintMsg);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
|
||||
PrintError(ErrorLoc, Msg);
|
||||
// The following call runs the file cleanup handlers.
|
||||
sys::RunInterruptHandlers();
|
||||
std::exit(1);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
// 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);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
// 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);
|
||||
fatal_exit();
|
||||
}
|
||||
|
||||
// Check an assertion: Obtain the condition value and be sure it is true.
|
||||
|
||||
14
llvm/test/TableGen/intrinsic-prefix-error.td
Normal file
14
llvm/test/TableGen/intrinsic-prefix-error.td
Normal file
@ -0,0 +1,14 @@
|
||||
// RUN: not llvm-tblgen -gen-intrinsic-enums --intrinsic-prefix=gen3 -I %p/../../include %s -DTEST_INTRINSICS_SUPPRESS_DEFS 2>&1 | FileCheck %s
|
||||
|
||||
include "llvm/IR/Intrinsics.td"
|
||||
|
||||
// CHECK: error: tried to generate intrinsics for unknown target gen3
|
||||
// CHECK-NEXT: Known targets are: gen1, gen2
|
||||
|
||||
let TargetPrefix = "gen1" in {
|
||||
def int_gen1_int0 : Intrinsic<[llvm_i32_ty]>;
|
||||
}
|
||||
|
||||
let TargetPrefix = "gen2" in {
|
||||
def int_gen2_int0 : Intrinsic<[llvm_i32_ty]>;
|
||||
}
|
||||
@ -1603,14 +1603,11 @@ static TreePatternNode &getOperandNum(unsigned OpNo, TreePatternNode &N,
|
||||
OpNo -= NumResults;
|
||||
|
||||
if (OpNo >= N.getNumChildren()) {
|
||||
std::string S;
|
||||
raw_string_ostream OS(S);
|
||||
OS << "Invalid operand number in type constraint " << (OpNo + NumResults)
|
||||
<< " ";
|
||||
N.print(OS);
|
||||
PrintFatalError(S);
|
||||
PrintFatalError([&N, OpNo, NumResults](raw_ostream &OS) {
|
||||
OS << "Invalid operand number in type constraint " << (OpNo + NumResults);
|
||||
N.print(OS);
|
||||
});
|
||||
}
|
||||
|
||||
return N.getChild(OpNo);
|
||||
}
|
||||
|
||||
|
||||
@ -1961,12 +1961,11 @@ void parseVarLenInstOperand(const Record &Def,
|
||||
}
|
||||
|
||||
static void debugDumpRecord(const Record &Rec) {
|
||||
// Dump the record, so we can see what's going on...
|
||||
std::string E;
|
||||
raw_string_ostream S(E);
|
||||
S << "Dumping record for previous error:\n";
|
||||
S << Rec;
|
||||
PrintNote(E);
|
||||
// Dump the record, so we can see what's going on.
|
||||
PrintNote([&Rec](raw_ostream &OS) {
|
||||
OS << "Dumping record for previous error:\n";
|
||||
OS << Rec;
|
||||
});
|
||||
}
|
||||
|
||||
/// For an operand field named OpName: populate OpInfo.InitValue with the
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
#include "Basic/SequenceToOffsetTable.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
@ -122,7 +121,8 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints,
|
||||
// Find the TargetSet for which to generate enums. There will be an initial
|
||||
// set with an empty target prefix which will include target independent
|
||||
// intrinsics like dbg.value.
|
||||
const CodeGenIntrinsicTable::TargetSet *Set = nullptr;
|
||||
using TargetSet = CodeGenIntrinsicTable::TargetSet;
|
||||
const TargetSet *Set = nullptr;
|
||||
for (const auto &Target : Ints.Targets) {
|
||||
if (Target.Name == IntrinsicPrefix) {
|
||||
Set = &Target;
|
||||
@ -130,13 +130,15 @@ void IntrinsicEmitter::EmitEnumInfo(const CodeGenIntrinsicTable &Ints,
|
||||
}
|
||||
}
|
||||
if (!Set) {
|
||||
std::vector<std::string> KnownTargets;
|
||||
for (const auto &Target : Ints.Targets)
|
||||
if (!Target.Name.empty())
|
||||
KnownTargets.push_back(Target.Name.str());
|
||||
PrintFatalError("tried to generate intrinsics for unknown target " +
|
||||
IntrinsicPrefix +
|
||||
"\nKnown targets are: " + join(KnownTargets, ", ") + "\n");
|
||||
// The first entry is for target independent intrinsics, so drop it.
|
||||
auto KnowTargets = ArrayRef<TargetSet>(Ints.Targets).drop_front();
|
||||
PrintFatalError([KnowTargets](raw_ostream &OS) {
|
||||
OS << "tried to generate intrinsics for unknown target "
|
||||
<< IntrinsicPrefix << "\nKnown targets are: ";
|
||||
interleaveComma(KnowTargets, OS,
|
||||
[&OS](const TargetSet &Target) { OS << Target.Name; });
|
||||
OS << '\n';
|
||||
});
|
||||
}
|
||||
|
||||
// Generate a complete header for target specific intrinsics.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user