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