summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Colombet <qcolombet@apple.com>2013-12-16 23:22:51 +0000
committerQuentin Colombet <qcolombet@apple.com>2013-12-16 23:22:51 +0000
commitb6c4a845927de16b585639f766a734daf6a861f1 (patch)
treece69befe218deb8838cdd2a31c4fef3a321e9662
parent4faf2ba0c7ef9f28a5d4a6c096105ff8aca94279 (diff)
downloadllvm-b6c4a845927de16b585639f766a734daf6a861f1.tar.gz
llvm-b6c4a845927de16b585639f766a734daf6a861f1.tar.bz2
llvm-b6c4a845927de16b585639f766a734daf6a861f1.tar.xz
Add warning capabilities in LLVM.
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> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197438 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/IR/LLVMContext.h33
-rw-r--r--include/llvm/Support/DiagnosticInfo.h165
-rw-r--r--include/llvm/Support/DiagnosticPrinter.h84
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp11
-rw-r--r--lib/IR/LLVMContext.cpp41
-rw-r--r--lib/IR/LLVMContextImpl.cpp2
-rw-r--r--lib/IR/LLVMContextImpl.h9
-rw-r--r--lib/Support/CMakeLists.txt2
-rw-r--r--lib/Support/DiagnosticInfo.cpp54
-rw-r--r--lib/Support/DiagnosticPrinter.cpp103
-rw-r--r--test/CodeGen/ARM/warn-stack.ll2
-rw-r--r--test/CodeGen/X86/warn-stack.ll2
12 files changed, 499 insertions, 9 deletions
diff --git a/include/llvm/IR/LLVMContext.h b/include/llvm/IR/LLVMContext.h
index dd379ae5e7..b80f7c82db 100644
--- a/include/llvm/IR/LLVMContext.h
+++ b/include/llvm/IR/LLVMContext.h
@@ -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
diff --git a/include/llvm/Support/DiagnosticInfo.h b/include/llvm/Support/DiagnosticInfo.h
new file mode 100644
index 0000000000..151e155eaf
--- /dev/null
+++ b/include/llvm/Support/DiagnosticInfo.h
@@ -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
diff --git a/include/llvm/Support/DiagnosticPrinter.h b/include/llvm/Support/DiagnosticPrinter.h
new file mode 100644
index 0000000000..721b1b4212
--- /dev/null
+++ b/include/llvm/Support/DiagnosticPrinter.h
@@ -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
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 0107a9cb44..556d92f0dd 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -30,9 +30,11 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.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"
+#include "llvm/Support/DiagnosticInfo.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetInstrInfo.h"
@@ -160,10 +162,11 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
// 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();
diff --git a/lib/IR/LLVMContext.cpp b/lib/IR/LLVMContext.cpp
index 883bb9878f..26541d8168 100644
--- a/lib/IR/LLVMContext.cpp
+++ b/lib/IR/LLVMContext.cpp
@@ -17,6 +17,8 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Metadata.h"
+#include "llvm/Support/DiagnosticInfo.h"
+#include "llvm/Support/DiagnosticPrinter.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/SourceMgr.h"
#include <cctype>
@@ -98,6 +100,20 @@ void *LLVMContext::getInlineAsmDiagnosticContext() const {
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 Instruction *I, const Twine &ErrorStr) {
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) {
diff --git a/lib/IR/LLVMContextImpl.cpp b/lib/IR/LLVMContextImpl.cpp
index 6a6a4d6801..ebff9d3a51 100644
--- a/lib/IR/LLVMContextImpl.cpp
+++ b/lib/IR/LLVMContextImpl.cpp
@@ -37,6 +37,8 @@ LLVMContextImpl::LLVMContextImpl(LLVMContext &C)
Int64Ty(C, 64) {
InlineAsmDiagHandler = 0;
InlineAsmDiagContext = 0;
+ DiagnosticHandler = 0;
+ DiagnosticContext = 0;
NamedStructTypesUniqueID = 0;
}
diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h
index 407b985689..39e5d778ed 100644
--- a/lib/IR/LLVMContextImpl.h
+++ b/lib/IR/LLVMContextImpl.h
@@ -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*,
diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt
index 3aecf3ffa4..50aab382ca 100644
--- a/lib/Support/CMakeLists.txt
+++ b/lib/Support/CMakeLists.txt
@@ -17,6 +17,8 @@ add_llvm_library(LLVMSupport
Debug.cpp
DeltaAlgorithm.cpp
DAGDeltaAlgorithm.cpp
+ DiagnosticInfo.cpp
+ DiagnosticPrinter.cpp
Dwarf.cpp
ErrorHandling.cpp
FileUtilities.cpp
diff --git a/lib/Support/DiagnosticInfo.cpp b/lib/Support/DiagnosticInfo.cpp
new file mode 100644
index 0000000000..0ce0d90a42
--- /dev/null
+++ b/lib/Support/DiagnosticInfo.cpp
@@ -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/Function.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/Support/Atomic.h"
+#include "llvm/Support/DiagnosticInfo.h"
+#include "llvm/Support/DiagnosticPrinter.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();
+}
diff --git a/lib/Support/DiagnosticPrinter.cpp b/lib/Support/DiagnosticPrinter.cpp
new file mode 100644
index 0000000000..826bec0d45
--- /dev/null
+++ b/lib/Support/DiagnosticPrinter.cpp
@@ -0,0 +1,103 @@
+//===- 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/Analysis/ScalarEvolution.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Support/DiagnosticPrinter.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;
+}
diff --git a/test/CodeGen/ARM/warn-stack.ll b/test/CodeGen/ARM/warn-stack.ll
index 9538bbf104..90a3e1f798 100644
--- a/test/CodeGen/ARM/warn-stack.ll
+++ b/test/CodeGen/ARM/warn-stack.ll
@@ -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
diff --git a/test/CodeGen/X86/warn-stack.ll b/test/CodeGen/X86/warn-stack.ll
index 5979f45b07..a76fd2801a 100644
--- a/test/CodeGen/X86/warn-stack.ll
+++ b/test/CodeGen/X86/warn-stack.ll
@@ -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