<div dir="ltr">Sorry, the IR dependency has always been there.  The new one is Analysis and CodeGen in DiagnosticPrinter.cpp.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Dec 16, 2013 at 4:41 PM, Reid Kleckner <span dir="ltr"><<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">DiagnosticInfo.cpp appears to introduce a bunch of link-time dependencies on IR from Support.  Are you sure that's the right library for it?</div>
<div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><br><div class="gmail_quote">
On Mon, Dec 16, 2013 at 3:22 PM, Quentin Colombet <span dir="ltr"><<a href="mailto:qcolombet@apple.com" target="_blank">qcolombet@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

Author: qcolombet<br>
Date: Mon Dec 16 17:22:51 2013<br>
New Revision: 197438<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=197438&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=197438&view=rev</a><br>
Log:<br>
Add warning capabilities in LLVM.<br>
<br>
The patch adds a new LLVMContext::diagnose that can be used to communicate to<br>
the front-end, if any, that something of interest happened.<br>
The diagnostics are supported by a new abstraction, the DiagnosticInfo class.<br>
The base class contains the following information:<br>
- The kind of the report: What this is about.<br>
- The severity of the report: How bad this is.<br>
<br>
This patch also adds 2 classes:<br>
- DiagnosticInfoInlineAsm: For inline asm reporting. Basically, this diagnostic<br>
will be used to switch to the new diagnostic API for LLVMContext::emitError.<br>
- DiagnosticStackSize: For stack size reporting. Comes as a replacement of the<br>
hard coded warning in PEI.<br>
<br>
This patch also features dynamic diagnostic identifiers. In other words plugins<br>
can use this infrastructure for their own diagnostics (for more details, see<br>
getNextAvailablePluginDiagnosticKind).<br>
<br>
This patch introduces a new DiagnosticHandlerTy and a new DiagnosticContext in<br>
the LLVMContext that should be set by the front-end to be able to map these<br>
diagnostics in its own system.<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D2376" target="_blank">http://llvm-reviews.chandlerc.com/D2376</a><br>
<rdar://problem/15515174><br>
<br>
Added:<br>
    llvm/trunk/include/llvm/Support/DiagnosticInfo.h<br>
    llvm/trunk/include/llvm/Support/DiagnosticPrinter.h<br>
    llvm/trunk/lib/Support/DiagnosticInfo.cpp<br>
    llvm/trunk/lib/Support/DiagnosticPrinter.cpp<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/LLVMContext.h<br>
    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp<br>
    llvm/trunk/lib/IR/LLVMContext.cpp<br>
    llvm/trunk/lib/IR/LLVMContextImpl.cpp<br>
    llvm/trunk/lib/IR/LLVMContextImpl.h<br>
    llvm/trunk/lib/Support/CMakeLists.txt<br>
    llvm/trunk/test/CodeGen/ARM/warn-stack.ll<br>
    llvm/trunk/test/CodeGen/X86/warn-stack.ll<br>
<br>
Modified: llvm/trunk/include/llvm/IR/LLVMContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=197438&r1=197437&r2=197438&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=197438&r1=197437&r2=197438&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/IR/LLVMContext.h (original)<br>
+++ llvm/trunk/include/llvm/IR/LLVMContext.h Mon Dec 16 17:22:51 2013<br>
@@ -27,6 +27,7 @@ class Twine;<br>
 class Instruction;<br>
 class Module;<br>
 class SMDiagnostic;<br>
+class DiagnosticInfo;<br>
 template <typename T> class SmallVectorImpl;<br>
<br>
 /// This is an important class for using LLVM in a threaded context.  It<br>
@@ -64,6 +65,11 @@ public:<br>
   typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,<br>
                                          unsigned LocCookie);<br>
<br>
+  /// Defines the type of a diagnostic handler.<br>
+  /// \see LLVMContext::setDiagnosticHandler.<br>
+  /// \see LLVMContext::diagnose.<br>
+  typedef void (*DiagnosticHandlerTy)(const DiagnosticInfo &DI, void *Context);<br>
+<br>
   /// setInlineAsmDiagnosticHandler - This method sets a handler that is invoked<br>
   /// when problems with inline asm are detected by the backend.  The first<br>
   /// argument is a function pointer and the second is a context pointer that<br>
