Prechádzať zdrojové kódy

[linux-port] Fix DiagnosticPrinter use of std::hex (#1298)

DiagnosticPrinter doesn't support io manipulators like std::hex,
in spite of that, they were included in some invocations of it. MSVC
seemed to allow this because it interpretted std::hex as a void
pointer, which is supported.

This adds support of std::hex and similar manipulators by adding an
overloaded operator<< that takes the type of std::hex and its friends
and sets a base number which is used when the base is not 10 to print
numbers in the specified base, which can only be 8 or 16 according to
what is passed in.

Also while I was changing things in raw_ostream.h I added a
missing override keyword that produced a lot of warnings on clang.
Greg Roth 7 rokov pred
rodič
commit
6f8c457799

+ 4 - 0
include/llvm/IR/DiagnosticPrinter.h

@@ -55,6 +55,8 @@ public:
 
 
   // Other types.
   // Other types.
   virtual DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) = 0;
   virtual DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) = 0;
+  virtual DiagnosticPrinter &
+  operator<<(std::ios_base &(*iomanip)(std::ios_base &)) = 0; // HLSL Change
 };
 };
 
 
 /// \brief Basic diagnostic printer that uses an underlying raw_ostream.
 /// \brief Basic diagnostic printer that uses an underlying raw_ostream.
@@ -88,6 +90,8 @@ public:
 
 
   // Other types.
   // Other types.
   DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) override;
   DiagnosticPrinter &operator<<(const SMDiagnostic &Diag) override;
+  DiagnosticPrinter &operator<<(
+      std::ios_base &(*iomanip)(std::ios_base &)) override; // HLSL Change
 };
 };
 } // End namespace llvm
 } // End namespace llvm
 
 

+ 13 - 2
include/llvm/Support/raw_ostream.h

@@ -60,6 +60,10 @@ private:
   /// this buffer.
   /// this buffer.
   char *OutBufStart, *OutBufEnd, *OutBufCur;
   char *OutBufStart, *OutBufEnd, *OutBufCur;
 
 
+  /// The base in which numbers will be written. default is 10. 8 and 16 are
+  /// also possible.
+  int writeBase;  // HLSL Change
+
   enum BufferKind {
   enum BufferKind {
     Unbuffered = 0,
     Unbuffered = 0,
     InternalBuffer,
     InternalBuffer,
@@ -84,6 +88,7 @@ public:
       : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
       : BufferMode(unbuffered ? Unbuffered : InternalBuffer) {
     // Start out ready to flush.
     // Start out ready to flush.
     OutBufStart = OutBufEnd = OutBufCur = nullptr;
     OutBufStart = OutBufEnd = OutBufCur = nullptr;
+    writeBase = 10; // HLSL Change
   }
   }
 
 
   virtual ~raw_ostream();
   virtual ~raw_ostream();
@@ -213,6 +218,9 @@ public:
   /// Output \p N in hexadecimal, without any prefix or padding.
   /// Output \p N in hexadecimal, without any prefix or padding.
   raw_ostream &write_hex(unsigned long long N);
   raw_ostream &write_hex(unsigned long long N);
 
 
+  /// Output \p N in writeBase, without any prefix or padding.
+  raw_ostream &write_base(unsigned long long N); // HLSL Change
+
   /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
   /// Output \p Str, turning '\\', '\t', '\n', '"', and anything that doesn't
   /// satisfy std::isprint into an escape sequence.
   /// satisfy std::isprint into an escape sequence.
   raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
   raw_ostream &write_escaped(StringRef Str, bool UseHexEscapes = false);
@@ -228,7 +236,10 @@ public:
   
   
   // Formatted output, see the formatHex() function in Support/Format.h.
   // Formatted output, see the formatHex() function in Support/Format.h.
   raw_ostream &operator<<(const FormattedNumber &);
   raw_ostream &operator<<(const FormattedNumber &);
-  
+
+  raw_ostream &
+  operator<<(std::ios_base &(*iomanip)(std::ios_base &)); // HLSL Change
+
   /// indent - Insert 'NumSpaces' spaces.
   /// indent - Insert 'NumSpaces' spaces.
   raw_ostream &indent(unsigned NumSpaces);
   raw_ostream &indent(unsigned NumSpaces);
 
 
@@ -402,7 +413,7 @@ public:
 
 
   /// Manually flush the stream and close the file. Note that this does not call
   /// Manually flush the stream and close the file. Note that this does not call
   /// fsync.
   /// fsync.
-  void close();
+  void close() override;
 
 
   bool supportsSeeking() { return SupportsSeeking; }
   bool supportsSeeking() { return SupportsSeeking; }
 
 

+ 8 - 0
lib/IR/DiagnosticPrinter.cpp

@@ -96,6 +96,14 @@ DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Twine &Str) {
   return *this;
   return *this;
 }
 }
 
 
