[llvm] r197508 - Add warning capabilities in LLVM.

Quentin Colombet qcolombet at apple.com
Tue Dec 17 09:47:23 PST 2013


Author: qcolombet
Date: Tue Dec 17 11:47:22 2013
New Revision: 197508

URL: http://llvm.org/viewvc/llvm-project?rev=197508&view=rev
Log:
Add warning capabilities in LLVM.
This reapplies r197438 and fixes the link-time circular dependency between
IR and Support. The fix consists in moving the diagnostic support into IR.

The patch adds a new LLVMContext::diagnose that can be used to communicate to
the front-end, if any, that something of interest happened.
The diagnostics are supported by a new abstraction, the DiagnosticInfo class.
The base class contains the following information:
- The kind of the report: What this is about.
- The severity of the report: How bad this is.

This patch also adds 2 classes:
- DiagnosticInfoInlineAsm: For inline asm reporting. Basically, this diagnostic
will be used to switch to the new diagnostic API for LLVMContext::emitError.
- DiagnosticStackSize: For stack size reporting. Comes as a replacement of the
hard coded warning in PEI.

This patch also features dynamic diagnostic identifiers. In other words plugins
can use this infrastructure for their own diagnostics (for more details, see
getNextAvailablePluginDiagnosticKind).

This patch introduces a new DiagnosticHandlerTy and a new DiagnosticContext in
the LLVMContext that should be set by the front-end to be able to map these
diagnostics in its own system.

http://llvm-reviews.chandlerc.com/D2376
<rdar://problem/15515174>

Added:
    llvm/trunk/include/llvm/IR/DiagnosticInfo.h
    llvm/trunk/include/llvm/IR/DiagnosticPrinter.h
    llvm/trunk/lib/IR/DiagnosticInfo.cpp
    llvm/trunk/lib/IR/DiagnosticPrinter.cpp
Modified:
    llvm/trunk/include/llvm/IR/LLVMContext.h
    llvm/trunk/lib/CodeGen/PrologEpilogInserter.cpp
    llvm/trunk/lib/IR/CMakeLists.txt
    llvm/trunk/lib/IR/LLVMContext.cpp
    llvm/trunk/lib/IR/LLVMContextImpl.cpp
    llvm/trunk/lib/IR/LLVMContextImpl.h
    llvm/trunk/test/CodeGen/ARM/warn-stack.ll
    llvm/trunk/test/CodeGen/X86/warn-stack.ll

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

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

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

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

Modified: llvm/trunk/lib/IR/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/CMakeLists.txt?rev=197508&r1=197507&r2=197508&view=diff
==============================================================================
--- llvm/trunk/lib/IR/CMakeLists.txt (original)
+++ llvm/trunk/lib/IR/CMakeLists.txt Tue Dec 17 11:47:22 2013
@@ -6,6 +6,8 @@ add_llvm_library(LLVMCore
   ConstantFold.cpp
   Constants.cpp
   Core.cpp
+  DiagnosticInfo.cpp
+  DiagnosticPrinter.cpp
   DIBuilder.cpp
   DataLayout.cpp
   DebugInfo.cpp

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

Added: llvm/trunk/lib/IR/DiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DiagnosticPrinter.cpp?rev=197508&view=auto
==============================================================================
--- llvm/trunk/lib/IR/DiagnosticPrinter.cpp (added)
+++ llvm/trunk/lib/IR/DiagnosticPrinter.cpp Tue Dec 17 11:47:22 2013
@@ -0,0 +1,101 @@
+//===- llvm/Support/DiagnosticInfo.cpp - Diagnostic Definitions -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the a diagnostic printer relying on raw_ostream.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Twine.h"
+#include "llvm/IR/DiagnosticPrinter.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(char C) {
+  Stream << C;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned char C) {
+  Stream << C;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(signed char C) {
+  Stream << C;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(StringRef Str) {
+  Stream << Str;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const char *Str) {
+  Stream << Str;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(
+    const std::string &Str) {
+  Stream << Str;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned long N) {
+  Stream << N;
+  return *this;
+}
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(long N) {
+  Stream << N;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(
+    unsigned long long N) {
+  Stream << N;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(long long N) {
+  Stream << N;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const void *P) {
+  Stream << P;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(unsigned int N) {
+  Stream << N;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(int N) {
+  Stream << N;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(double N) {
+  Stream << N;
+  return *this;
+}
+
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Twine &Str) {
+  Stream << Str.getSingleStringRef();
+  return *this;
+}
+
+// IR related types.
+DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Value &V) {
+  Stream << V.getName();
+  return *this;
+}

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

Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=197508&r1=197507&r2=197508&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Tue Dec 17 11:47:22 2013
@@ -37,6 +37,8 @@ LLVMContextImpl::LLVMContextImpl(LLVMCon
     Int64Ty(C, 64) {
   InlineAsmDiagHandler = 0;
   InlineAsmDiagContext = 0;
+  DiagnosticHandler = 0;
+  DiagnosticContext = 0;
   NamedStructTypesUniqueID = 0;
 }
 

Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=197508&r1=197507&r2=197508&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Tue Dec 17 11:47:22 2013
@@ -238,9 +238,12 @@ public:
   
   LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler;
   void *InlineAsmDiagContext;
-  
-  typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*, 
-                         DenseMapAPIntKeyInfo> IntMapTy;
+
+  LLVMContext::DiagnosticHandlerTy DiagnosticHandler;
+  void *DiagnosticContext;
+
+  typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt *,
+                   DenseMapAPIntKeyInfo> IntMapTy;
   IntMapTy IntConstants;
   
   typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*, 

Modified: llvm/trunk/test/CodeGen/ARM/warn-stack.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/warn-stack.ll?rev=197508&r1=197507&r2=197508&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/warn-stack.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/warn-stack.ll Tue Dec 17 11:47:22 2013
@@ -12,7 +12,7 @@ entry:
   ret void
 }
 
-; CHECK: warning: Stack size limit exceeded (96) in warn.
+; CHECK: warning: stack size limit exceeded (96) in warn
 define void @warn() nounwind ssp {
 entry:
   %buffer = alloca [80 x i8], align 1

Modified: llvm/trunk/test/CodeGen/X86/warn-stack.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/warn-stack.ll?rev=197508&r1=197507&r2=197508&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/warn-stack.ll (original)
+++ llvm/trunk/test/CodeGen/X86/warn-stack.ll Tue Dec 17 11:47:22 2013
@@ -12,7 +12,7 @@ entry:
   ret void
 }
 
-; CHECK: warning: Stack size limit exceeded (104) in warn.
+; CHECK: warning: stack size limit exceeded (104) in warn
 define void @warn() nounwind ssp {
 entry:
   %buffer = alloca [80 x i8], align 1





More information about the llvm-commits mailing list