Error.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. #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>
  20. namespace llvm {
  21. SourceMgr SrcMgr;
  22. unsigned ErrorsPrinted = 0;
  23. static void PrintMessage(ArrayRef<SMLoc> Loc, SourceMgr::DiagKind Kind,
  24. const Twine &Msg) {
  25. // Count the total number of errors printed.
  26. // This is used to exit with an error code if there were any errors.
  27. if (Kind == SourceMgr::DK_Error)
  28. ++ErrorsPrinted;
  29. SMLoc NullLoc;
  30. if (Loc.empty())
  31. Loc = NullLoc;
  32. SrcMgr.PrintMessage(Loc.front(), Kind, Msg);
  33. for (unsigned i = 1; i < Loc.size(); ++i)
  34. SrcMgr.PrintMessage(Loc[i], SourceMgr::DK_Note,
  35. "instantiated from multiclass");
  36. }
  37. // Functions to print notes.
  38. void PrintNote(const Twine &Msg) {
  39. WithColor::note() << Msg << "\n";
  40. }
  41. void PrintNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
  42. PrintMessage(NoteLoc, SourceMgr::DK_Note, Msg);
  43. }
  44. // Functions to print fatal notes.
  45. void PrintFatalNote(const Twine &Msg) {
  46. PrintNote(Msg);
  47. // The following call runs the file cleanup handlers.
  48. sys::RunInterruptHandlers();
  49. std::exit(1);
  50. }
  51. void PrintFatalNote(ArrayRef<SMLoc> NoteLoc, const Twine &Msg) {
  52. PrintNote(NoteLoc, Msg);
  53. // The following call runs the file cleanup handlers.
  54. sys::RunInterruptHandlers();
  55. std::exit(1);
  56. }
  57. // This method takes a Record and uses the source location
  58. // stored in it.
  59. void PrintFatalNote(const Record *Rec, const Twine &Msg) {
  60. PrintNote(Rec->getLoc(), Msg);
  61. // The following call runs the file cleanup handlers.
  62. sys::RunInterruptHandlers();
  63. std::exit(1);
  64. }
  65. // This method takes a RecordVal and uses the source location
  66. // stored in it.
  67. void PrintFatalNote(const RecordVal *RecVal, const Twine &Msg) {
  68. PrintNote(RecVal->getLoc(), Msg);
  69. // The following call runs the file cleanup handlers.
  70. sys::RunInterruptHandlers();
  71. std::exit(1);
  72. }
  73. // Functions to print warnings.
  74. void PrintWarning(const Twine &Msg) { WithColor::warning() << Msg << "\n"; }
  75. void PrintWarning(ArrayRef<SMLoc> WarningLoc, const Twine &Msg) {
  76. PrintMessage(WarningLoc, SourceMgr::DK_Warning, Msg);
  77. }
  78. void PrintWarning(const char *Loc, const Twine &Msg) {
  79. SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Warning, Msg);
  80. }
  81. // Functions to print errors.
  82. void PrintError(const Twine &Msg) { WithColor::error() << Msg << "\n"; }
  83. void PrintError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
  84. PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
  85. }
  86. void PrintError(const char *Loc, const Twine &Msg) {
  87. SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
  88. }
  89. // This method takes a Record and uses the source location
  90. // stored in it.
  91. void PrintError(const Record *Rec, const Twine &Msg) {
  92. PrintMessage(Rec->getLoc(), SourceMgr::DK_Error, Msg);
  93. }
  94. // This method takes a RecordVal and uses the source location
  95. // stored in it.
  96. void PrintError(const RecordVal *RecVal, const Twine &Msg) {
  97. PrintMessage(RecVal->getLoc(), SourceMgr::DK_Error, Msg);
  98. }
  99. // Functions to print fatal errors.
  100. void PrintFatalError(const Twine &Msg) {
  101. PrintError(Msg);
  102. // The following call runs the file cleanup handlers.
  103. sys::RunInterruptHandlers();
  104. std::exit(1);
  105. }
  106. void PrintFatalError(ArrayRef<SMLoc> ErrorLoc, const Twine &Msg) {
  107. PrintError(ErrorLoc, Msg);
  108. // The following call runs the file cleanup handlers.
  109. sys::RunInterruptHandlers();
  110. std::exit(1);
  111. }
  112. // This method takes a Record and uses the source location
  113. // stored in it.
  114. void PrintFatalError(const Record *Rec, const Twine &Msg) {
  115. PrintError(Rec->getLoc(), Msg);
  116. // The following call runs the file cleanup handlers.
  117. sys::RunInterruptHandlers();
  118. std::exit(1);
  119. }
  120. // This method takes a RecordVal and uses the source location
  121. // stored in it.
  122. void PrintFatalError(const RecordVal *RecVal, const Twine &Msg) {
  123. PrintError(RecVal->getLoc(), Msg);
  124. // The following call runs the file cleanup handlers.
  125. sys::RunInterruptHandlers();
  126. std::exit(1);
  127. }
  128. // Check an assertion: Obtain the condition value and be sure it is true.
  129. // If not, print a nonfatal error along with the message.
  130. void CheckAssert(SMLoc Loc, Init *Condition, Init *Message) {
  131. auto *CondValue = dyn_cast_or_null<IntInit>(
  132. Condition->convertInitializerTo(IntRecTy::get()));
  133. if (!CondValue)
  134. PrintError(Loc, "assert condition must of type bit, bits, or int.");
  135. else if (!CondValue->getValue()) {
  136. PrintError(Loc, "assertion failed");
  137. if (auto *MessageInit = dyn_cast<StringInit>(Message))
  138. PrintNote(MessageInit->getValue());
  139. else
  140. PrintNote("(assert message is not a string)");
  141. }
  142. }
  143. } // end namespace llvm