[llvm] 332c4af - Revert "[NFC] Make format() more amenable to format attributes"

Muhammad Omair Javaid via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 16 07:19:10 PST 2022


Author: Muhammad Omair Javaid
Date: 2022-11-16T19:09:49+04:00
New Revision: 332c4af35db96674eda3d33796ca55b4cc4a969c

URL: https://github.com/llvm/llvm-project/commit/332c4af35db96674eda3d33796ca55b4cc4a969c
DIFF: https://github.com/llvm/llvm-project/commit/332c4af35db96674eda3d33796ca55b4cc4a969c.diff

LOG: Revert "[NFC] Make format() more amenable to format attributes"

This reverts commit cf239c2f1777eb94a4801a086acf1332a7d3cccf.
It has broken tools/llvm-dwarfdump/X86/simplified-template-names.s on
following buildbot:
https://lab.llvm.org/buildbot/#/builders/178/builds/3148

Added: 
    

Modified: 
    llvm/include/llvm/Support/Format.h
    llvm/lib/Support/CMakeLists.txt
    llvm/lib/TableGen/SetTheory.cpp
    llvm/unittests/Support/CMakeLists.txt
    llvm/utils/TableGen/GlobalISel/GIMatchDag.cpp

Removed: 
    llvm/lib/Support/Format.cpp
    llvm/unittests/Support/FormatChkTest.cpp