@@ -82,6 +88,33 @@ public:<br>
   /// setInlineAsmDiagnosticHandler.<br>
   void *getInlineAsmDiagnosticContext() const;<br>
<br>
+  /// setDiagnosticHandler - This method sets a handler that is invoked<br>
+  /// when the backend needs to report anything to the user.  The first<br>
+  /// argument is a function pointer and the second is a context pointer that<br>
+  /// gets passed into the DiagHandler.<br>
+  ///<br>
+  /// LLVMContext doesn't take ownership or interpret either of these<br>
+  /// pointers.<br>
+  void setDiagnosticHandler(DiagnosticHandlerTy DiagHandler,<br>
+                            void *DiagContext = 0);<br>
+<br>
+  /// getDiagnosticHandler - Return the diagnostic handler set by<br>
+  /// setDiagnosticHandler.<br>
+  DiagnosticHandlerTy getDiagnosticHandler() const;<br>
+<br>
+  /// getDiagnosticContext - Return the diagnostic context set by<br>
+  /// setDiagnosticContext.<br>
+  void *getDiagnosticContext() const;<br>
+<br>
+  /// diagnose - Report a message to the currently installed diagnostic handler.<br>
+  /// This function returns, in particular in the case of error reporting<br>
+  /// (DI.Severity == RS_Error), so the caller should leave the compilation<br>
+  /// process in a self-consistent state, even though the generated code<br>
+  /// need not be correct.<br>
+  /// The diagnostic message will be implicitly prefixed with a severity<br>
+  /// keyword according to \p DI.getSeverity(), i.e., "error: "<br>
+  /// for RS_Error, "warning: " for RS_Warning, and "note: " for RS_Note.<br>
+  void diagnose(const DiagnosticInfo &DI);<br>
<br>
   /// emitError - Emit an error message to the currently installed error handler<br>
   /// with optional location information.  This function returns, so code should<br>
