DiagnosticInfo.cpp revision cd81d94322a39503e4a3e87b6ee03d4fcb3465fb
1//===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//
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 defines the different classes involved in low level diagnostics.
11//
12// Diagnostics reporting is still done as part of the LLVMContext.
13//===----------------------------------------------------------------------===//
14
15#include "LLVMContextImpl.h"
16#include "llvm/ADT/Twine.h"
17#include "llvm/IR/Constants.h"
18#include "llvm/IR/DebugInfo.h"
19#include "llvm/IR/DiagnosticInfo.h"
20#include "llvm/IR/DiagnosticPrinter.h"
21#include "llvm/IR/Function.h"
22#include "llvm/IR/Instruction.h"
23#include "llvm/IR/Metadata.h"
24#include "llvm/IR/Module.h"
25#include "llvm/Support/Atomic.h"
26#include "llvm/Support/CommandLine.h"
27#include "llvm/Support/Regex.h"
28#include <string>
29
30using namespace llvm;
31
32namespace {
33
34/// \brief Regular expression corresponding to the value given in one of the
35/// -pass-remarks* command line flags. Passes whose name matches this regexp
36/// will emit a diagnostic when calling the associated diagnostic function
37/// (emitOptimizationRemark, emitOptimizationRemarkMissed or
38/// emitOptimizationRemarkAnalysis).
39struct PassRemarksOpt {
40  std::shared_ptr<Regex> Pattern;
41
42  void operator=(const std::string &Val) {
43    // Create a regexp object to match pass names for emitOptimizationRemark.
44    if (!Val.empty()) {
45      Pattern = std::make_shared<Regex>(Val);
46      std::string RegexError;
47      if (!Pattern->isValid(RegexError))
48        report_fatal_error("Invalid regular expression '" + Val +
49                               "' in -pass-remarks: " + RegexError,
50                           false);
51    }
52  };
53};
54
55static PassRemarksOpt PassRemarksOptLoc;
56static PassRemarksOpt PassRemarksMissedOptLoc;
57static PassRemarksOpt PassRemarksAnalysisOptLoc;
58
59// -pass-remarks
60//    Command line flag to enable emitOptimizationRemark()
61static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
62PassRemarks("pass-remarks", cl::value_desc("pattern"),
63            cl::desc("Enable optimization remarks from passes whose name match "
64                     "the given regular expression"),
65            cl::Hidden, cl::location(PassRemarksOptLoc), cl::ValueRequired,
66            cl::ZeroOrMore);
67
68// -pass-remarks-missed
69//    Command line flag to enable emitOptimizationRemarkMissed()
70static cl::opt<PassRemarksOpt, true, cl::parser<std::string>> PassRemarksMissed(
71    "pass-remarks-missed", cl::value_desc("pattern"),
72    cl::desc("Enable missed optimization remarks from passes whose name match "
73             "the given regular expression"),
74    cl::Hidden, cl::location(PassRemarksMissedOptLoc), cl::ValueRequired,
75    cl::ZeroOrMore);
76
77// -pass-remarks-analysis
78//    Command line flag to enable emitOptimizationRemarkAnalysis()
79static cl::opt<PassRemarksOpt, true, cl::parser<std::string>>
80PassRemarksAnalysis(
81    "pass-remarks-analysis", cl::value_desc("pattern"),
82    cl::desc(
83        "Enable optimization analysis remarks from passes whose name match "
84        "the given regular expression"),
85    cl::Hidden, cl::location(PassRemarksAnalysisOptLoc), cl::ValueRequired,
86    cl::ZeroOrMore);
87}
88
89int llvm::getNextAvailablePluginDiagnosticKind() {
90  static sys::cas_flag PluginKindID = DK_FirstPluginKind;
91  return (int)sys::AtomicIncrement(&PluginKindID);
92}
93
94DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,
95                                                 const Twine &MsgStr,
96                                                 DiagnosticSeverity Severity)
97    : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),
98      Instr(&I) {
99  if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {
100    if (SrcLoc->getNumOperands() != 0)
101      if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))
102        LocCookie = CI->getZExtValue();
103  }
104}
105
106void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
107  DP << getMsgStr();
108  if (getLocCookie())
109    DP << " at line " << getLocCookie();
110}
111
112void DiagnosticInfoStackSize::print(DiagnosticPrinter &DP) const {
113  DP << "stack size limit exceeded (" << getStackSize() << ") in "
114     << getFunction();
115}
116
117void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const {
118  DP << "ignoring debug info with an invalid version (" << getMetadataVersion()
119     << ") in " << getModule();
120}
121
122void DiagnosticInfoSampleProfile::print(DiagnosticPrinter &DP) const {
123  if (getFileName() && getLineNum() > 0)
124    DP << getFileName() << ":" << getLineNum() << ": ";
125  else if (getFileName())
126    DP << getFileName() << ": ";
127  DP << getMsg();
128}
129
130bool DiagnosticInfoOptimizationRemarkBase::isLocationAvailable() const {
131  return getDebugLoc().isUnknown() == false;
132}
133
134void DiagnosticInfoOptimizationRemarkBase::getLocation(StringRef *Filename,
135                                                       unsigned *Line,
136                                                       unsigned *Column) const {
137  DILocation DIL(getDebugLoc().getAsMDNode(getFunction().getContext()));
138  *Filename = DIL.getFilename();
139  *Line = DIL.getLineNumber();
140  *Column = DIL.getColumnNumber();
141}
142
143const std::string DiagnosticInfoOptimizationRemarkBase::getLocationStr() const {
144  StringRef Filename("<unknown>");
145  unsigned Line = 0;
146  unsigned Column = 0;
147  if (isLocationAvailable())
148    getLocation(&Filename, &Line, &Column);
149  return Twine(Filename + ":" + Twine(Line) + ":" + Twine(Column)).str();
150}
151
152void DiagnosticInfoOptimizationRemarkBase::print(DiagnosticPrinter &DP) const {
153  DP << getLocationStr() << ": " << getMsg();
154}
155
156bool DiagnosticInfoOptimizationRemark::isEnabled() const {
157  return PassRemarksOptLoc.Pattern &&
158         PassRemarksOptLoc.Pattern->match(getPassName());
159}
160
161bool DiagnosticInfoOptimizationRemarkMissed::isEnabled() const {
162  return PassRemarksMissedOptLoc.Pattern &&
163         PassRemarksMissedOptLoc.Pattern->match(getPassName());
164}
165
166bool DiagnosticInfoOptimizationRemarkAnalysis::isEnabled() const {
167  return PassRemarksAnalysisOptLoc.Pattern &&
168         PassRemarksAnalysisOptLoc.Pattern->match(getPassName());
169}
170
171void llvm::emitOptimizationRemark(LLVMContext &Ctx, const char *PassName,
172                                  const Function &Fn, const DebugLoc &DLoc,
173                                  const Twine &Msg) {
174  Ctx.diagnose(DiagnosticInfoOptimizationRemark(PassName, Fn, DLoc, Msg));
175}
176
177void llvm::emitOptimizationRemarkMissed(LLVMContext &Ctx, const char *PassName,
178                                        const Function &Fn,
179                                        const DebugLoc &DLoc,
180                                        const Twine &Msg) {
181  Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, Fn, DLoc, Msg));
182}
183
184void llvm::emitOptimizationRemarkAnalysis(LLVMContext &Ctx,
185                                          const char *PassName,
186                                          const Function &Fn,
187                                          const DebugLoc &DLoc,
188                                          const Twine &Msg) {
189  Ctx.diagnose(
190      DiagnosticInfoOptimizationRemarkAnalysis(PassName, Fn, DLoc, Msg));
191}
192