+// HLSL Change Starts
+DiagnosticPrinter &DiagnosticPrinterRawOStream::
+operator<<(std::ios_base &(*iomanip)(std::ios_base &)) {
+  Stream << iomanip;
+  return *this;
+}
+// HLSL Change Ends.
+
 // IR related types.
 // IR related types.
 DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Value &V) {
 DiagnosticPrinter &DiagnosticPrinterRawOStream::operator<<(const Value &V) {
   Stream << V.getName();
   Stream << V.getName();

+ 49 - 6
lib/Support/raw_ostream.cpp

@@ -25,6 +25,7 @@
 #include "llvm/Support/Program.h"
 #include "llvm/Support/Program.h"
 #include <cctype>
 #include <cctype>
 #include <cerrno>
 #include <cerrno>
+#include <ios>
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <system_error>
 #include <system_error>
 
 
@@ -106,6 +107,16 @@ void raw_ostream::SetBufferAndMode(_In_opt_ char *BufferStart, size_t Size,
 }
 }
 
 
 raw_ostream &raw_ostream::operator<<(unsigned long N) {
 raw_ostream &raw_ostream::operator<<(unsigned long N) {
+
+  // HLSL Change Starts - Handle non-base10 printing
+  if (writeBase != 10) {
+    *this << '0';
+    if (writeBase == 16)
+      *this << 'x';
+    return write_base((unsigned long long)N);
+  }
+  // HLSL Change Ends
+
   // Zero is a special case.
   // Zero is a special case.
   if (N == 0)
   if (N == 0)
     return *this << '0';
     return *this << '0';
@@ -122,7 +133,7 @@ raw_ostream &raw_ostream::operator<<(unsigned long N) {
 }
 }
 
 
 raw_ostream &raw_ostream::operator<<(long N) {
 raw_ostream &raw_ostream::operator<<(long N) {
-  if (N <  0) {
+  if (N < 0 && writeBase == 10) {
     *this << '-';
     *this << '-';
     // Avoid undefined behavior on LONG_MIN with a cast.
     // Avoid undefined behavior on LONG_MIN with a cast.
     N = -(unsigned long)N;
     N = -(unsigned long)N;
@@ -136,6 +147,15 @@ raw_ostream &raw_ostream::operator<<(unsigned long long N) {
   if (N == static_cast<unsigned long>(N))
   if (N == static_cast<unsigned long>(N))
     return this->operator<<(static_cast<unsigned long>(N));
     return this->operator<<(static_cast<unsigned long>(N));
 
 
+  // HLSL Change Starts - Handle non-base10 printing
+  if (writeBase != 10) {
+    *this << '0';
+    if (writeBase == 16)
+      *this << 'x';
+    return write_base((unsigned long long)N);
+  }
+  // HLSL Change Ends
+
   char NumberBuffer[20];
   char NumberBuffer[20];
   char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
   char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
   char *CurPtr = EndPtr;
   char *CurPtr = EndPtr;
@@ -148,7 +168,7 @@ raw_ostream &raw_ostream::operator<<(unsigned long long N) {
 }
 }
 
 
 raw_ostream &raw_ostream::operator<<(long long N) {
 raw_ostream &raw_ostream::operator<<(long long N) {
-  if (N < 0) {
+  if (N < 0 && writeBase == 10) {
     *this << '-';
     *this << '-';
     // Avoid undefined behavior on INT64_MIN with a cast.
     // Avoid undefined behavior on INT64_MIN with a cast.
     N = -(unsigned long long)N;
     N = -(unsigned long long)N;
@@ -157,23 +177,33 @@ raw_ostream &raw_ostream::operator<<(long long N) {
   return this->operator<<(static_cast<unsigned long long>(N));
   return this->operator<<(static_cast<unsigned long long>(N));
 }
 }
 
 
+// HLSL Change Starts - Generalize non-base10 printing.
 raw_ostream &raw_ostream::write_hex(unsigned long long N) {
 raw_ostream &raw_ostream::write_hex(unsigned long long N) {
+  int oldBase = writeBase;
+  writeBase = 16;
+  raw_ostream &rv = write_base(N);
+  writeBase = oldBase;
+  return rv;
+}
+
+raw_ostream &raw_ostream::write_base(unsigned long long N) {
   // Zero is a special case.
   // Zero is a special case.
   if (N == 0)
   if (N == 0)
     return *this << '0';
     return *this << '0';
 
 
   char NumberBuffer[20];
   char NumberBuffer[20];
-  char *EndPtr = NumberBuffer+sizeof(NumberBuffer);
+  char *EndPtr = NumberBuffer + sizeof(NumberBuffer);
   char *CurPtr = EndPtr;
   char *CurPtr = EndPtr;
 
 
   while (N) {
   while (N) {
-    uintptr_t x = N % 16;
+    uintptr_t x = N % writeBase;
     *--CurPtr = (x < 10 ? '0' + x : 'a' + x - 10);
     *--CurPtr = (x < 10 ? '0' + x : 'a' + x - 10);
-    N /= 16;
+    N /= writeBase;
   }
   }
 
 
-  return write(CurPtr, EndPtr-CurPtr);
+  return write(CurPtr, EndPtr - CurPtr);
 }
 }
+// HLSL Change Ends
 
 
 raw_ostream &raw_ostream::write_escaped(StringRef Str,
 raw_ostream &raw_ostream::write_escaped(StringRef Str,
                                         bool UseHexEscapes) {
                                         bool UseHexEscapes) {
@@ -456,6 +486,19 @@ raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
   }
   }
 }
 }
 
 
+// HLSL Change Starts - Add handling of numerical base IO manipulators.
+raw_ostream &raw_ostream::
+operator<<(std::ios_base &(*iomanip)(std::ios_base &)) {
+  if (iomanip == std::hex)
+    writeBase = 16;
+  else if (iomanip == std::oct)
+    writeBase = 8;
+  else
+    writeBase = 10;
+
+  return *this;
+}
+// HLSL Change Ends
 
 
 /// indent - Insert 'NumSpaces' spaces.
 /// indent - Insert 'NumSpaces' spaces.
 raw_ostream &raw_ostream::indent(unsigned NumSpaces) {
 raw_ostream &raw_ostream::indent(unsigned NumSpaces) {