<br>
Added: llvm/trunk/include/llvm/Support/DiagnosticInfo.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DiagnosticInfo.h?rev=197438&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DiagnosticInfo.h?rev=197438&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/Support/DiagnosticInfo.h (added)<br>
+++ llvm/trunk/include/llvm/Support/DiagnosticInfo.h Mon Dec 16 17:22:51 2013<br>
@@ -0,0 +1,165 @@<br>
+//===- llvm/Support/DiagnosticInfo.h - Diagnostic Declaration ---*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file declares the different classes involved in low level diagnostics.<br>
+//<br>
+// Diagnostics reporting is still done as part of the LLVMContext.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_SUPPORT_DIAGNOSTICINFO_H<br>
+#define LLVM_SUPPORT_DIAGNOSTICINFO_H<br>
+<br>
+#include "llvm/ADT/ArrayRef.h"<br>
+#include "llvm/Support/Casting.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+// Forward declarations.<br>
+class DiagnosticPrinter;<br>
+class Function;<br>
+class Instruction;<br>
+class Twine;<br>
+class Value;<br>
+<br>
+/// \brief Defines the different supported severity of a diagnostic.<br>
+enum DiagnosticSeverity {<br>
+  DS_Error,<br>
+  DS_Warning,<br>
+  DS_Note<br>
+};<br>
+<br>
+/// \brief Defines the different supported kind of a diagnostic.<br>
+/// This enum should be extended with a new ID for each added concrete subclass.<br>
+enum DiagnosticKind {<br>
+  DK_InlineAsm,<br>
+  DK_StackSize,<br>
+  DK_FirstPluginKind<br>
+};<br>
+<br>
+/// \brief Get the next available kind ID for a plugin diagnostic.<br>
+/// Each time this function is called, it returns a different number.<br>
+/// Therefore, a plugin that wants to "identify" its own classes<br>
+/// with a dynamic identifier, just have to use this method to get a new ID<br>
+/// and assign it to each of its classes.<br>
+/// The returned ID will be greater than or equal to DK_FirstPluginKind.<br>
+/// Thus, the plugin identifiers will not conflict with the<br>
+/// DiagnosticKind values.<br>
+int getNextAvailablePluginDiagnosticKind();<br>
+<br>
+/// \brief This is the base abstract class for diagnostic reporting in<br>
+/// the backend.<br>
+/// The print method must be overloaded by the subclasses to print a<br>
+/// user-friendly message in the client of the backend (let us call it a<br>
+/// frontend).<br>
+class DiagnosticInfo {<br>
+private:<br>
+  /// Kind defines the kind of report this is about.<br>
+  const /* DiagnosticKind */ int Kind;<br>
+  /// Severity gives the severity of the diagnostic.<br>
+  const DiagnosticSeverity Severity;<br>
+<br>
+public:<br>
+  DiagnosticInfo(/* DiagnosticKind */ int Kind, DiagnosticSeverity Severity)<br>
+      : Kind(Kind), Severity(Severity) {}<br>
+<br>
+  virtual ~DiagnosticInfo() {}<br>
+<br>
+  /* DiagnosticKind */ int getKind() const { return Kind; }<br>
+  DiagnosticSeverity getSeverity() const { return Severity; }<br>
+<br>
+  /// Print using the given \p DP a user-friendly message.<br>
+  /// This is the default message that will be printed to the user.<br>
+  /// It is used when the frontend does not directly take advantage<br>
+  /// of the information contained in fields of the subclasses.<br>
+  /// The printed message must not end with '.' nor start with a severity<br>
+  /// keyword.<br>
+  virtual void print(DiagnosticPrinter &DP) const = 0;<br>
+};<br>
+<br>
+/// Diagnostic information for inline asm reporting.<br>
+/// This is basically a message and an optional location.<br>
+class DiagnosticInfoInlineAsm : public DiagnosticInfo {<br>
+private:<br>
+  /// Optional line information. 0 if not set.<br>
+  unsigned LocCookie;<br>
+  /// Message to be reported.<br>
+  const Twine &MsgStr;<br>
+  /// Optional origin of the problem.<br>
+  const Instruction *Instr;<br>
+<br>
+public:<br>
+  /// \p MsgStr is the message to be reported to the frontend.<br>
+  /// This class does not copy \p MsgStr, therefore the reference must be valid<br>
+  /// for the whole life time of the Diagnostic.<br>
+  DiagnosticInfoInlineAsm(const Twine &MsgStr,<br>
+                          DiagnosticSeverity Severity = DS_Error)<br>
+      : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),<br>
+        Instr(NULL) {}<br>
+<br>
+  /// \p LocCookie if non-zero gives the line number for this report.<br>
+  /// \p MsgStr gives the message.<br>
+  /// This class does not copy \p MsgStr, therefore the reference must be valid<br>
+  /// for the whole life time of the Diagnostic.<br>
+  DiagnosticInfoInlineAsm(unsigned LocCookie, const Twine &MsgStr,<br>
+                          DiagnosticSeverity Severity = DS_Error)<br>
+      : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(LocCookie),<br>
+        MsgStr(MsgStr), Instr(NULL) {}<br>
+<br>
+  /// \p Instr gives the original instruction that triggered the diagnostic.<br>
+  /// \p MsgStr gives the message.<br>
+  /// This class does not copy \p MsgStr, therefore the reference must be valid<br>
+  /// for the whole life time of the Diagnostic.<br>
+  /// Same for \p I.<br>
+  DiagnosticInfoInlineAsm(const Instruction &I, const Twine &MsgStr,<br>
+                          DiagnosticSeverity Severity = DS_Error);<br>
+<br>
+  unsigned getLocCookie() const { return LocCookie; }<br>
+  const Twine &getMsgStr() const { return MsgStr; }<br>
+  const Instruction *getInstruction() const { return Instr; }<br>
+<br>
+  /// \see DiagnosticInfo::print.<br>
+  virtual void print(DiagnosticPrinter &DP) const;<br>
+<br>
+  /// Hand rolled RTTI.<br>
+  static bool classof(const DiagnosticInfo *DI) {<br>
+    return DI->getKind() == DK_InlineAsm;<br>
+  }<br>
+};<br>
+<br>
+/// Diagnostic information for stack size reporting.<br>
+/// This is basically a function and a size.<br>
+class DiagnosticInfoStackSize : public DiagnosticInfo {<br>
+private:<br>
+  /// The function that is concerned by this stack size diagnostic.<br>
+  const Function &Fn;<br>
+  /// The computed stack size.<br>
+  unsigned StackSize;<br>
+<br>
+public:<br>
+  /// \p The function that is concerned by this stack size diagnostic.<br>
+  /// \p The computed stack size.<br>
+  DiagnosticInfoStackSize(const Function &Fn, unsigned StackSize,<br>
+                          DiagnosticSeverity Severity = DS_Warning)<br>
+      : DiagnosticInfo(DK_StackSize, Severity), Fn(Fn), StackSize(StackSize) {}<br>
+<br>
+  const Function &getFunction() const { return Fn; }<br>
+  unsigned getStackSize() const { return StackSize; }<br>
+<br>
+  /// \see DiagnosticInfo::print.<br>
+  virtual void print(DiagnosticPrinter &DP) const;<br>
+<br>
+  /// Hand rolled RTTI.<br>
+  static bool classof(const DiagnosticInfo *DI) {<br>
+    return DI->getKind() == DK_StackSize;<br>
+  }<br>
+};<br>
+<br>
+} // End namespace llvm<br>
+<br>
+#endif<br>
<br>
Added: llvm/trunk/include/llvm/Support/DiagnosticPrinter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DiagnosticPrinter.h?rev=197438&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/DiagnosticPrinter.h?rev=197438&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/Support/DiagnosticPrinter.h (added)<br>
+++ llvm/trunk/include/llvm/Support/DiagnosticPrinter.h Mon Dec 16 17:22:51 2013<br>
@@ -0,0 +1,84 @@<br>
+//===- llvm/Support/DiagnosticPrinter.h - Diagnostic Printer ----*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file declares the main interface for printer backend diagnostic.<br>
+//<br>
+// Clients of the backend diagnostics should overload this interface based<br>
+// on their needs.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_SUPPORT_DIAGNOSTICPRINTER_H<br>
+#define LLVM_SUPPORT_DIAGNOSTICPRINTER_H<br>
+<br>
+#include <string><br>
+<br>
+namespace llvm {<br>
+// Forward declarations.<br>
+class raw_ostream;<br>
+class StringRef;<br>
+class Twine;<br>
+class Value;<br>
+<br>
+/// \brief Interface for custom diagnostic printing.<br>
+class DiagnosticPrinter {<br>
+public:<br>
+  virtual ~DiagnosticPrinter() {}<br>
+<br>
+  // Simple types.<br>
+  virtual DiagnosticPrinter &operator<<(char C) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(unsigned char C) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(signed char C) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(StringRef Str) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(const char *Str) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(const std::string &Str) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(unsigned long N) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(long N) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(unsigned long long N) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(long long N) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(const void *P) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(unsigned int N) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(int N) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(double N) = 0;<br>
+  virtual DiagnosticPrinter &operator<<(const Twine &Str) = 0;<br>
+<br>
+  // IR related types.<br>
+  virtual DiagnosticPrinter &operator<<(const Value &V) = 0;<br>
+};<br>
+<br>
+/// \brief Basic diagnostic printer that uses an underlying raw_ostream.<br>
+class DiagnosticPrinterRawOStream : public DiagnosticPrinter {<br>
+protected:<br>
+  raw_ostream &Stream;<br>
+<br>
+public:<br>
+  DiagnosticPrinterRawOStream(raw_ostream &Stream) : Stream(Stream) {};<br>
+<br>
+  // Simple types.<br>
+  virtual DiagnosticPrinter &operator<<(char C);<br>
+  virtual DiagnosticPrinter &operator<<(unsigned char C);<br>
+  virtual DiagnosticPrinter &operator<<(signed char C);<br>
+  virtual DiagnosticPrinter &operator<<(StringRef Str);<br>
+  virtual DiagnosticPrinter &operator<<(const char *Str);<br>
+  virtual DiagnosticPrinter &operator<<(const std::string &Str);<br>
+  virtual DiagnosticPrinter &operator<<(unsigned long N);<br>
+  virtual DiagnosticPrinter &operator<<(long N);<br>
+  virtual DiagnosticPrinter &operator<<(unsigned long long N);<br>
+  virtual DiagnosticPrinter &operator<<(long long N);<br>
+  virtual DiagnosticPrinter &operator<<(const void *P);<br>
+  virtual DiagnosticPrinter &operator<<(unsigned int N);<br>
+  virtual DiagnosticPrinter &operator<<(int N);<br>
+  virtual DiagnosticPrinter &operator<<(double N);<br>
+  virtual DiagnosticPrinter &operator<<(const Twine &Str);<br>
+<br>
+  // IR related types.<br>
+  virtual DiagnosticPrinter &operator<<(const Value &V);<br>
+};<br>
+} // End namespace llvm<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=197438&r1=197437&r2=197438&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp?rev=197438&r1=197437&r2=197438&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp Mon Dec 16 17:22:51 2013<br>
@@ -30,9 +30,11 @@<br>
 #include "llvm/CodeGen/MachineRegisterInfo.h"<br>
 #include "llvm/CodeGen/RegisterScavenging.h"<br>
 #include "llvm/IR/InlineAsm.h"<br>