################################################################################
diff  --git a/llvm/include/llvm/Support/Format.h b/llvm/include/llvm/Support/Format.h
index 4d336ab0a3660..a12f00b87ee43 100644
--- a/llvm/include/llvm/Support/Format.h
+++ b/llvm/include/llvm/Support/Format.h
@@ -33,63 +33,11 @@
 
 namespace llvm {
 
-/// Utility class that parses printf-style format strings to yield the expected
-/// C type(s) of each specifier. This class is used to verify that a format
-/// string unknown at compile-time is equivalent to another format string (which
-/// itself is hopefully known at compile-time).
-class PrintfStyleFormatReader {
-public:
-  enum SpecifierType : char {
-    ST_EndOfFormatString,
-    ST_Unknown,
-    ST_WideChar,
-    ST_Int,
-    ST_Long,
-    ST_LongLong,
-    ST_IntMax,
-    ST_Size,
-    ST_Ptr
diff ,
-    ST_Double,
-    ST_LongDouble,
-    ST_CString,
-    ST_WideCString,
-    ST_VoidPointer,
-    ST_Count_Char,
-    ST_Count_Short,
-    ST_Count_Int,
-    ST_Count_Long,
-    ST_Count_LongLong,
-    ST_Count_IntMax,
-    ST_Count_Size,
-    ST_Count_Ptr
diff 
-  };
-
-private:
-  const char *Fmt;
-  llvm::SmallVector<SpecifierType, 3> SpecifierQueue;
-
-  void refillSpecifierQueue();
-
-public:
-  /// Verify that the format specifiers in \p Fmt consume no more arguments than
-  /// those in \p Expected, and that all consumed arguments have a compatible
-  /// type. If \p Fmt is compatible with \p Expected in this way, \p Fmt is
-  /// returned. Otherwise, \p Expected is returned.
-  static const char *ensureCompatible(const char *Expected, const char *Fmt);
-
-  PrintfStyleFormatReader(const char *Fmt) : Fmt(Fmt) {}
-
-  SpecifierType nextSpecifier() {
-    if (SpecifierQueue.empty())
-      refillSpecifierQueue();
-    return SpecifierQueue.pop_back_val();
-  }
-};
-
 /// This is a helper class used for handling formatted output.  It is the
 /// abstract base class of a templated derived class.
 class format_object_base {
 protected:
+  const char *Fmt;
   ~format_object_base() = default; // Disallow polymorphic deletion.
   format_object_base(const format_object_base &) = default;
   virtual void home(); // Out of line virtual method.
@@ -98,7 +46,7 @@ class format_object_base {
   virtual int snprint(char *Buffer, unsigned BufferSize) const = 0;
 
 public:
-  format_object_base() = default;
+  format_object_base(const char *fmt) : Fmt(fmt) {}
 
   /// Format the object into the specified buffer.  On success, this returns
   /// the length of the formatted string.  If the buffer is too small, this
@@ -138,27 +86,28 @@ struct validate_format_parameters<Arg, Args...> {
 };
 template <> struct validate_format_parameters<> {};
 
-template <typename... Ts> auto format_capture(const char *Fmt, Ts... Vals) {
-  validate_format_parameters<Ts...>();
-  return [=](char *Buffer, unsigned BufferSize) {
+template <typename... Ts>
+class format_object final : public format_object_base {
+  std::tuple<Ts...> Vals;
+
+  template <std::size_t... Is>
+  int snprint_tuple(char *Buffer, unsigned BufferSize,
+                    std::index_sequence<Is...>) const {
 #ifdef _MSC_VER
-    return _snprintf(Buffer, BufferSize, Fmt, Vals...);
+    return _snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
 #else
-    return snprintf(Buffer, BufferSize, Fmt, Vals...);
+    return snprintf(Buffer, BufferSize, Fmt, std::get<Is>(Vals)...);
 #endif
-  };
-}
-
-template <typename... Ts>
-class format_object final : public format_object_base {
-  decltype(format_capture<Ts...>("", std::declval<Ts>()...)) Format;
+  }
 
 public:
-  format_object(const char *Fmt, const Ts &...vals)
-      : Format(format_capture(Fmt, vals...)) {}
+  format_object(const char *fmt, const Ts &... vals)
+      : format_object_base(fmt), Vals(vals...) {
+    validate_format_parameters<Ts...>();
+  }
 
   int snprint(char *Buffer, unsigned BufferSize) const override {
-    return Format(Buffer, BufferSize);
+    return snprint_tuple(Buffer, BufferSize, std::index_sequence_for<Ts...>());
   }
 };
 

diff  --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index 7ba033ac30b44..16145d019e3b4 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -171,7 +171,6 @@ add_llvm_component_library(LLVMSupport
   FileUtilities.cpp
   FileOutputBuffer.cpp
   FoldingSet.cpp
-  Format.cpp
   FormattedStream.cpp
   FormatVariadic.cpp
   GlobPattern.cpp

diff  --git a/llvm/lib/Support/Format.cpp b/llvm/lib/Support/Format.cpp
deleted file mode 100644
index 45b279915afac..0000000000000
--- a/llvm/lib/Support/Format.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-//===- Format.cpp - Efficient printf-style formatting for streams -*- C++ -*-=//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements the non-template part of Format.h, which is used to
-// provide a type-safe-ish interface to printf-style formatting.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/Format.h"
-
-namespace {
-/// Enum representation of a printf-style length specifier.
-enum ArgLength : char {
-  /// Corresponds to 'hh' length specifier.
-  AL_ShortShort,
-  /// Corresponds to 'h' length specifier.
-  AL_Short,
-  /// Corresponds to default length specifier.
-  AL_Default,
-  /// Corresponds to 'l' length specifier.
-  AL_Long,
-  /// Corresponds to 'll' length specifier.
-  AL_LongLong,
-  /// Corresponds to 'j' length specifier.
-  AL_IntMax,
-  /// Corresponds to 'z' length specifier.
-  AL_Size,
-  /// Corresponds to 't' length specifier.
-  AL_Ptr
diff ,
-  /// Corresponds to 'L' length specifier.
-  AL_LongDouble,
-  /// First invalid value of \p ArgLength.
-  AL_End,
-};
-
-/// Enum representation of a printf-style specifier.
-enum SpecifierChar : char {
-  /// Corresponds to any of 'd', 'i', 'u', 'o', 'x' or 'X' specifiers.
-  SC_Int,
-  /// Corresponds to any of 'f', 'F', 'e', 'E', 'g', 'G', 'a' or 'A' specifiers.
-  SC_Float,
-  /// Corresponds to 'c' specifier.
-  SC_Char,
-  /// Corresponds to 's' specifier.
-  SC_String,
-  /// Corresponds to 'p' specifier.
-  SC_VoidPointer,
-  /// Corresponds to 'n' specifier.
-  SC_Count,
-  /// First invalid value of \p SpecifierChar.
-  SC_End,
-};
-
-constexpr uint64_t specifierBit(char C) {
-  // specifierMask builds a bit map where each set bit indicates that the
-  // character whose ASCII value is 64 + <bit index> would be legal to use
-  // as a format specifier in the current parsing context.
-  // To cover all ASCII characters, we would need 128 bits; however, the only
-  // character with an ASCII value less than 64 that can be used as a specifier
-  // is % (as in %%), so we save some space and complexity by dropping the
-  // lower half of the bit map, which is going to be all zeroes anyway.
-  // % is handled as a special case.
-  return (uint64_t)1 << (C - 64);
-}
-
-template <size_t N>
-constexpr /* consteval */ uint64_t specifierMask(const char (&Specifiers)[N]) {
-  uint64_t Mask = 0;
-  for (const char *I = std::begin(Specifiers); I != std::end(Specifiers); ++I) {
-    if (*I == 0)
-      break;
-    Mask |= specifierBit(*I);
-  }
-  return Mask;
-}
-
-constexpr auto ST_Unknown = llvm::PrintfStyleFormatReader::ST_Unknown;
-constexpr auto ST_WideChar = llvm::PrintfStyleFormatReader::ST_WideChar;
-constexpr auto ST_Int = llvm::PrintfStyleFormatReader::ST_Int;
-constexpr auto ST_Long = llvm::PrintfStyleFormatReader::ST_Long;
-constexpr auto ST_LongLong = llvm::PrintfStyleFormatReader::ST_LongLong;
-constexpr auto ST_IntMax = llvm::PrintfStyleFormatReader::ST_IntMax;
-constexpr auto ST_Size = llvm::PrintfStyleFormatReader::ST_Size;
-constexpr auto ST_Ptr
diff  = llvm::PrintfStyleFormatReader::ST_Ptr
diff ;
-constexpr auto ST_Double = llvm::PrintfStyleFormatReader::ST_Double;
-constexpr auto ST_LongDouble = llvm::PrintfStyleFormatReader::ST_LongDouble;
-constexpr auto ST_CString = llvm::PrintfStyleFormatReader::ST_CString;
-constexpr auto ST_WideCString = llvm::PrintfStyleFormatReader::ST_WideCString;
-constexpr auto ST_VoidPointer = llvm::PrintfStyleFormatReader::ST_VoidPointer;
-constexpr auto ST_Count_Char = llvm::PrintfStyleFormatReader::ST_Count_Char;
-constexpr auto ST_Count_Short = llvm::PrintfStyleFormatReader::ST_Count_Short;
-constexpr auto ST_Count_Int = llvm::PrintfStyleFormatReader::ST_Count_Int;
-constexpr auto ST_Count_Long = llvm::PrintfStyleFormatReader::ST_Count_Long;
-constexpr auto ST_Count_LongLong =
-    llvm::PrintfStyleFormatReader::ST_Count_LongLong;
-constexpr auto ST_Count_IntMax = llvm::PrintfStyleFormatReader::ST_Count_IntMax;
-constexpr auto ST_Count_Size = llvm::PrintfStyleFormatReader::ST_Count_Size;
-constexpr auto ST_Count_Ptr
diff  =
-    llvm::PrintfStyleFormatReader::ST_Count_Ptr
diff ;
-
-llvm::PrintfStyleFormatReader::SpecifierType SpecifierTable[SC_End][AL_End] = {
-    {
-        // SC_Int
-        ST_Int,
-        ST_Int,
-        ST_Int,
-        ST_Long,
-        ST_LongLong,
-        ST_IntMax,
-        ST_Size,
-        ST_Ptr
diff ,
-        ST_Unknown,
-    },
-    {
-        // SC_Float
-        ST_Unknown,
-        ST_Unknown,
-        ST_Double,
-        ST_Double,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_LongDouble,
-    },
-    {
-        // SC_Char
-        ST_Unknown,
-        ST_Unknown,
-        ST_Int,
-        ST_WideChar,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-    },
-    {
-        // SC_String
-        ST_Unknown,
-        ST_Unknown,
-        ST_CString,
-        ST_WideCString,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-    },
-    {
-        // SC_VoidPointer
-        ST_Unknown,
-        ST_Unknown,
-        ST_VoidPointer,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-        ST_Unknown,
-    },
-    {
-        // SC_Count
-        ST_Count_Char,
-        ST_Count_Short,
-        ST_Count_Int,
-        ST_Count_Long,
-        ST_Count_LongLong,
-        ST_Count_IntMax,
-        ST_Count_Size,
-        ST_Count_Ptr
diff ,
-        ST_Unknown,
-    },
-};
-} // namespace
-
-namespace llvm {
-
-void PrintfStyleFormatReader::refillSpecifierQueue() {
-  if (auto PercentPtr = strchr(Fmt, '%')) {
-    Fmt = PercentPtr;
-  } else {
-    SpecifierQueue.push_back(ST_EndOfFormatString);
-    return;
-  }
-
-  if (*++Fmt == '%') {
-    // %% case: skip and try again
-    ++Fmt;
-    refillSpecifierQueue();
-    return;
-  }
-
-  // Push ST_Unknown to SpecifierQueue. If we bail out early, this is what
-  // the caller gets. Fill in real specifiers to Specifiers: if we
-  // successfully get to the end, then swap Specifiers with SpecifierQueue.
-  SpecifierQueue.push_back(ST_Unknown);
-  llvm::SmallVector<SpecifierType, 3> Specifiers;
-
-  // Bitfield keeping track of which specifier characters are allowed given
-  // flags and precision settings. Each bit tells whether ascii character
-  // 0x40 + <bit index> is allowed as a specifier. '%', which has an ASCII value
-  // less than 0x40 and does not allow any customization, is handled by a check
-  // above. The starting value contains all standard specifiers.
-  uint64_t ValidSpecifiers = specifierMask("diuoxXfFeEgGaAcspn");
-
-  // update specifier mask based on flags
-  bool ReadAllFlags = false;
-  while (!ReadAllFlags) {
-    switch (*Fmt) {
-    case '+':
-    case '-':
-    case ' ':
-      // valid for all specifiers
-      ++Fmt;
-      break;
-    case '#':
-      ValidSpecifiers &= specifierMask("xXaAeEfFgG");
-      ++Fmt;
-      break;
-    case '0':
-      ValidSpecifiers &= specifierMask("diouxXaAeEfFgG");
-      ++Fmt;
-      break;
-    default:
-      ReadAllFlags = true;
-      break;
-    }
-  }
-
-  // skip width
-  if (*Fmt == '*') {
-    Specifiers.push_back(ST_Int);
-    ++Fmt;
-  } else
-    while (*Fmt >= '0' && *Fmt <= '9')
-      ++Fmt;
-
-  // test precision
-  if (*Fmt == '.') {
-    ValidSpecifiers &= specifierMask("diouxXaAeEfFgGs");
-    ++Fmt;
-    if (*Fmt == '*') {
-      Specifiers.push_back(ST_Int);
-      ++Fmt;
-    } else
-      while (*Fmt >= '0' && *Fmt <= '9')
-        ++Fmt;
-  }
-
-  // parse length
-  bool FoundLength = false;
-  ArgLength AL = AL_Default;
-  while (!FoundLength) {
-    ArgLength NewAL;
-    switch (*Fmt) {
-    case 'h':
-      NewAL = AL_Short;
-      break;
-    case 'l':
-      NewAL = AL_Long;
-      break;
-    case 'j':
-      NewAL = AL_IntMax;
-      break;
-    case 'z':
-      NewAL = AL_Size;
-      break;
-    case 't':
-      NewAL = AL_Ptr
diff ;
-      break;
-    case 'L':
-      NewAL = AL_LongDouble;
-      break;
-    default:
-      FoundLength = true;
-      continue;
-    }
-
-    if (NewAL == AL_Long && AL == AL_Long)
-      AL = AL_LongLong;
-    else if (NewAL == AL_Short && AL == AL_Short)
-      AL = AL_ShortShort;
-    else if (AL == AL_Default)
-      AL = NewAL;
-    else
-      return;
-    ++Fmt;
-  }
-
-  // parse specifier; verify that the character is a valid specifier given
-  // restrictions imposed by by the use of flags and precision values
-  char Next = *Fmt;
-  if (Next == 0)
-    return;
-
-  ++Fmt;
-  if (Next < 0x40 || (specifierBit(Next) & ValidSpecifiers) == 0)
-    return;
-
-  SpecifierChar SC;
-  switch (Next) {
-  case 'd':
-  case 'i':
-  case 'u':
-  case 'o':
-  case 'x':
-  case 'X':
-    SC = SC_Int;
-    break;
-
-  case 'a':
-  case 'A':
-  case 'e':
-  case 'E':
-  case 'f':
-  case 'F':
-  case 'g':
-  case 'G':
-    SC = SC_Float;
-    break;
-
-  case 'c':
-    SC = SC_Char;
-    break;
-
-  case 's':
-    SC = SC_String;
-    break;
-
-  case 'p':
-    SC = SC_VoidPointer;
-    break;
-
-  case 'n':
-    SC = SC_Count;
-    break;
-
-  default:
-    return;
-  }
-
-  auto Spec = SpecifierTable[SC][AL];
-  if (Spec == ST_Unknown)
-    return;
-
-  Specifiers.push_back(Spec);
-  std::reverse(Specifiers.begin(), Specifiers.end());
-  std::swap(Specifiers, SpecifierQueue);
-}
-
-const char *PrintfStyleFormatReader::ensureCompatible(const char *Expected,
-                                                      const char *Fmt) {
-  PrintfStyleFormatReader EFR(Expected);
-  PrintfStyleFormatReader FFR(Fmt);
-  SpecifierType EST;
-  do {
-    EST = EFR.nextSpecifier();
-    if (EST != FFR.nextSpecifier())
-      return Expected;
-  } while (EST);
-  return Fmt;
-}
-
-} // namespace llvm

diff  --git a/llvm/lib/TableGen/SetTheory.cpp b/llvm/lib/TableGen/SetTheory.cpp
index 34fdd35269164..3db46aae6d967 100644
--- a/llvm/lib/TableGen/SetTheory.cpp
+++ b/llvm/lib/TableGen/SetTheory.cpp
@@ -210,26 +210,21 @@ struct SequenceOp : public SetTheory::Operator {
       PrintFatalError(Loc, "To out of range");
 
     RecordKeeper &Records =
-        cast<DefInit>(Expr->getOperator())->getDef()->getRecords();
+      cast<DefInit>(Expr->getOperator())->getDef()->getRecords();
 
     Step *= From <= To ? 1 : -1;
-    const char FallbackFmt[] = "%u";
     while (true) {
       if (Step > 0 && From > To)
         break;
       else if (Step < 0 && From < To)
         break;
-      const char *const VerifiedFmt = PrintfStyleFormatReader::ensureCompatible(
-          FallbackFmt, Format.c_str());
-      if (VerifiedFmt == FallbackFmt)
-        PrintFatalError(Loc, "Format string '" + Format +
-                                 "' is incompatible with '%u'!");
       std::string Name;
-      raw_string_ostream(Name) << format(VerifiedFmt, unsigned(From));
-      Record *Rec = Records.getDef(Name);
+      raw_string_ostream OS(Name);
+      OS << format(Format.c_str(), unsigned(From));
+      Record *Rec = Records.getDef(OS.str());
       if (!Rec)
-        PrintFatalError(Loc,
-                        "No def named '" + Name + "': " + Expr->getAsString());
+        PrintFatalError(Loc, "No def named '" + Name + "': " +
+          Expr->getAsString());
       // Try to reevaluate Rec in case it is a set.
       if (const RecVec *Result = ST.expand(Rec))
         Elts.insert(Result->begin(), Result->end());

diff  --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt
index b7a3d80019013..7ac6940f7ac47 100644
--- a/llvm/unittests/Support/CMakeLists.txt
+++ b/llvm/unittests/Support/CMakeLists.txt
@@ -40,7 +40,6 @@ add_llvm_unittest(SupportTests
   FileCollectorTest.cpp
   FileOutputBufferTest.cpp
   FileUtilitiesTest.cpp
-  FormatChkTest.cpp
   FormatVariadicTest.cpp
   FSUniqueIDTest.cpp
   GlobPatternTest.cpp

diff  --git a/llvm/unittests/Support/FormatChkTest.cpp b/llvm/unittests/Support/FormatChkTest.cpp
deleted file mode 100644
index 48023b8e48b81..0000000000000
--- a/llvm/unittests/Support/FormatChkTest.cpp
+++ /dev/null
@@ -1,314 +0,0 @@
-//===- FormatChkTest.cpp - Unit tests for checked string formatting -------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Support/Format.h"
-#include "gtest/gtest.h"
-#include <vector>
-
-using namespace llvm;
-
-namespace {
-
-constexpr auto ST_Unknown = llvm::PrintfStyleFormatReader::ST_Unknown;
-constexpr auto ST_WideChar = llvm::PrintfStyleFormatReader::ST_WideChar;
-constexpr auto ST_Int = llvm::PrintfStyleFormatReader::ST_Int;
-constexpr auto ST_Long = llvm::PrintfStyleFormatReader::ST_Long;
-constexpr auto ST_LongLong = llvm::PrintfStyleFormatReader::ST_LongLong;
-constexpr auto ST_IntMax = llvm::PrintfStyleFormatReader::ST_IntMax;
-constexpr auto ST_Size = llvm::PrintfStyleFormatReader::ST_Size;
-constexpr auto ST_Ptr
diff  = llvm::PrintfStyleFormatReader::ST_Ptr
diff ;
-constexpr auto ST_Double = llvm::PrintfStyleFormatReader::ST_Double;
-constexpr auto ST_LongDouble = llvm::PrintfStyleFormatReader::ST_LongDouble;
-constexpr auto ST_CString = llvm::PrintfStyleFormatReader::ST_CString;
-constexpr auto ST_WideCString = llvm::PrintfStyleFormatReader::ST_WideCString;
-constexpr auto ST_VoidPointer = llvm::PrintfStyleFormatReader::ST_VoidPointer;
-constexpr auto ST_Count_Char = llvm::PrintfStyleFormatReader::ST_Count_Char;
-constexpr auto ST_Count_Short = llvm::PrintfStyleFormatReader::ST_Count_Short;
-constexpr auto ST_Count_Int = llvm::PrintfStyleFormatReader::ST_Count_Int;
-constexpr auto ST_Count_Long = llvm::PrintfStyleFormatReader::ST_Count_Long;
-constexpr auto ST_Count_LongLong =
-    llvm::PrintfStyleFormatReader::ST_Count_LongLong;
-constexpr auto ST_Count_IntMax = llvm::PrintfStyleFormatReader::ST_Count_IntMax;
-constexpr auto ST_Count_Size = llvm::PrintfStyleFormatReader::ST_Count_Size;
-constexpr auto ST_Count_Ptr
diff  =
-    llvm::PrintfStyleFormatReader::ST_Count_Ptr
diff ;
-
-using STVec = std::vector<PrintfStyleFormatReader::SpecifierType>;
-
-STVec ParseFormatString(const char *Fmt) {
-  STVec Result;
-  PrintfStyleFormatReader Reader(Fmt);
-  while (auto Spec = Reader.nextSpecifier()) {
-    Result.push_back(Spec);
-  }
-  return Result;
-}
-
-#define EXPECT_FMT_EQ(FMT, ...)                                                \
-  EXPECT_EQ(ParseFormatString(FMT), STVec({__VA_ARGS__}))
-
-} // namespace
-
-TEST(FormatReader, EmptyFormatString) {
-  EXPECT_EQ(ParseFormatString(""),
-            std::vector<PrintfStyleFormatReader::SpecifierType>());
-}
-
-TEST(FormatReader, PercentEscape) {
-  EXPECT_EQ(ParseFormatString("%%"),
-            std::vector<PrintfStyleFormatReader::SpecifierType>());
-}
-
-TEST(FormatReader, PercentAtEnd) { EXPECT_FMT_EQ("%", ST_Unknown); }
-
-TEST(FormatReader, PercentWithWidth) { EXPECT_FMT_EQ("%ll%", ST_Unknown); }
-
-TEST(FormatReader, OneFormat) {
-  EXPECT_FMT_EQ("%i xx", ST_Int);
-  EXPECT_FMT_EQ("yy %i", ST_Int);
-  EXPECT_FMT_EQ("yy %i xx", ST_Int);
-}
-
-TEST(FormatReader, TwoFormats) {
-  EXPECT_FMT_EQ("%i yy %f xx", ST_Int, ST_Double);
-  EXPECT_FMT_EQ("zz %i yy %f", ST_Int, ST_Double);
-  EXPECT_FMT_EQ("zz %i yy %f xx", ST_Int, ST_Double);
-}
-
-TEST(FormatReader, PoundFlagValid) {
-  EXPECT_FMT_EQ("%#x", ST_Int);
-  EXPECT_FMT_EQ("%#X", ST_Int);
-  EXPECT_FMT_EQ("%#a", ST_Double);
-  EXPECT_FMT_EQ("%#A", ST_Double);
-  EXPECT_FMT_EQ("%#e", ST_Double);
-  EXPECT_FMT_EQ("%#E", ST_Double);
-  EXPECT_FMT_EQ("%#f", ST_Double);
-  EXPECT_FMT_EQ("%#F", ST_Double);
-  EXPECT_FMT_EQ("%#g", ST_Double);
-  EXPECT_FMT_EQ("%#G", ST_Double);
-
-  EXPECT_FMT_EQ("%#p", ST_Unknown);
-  EXPECT_FMT_EQ("%#i", ST_Unknown);
-  EXPECT_FMT_EQ("%#c", ST_Unknown);
-  EXPECT_FMT_EQ("%#s", ST_Unknown);
-  EXPECT_FMT_EQ("%#d", ST_Unknown);
-  EXPECT_FMT_EQ("%#u", ST_Unknown);
-  EXPECT_FMT_EQ("%#o", ST_Unknown);
-  EXPECT_FMT_EQ("%#n", ST_Unknown);
-}
-
-TEST(FormatReader, ZeroFlagValid) {
-  EXPECT_FMT_EQ("%0x", ST_Int);
-  EXPECT_FMT_EQ("%0X", ST_Int);
-  EXPECT_FMT_EQ("%0i", ST_Int);
-  EXPECT_FMT_EQ("%0d", ST_Int);
-  EXPECT_FMT_EQ("%0u", ST_Int);
-  EXPECT_FMT_EQ("%0o", ST_Int);
-  EXPECT_FMT_EQ("%0a", ST_Double);
-  EXPECT_FMT_EQ("%0A", ST_Double);
-  EXPECT_FMT_EQ("%0e", ST_Double);
-  EXPECT_FMT_EQ("%0E", ST_Double);
-  EXPECT_FMT_EQ("%0f", ST_Double);
-  EXPECT_FMT_EQ("%0F", ST_Double);
-  EXPECT_FMT_EQ("%0g", ST_Double);
-  EXPECT_FMT_EQ("%0G", ST_Double);
-
-  EXPECT_FMT_EQ("%0p", ST_Unknown);
-  EXPECT_FMT_EQ("%0n", ST_Unknown);
-  EXPECT_FMT_EQ("%0c", ST_Unknown);
-  EXPECT_FMT_EQ("%0s", ST_Unknown);
-}
-
-TEST(FormatReader, PrecisionValid) {
-  EXPECT_FMT_EQ("%.1x", ST_Int);
-  EXPECT_FMT_EQ("%.1X", ST_Int);
-  EXPECT_FMT_EQ("%.1i", ST_Int);
-  EXPECT_FMT_EQ("%.1d", ST_Int);
-  EXPECT_FMT_EQ("%.1u", ST_Int);
-  EXPECT_FMT_EQ("%.1o", ST_Int);
-  EXPECT_FMT_EQ("%.1a", ST_Double);
-  EXPECT_FMT_EQ("%.1A", ST_Double);
-  EXPECT_FMT_EQ("%.1e", ST_Double);
-  EXPECT_FMT_EQ("%.1E", ST_Double);
-  EXPECT_FMT_EQ("%.1f", ST_Double);
-  EXPECT_FMT_EQ("%.1F", ST_Double);
-  EXPECT_FMT_EQ("%.1g", ST_Double);
-  EXPECT_FMT_EQ("%.1G", ST_Double);
-  EXPECT_FMT_EQ("%.1s", ST_CString);
-
-  EXPECT_FMT_EQ("%.1p", ST_Unknown);
-  EXPECT_FMT_EQ("%.1n", ST_Unknown);
-  EXPECT_FMT_EQ("%.1c", ST_Unknown);
-}
-
-TEST(FormatReader, LongWidth) {
-  EXPECT_FMT_EQ("%1li", ST_Long);
-  EXPECT_FMT_EQ("%11li", ST_Long);
-  EXPECT_FMT_EQ("%1111li", ST_Long);
-  EXPECT_FMT_EQ("%10li", ST_Long);
-  EXPECT_FMT_EQ("%*li", ST_Int, ST_Long);
-  EXPECT_FMT_EQ("%*l!", ST_Unknown);
-}
-
-TEST(FormatReader, LongPrecision) {
-  EXPECT_FMT_EQ("%.1li", ST_Long);
-  EXPECT_FMT_EQ("%.11li", ST_Long);
-  EXPECT_FMT_EQ("%.1111li", ST_Long);
-  EXPECT_FMT_EQ("%.10li", ST_Long);
-  EXPECT_FMT_EQ("%.*li", ST_Int, ST_Long);
-  EXPECT_FMT_EQ("%.*l!", ST_Unknown);
-
-  EXPECT_FMT_EQ("%1.1li", ST_Long);
-  EXPECT_FMT_EQ("%11.11li", ST_Long);
-  EXPECT_FMT_EQ("%111.1111li", ST_Long);
-  EXPECT_FMT_EQ("%110.10li", ST_Long);
-  EXPECT_FMT_EQ("%1.*li", ST_Int, ST_Long);
-  EXPECT_FMT_EQ("%1.*l!", ST_Unknown);
-
-  EXPECT_FMT_EQ("%*.*li", ST_Int, ST_Int, ST_Long);
-  EXPECT_FMT_EQ("%*.*l!", ST_Unknown);
-}
-
-TEST(FormatReader, IntSpecifiers) {
-  EXPECT_FMT_EQ("%hhi", ST_Int);
-  EXPECT_FMT_EQ("%hhd", ST_Int);
-  EXPECT_FMT_EQ("%hi", ST_Int);
-  EXPECT_FMT_EQ("%hd", ST_Int);
-  EXPECT_FMT_EQ("%i", ST_Int);
-  EXPECT_FMT_EQ("%d", ST_Int);
-  EXPECT_FMT_EQ("%li", ST_Long);
-  EXPECT_FMT_EQ("%ld", ST_Long);
-  EXPECT_FMT_EQ("%lli", ST_LongLong);
-  EXPECT_FMT_EQ("%lld", ST_LongLong);
-  EXPECT_FMT_EQ("%ji", ST_IntMax);
-  EXPECT_FMT_EQ("%jd", ST_IntMax);
-  EXPECT_FMT_EQ("%zi", ST_Size);
-  EXPECT_FMT_EQ("%zd", ST_Size);
-  EXPECT_FMT_EQ("%ti", ST_Ptr
diff );
-  EXPECT_FMT_EQ("%td", ST_Ptr
diff );
-
-  EXPECT_FMT_EQ("%Li", ST_Unknown);
-  EXPECT_FMT_EQ("%Ld", ST_Unknown);
-}
-
-TEST(FormatReader, UIntSpecifiers) {
-  EXPECT_FMT_EQ("%hhu", ST_Int);
-  EXPECT_FMT_EQ("%hho", ST_Int);
-  EXPECT_FMT_EQ("%hhx", ST_Int);
-  EXPECT_FMT_EQ("%hhX", ST_Int);
-  EXPECT_FMT_EQ("%hu", ST_Int);
-  EXPECT_FMT_EQ("%ho", ST_Int);
-  EXPECT_FMT_EQ("%hx", ST_Int);
-  EXPECT_FMT_EQ("%hX", ST_Int);
-  EXPECT_FMT_EQ("%u", ST_Int);
-  EXPECT_FMT_EQ("%o", ST_Int);
-  EXPECT_FMT_EQ("%x", ST_Int);
-  EXPECT_FMT_EQ("%X", ST_Int);
-  EXPECT_FMT_EQ("%lu", ST_Long);
-  EXPECT_FMT_EQ("%lo", ST_Long);
-  EXPECT_FMT_EQ("%lx", ST_Long);
-  EXPECT_FMT_EQ("%lX", ST_Long);
-  EXPECT_FMT_EQ("%llu", ST_LongLong);
-  EXPECT_FMT_EQ("%llo", ST_LongLong);
-  EXPECT_FMT_EQ("%llx", ST_LongLong);
-  EXPECT_FMT_EQ("%llX", ST_LongLong);
-  EXPECT_FMT_EQ("%ju", ST_IntMax);
-  EXPECT_FMT_EQ("%jo", ST_IntMax);
-  EXPECT_FMT_EQ("%jx", ST_IntMax);
-  EXPECT_FMT_EQ("%jX", ST_IntMax);
-  EXPECT_FMT_EQ("%zu", ST_Size);
-  EXPECT_FMT_EQ("%zo", ST_Size);
-  EXPECT_FMT_EQ("%zx", ST_Size);
-  EXPECT_FMT_EQ("%zX", ST_Size);
-  EXPECT_FMT_EQ("%tu", ST_Ptr
diff );
-  EXPECT_FMT_EQ("%to", ST_Ptr
diff );
-  EXPECT_FMT_EQ("%tx", ST_Ptr
diff );
-  EXPECT_FMT_EQ("%tX", ST_Ptr
diff );
-
-  EXPECT_FMT_EQ("%Lu", ST_Unknown);
-  EXPECT_FMT_EQ("%Lo", ST_Unknown);
-  EXPECT_FMT_EQ("%Lx", ST_Unknown);
-  EXPECT_FMT_EQ("%LX", ST_Unknown);
-}
-
-TEST(FormatReader, FloatSpecifiers) {
-  EXPECT_FMT_EQ("%a", ST_Double);
-  EXPECT_FMT_EQ("%e", ST_Double);
-  EXPECT_FMT_EQ("%f", ST_Double);
-  EXPECT_FMT_EQ("%g", ST_Double);
-  EXPECT_FMT_EQ("%la", ST_Double);
-  EXPECT_FMT_EQ("%le", ST_Double);
-  EXPECT_FMT_EQ("%lf", ST_Double);
-  EXPECT_FMT_EQ("%lg", ST_Double);
-
-  EXPECT_FMT_EQ("%La", ST_LongDouble);
-  EXPECT_FMT_EQ("%Le", ST_LongDouble);
-  EXPECT_FMT_EQ("%Lf", ST_LongDouble);
-  EXPECT_FMT_EQ("%Lg", ST_LongDouble);
-
-  EXPECT_FMT_EQ("%ha", ST_Unknown);
-  EXPECT_FMT_EQ("%he", ST_Unknown);
-  EXPECT_FMT_EQ("%hf", ST_Unknown);
-  EXPECT_FMT_EQ("%hg", ST_Unknown);
-  EXPECT_FMT_EQ("%hha", ST_Unknown);
-  EXPECT_FMT_EQ("%hhe", ST_Unknown);
-  EXPECT_FMT_EQ("%hhf", ST_Unknown);
-  EXPECT_FMT_EQ("%hhg", ST_Unknown);
-  EXPECT_FMT_EQ("%lla", ST_Unknown);
-  EXPECT_FMT_EQ("%lle", ST_Unknown);
-  EXPECT_FMT_EQ("%llf", ST_Unknown);
-  EXPECT_FMT_EQ("%llg", ST_Unknown);
-}
-
-TEST(FormatReader, CharSpecifiers) {
-  EXPECT_FMT_EQ("%hhc", ST_Unknown);
-  EXPECT_FMT_EQ("%hc", ST_Unknown);
-  EXPECT_FMT_EQ("%c", ST_Int);
-  EXPECT_FMT_EQ("%lc", ST_WideChar);
-  EXPECT_FMT_EQ("%llc", ST_Unknown);
-  EXPECT_FMT_EQ("%jc", ST_Unknown);
-  EXPECT_FMT_EQ("%zc", ST_Unknown);
-  EXPECT_FMT_EQ("%tc", ST_Unknown);
-  EXPECT_FMT_EQ("%Lc", ST_Unknown);
-}
-
-TEST(FormatReader, StringSpecifiers) {
-  EXPECT_FMT_EQ("%hhs", ST_Unknown);
-  EXPECT_FMT_EQ("%hs", ST_Unknown);
-  EXPECT_FMT_EQ("%s", ST_CString);
-  EXPECT_FMT_EQ("%ls", ST_WideCString);
-  EXPECT_FMT_EQ("%lls", ST_Unknown);
-  EXPECT_FMT_EQ("%js", ST_Unknown);
-  EXPECT_FMT_EQ("%zs", ST_Unknown);
-  EXPECT_FMT_EQ("%ts", ST_Unknown);
-  EXPECT_FMT_EQ("%Ls", ST_Unknown);
-}
-
-TEST(FormatReader, VoidPointerSpecifiers) {
-  EXPECT_FMT_EQ("%hhp", ST_Unknown);
-  EXPECT_FMT_EQ("%hp", ST_Unknown);
-  EXPECT_FMT_EQ("%p", ST_VoidPointer);
-  EXPECT_FMT_EQ("%lp", ST_Unknown);
-  EXPECT_FMT_EQ("%llp", ST_Unknown);
-  EXPECT_FMT_EQ("%jp", ST_Unknown);
-  EXPECT_FMT_EQ("%zp", ST_Unknown);
-  EXPECT_FMT_EQ("%tp", ST_Unknown);
-  EXPECT_FMT_EQ("%Lp", ST_Unknown);
-}
-
-TEST(FormatReader, CountSpecifiers) {
-  EXPECT_FMT_EQ("%hhn", ST_Count_Char);
-  EXPECT_FMT_EQ("%hn", ST_Count_Short);
-  EXPECT_FMT_EQ("%n", ST_Count_Int);
-  EXPECT_FMT_EQ("%ln", ST_Count_Long);
-  EXPECT_FMT_EQ("%lln", ST_Count_LongLong);
-  EXPECT_FMT_EQ("%jn", ST_Count_IntMax);
-  EXPECT_FMT_EQ("%zn", ST_Count_Size);
-  EXPECT_FMT_EQ("%tn", ST_Count_Ptr
diff );
-  EXPECT_FMT_EQ("%Ln", ST_Unknown);
-}

diff  --git a/llvm/utils/TableGen/GlobalISel/GIMatchDag.cpp b/llvm/utils/TableGen/GlobalISel/GIMatchDag.cpp
index 56082f374ae80..8be32d2effa6e 100644
--- a/llvm/utils/TableGen/GlobalISel/GIMatchDag.cpp
+++ b/llvm/utils/TableGen/GlobalISel/GIMatchDag.cpp
@@ -61,11 +61,10 @@ void GIMatchDag::writeDOTGraph(raw_ostream &OS, StringRef ID) const {
     const char *ToFmt = "Node%p:d%d:s";
     if (E->getFromMO()->isDef() && !E->getToMO()->isDef())
       std::swap(FromFmt, ToFmt);
-    auto FromF = format(FromFmt, E->getFromMI(), E->getFromMO()->getIdx());
-    auto ToF = format(ToFmt, E->getToMI(), E->getToMO()->getIdx());
-    bool Swap = E->getFromMO()->isDef() && !E->getToMO()->isDef();
-    auto &From = Swap ? ToF : FromF;
-    auto &To = Swap ? FromF : ToF;
+    auto From = format(FromFmt, E->getFromMI(), E->getFromMO()->getIdx());
+    auto To = format(ToFmt, E->getToMI(), E->getToMO()->getIdx());
+    if (E->getFromMO()->isDef() && !E->getToMO()->isDef())
+      std::swap(From, To);
 
     OS << "  " << From << " -> " << To << " [label=\"$" << E->getName();
     if (E->getFromMO()->isDef() == E->getToMO()->isDef())


        


More information about the llvm-commits mailing list