1193323Sed//===-- Debug.cpp - An easy way to add debug output to your code ----------===//
2193323Sed//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6193323Sed//
7193323Sed//===----------------------------------------------------------------------===//
8193323Sed//
9239462Sdim// This file implements a handy way of adding debugging information to your
10193323Sed// code, without it being enabled all of the time, and without having to add
11193323Sed// command line options to enable it.
12193323Sed//
13341825Sdim// In particular, just wrap your code with the LLVM_DEBUG() macro, and it will
14341825Sdim// be enabled automatically if you specify '-debug' on the command-line.
15193323Sed// Alternatively, you can also use the SET_DEBUG_TYPE("foo") macro to specify
16193323Sed// that your debug code belongs to class "foo".  Then, on the command line, you
17193323Sed// can specify '-debug-only=foo' to enable JUST the debug information for the
18193323Sed// foo class.
19193323Sed//
20239462Sdim// When compiling without assertions, the -debug-* options and all code in
21341825Sdim// LLVM_DEBUG() statements disappears, so it does not affect the runtime of the
22341825Sdim// code.
23193323Sed//
24193323Sed//===----------------------------------------------------------------------===//
25193323Sed
26249423Sdim#include "llvm/Support/Debug.h"
27193323Sed#include "llvm/Support/CommandLine.h"
28280031Sdim#include "llvm/Support/ManagedStatic.h"
29249423Sdim#include "llvm/Support/Signals.h"
30201360Srdivacky#include "llvm/Support/circular_raw_ostream.h"
31288943Sdim#include "llvm/Support/raw_ostream.h"
32201360Srdivacky
33288943Sdim#undef isCurrentDebugType
34288943Sdim#undef setCurrentDebugType
35314564Sdim#undef setCurrentDebugTypes
36288943Sdim
37193323Sedusing namespace llvm;
38193323Sed
39288943Sdim// Even though LLVM might be built with NDEBUG, define symbols that the code
40288943Sdim// built without NDEBUG can depend on via the llvm/Support/Debug.h header.
41288943Sdimnamespace llvm {
42288943Sdim/// Exported boolean set by the -debug option.
43288943Sdimbool DebugFlag = false;
44288943Sdim
45288943Sdimstatic ManagedStatic<std::vector<std::string>> CurrentDebugType;
46288943Sdim
47288943Sdim/// Return true if the specified string is the debug type
48288943Sdim/// specified on the command line, or if none was specified on the command line
49288943Sdim/// with the -debug-only=X option.
50288943Sdimbool isCurrentDebugType(const char *DebugType) {
51288943Sdim  if (CurrentDebugType->empty())
52288943Sdim    return true;
53288943Sdim  // See if DebugType is in list. Note: do not use find() as that forces us to
54288943Sdim  // unnecessarily create an std::string instance.
55288943Sdim  for (auto &d : *CurrentDebugType) {
56288943Sdim    if (d == DebugType)
57288943Sdim      return true;
58288943Sdim  }
59288943Sdim  return false;
60288943Sdim}
61288943Sdim
62288943Sdim/// Set the current debug type, as if the -debug-only=X
63288943Sdim/// option were specified.  Note that DebugFlag also needs to be set to true for
64288943Sdim/// debug output to be produced.
65288943Sdim///
66314564Sdimvoid setCurrentDebugTypes(const char **Types, unsigned Count);
67314564Sdim
68288943Sdimvoid setCurrentDebugType(const char *Type) {
69314564Sdim  setCurrentDebugTypes(&Type, 1);
70314564Sdim}
71314564Sdim
72314564Sdimvoid setCurrentDebugTypes(const char **Types, unsigned Count) {
73288943Sdim  CurrentDebugType->clear();
74314564Sdim  for (size_t T = 0; T < Count; ++T)
75314564Sdim    CurrentDebugType->push_back(Types[T]);
76288943Sdim}
77288943Sdim} // namespace llvm
78288943Sdim
79198090Srdivacky// All Debug.h functionality is a no-op in NDEBUG mode.
80198090Srdivacky#ifndef NDEBUG
81193323Sed
82198090Srdivacky// -debug - Command line option to enable the DEBUG statements in the passes.
83198090Srdivacky// This flag may only be enabled in debug builds.
84198090Srdivackystatic cl::opt<bool, true>
85198090SrdivackyDebug("debug", cl::desc("Enable debug output"), cl::Hidden,
86198090Srdivacky      cl::location(DebugFlag));
87193323Sed
88201360Srdivacky// -debug-buffer-size - Buffer the last N characters of debug output
89201360Srdivacky//until program termination.
90201360Srdivackystatic cl::opt<unsigned>
91201360SrdivackyDebugBufferSize("debug-buffer-size",
92249423Sdim                cl::desc("Buffer the last N characters of debug output "
93201360Srdivacky                         "until program termination. "
94201360Srdivacky                         "[default 0 -- immediate print-out]"),
95201360Srdivacky                cl::Hidden,
96201360Srdivacky                cl::init(0));
97201360Srdivacky
98207618Srdivackynamespace {
99207618Srdivacky
100207618Srdivackystruct DebugOnlyOpt {
101198090Srdivacky  void operator=(const std::string &Val) const {
102280031Sdim    if (Val.empty())
103280031Sdim      return;
104280031Sdim    DebugFlag = true;
105296417Sdim    SmallVector<StringRef,8> dbgTypes;
106296417Sdim    StringRef(Val).split(dbgTypes, ',', -1, false);
107296417Sdim    for (auto dbgType : dbgTypes)
108296417Sdim      CurrentDebugType->push_back(dbgType);
109198090Srdivacky  }
110207618Srdivacky};
111193323Sed
112207618Srdivacky}
113207618Srdivacky
114207618Srdivackystatic DebugOnlyOpt DebugOnlyOptLoc;
115207618Srdivacky
116198090Srdivackystatic cl::opt<DebugOnlyOpt, true, cl::parser<std::string> >
117296417SdimDebugOnly("debug-only", cl::desc("Enable a specific type of debug output (comma separated list of types)"),
118280031Sdim          cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"),
119198090Srdivacky          cl::location(DebugOnlyOptLoc), cl::ValueRequired);
120201360Srdivacky// Signal handlers - dump debug output on termination.
121206083Srdivackystatic void debug_user_sig_handler(void *Cookie) {
122201360Srdivacky  // This is a bit sneaky.  Since this is under #ifndef NDEBUG, we
123201360Srdivacky  // know that debug mode is enabled and dbgs() really is a
124201360Srdivacky  // circular_raw_ostream.  If NDEBUG is defined, then dbgs() ==
125201360Srdivacky  // errs() but this will never be invoked.
126288943Sdim  llvm::circular_raw_ostream &dbgout =
127288943Sdim      static_cast<circular_raw_ostream &>(llvm::dbgs());
128288943Sdim  dbgout.flushBufferWithBanner();
129201360Srdivacky}
130201360Srdivacky
131201360Srdivacky/// dbgs - Return a circular-buffered debug stream.
132201360Srdivackyraw_ostream &llvm::dbgs() {
133201360Srdivacky  // Do one-time initialization in a thread-safe way.
134201360Srdivacky  static struct dbgstream {
135201360Srdivacky    circular_raw_ostream strm;
136201360Srdivacky
137201360Srdivacky    dbgstream() :
138201360Srdivacky        strm(errs(), "*** Debug Log Output ***\n",
139201360Srdivacky             (!EnableDebugBuffering || !DebugFlag) ? 0 : DebugBufferSize) {
140201360Srdivacky      if (EnableDebugBuffering && DebugFlag && DebugBufferSize != 0)
141201360Srdivacky        // TODO: Add a handler for SIGUSER1-type signals so the user can
142201360Srdivacky        // force a debug dump.
143276479Sdim        sys::AddSignalHandler(&debug_user_sig_handler, nullptr);
144201360Srdivacky      // Otherwise we've already set the debug stream buffer size to
145201360Srdivacky      // zero, disabling buffering so it will output directly to errs().
146201360Srdivacky    }
147201360Srdivacky  } thestrm;
148201360Srdivacky
149201360Srdivacky  return thestrm.strm;
150201360Srdivacky}
151201360Srdivacky
152193323Sed#else
153198090Srdivacky// Avoid "has no symbols" warning.
154198892Srdivackynamespace llvm {
155202878Srdivacky  /// dbgs - Return errs().
156201360Srdivacky  raw_ostream &dbgs() {
157202878Srdivacky    return errs();
158201360Srdivacky  }
159198892Srdivacky}
160201360Srdivacky
161193323Sed#endif
162201360Srdivacky
163201360Srdivacky/// EnableDebugBuffering - Turn on signal handler installation.
164201360Srdivacky///
165201360Srdivackybool llvm::EnableDebugBuffering = false;
166