+#include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/Support/CommandLine.h"<br>
 #include "llvm/Support/Compiler.h"<br>
 #include "llvm/Support/Debug.h"<br>
+#include "llvm/Support/DiagnosticInfo.h"<br>
 #include "llvm/Support/raw_ostream.h"<br>
 #include "llvm/Target/TargetFrameLowering.h"<br>
 #include "llvm/Target/TargetInstrInfo.h"<br>
@@ -160,10 +162,11 @@ bool PEI::runOnMachineFunction(MachineFu<br>
<br>
   // Warn on stack size when we exceeds the given limit.<br>
   MachineFrameInfo *MFI = Fn.getFrameInfo();<br>
-  if (WarnStackSize.getNumOccurrences() > 0 &&<br>
-      WarnStackSize < MFI->getStackSize())<br>
-    errs() << "warning: Stack size limit exceeded (" << MFI->getStackSize()<br>
-           << ") in " << Fn.getName()  << ".\n";<br>
+  uint64_t StackSize = MFI->getStackSize();<br>
+  if (WarnStackSize.getNumOccurrences() > 0 && WarnStackSize < StackSize) {<br>
+    DiagnosticInfoStackSize DiagStackSize(*F, StackSize);<br>
+    F->getContext().diagnose(DiagStackSize);<br>
+  }<br>
<br>
   delete RS;<br>
   ReturnBlocks.clear();<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContext.cpp?rev=197438&r1=197437&r2=197438&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContext.cpp?rev=197438&r1=197437&r2=197438&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContext.cpp (original)<br>
+++ llvm/trunk/lib/IR/LLVMContext.cpp Mon Dec 16 17:22:51 2013<br>
@@ -17,6 +17,8 @@<br>
 #include "llvm/IR/Constants.h"<br>
 #include "llvm/IR/Instruction.h"<br>
 #include "llvm/IR/Metadata.h"<br>
+#include "llvm/Support/DiagnosticInfo.h"<br>
+#include "llvm/Support/DiagnosticPrinter.h"<br>
 #include "llvm/Support/ManagedStatic.h"<br>
 #include "llvm/Support/SourceMgr.h"<br>
 #include <cctype><br>
@@ -98,6 +100,20 @@ void *LLVMContext::getInlineAsmDiagnosti<br>
   return pImpl->InlineAsmDiagContext;<br>
 }<br>
