Debug.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //===-- Debug.cpp - An easy way to add debug output to your code ----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements a handy way of adding debugging information to your
  11. // code, without it being enabled all of the time, and without having to add
  12. // command line options to enable it.
  13. //
  14. // In particular, just wrap your code with the DEBUG() macro, and it will be
  15. // enabled automatically if you specify '-debug' on the command-line.
  16. // Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
  17. // that your debug code belongs to class "foo". Then, on the command line, you
  18. // can specify '-debug-only=foo' to enable JUST the debug information for the
  19. // foo class.
  20. //
  21. // When compiling without assertions, the -debug-* options and all code in
  22. // DEBUG() statements disappears, so it does not affect the runtime of the code.
  23. //
  24. //===----------------------------------------------------------------------===//
  25. #include "llvm/Support/Debug.h"
  26. #include "llvm/Support/CommandLine.h"
  27. #include "llvm/Support/ManagedStatic.h"
  28. #include "llvm/Support/Signals.h"
  29. #include "llvm/Support/circular_raw_ostream.h"
  30. #include "llvm/Support/raw_ostream.h"
  31. #include "dxc/Support/WinIncludes.h" // HLSL Change
  32. #undef isCurrentDebugType
  33. #undef setCurrentDebugType
  34. using namespace llvm;
  35. // Even though LLVM might be built with NDEBUG, define symbols that the code
  36. // built without NDEBUG can depend on via the llvm/Support/Debug.h header.
  37. namespace llvm {
  38. /// Exported boolean set by the -debug option.
  39. bool DebugFlag = false;
  40. static ManagedStatic<std::vector<std::string>> CurrentDebugType;
  41. /// Return true if the specified string is the debug type
  42. /// specified on the command line, or if none was specified on the command line
  43. /// with the -debug-only=X option.
  44. bool isCurrentDebugType(const char *DebugType) {
  45. if (CurrentDebugType->empty())
  46. return true;
  47. // See if DebugType is in list. Note: do not use find() as that forces us to
  48. // unnecessarily create an std::string instance.
  49. for (auto &d : *CurrentDebugType) {
  50. if (d == DebugType)
  51. return true;
  52. }
  53. return false;
  54. }
  55. /// Set the current debug type, as if the -debug-only=X
  56. /// option were specified. Note that DebugFlag also needs to be set to true for
  57. /// debug output to be produced.
  58. ///
  59. void setCurrentDebugType(const char *Type) {
  60. CurrentDebugType->clear();
  61. CurrentDebugType->push_back(Type);
  62. }
  63. } // namespace llvm
  64. // All Debug.h functionality is a no-op in NDEBUG mode.
  65. #ifndef NDEBUG
  66. #if 1 // HLSL Change Starts - redirect to OutputDebugString
  67. namespace llvm {
  68. raw_ostream &dbgs() {
  69. struct ods_ostream : public llvm::raw_ostream {
  70. ods_ostream() {
  71. SetUnbuffered();
  72. }
  73. uint64_t current_pos() const override { return 0; }
  74. void write_impl(const char *Ptr, size_t Size) override {
  75. // Need a null-terminated string here.
  76. char chunk[512];
  77. while (Size > 0) {
  78. size_t len = std::min(Size, _countof(chunk) - 1);
  79. memcpy(chunk, Ptr, len);
  80. chunk[len] = '\0';
  81. OutputDebugStringA(chunk);
  82. Size -= len;
  83. Ptr += len;
  84. }
  85. }
  86. };
  87. static ods_ostream the_stream;
  88. return the_stream;
  89. }
  90. }
  91. #else
  92. // -debug - Command line option to enable the DEBUG statements in the passes.
  93. // This flag may only be enabled in debug builds.
  94. static cl::opt<bool, true>
  95. Debug("debug", cl::desc("Enable debug output"), cl::Hidden,
  96. cl::location(DebugFlag));
  97. // -debug-buffer-size - Buffer the last N characters of debug output
  98. //until program termination.
  99. static cl::opt<unsigned>
  100. DebugBufferSize("debug-buffer-size",
  101. cl::desc("Buffer the last N characters of debug output "
  102. "until program termination. "
  103. "[default 0 -- immediate print-out]"),
  104. cl::Hidden,
  105. cl::init(0));
  106. namespace {
  107. struct DebugOnlyOpt {
  108. void operator=(const std::string &Val) const {
  109. if (Val.empty())
  110. return;
  111. DebugFlag = true;
  112. CurrentDebugType->push_back(Val);
  113. }
  114. };
  115. }
  116. static DebugOnlyOpt DebugOnlyOptLoc;
  117. static cl::opt<DebugOnlyOpt, true, cl::parser<std::string> >
  118. DebugOnly("debug-only", cl::desc("Enable a specific type of debug output"),
  119. cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"),
  120. cl::location(DebugOnlyOptLoc), cl::ValueRequired);
  121. // Signal handlers - dump debug output on termination.
  122. static void debug_user_sig_handler(void *Cookie) {
  123. // This is a bit sneaky. Since this is under #ifndef NDEBUG, we
  124. // know that debug mode is enabled and dbgs() really is a
  125. // circular_raw_ostream. If NDEBUG is defined, then dbgs() ==
  126. // errs() but this will never be invoked.
  127. llvm::circular_raw_ostream &dbgout =
  128. static_cast<circular_raw_ostream &>(llvm::dbgs());
  129. dbgout.flushBufferWithBanner();
  130. }
  131. /// dbgs - Return a circular-buffered debug stream.
  132. raw_ostream &llvm::dbgs() {
  133. // Do one-time initialization in a thread-safe way.
  134. static struct dbgstream {
  135. circular_raw_ostream strm;
  136. dbgstream() :
  137. strm(errs(), "*** Debug Log Output ***\n",
  138. (!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) {
  139. if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0)
  140. // TODO: Add a handler for SIGUSER1-type signals so the user can
  141. // force a debug dump.
  142. sys::AddSignalHandler(&debug_user_sig_handler, nullptr);
  143. // Otherwise we've already set the debug stream buffer size to
  144. // zero, disabling buffering so it will output directly to errs().
  145. }
  146. } thestrm;
  147. return thestrm.strm;
  148. }
  149. #endif // HLSL Change Ends - redirect to OutputDebugString
  150. #else
  151. // Avoid "has no symbols" warning.
  152. namespace llvm {
  153. /// dbgs - Return errs().
  154. raw_ostream &dbgs() {
  155. return errs();
  156. }
  157. }
  158. #endif
  159. /// EnableDebugBuffering - Turn on signal handler installation.
  160. ///
  161. bool llvm::EnableDebugBuffering = false;