Nice. Were you planning on doing the inline assembly changes?<div><br></div><div>-eric<br><br><div>On Mon Dec 16 2013 at 3:28:56 PM, Quentin Colombet <<a href="mailto:qcolombet@apple.com">qcolombet@apple.com</a>> wrote:</div>
<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-<u></u>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>
getNextAvailablePluginDiagnost<u></u>icKind).<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.<u></u>com/D2376</a><br>
<rdar://problem/15515174><br>
<br>
Added:<br>
llvm/trunk/include/llvm/<u></u>Support/DiagnosticInfo.h<br>
llvm/trunk/include/llvm/<u></u>Support/DiagnosticPrinter.h<br>
llvm/trunk/lib/Support/<u></u>DiagnosticInfo.cpp<br>
llvm/trunk/lib/Support/<u></u>DiagnosticPrinter.cpp<br>
Modified:<br>
llvm/trunk/include/llvm/IR/<u></u>LLVMContext.h<br>
llvm/trunk/lib/CodeGen/<u></u>PrologEpilogInserter.cpp<br>
llvm/trunk/lib/IR/LLVMContext.<u></u>cpp<br>
llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp<br>
llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h<br>
llvm/trunk/lib/Support/<u></u>CMakeLists.txt<br>
llvm/trunk/test/CodeGen/ARM/<u></u>warn-stack.ll<br>
llvm/trunk/test/CodeGen/X86/<u></u>warn-stack.ll<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>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-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/LLVMContext.h?rev=<u></u>197438&r1=197437&r2=197438&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>LLVMContext.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>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)(<u></u>const SMDiagnostic&, void *Context,<br>
unsigned LocCookie);<br>
<br>
+ /// Defines the type of a diagnostic handler.<br>
+ /// \see LLVMContext::<u></u>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 *<u></u>getInlineAsmDiagnosticContext(<u></u>) 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(<u></u>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/<u></u>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-<u></u>project/llvm/trunk/include/<u></u>llvm/Support/DiagnosticInfo.h?<u></u>rev=197438&view=auto</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/<u></u>Support/DiagnosticInfo.h (added)<br>
+++ llvm/trunk/include/llvm/<u></u>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>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<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>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<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 getNextAvailablePluginDiagnost<u></u>icKind();<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(<u></u>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/<u></u>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-<u></u>project/llvm/trunk/include/<u></u>llvm/Support/<u></u>DiagnosticPrinter.h?rev=<u></u>197438&view=auto</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/<u></u>Support/DiagnosticPrinter.h (added)<br>
+++ llvm/trunk/include/llvm/<u></u>Support/DiagnosticPrinter.h Mon Dec 16 17:22:51 2013<br>
@@ -0,0 +1,84 @@<br>
+//===- llvm/Support/<u></u>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>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<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>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<br>
+<br>
+#ifndef LLVM_SUPPORT_<u></u>DIAGNOSTICPRINTER_H<br>
+#define LLVM_SUPPORT_<u></u>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(<u></u>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/<u></u>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-<u></u>project/llvm/trunk/lib/<u></u>CodeGen/PrologEpilogInserter.<u></u>cpp?rev=197438&r1=197437&r2=<u></u>197438&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/CodeGen/<u></u>PrologEpilogInserter.cpp (original)<br>
+++ llvm/trunk/lib/CodeGen/<u></u>PrologEpilogInserter.cpp Mon Dec 16 17:22:51 2013<br>
@@ -30,9 +30,11 @@<br>
#include "llvm/CodeGen/<u></u>MachineRegisterInfo.h"<br>
#include "llvm/CodeGen/<u></u>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.<u></u>h"<br>
#include "llvm/Support/raw_ostream.h"<br>
#include "llvm/Target/<u></u>TargetFrameLowering.h"<br>
#include "llvm/Target/TargetInstrInfo.<u></u>h"<br>
@@ -160,10 +162,11 @@ bool PEI::runOnMachineFunction(<u></u>MachineFu<br>
<br>
// Warn on stack size when we exceeds the given limit.<br>
MachineFrameInfo *MFI = Fn.getFrameInfo();<br>
- if (WarnStackSize.<u></u>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.<u></u>getNumOccurrences() > 0 && WarnStackSize < StackSize) {<br>
+ DiagnosticInfoStackSize DiagStackSize(*F, StackSize);<br>
+ F->getContext().diagnose(<u></u>DiagStackSize);<br>
+ }<br>
<br>
delete RS;<br>
ReturnBlocks.clear();<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContext.<u></u>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-<u></u>project/llvm/trunk/lib/IR/<u></u>LLVMContext.cpp?rev=197438&r1=<u></u>197437&r2=197438&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/LLVMContext.<u></u>cpp (original)<br>
+++ llvm/trunk/lib/IR/LLVMContext.<u></u>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.<u></u>h"<br>
+#include "llvm/Support/<u></u>DiagnosticPrinter.h"<br>
#include "llvm/Support/ManagedStatic.h"<br>
#include "llvm/Support/SourceMgr.h"<br>
#include <cctype><br>
@@ -98,6 +100,20 @@ void *LLVMContext::<u></u>getInlineAsmDiagnosti<br>
return pImpl->InlineAsmDiagContext;<br>
}<br>
<br>
+void LLVMContext::<u></u>setDiagnosticHandler(<u></u>DiagnosticHandlerTy DiagnosticHandler,<br>
+ void *DiagnosticContext) {<br>
+ pImpl->DiagnosticHandler = DiagnosticHandler;<br>
+ pImpl->DiagnosticContext = DiagnosticContext;<br>
+}<br>
+<br>
+LLVMContext::<u></u>DiagnosticHandlerTy LLVMContext::<u></u>getDiagnosticHandler() const {<br>
+ return pImpl->DiagnosticHandler;<br>
+}<br>
+<br>
+void *LLVMContext::<u></u>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(<u></u>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/<u></u>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-<u></u>project/llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp?rev=<u></u>197438&r1=197437&r2=197438&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp (original)<br>
+++ llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp Mon Dec 16 17:22:51 2013<br>
@@ -37,6 +37,8 @@ LLVMContextImpl::<u></u>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/<u></u>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-<u></u>project/llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h?rev=197438&<u></u>r1=197437&r2=197438&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h (original)<br>
+++ llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h Mon Dec 16 17:22:51 2013<br>
@@ -238,9 +238,12 @@ public:<br>
<br>
LLVMContext::<u></u>InlineAsmDiagHandlerTy InlineAsmDiagHandler;<br>
void *InlineAsmDiagContext;<br>
-<br>
- typedef DenseMap<DenseMapAPIntKeyInfo:<u></u>:KeyTy, ConstantInt*,<br>
- DenseMapAPIntKeyInfo> IntMapTy;<br>
+<br>
+ LLVMContext::<u></u>DiagnosticHandlerTy DiagnosticHandler;<br>
+ void *DiagnosticContext;<br>
+<br>
+ typedef DenseMap<DenseMapAPIntKeyInfo:<u></u>:KeyTy, ConstantInt *,<br>
+ DenseMapAPIntKeyInfo> IntMapTy;<br>
IntMapTy IntConstants;<br>
<br>
typedef DenseMap<<u></u>DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*,<br>
<br>
Modified: llvm/trunk/lib/Support/<u></u>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-<u></u>project/llvm/trunk/lib/<u></u>Support/CMakeLists.txt?rev=<u></u>197438&r1=197437&r2=197438&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/Support/<u></u>CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/Support/<u></u>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/<u></u>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-<u></u>project/llvm/trunk/lib/<u></u>Support/DiagnosticInfo.cpp?<u></u>rev=197438&view=auto</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/Support/<u></u>DiagnosticInfo.cpp (added)<br>
+++ llvm/trunk/lib/Support/<u></u>DiagnosticInfo.cpp Mon Dec 16 17:22:51 2013<br>
@@ -0,0 +1,54 @@<br>
+//===- llvm/Support/DiagnosticInfo.<u></u>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>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<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>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<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.<u></u>h"<br>
+#include "llvm/Support/<u></u>DiagnosticPrinter.h"<br>
+<br>
+#include <string><br>
+<br>
+using namespace llvm;<br>
+<br>
+int getNextAvailablePluginDiagnost<u></u>icKind() {<br>
+ static sys::cas_flag PluginKindID = DK_FirstPluginKind;<br>
+ return (int)sys::AtomicIncrement(&<u></u>PluginKindID);<br>
+}<br>
+<br>
+DiagnosticInfoInlineAsm::<u></u>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-><u></u>getOperand(0)))<br>
+ LocCookie = CI->getZExtValue();<br>
+ }<br>
+}<br>
+<br>
+void DiagnosticInfoInlineAsm::<u></u>print(DiagnosticPrinter &DP) const {<br>
+ DP << getMsgStr();<br>
+ if (getLocCookie())<br>
+ DP << " at line " << getLocCookie();<br>
+}<br>
+<br>
+void DiagnosticInfoStackSize::<u></u>print(DiagnosticPrinter &DP) const {<br>
+ DP << "stack size limit exceeded (" << getStackSize() << ") in "<br>
+ << getFunction();<br>
+}<br>
<br>
Added: llvm/trunk/lib/Support/<u></u>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-<u></u>project/llvm/trunk/lib/<u></u>Support/DiagnosticPrinter.cpp?<u></u>rev=197438&view=auto</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/Support/<u></u>DiagnosticPrinter.cpp (added)<br>
+++ llvm/trunk/lib/Support/<u></u>DiagnosticPrinter.cpp Mon Dec 16 17:22:51 2013<br>
@@ -0,0 +1,103 @@<br>
+//===- llvm/Support/DiagnosticInfo.<u></u>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>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<br>
+//<br>
+// This file defines the a diagnostic printer relying on raw_ostream.<br>
+//<br>
+//===------------------------<u></u>------------------------------<u></u>----------------===//<br>
+<br>
+#include "llvm/ADT/Twine.h"<br>
+#include "llvm/Analysis/<u></u>ScalarEvolution.h"<br>
+#include "llvm/CodeGen/MachineInstr.h"<br>
+#include "llvm/IR/Value.h"<br>
+#include "llvm/Support/<u></u>DiagnosticPrinter.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(char C) {<br>
+ Stream << C;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(unsigned char C) {<br>
+ Stream << C;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(signed char C) {<br>
+ Stream << C;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(StringRef Str) {<br>
+ Stream << Str;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(const char *Str) {<br>
+ Stream << Str;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(<br>
+ const std::string &Str) {<br>
+ Stream << Str;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(unsigned long N) {<br>
+ Stream << N;<br>
+ return *this;<br>
+}<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(long N) {<br>
+ Stream << N;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(<br>
+ unsigned long long N) {<br>
+ Stream << N;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(long long N) {<br>
+ Stream << N;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(const void *P) {<br>
+ Stream << P;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(unsigned int N) {<br>
+ Stream << N;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(int N) {<br>
+ Stream << N;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(double N) {<br>
+ Stream << N;<br>
+ return *this;<br>
+}<br>
+<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(const Twine &Str) {<br>
+ Stream << Str.getSingleStringRef();<br>
+ return *this;<br>
+}<br>
+<br>
+// IR related types.<br>
+DiagnosticPrinter &DiagnosticPrinterRawOStream::<u></u>operator<<(const Value &V) {<br>
+ Stream << V.getName();<br>
+ return *this;<br>
+}<br>
<br>
Modified: llvm/trunk/test/CodeGen/ARM/<u></u>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-<u></u>project/llvm/trunk/test/<u></u>CodeGen/ARM/warn-stack.ll?rev=<u></u>197438&r1=197437&r2=197438&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/test/CodeGen/ARM/<u></u>warn-stack.ll (original)<br>
+++ llvm/trunk/test/CodeGen/ARM/<u></u>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/<u></u>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-<u></u>project/llvm/trunk/test/<u></u>CodeGen/X86/warn-stack.ll?rev=<u></u>197438&r1=197437&r2=197438&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/test/CodeGen/X86/<u></u>warn-stack.ll (original)<br>
+++ llvm/trunk/test/CodeGen/X86/<u></u>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>
______________________________<u></u>_________________<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/<u></u>mailman/listinfo/llvm-commits</a><br>
</blockquote></div>