<br>
+void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,<br>
+                                       void *DiagnosticContext) {<br>
+  pImpl->DiagnosticHandler = DiagnosticHandler;<br>
+  pImpl->DiagnosticContext = DiagnosticContext;<br>
+}<br>
+<br>
+LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {<br>
+  return pImpl->DiagnosticHandler;<br>
+}<br>
+<br>
+void *LLVMContext::getDiagnosticContext() const {<br>
+  return pImpl->DiagnosticContext;<br>
+}<br>
+<br>
 void LLVMContext::emitError(const Twine &ErrorStr) {<br>
   emitError(0U, ErrorStr);<br>
 }<br>
@@ -112,6 +128,31 @@ void LLVMContext::emitError(const Instru<br>
   return emitError(LocCookie, ErrorStr);<br>
 }<br>
<br>
+void LLVMContext::diagnose(const DiagnosticInfo &DI) {<br>
+  // If there is a report handler, use it.<br>
+  if (pImpl->DiagnosticHandler != 0) {<br>
+    pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext);<br>
+    return;<br>
+  }<br>
+  // Otherwise, print the message with a prefix based on the severity.<br>
+  std::string MsgStorage;<br>
+  raw_string_ostream Stream(MsgStorage);<br>
+  DiagnosticPrinterRawOStream DP(Stream);<br>
+  DI.print(DP);<br>
+  Stream.flush();<br>
+  switch (DI.getSeverity()) {<br>
+  case DS_Error:<br>
+    errs() << "error: " << MsgStorage << "\n";<br>
+    exit(1);<br>
+  case DS_Warning:<br>
+    errs() << "warning: " << MsgStorage << "\n";<br>
+    break;<br>
+  case DS_Note:<br>
+    errs() << "note: " << MsgStorage << "\n";<br>
+    break;<br>
+  }<br>
+}<br>
+<br>
 void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {<br>
   // If there is no error handler installed, just print the error and exit.<br>
   if (pImpl->InlineAsmDiagHandler == 0) {<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=197438&r1=197437&r2=197438&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=197438&r1=197437&r2=197438&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)<br>
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Mon Dec 16 17:22:51 2013<br>
@@ -37,6 +37,8 @@ LLVMContextImpl::LLVMContextImpl(LLVMCon<br>
     Int64Ty(C, 64) {<br>
   InlineAsmDiagHandler = 0;<br>
   InlineAsmDiagContext = 0;<br>
+  DiagnosticHandler = 0;<br>
+  DiagnosticContext = 0;<br>
   NamedStructTypesUniqueID = 0;<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=197438&r1=197437&r2=197438&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=197438&r1=197437&r2=197438&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)<br>
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Mon Dec 16 17:22:51 2013<br>
@@ -238,9 +238,12 @@ public:<br>
<br>
   LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler;<br>
   void *InlineAsmDiagContext;<br>
-<br>
-  typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,<br>
-                         DenseMapAPIntKeyInfo> IntMapTy;<br>
+<br>
+  LLVMContext::DiagnosticHandlerTy DiagnosticHandler;<br>
+  void *DiagnosticContext;<br>
+<br>
+  typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt *,<br>
+                   DenseMapAPIntKeyInfo> IntMapTy;<br>
   IntMapTy IntConstants;<br>
<br>
   typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*,<br>
<br>
Modified: llvm/trunk/lib/Support/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=197438&r1=197437&r2=197438&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/CMakeLists.txt?rev=197438&r1=197437&r2=197438&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/Support/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/Support/CMakeLists.txt Mon Dec 16 17:22:51 2013<br>
@@ -17,6 +17,8 @@ add_llvm_library(LLVMSupport<br>
   Debug.cpp<br>
   DeltaAlgorithm.cpp<br>
   DAGDeltaAlgorithm.cpp<br>
+  DiagnosticInfo.cpp<br>
+  DiagnosticPrinter.cpp<br>
   Dwarf.cpp<br>
   ErrorHandling.cpp<br>
   FileUtilities.cpp<br>
<br>
Added: llvm/trunk/lib/Support/DiagnosticInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DiagnosticInfo.cpp?rev=197438&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DiagnosticInfo.cpp?rev=197438&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/lib/Support/DiagnosticInfo.cpp (added)<br>
+++ llvm/trunk/lib/Support/DiagnosticInfo.cpp Mon Dec 16 17:22:51 2013<br>
@@ -0,0 +1,54 @@<br>
+//===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines the different classes involved in low level diagnostics.<br>
+//<br>
+// Diagnostics reporting is still done as part of the LLVMContext.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/ADT/Twine.h"<br>
+#include "llvm/IR/Constants.h"<br>
+#include "llvm/IR/Function.h"<br>
+#include "llvm/IR/Instruction.h"<br>
+#include "llvm/IR/Metadata.h"<br>
+#include "llvm/Support/Atomic.h"<br>
+#include "llvm/Support/DiagnosticInfo.h"<br>
+#include "llvm/Support/DiagnosticPrinter.h"<br>
+<br>
+#include <string><br>
+<br>
+using namespace llvm;<br>
+<br>
+int getNextAvailablePluginDiagnosticKind() {<br>
+  static sys::cas_flag PluginKindID = DK_FirstPluginKind;<br>
+  return (int)sys::AtomicIncrement(&PluginKindID);<br>
+}<br>
+<br>
+DiagnosticInfoInlineAsm::DiagnosticInfoInlineAsm(const Instruction &I,<br>
+                                                 const Twine &MsgStr,<br>
+                                                 DiagnosticSeverity Severity)<br>
+    : DiagnosticInfo(DK_InlineAsm, Severity), LocCookie(0), MsgStr(MsgStr),<br>
+      Instr(&I) {<br>
+  if (const MDNode *SrcLoc = I.getMetadata("srcloc")) {<br>
+    if (SrcLoc->getNumOperands() != 0)<br>
+      if (const ConstantInt *CI = dyn_cast<ConstantInt>(SrcLoc->getOperand(0)))<br>
+        LocCookie = CI->getZExtValue();<br>
+  }<br>
+}<br>
+<br>
+void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {<br>
+  DP << getMsgStr();<br>
+  if (getLocCookie())<br>
+    DP << " at line " << getLocCookie();<br>
+}<br>
+<br>
+void DiagnosticInfoStackSize::print(DiagnosticPrinter &DP) const {<br>
+  DP << "stack size limit exceeded (" << getStackSize() << ") in "<br>
+     << getFunction();<br>
+}<br>
<br>
Added: llvm/trunk/lib/Support/DiagnosticPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DiagnosticPrinter.cpp?rev=197438&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/DiagnosticPrinter.cpp?rev=197438&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/lib/Support/DiagnosticPrinter.cpp (added)<br>
+++ llvm/trunk/lib/Support/DiagnosticPrinter.cpp Mon Dec 16 17:22:51 2013<br>
@@ -0,0 +1,103 @@<br>
+//===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines the a diagnostic printer relying on raw_ostream.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/ADT/Twine.h"<br>
+#include "llvm/Analysis/ScalarEvolution.h"<br>
+#include "llvm/CodeGen/MachineInstr.h"<br>
+#include "llvm/IR/Value.h"<br>
+#include "llvm/Support/DiagnosticPrinter.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(char C) {<br>
+  Stream << C;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned char C) {<br>
+  Stream << C;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(signed char C) {<br>
+  Stream << C;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(StringRef Str) {<br>
+  Stream << Str;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const char *Str) {<br>
+  Stream << Str;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(<br>
+    const std::string &Str) {<br>
+  Stream << Str;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned long N) {<br>
+  Stream << N;<br>
+  return *this;<br>
+}<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(long N) {<br>
+  Stream << N;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(<br>
+    unsigned long long N) {<br>
+  Stream << N;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(long long N) {<br>
+  Stream << N;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const void *P) {<br>
+  Stream << P;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned int N) {<br>
+  Stream << N;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(int N) {<br>
+  Stream << N;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(double N) {<br>
+  Stream << N;<br>
+  return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Twine &Str) {<br>
+  Stream << Str.getSingleStringRef();<br>
+  return *this;<br>
+}<br>
+<br>
+// IR related types.<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Value &V) {<br>
+  Stream << V.getName();<br>
+  return *this;<br>
+}<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/warn-stack.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/warn-stack.ll?rev=197438&r1=197437&r2=197438&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/warn-stack.ll?rev=197438&r1=197437&r2=197438&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/test/CodeGen/ARM/warn-stack.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/warn-stack.ll Mon Dec 16 17:22:51 2013<br>
@@ -12,7 +12,7 @@ entry:<br>
   ret void<br>
 }<br>
<br>
-; CHECK: warning: Stack size limit exceeded (96) in warn.<br>
+; CHECK: warning: stack size limit exceeded (96) in warn<br>
 define void @warn() nounwind ssp {<br>
 entry:<br>
   %buffer = alloca [80 x i8], align 1<br>
<br>
Modified: llvm/trunk/test/CodeGen/X86/warn-stack.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/warn-stack.ll?rev=197438&r1=197437&r2=197438&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/warn-stack.ll?rev=197438&r1=197437&r2=197438&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/test/CodeGen/X86/warn-stack.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/warn-stack.ll Mon Dec 16 17:22:51 2013<br>
@@ -12,7 +12,7 @@ entry:<br>
   ret void<br>
 }<br>
<br>
-; CHECK: warning: Stack size limit exceeded (104) in warn.<br>
+; CHECK: warning: stack size limit exceeded (104) in warn<br>
 define void @warn() nounwind ssp {<br>
 entry:<br>
   %buffer = alloca [80 x i8], align 1<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>