xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/TableGen/Error.cpp (revision 82d56013d7b633d116a93943de88e08335357a7c)
17330f729Sjoerg //===- Error.cpp - tblgen error handling helper routines --------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This file contains error handling helper routines to pretty-print diagnostic
107330f729Sjoerg // messages from tblgen.
117330f729Sjoerg //
127330f729Sjoerg //===----------------------------------------------------------------------===//
137330f729Sjoerg 
147330f729Sjoerg #include "llvm/ADT/Twine.h"
15*82d56013Sjoerg #include "llvm/Support/raw_ostream.h"
167330f729Sjoerg #include "llvm/Support/Signals.h"
177330f729Sjoerg #include "llvm/Support/WithColor.h"
18*82d56013Sjoerg #include "llvm/TableGen/Error.h"
19*82d56013Sjoerg #include "llvm/TableGen/Record.h"
207330f729Sjoerg #include <cstdlib>
217330f729Sjoerg 
227330f729Sjoerg namespace llvm {
237330f729Sjoerg 
247330f729Sjoerg SourceMgr SrcMgr;
257330f729Sjoerg unsigned ErrorsPrinted = 0;
267330f729Sjoerg 
PrintMessage(ArrayRef<SMLoc> Loc,SourceMgr::DiagKind Kind,const Twine & Msg)277330f729Sjoerg static void PrintMessage(ArrayRef<SMLoc> Loc, SourceMgr::DiagKind Kind,
287330f729Sjoerg                          const Twine &Msg) {
297330f729Sjoerg   // Count the total number of errors printed.
307330f729Sjoerg   // This is used to exit with an error code if there were any errors.
317330f729Sjoerg   if (Kind == SourceMgr::DK_Error)
327330f729Sjoerg     ++ErrorsPrinted;
337330f729Sjoerg 
347330f729Sjoerg   SMLoc NullLoc;
357330f729Sjoerg   if (Loc.empty())
367330f729Sjoerg     Loc = NullLoc;
377330f729Sjoerg   SrcMgr.PrintMessage(Loc.front(), Kind, Msg);
387330f729Sjoerg   for (unsigned i = 1; i < Loc.size(); ++i)
397330f729Sjoerg     SrcMgr.PrintMessage(Loc[i], SourceMgr::DK_Note,
407330f729Sjoerg                         "instantiated from multiclass");
417330f729Sjoerg }
427330f729Sjoerg 
43*82d56013Sjoerg // Functions to print notes.
44*82d56013Sjoerg 
PrintNote(const Twine & Msg)45*82d56013Sjoerg void PrintNote(const Twine &Msg) {
46*82d56013Sjoerg   WithColor::note() << Msg << "\n";
47*82d56013Sjoerg }
487330f729Sjoerg 
PrintNote(ArrayRef<SMLoc> NoteLoc,const Twine & Msg)497330f729Sjoerg void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
507330f729Sjoerg   PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg);
517330f729Sjoerg }
527330f729Sjoerg 
53*82d56013Sjoerg // Functions to print fatal notes.
54*82d56013Sjoerg 
PrintFatalNote(const Twine & Msg)55*82d56013Sjoerg void PrintFatalNote(const Twine &Msg) {
56*82d56013Sjoerg   PrintNote(Msg);
57*82d56013Sjoerg   // The following call runs the file cleanup handlers.
58*82d56013Sjoerg   sys::RunInterruptHandlers();
59*82d56013Sjoerg   std::exit(1);
60*82d56013Sjoerg }
61*82d56013Sjoerg 
PrintFatalNote(ArrayRef<SMLoc> NoteLoc,const Twine & Msg)62*82d56013Sjoerg void PrintFatalNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
63*82d56013Sjoerg   PrintNote(NoteLoc, Msg);
64*82d56013Sjoerg   // The following call runs the file cleanup handlers.
65*82d56013Sjoerg   sys::RunInterruptHandlers();
66*82d56013Sjoerg   std::exit(1);
67*82d56013Sjoerg }
68*82d56013Sjoerg 
69*82d56013Sjoerg // This method takes a Record and uses the source location
70*82d56013Sjoerg // stored in it.
PrintFatalNote(const Record * Rec,const Twine & Msg)71*82d56013Sjoerg void PrintFatalNote(const Record *Rec, const Twine &Msg) {
72*82d56013Sjoerg   PrintNote(Rec->getLoc(), Msg);
73*82d56013Sjoerg   // The following call runs the file cleanup handlers.
74*82d56013Sjoerg   sys::RunInterruptHandlers();
75*82d56013Sjoerg   std::exit(1);
76*82d56013Sjoerg }
77*82d56013Sjoerg 
78*82d56013Sjoerg // This method takes a RecordVal and uses the source location
79*82d56013Sjoerg // stored in it.
PrintFatalNote(const RecordVal * RecVal,const Twine & Msg)80*82d56013Sjoerg void PrintFatalNote(const RecordVal *RecVal, const Twine &Msg) {
81*82d56013Sjoerg   PrintNote(RecVal->getLoc(), Msg);
82*82d56013Sjoerg   // The following call runs the file cleanup handlers.
83*82d56013Sjoerg   sys::RunInterruptHandlers();
84*82d56013Sjoerg   std::exit(1);
85*82d56013Sjoerg }
86*82d56013Sjoerg 
87*82d56013Sjoerg // Functions to print warnings.
88*82d56013Sjoerg 
PrintWarning(const Twine & Msg)89*82d56013Sjoerg void PrintWarning(const Twine &Msg) { WithColor::warning() << Msg << "\n"; }
90*82d56013Sjoerg 
PrintWarning(ArrayRef<SMLoc> WarningLoc,const Twine & Msg)917330f729Sjoerg void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg) {
927330f729Sjoerg   PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);
937330f729Sjoerg }
947330f729Sjoerg 
PrintWarning(const char * Loc,const Twine & Msg)957330f729Sjoerg void PrintWarning(const char *Loc, const Twine &Msg) {
967330f729Sjoerg   SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg);
977330f729Sjoerg }
987330f729Sjoerg 
99*82d56013Sjoerg // Functions to print errors.
100*82d56013Sjoerg 
PrintError(const Twine & Msg)101*82d56013Sjoerg void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; }
1027330f729Sjoerg 
PrintError(ArrayRef<SMLoc> ErrorLoc,const Twine & Msg)1037330f729Sjoerg void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
1047330f729Sjoerg   PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
1057330f729Sjoerg }
1067330f729Sjoerg 
PrintError(const char * Loc,const Twine & Msg)1077330f729Sjoerg void PrintError(const char *Loc, const Twine &Msg) {
1087330f729Sjoerg   SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
1097330f729Sjoerg }
1107330f729Sjoerg 
111*82d56013Sjoerg // This method takes a Record and uses the source location
112*82d56013Sjoerg // stored in it.
PrintError(const Record * Rec,const Twine & Msg)113*82d56013Sjoerg void PrintError(const Record *Rec, const Twine &Msg) {
114*82d56013Sjoerg   PrintMessage(Rec->getLoc(), SourceMgr::DK_Error, Msg);
115*82d56013Sjoerg }
116*82d56013Sjoerg 
117*82d56013Sjoerg // This method takes a RecordVal and uses the source location
118*82d56013Sjoerg // stored in it.
PrintError(const RecordVal * RecVal,const Twine & Msg)119*82d56013Sjoerg void PrintError(const RecordVal *RecVal, const Twine &Msg) {
120*82d56013Sjoerg   PrintMessage(RecVal->getLoc(), SourceMgr::DK_Error, Msg);
121*82d56013Sjoerg }
122*82d56013Sjoerg 
123*82d56013Sjoerg // Functions to print fatal errors.
1247330f729Sjoerg 
PrintFatalError(const Twine & Msg)1257330f729Sjoerg void PrintFatalError(const Twine &Msg) {
1267330f729Sjoerg   PrintError(Msg);
1277330f729Sjoerg   // The following call runs the file cleanup handlers.
1287330f729Sjoerg   sys::RunInterruptHandlers();
1297330f729Sjoerg   std::exit(1);
1307330f729Sjoerg }
1317330f729Sjoerg 
PrintFatalError(ArrayRef<SMLoc> ErrorLoc,const Twine & Msg)1327330f729Sjoerg void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
1337330f729Sjoerg   PrintError(ErrorLoc, Msg);
1347330f729Sjoerg   // The following call runs the file cleanup handlers.
1357330f729Sjoerg   sys::RunInterruptHandlers();
1367330f729Sjoerg   std::exit(1);
1377330f729Sjoerg }
1387330f729Sjoerg 
139*82d56013Sjoerg // This method takes a Record and uses the source location
140*82d56013Sjoerg // stored in it.
PrintFatalError(const Record * Rec,const Twine & Msg)141*82d56013Sjoerg void PrintFatalError(const Record *Rec, const Twine &Msg) {
142*82d56013Sjoerg   PrintError(Rec->getLoc(), Msg);
143*82d56013Sjoerg   // The following call runs the file cleanup handlers.
144*82d56013Sjoerg   sys::RunInterruptHandlers();
145*82d56013Sjoerg   std::exit(1);
146*82d56013Sjoerg }
147*82d56013Sjoerg 
148*82d56013Sjoerg // This method takes a RecordVal and uses the source location
149*82d56013Sjoerg // stored in it.
PrintFatalError(const RecordVal * RecVal,const Twine & Msg)150*82d56013Sjoerg void PrintFatalError(const RecordVal *RecVal, const Twine &Msg) {
151*82d56013Sjoerg   PrintError(RecVal->getLoc(), Msg);
152*82d56013Sjoerg   // The following call runs the file cleanup handlers.
153*82d56013Sjoerg   sys::RunInterruptHandlers();
154*82d56013Sjoerg   std::exit(1);
155*82d56013Sjoerg }
156*82d56013Sjoerg 
157*82d56013Sjoerg // Check an assertion: Obtain the condition value and be sure it is true.
158*82d56013Sjoerg // If not, print a nonfatal error along with the message.
CheckAssert(SMLoc Loc,Init * Condition,Init * Message)159*82d56013Sjoerg void CheckAssert(SMLoc Loc, Init *Condition, Init *Message) {
160*82d56013Sjoerg   auto *CondValue = dyn_cast_or_null<IntInit>(
161*82d56013Sjoerg                         Condition->convertInitializerTo(IntRecTy::get()));
162*82d56013Sjoerg   if (!CondValue)
163*82d56013Sjoerg     PrintError(Loc, "assert condition must of type bit, bits, or int.");
164*82d56013Sjoerg   else if (!CondValue->getValue()) {
165*82d56013Sjoerg     PrintError(Loc, "assertion failed");
166*82d56013Sjoerg     if (auto *MessageInit = dyn_cast<StringInit>(Message))
167*82d56013Sjoerg       PrintNote(MessageInit->getValue());
168*82d56013Sjoerg     else
169*82d56013Sjoerg       PrintNote("(assert message is not a string)");
170*82d56013Sjoerg   }
171*82d56013Sjoerg }
172*82d56013Sjoerg 
1737330f729Sjoerg } // end namespace llvm
174