[Mlir-commits] [clang] [clang-tools-extra] [lldb] [llvm] [mlir] [Support] Validate number of arguments passed to formatv() (PR #105745)
Rahul Joshi
llvmlistbot at llvm.org
Thu Aug 22 15:41:01 PDT 2024
https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/105745
- Change formatv() to validate that the number of arguments passed matches number of
replacement parameters in the format string.
- When the format string is a literal, this failure can be easily fixed, but when its dynamically
generated, it may not be as straightforward.
- So changed existing formatv() to only accept literal strings as a format string and enable
argument count validation for that case only.
- Add a `formatvv` variant that allows non-literal format strings and disables argument count
verification.
>From afbbe584430034c8ef21905218849b11e23ffb81 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Thu, 22 Aug 2024 08:47:02 -0700
Subject: [PATCH 1/2] [Support] Detect invalid formatv() calls
- Detect formatv() calls where the number of replacement parameters
expected after parsing the format string does not match the number
provides in the formatv() call.
- assert() in debug builds, and fail the formatv() call in release
builds by just emitting an error message in the stream.
---
llvm/include/llvm/Support/FormatVariadic.h | 21 ++++-
llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp | 3 +-
llvm/lib/Support/FormatVariadic.cpp | 10 ++-
llvm/unittests/Support/FormatVariadicTest.cpp | 79 +++++++++++++------
4 files changed, 81 insertions(+), 32 deletions(-)
diff --git a/llvm/include/llvm/Support/FormatVariadic.h b/llvm/include/llvm/Support/FormatVariadic.h
index 595f2cf559a428..c0c931b3541040 100644
--- a/llvm/include/llvm/Support/FormatVariadic.h
+++ b/llvm/include/llvm/Support/FormatVariadic.h
@@ -83,7 +83,20 @@ class formatv_object_base {
public:
void format(raw_ostream &S) const {
- for (auto &R : parseFormatString(Fmt)) {
+ const auto [Replacements, NumExpectedParams] = parseFormatString(Fmt);
+ // Fail formatv() call if the number of replacement parameters provided
+ // does not match the expected number after parsing the format string.
+ // Assert in debug builds.
+ assert(NumExpectedParams == Adapters.size() &&
+ "Mismatch between replacement parameters expected and provided");
+ if (NumExpectedParams != Adapters.size()) {
+ S << "formatv() error: " << NumExpectedParams
+ << " replacement parameters expected, but " << Adapters.size()
+ << " provided";
+ return;
+ }
+
+ for (const auto &R : Replacements) {
if (R.Type == ReplacementType::Empty)
continue;
if (R.Type == ReplacementType::Literal) {
@@ -101,7 +114,11 @@ class formatv_object_base {
Align.format(S, R.Options);
}
}
- static SmallVector<ReplacementItem, 2> parseFormatString(StringRef Fmt);
+
+ // Parse format string and return the array of replacement items as well as
+ // the number of values we expect to be supplied to the formatv() call.
+ static std::pair<SmallVector<ReplacementItem, 2>, size_t>
+ parseFormatString(StringRef Fmt);
static std::optional<ReplacementItem> parseReplacementItem(StringRef Spec);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index 77e8ece9439cf9..eb2751ab30ac50 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -1518,8 +1518,7 @@ DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
"and abbreviation {1:x} has no DW_IDX_compile_unit "
"or DW_IDX_type_unit attribute.\n",
- NI.getUnitOffset(), Abbrev.Code,
- dwarf::DW_IDX_compile_unit);
+ NI.getUnitOffset(), Abbrev.Code);
});
++NumErrors;
}
diff --git a/llvm/lib/Support/FormatVariadic.cpp b/llvm/lib/Support/FormatVariadic.cpp
index e25d036cdf1e8c..c355aa519b8c53 100644
--- a/llvm/lib/Support/FormatVariadic.cpp
+++ b/llvm/lib/Support/FormatVariadic.cpp
@@ -35,8 +35,7 @@ bool formatv_object_base::consumeFieldLayout(StringRef &Spec, AlignStyle &Where,
if (Spec.size() > 1) {
// A maximum of 2 characters at the beginning can be used for something
- // other
- // than the width.
+ // other than the width.
// If Spec[1] is a loc char, then Spec[0] is a pad char and Spec[2:...]
// contains the width.
// Otherwise, if Spec[0] is a loc char, then Spec[1:...] contains the width.
@@ -143,16 +142,19 @@ formatv_object_base::splitLiteralAndReplacement(StringRef Fmt) {
return std::make_pair(ReplacementItem{Fmt}, StringRef());
}
-SmallVector<ReplacementItem, 2>
+std::pair<SmallVector<ReplacementItem, 2>, size_t>
formatv_object_base::parseFormatString(StringRef Fmt) {
SmallVector<ReplacementItem, 2> Replacements;
+ size_t NumExpectedParams = 0;
ReplacementItem I;
while (!Fmt.empty()) {
std::tie(I, Fmt) = splitLiteralAndReplacement(Fmt);
if (I.Type != ReplacementType::Empty)
Replacements.push_back(I);
+ if (I.Type == ReplacementType::Format)
+ NumExpectedParams = std::max(NumExpectedParams, I.Index + 1);
}
- return Replacements;
+ return {Replacements, NumExpectedParams};
}
void support::detail::format_adapter::anchor() {}
diff --git a/llvm/unittests/Support/FormatVariadicTest.cpp b/llvm/unittests/Support/FormatVariadicTest.cpp
index a78b25c53d7e43..b94c432f73b41a 100644
--- a/llvm/unittests/Support/FormatVariadicTest.cpp
+++ b/llvm/unittests/Support/FormatVariadicTest.cpp
@@ -36,13 +36,15 @@ static_assert(uses_missing_provider<NoFormat>::value, "");
}
TEST(FormatVariadicTest, EmptyFormatString) {
- auto Replacements = formatv_object_base::parseFormatString("");
+ auto [Replacements, NumVals] = formatv_object_base::parseFormatString("");
EXPECT_EQ(0U, Replacements.size());
+ EXPECT_EQ(0U, NumVals);
}
TEST(FormatVariadicTest, NoReplacements) {
const StringRef kFormatString = "This is a test";
- auto Replacements = formatv_object_base::parseFormatString(kFormatString);
+ auto [Replacements, NumVals] =
+ formatv_object_base::parseFormatString(kFormatString);
ASSERT_EQ(1U, Replacements.size());
EXPECT_EQ(kFormatString, Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Literal, Replacements[0].Type);
@@ -50,25 +52,27 @@ TEST(FormatVariadicTest, NoReplacements) {
TEST(FormatVariadicTest, EscapedBrace) {
// {{ should be replaced with {
- auto Replacements = formatv_object_base::parseFormatString("{{");
+ auto [Replacements, NumVals] = formatv_object_base::parseFormatString("{{");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("{", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Literal, Replacements[0].Type);
// An even number N of braces should be replaced with N/2 braces.
- Replacements = formatv_object_base::parseFormatString("{{{{{{");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{{{{{{");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("{{{", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Literal, Replacements[0].Type);
// } does not require doubling up.
- Replacements = formatv_object_base::parseFormatString("}");
+ std::tie(Replacements, NumVals) = formatv_object_base::parseFormatString("}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("}", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Literal, Replacements[0].Type);
// } does not require doubling up.
- Replacements = formatv_object_base::parseFormatString("}}}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("}}}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("}}}", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Literal, Replacements[0].Type);
@@ -76,14 +80,15 @@ TEST(FormatVariadicTest, EscapedBrace) {
TEST(FormatVariadicTest, ValidReplacementSequence) {
// 1. Simple replacement - parameter index only
- auto Replacements = formatv_object_base::parseFormatString("{0}");
+ auto [Replacements, NumVals] = formatv_object_base::parseFormatString("{0}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
EXPECT_EQ(0u, Replacements[0].Align);
EXPECT_EQ("", Replacements[0].Options);
- Replacements = formatv_object_base::parseFormatString("{1}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{1}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(1u, Replacements[0].Index);
@@ -92,7 +97,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ("", Replacements[0].Options);
// 2. Parameter index with right alignment
- Replacements = formatv_object_base::parseFormatString("{0,3}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,3}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
@@ -101,7 +107,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ("", Replacements[0].Options);
// 3. And left alignment
- Replacements = formatv_object_base::parseFormatString("{0,-3}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,-3}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
@@ -110,7 +117,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ("", Replacements[0].Options);
// 4. And center alignment
- Replacements = formatv_object_base::parseFormatString("{0,=3}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,=3}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
@@ -119,7 +127,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ("", Replacements[0].Options);
// 4. Parameter index with option string
- Replacements = formatv_object_base::parseFormatString("{0:foo}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0:foo}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
@@ -128,7 +137,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ("foo", Replacements[0].Options);
// 5. Parameter index with alignment before option string
- Replacements = formatv_object_base::parseFormatString("{0,-3:foo}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,-3:foo}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
@@ -137,7 +147,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ("foo", Replacements[0].Options);
// 7. Parameter indices, options, and alignment can all have whitespace.
- Replacements = formatv_object_base::parseFormatString("{ 0, -3 : foo }");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{ 0, -3 : foo }");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
@@ -147,7 +158,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
// 8. Everything after the first option specifier is part of the style, even
// if it contains another option specifier.
- Replacements = formatv_object_base::parseFormatString("{0:0:1}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0:0:1}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("0:0:1", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
@@ -157,7 +169,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ("0:1", Replacements[0].Options);
// 9. Custom padding character
- Replacements = formatv_object_base::parseFormatString("{0,p+4:foo}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,p+4:foo}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("0,p+4:foo", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
@@ -168,7 +181,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ("foo", Replacements[0].Options);
// Format string special characters are allowed as padding character
- Replacements = formatv_object_base::parseFormatString("{0,-+4:foo}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,-+4:foo}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("0,-+4:foo", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
@@ -178,7 +192,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ('-', Replacements[0].Pad);
EXPECT_EQ("foo", Replacements[0].Options);
- Replacements = formatv_object_base::parseFormatString("{0,+-4:foo}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,+-4:foo}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("0,+-4:foo", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
@@ -188,7 +203,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ('+', Replacements[0].Pad);
EXPECT_EQ("foo", Replacements[0].Options);
- Replacements = formatv_object_base::parseFormatString("{0,==4:foo}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,==4:foo}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("0,==4:foo", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
@@ -198,7 +214,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
EXPECT_EQ('=', Replacements[0].Pad);
EXPECT_EQ("foo", Replacements[0].Options);
- Replacements = formatv_object_base::parseFormatString("{0,:=4:foo}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,:=4:foo}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ("0,:=4:foo", Replacements[0].Spec);
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
@@ -211,7 +228,8 @@ TEST(FormatVariadicTest, ValidReplacementSequence) {
TEST(FormatVariadicTest, DefaultReplacementValues) {
// 2. If options string is missing, it defaults to empty.
- auto Replacements = formatv_object_base::parseFormatString("{0,3}");
+ auto [Replacements, NumVals] =
+ formatv_object_base::parseFormatString("{0,3}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
@@ -219,7 +237,8 @@ TEST(FormatVariadicTest, DefaultReplacementValues) {
EXPECT_EQ("", Replacements[0].Options);
// Including if the colon is present but contains no text.
- Replacements = formatv_object_base::parseFormatString("{0,3:}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0,3:}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(0u, Replacements[0].Index);
@@ -227,7 +246,8 @@ TEST(FormatVariadicTest, DefaultReplacementValues) {
EXPECT_EQ("", Replacements[0].Options);
// 3. If alignment is missing, it defaults to 0, right, space
- Replacements = formatv_object_base::parseFormatString("{0:foo}");
+ std::tie(Replacements, NumVals) =
+ formatv_object_base::parseFormatString("{0:foo}");
ASSERT_EQ(1u, Replacements.size());
EXPECT_EQ(ReplacementType::Format, Replacements[0].Type);
EXPECT_EQ(AlignStyle::Right, Replacements[0].Where);
@@ -238,7 +258,7 @@ TEST(FormatVariadicTest, DefaultReplacementValues) {
}
TEST(FormatVariadicTest, MultipleReplacements) {
- auto Replacements =
+ auto [Replacements, NumVals] =
formatv_object_base::parseFormatString("{0} {1:foo}-{2,-3:bar}");
ASSERT_EQ(5u, Replacements.size());
// {0}
@@ -698,6 +718,17 @@ TEST(FormatVariadicTest, FormatError) {
EXPECT_FALSE(E1.isA<StringError>()); // consumed
}
+TEST(FormatVariadicTest, FormatErrorNumArgMismatch) {
+#ifndef NDEBUG
+ EXPECT_EQ(
+ formatv("{0}", 0, 1).str(),
+ "formatv() error: 1 replacement parameters expected, but 2 provided");
+ EXPECT_EQ(
+ formatv("{0} {4}", 0, 1).str(),
+ "formatv() error: 5 replacement parameters expected, but 2 provided");
+#endif
+}
+
TEST(FormatVariadicTest, FormatFilterRange) {
std::vector<int> Vec{0, 1, 2};
auto Range = map_range(Vec, [](int V) { return V + 1; });
>From cf09ced96d132b1da206d3ad01be2cf3bb836d05 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Thu, 22 Aug 2024 14:48:53 -0700
Subject: [PATCH 2/2] [Support] Validate number of arguments passed to
formatv()
- Change formatv() to validate that the number of arguments passed matches
number of replacement parameters in the format string.
- When the format string is a literal, this failure can be easily fixed,
but when its dynamically generated, it may not be as straightforward.
- So changed existing formatv() to only accept literal strings as a
format string and enable argument count validation for that case only.
- Add a `formatvv` variant that allows non-literal format strings and
disables argument count verification.
---
clang-tools-extra/clangd/JSONTransport.cpp | 2 +-
.../clangd/index/dex/dexp/Dexp.cpp | 2 +-
.../clangd/refactor/tweaks/SpecialMembers.cpp | 4 +-
clang-tools-extra/clangd/support/Logger.h | 6 +-
.../GlobalCompilationDatabaseTests.cpp | 8 +-
clang-tools-extra/pseudo/lib/Forest.cpp | 5 +-
.../Checkers/CheckPlacementNew.cpp | 2 +-
.../Checkers/StdLibraryFunctionsChecker.cpp | 2 +-
lldb/include/lldb/Core/Debugger.h | 4 +-
lldb/include/lldb/Core/Module.h | 10 +-
.../lldb/Interpreter/CommandReturnObject.h | 6 +-
lldb/include/lldb/Utility/Log.h | 6 +-
lldb/include/lldb/Utility/Status.h | 4 +-
lldb/include/lldb/Utility/Stream.h | 2 +-
lldb/source/Core/FormatEntity.cpp | 4 +-
.../SymbolFile/DWARF/DWARFDebugInfoEntry.cpp | 2 +-
lldb/source/Utility/Log.cpp | 2 +-
lldb/tools/lldb-test/FormatUtil.h | 2 +-
lldb/tools/lldb-test/lldb-test.cpp | 2 +-
.../tools/lldb-server/tests/MessageObjects.h | 2 +-
.../llvm/DebugInfo/PDB/Native/LinePrinter.h | 4 +-
llvm/include/llvm/Support/FormatVariadic.h | 39 ++++--
llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 2 +-
.../DWARFLinker/Parallel/DWARFLinkerImpl.cpp | 2 +-
.../Orc/CompileOnDemandLayer.cpp | 8 +-
llvm/tools/llvm-exegesis/lib/Analysis.cpp | 2 +-
.../Analysis/ProfileSummaryInfoTest.cpp | 4 +-
llvm/unittests/Support/FormatVariadicTest.cpp | 10 +-
mlir/include/mlir/TableGen/CodeGenHelpers.h | 9 +-
.../mlir/Tools/lsp-server-support/Logging.h | 6 +-
.../Linalg/TransformOps/LinalgMatchOps.cpp | 2 +-
.../X86Vector/Transforms/AVXTranspose.cpp | 2 +-
mlir/lib/TableGen/CodeGenHelpers.cpp | 16 +--
mlir/lib/TableGen/Pattern.cpp | 31 ++---
mlir/lib/Tools/PDLL/CodeGen/CPPGen.cpp | 2 +-
.../Tools/lsp-server-support/Transport.cpp | 2 +-
.../Transforms/Utils/DialectConversion.cpp | 5 +-
mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp | 22 ++--
.../tools/mlir-tblgen/AttrOrTypeFormatGen.cpp | 22 ++--
mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp | 12 +-
mlir/tools/mlir-tblgen/DialectGen.cpp | 26 ++--
mlir/tools/mlir-tblgen/EnumsGen.cpp | 16 +--
.../tools/mlir-tblgen/LLVMIRConversionGen.cpp | 2 +-
mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 118 +++++++++---------
mlir/tools/mlir-tblgen/OpFormatGen.cpp | 105 ++++++++--------
mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp | 101 +++++++--------
mlir/tools/mlir-tblgen/PassCAPIGen.cpp | 10 +-
mlir/tools/mlir-tblgen/PassGen.cpp | 24 ++--
mlir/tools/mlir-tblgen/RewriterGen.cpp | 4 +-
49 files changed, 355 insertions(+), 330 deletions(-)
diff --git a/clang-tools-extra/clangd/JSONTransport.cpp b/clang-tools-extra/clangd/JSONTransport.cpp
index 3c0e198433f360..eebc9cab8acc88 100644
--- a/clang-tools-extra/clangd/JSONTransport.cpp
+++ b/clang-tools-extra/clangd/JSONTransport.cpp
@@ -135,7 +135,7 @@ class JSONTransport : public Transport {
void sendMessage(llvm::json::Value Message) {
OutputBuffer.clear();
llvm::raw_svector_ostream OS(OutputBuffer);
- OS << llvm::formatv(Pretty ? "{0:2}" : "{0}", Message);
+ OS << llvm::formatvv(Pretty ? "{0:2}" : "{0}", Message);
Out << "Content-Length: " << OutputBuffer.size() << "\r\n\r\n"
<< OutputBuffer;
Out.flush();
diff --git a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
index cea59ae409914c..d3e6ab58bbed2a 100644
--- a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
+++ b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
@@ -161,7 +161,7 @@ class FuzzyFind : public Command {
}
Request.AnyScope = Request.Scopes.empty();
// FIXME(kbobyrev): Print symbol final scores to see the distribution.
- static const auto *OutputFormat = "{0,-4} | {1,-40} | {2,-25}\n";
+ static const char OutputFormat[] = "{0,-4} | {1,-40} | {2,-25}\n";
llvm::outs() << llvm::formatv(OutputFormat, "Rank", "Symbol ID",
"Symbol Name");
size_t Rank = 0;
diff --git a/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp b/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp
index 0b86b484227071..54178535fc0177 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/SpecialMembers.cpp
@@ -50,8 +50,8 @@ std::string buildSpecialMemberDeclarations(const CXXRecordDecl &Class) {
bool Delete = !D || D->isDeleted();
OS << llvm::formatv(
"{0} = {1};\n",
- llvm::formatv(MemberPattern, Class.getName(),
- llvm::formatv(ParmPattern, Class.getName())),
+ llvm::formatvv(MemberPattern, Class.getName(),
+ llvm::formatvv(ParmPattern, Class.getName())),
Delete ? "delete" : "default");
};
auto PrintMembers = [&](const Members &M, const char *MemberPattern) {
diff --git a/clang-tools-extra/clangd/support/Logger.h b/clang-tools-extra/clangd/support/Logger.h
index dba33be48f56df..1cc872114b6b1e 100644
--- a/clang-tools-extra/clangd/support/Logger.h
+++ b/clang-tools-extra/clangd/support/Logger.h
@@ -46,7 +46,7 @@ inline decltype(fmt_consume(llvm::Error::success())) wrap(llvm::Error &&V) {
template <typename... Ts>
void log(Logger::Level L, const char *Fmt, Ts &&... Vals) {
detail::logImpl(L, Fmt,
- llvm::formatv(Fmt, detail::wrap(std::forward<Ts>(Vals))...));
+ llvm::formatvv(Fmt, detail::wrap(std::forward<Ts>(Vals))...));
}
llvm::Error error(std::error_code, std::string &&);
@@ -79,13 +79,13 @@ template <typename... Ts>
llvm::Error error(std::error_code EC, const char *Fmt, Ts &&... Vals) {
// We must render the formatv_object eagerly, while references are valid.
return detail::error(
- EC, llvm::formatv(Fmt, detail::wrap(std::forward<Ts>(Vals))...).str());
+ EC, llvm::formatvv(Fmt, detail::wrap(std::forward<Ts>(Vals))...).str());
}
// Overload with no error_code conversion, the error will be inconvertible.
template <typename... Ts> llvm::Error error(const char *Fmt, Ts &&... Vals) {
return detail::error(
llvm::inconvertibleErrorCode(),
- llvm::formatv(Fmt, detail::wrap(std::forward<Ts>(Vals))...).str());
+ llvm::formatvv(Fmt, detail::wrap(std::forward<Ts>(Vals))...).str());
}
// Overload to avoid formatv complexity for simple strings.
inline llvm::Error error(std::error_code EC, std::string Msg) {
diff --git a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
index a2ffdefe1bbcb2..1299e1fdfb6c6d 100644
--- a/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
+++ b/clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp
@@ -179,7 +179,7 @@ TEST_F(OverlayCDBTest, ExpandedResponseFiles) {
}
TEST(GlobalCompilationDatabaseTest, DiscoveryWithNestedCDBs) {
- const char *const CDBOuter =
+ const char CDBOuter[] =
R"cdb(
[
{
@@ -199,7 +199,7 @@ TEST(GlobalCompilationDatabaseTest, DiscoveryWithNestedCDBs) {
}
]
)cdb";
- const char *const CDBInner =
+ const char CDBInner[] =
R"cdb(
[
{
@@ -317,7 +317,7 @@ TEST(GlobalCompilationDatabaseTest, BuildDir) {
.CommandLine;
};
EXPECT_THAT(Command("x/foo.cc"), IsEmpty());
- const char *const CDB =
+ const char CDB[] =
R"cdb(
[
{
@@ -456,7 +456,7 @@ TEST(GlobalCompilationDatabaseTest, InferenceWithResponseFile) {
OutStream << "-DXYZZY";
OutStream.close();
- const char *const CDB =
+ const char CDB[] =
R"cdb(
[
{
diff --git a/clang-tools-extra/pseudo/lib/Forest.cpp b/clang-tools-extra/pseudo/lib/Forest.cpp
index e8e60e5ec475a4..99d40161679cbc 100644
--- a/clang-tools-extra/pseudo/lib/Forest.cpp
+++ b/clang-tools-extra/pseudo/lib/Forest.cpp
@@ -63,6 +63,7 @@ std::string ForestNode::dump(const Grammar &G) const {
std::string ForestNode::dumpRecursive(const Grammar &G,
bool Abbreviated) const {
using llvm::formatv;
+ using llvm::formatvv;
Token::Index MaxToken = 0;
// Count visits of nodes so we can mark those seen multiple times.
llvm::DenseMap<const ForestNode *, /*VisitCount*/ unsigned> VisitCounts;
@@ -128,9 +129,9 @@ std::string ForestNode::dumpRecursive(const Grammar &G,
}
if (End == KEnd)
- Result += formatv(RangeFormat.c_str(), P->startTokenIndex(), "end");
+ Result += formatvv(RangeFormat.c_str(), P->startTokenIndex(), "end");
else
- Result += formatv(RangeFormat.c_str(), P->startTokenIndex(), End);
+ Result += formatvv(RangeFormat.c_str(), P->startTokenIndex(), End);
Result += LineDec.Prefix;
Result += LineDec.First;
if (ElidedParent) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp b/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
index 99e11a15c08dc2..1b89951397cfb1 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CheckPlacementNew.cpp
@@ -131,7 +131,7 @@ bool PlacementNewChecker::checkPlaceCapacityIsSufficient(
"Storage provided to placement new is only {0} bytes, "
"whereas the allocated array type requires more space for "
"internal needs",
- SizeOfPlaceCI->getValue(), SizeOfTargetCI->getValue()));
+ SizeOfPlaceCI->getValue()));
else
Msg = std::string(llvm::formatv(
"Storage provided to placement new is only {0} bytes, "
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 8f4bd17afc8581..60c035612dcd44 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -1401,7 +1401,7 @@ void StdLibraryFunctionsChecker::checkPostCall(const CallEvent &Call,
ErrnoNote =
llvm::formatv("After calling '{0}' {1}", FunctionName, ErrnoNote);
} else {
- CaseNote = llvm::formatv(Case.getNote().str().c_str(), FunctionName);
+ CaseNote = llvm::formatvv(Case.getNote().str().c_str(), FunctionName);
}
const SVal RV = Call.getReturnValue();
diff --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index a72c2596cc2c5e..cbfd688b536f8f 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -435,7 +435,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
if (!cur_func)
cur_func = "<UNKNOWN>";
ReportInterruption(InterruptionReport(
- cur_func, llvm::formatv(formatv, std::forward<Args>(args)...)));
+ cur_func, llvm::formatvv(formatv, std::forward<Args>(args)...)));
}
return ret_val;
}
@@ -466,7 +466,7 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
Args &&...args)
: InterruptionReport(
function_name,
- llvm::formatv(format, std::forward<Args>(args)...)) {}
+ llvm::formatvv(format, std::forward<Args>(args)...)) {}
std::string m_function_name;
std::string m_description;
diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 5589c1c9a350dc..6efda666c86e3d 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -781,24 +781,24 @@ class Module : public std::enable_shared_from_this<Module>,
// own and keeps the output a bit more consistent.
template <typename... Args>
void LogMessage(Log *log, const char *format, Args &&...args) {
- LogMessage(log, llvm::formatv(format, std::forward<Args>(args)...));
+ LogMessage(log, llvm::formatvv(format, std::forward<Args>(args)...));
}
template <typename... Args>
void LogMessageVerboseBacktrace(Log *log, const char *format,
Args &&...args) {
LogMessageVerboseBacktrace(
- log, llvm::formatv(format, std::forward<Args>(args)...));
+ log, llvm::formatvv(format, std::forward<Args>(args)...));
}
template <typename... Args>
void ReportWarning(const char *format, Args &&...args) {
- ReportWarning(llvm::formatv(format, std::forward<Args>(args)...));
+ ReportWarning(llvm::formatvv(format, std::forward<Args>(args)...));
}
template <typename... Args>
void ReportError(const char *format, Args &&...args) {
- ReportError(llvm::formatv(format, std::forward<Args>(args)...));
+ ReportError(llvm::formatvv(format, std::forward<Args>(args)...));
}
// Only report an error once when the module is first detected to be modified
@@ -806,7 +806,7 @@ class Module : public std::enable_shared_from_this<Module>,
template <typename... Args>
void ReportErrorIfModifyDetected(const char *format, Args &&...args) {
ReportErrorIfModifyDetected(
- llvm::formatv(format, std::forward<Args>(args)...));
+ llvm::formatvv(format, std::forward<Args>(args)...));
}
void ReportWarningOptimization(std::optional<lldb::user_id_t> debugger_id);
diff --git a/lldb/include/lldb/Interpreter/CommandReturnObject.h b/lldb/include/lldb/Interpreter/CommandReturnObject.h
index 8c4dcb54d708f0..d580dffb7dbdb6 100644
--- a/lldb/include/lldb/Interpreter/CommandReturnObject.h
+++ b/lldb/include/lldb/Interpreter/CommandReturnObject.h
@@ -118,17 +118,17 @@ class CommandReturnObject {
template <typename... Args>
void AppendMessageWithFormatv(const char *format, Args &&... args) {
- AppendMessage(llvm::formatv(format, std::forward<Args>(args)...).str());
+ AppendMessage(llvm::formatvv(format, std::forward<Args>(args)...).str());
}
template <typename... Args>
void AppendWarningWithFormatv(const char *format, Args &&... args) {
- AppendWarning(llvm::formatv(format, std::forward<Args>(args)...).str());
+ AppendWarning(llvm::formatvv(format, std::forward<Args>(args)...).str());
}
template <typename... Args>
void AppendErrorWithFormatv(const char *format, Args &&... args) {
- AppendError(llvm::formatv(format, std::forward<Args>(args)...).str());
+ AppendError(llvm::formatvv(format, std::forward<Args>(args)...).str());
}
void SetError(const Status &error, const char *fallback_error_cstr = nullptr);
diff --git a/lldb/include/lldb/Utility/Log.h b/lldb/include/lldb/Utility/Log.h
index 27707c17f9b824..3357ce579433be 100644
--- a/lldb/include/lldb/Utility/Log.h
+++ b/lldb/include/lldb/Utility/Log.h
@@ -237,7 +237,7 @@ class Log final {
template <typename... Args>
void Format(llvm::StringRef file, llvm::StringRef function,
const char *format, Args &&... args) {
- Format(file, function, llvm::formatv(format, std::forward<Args>(args)...));
+ Format(file, function, llvm::formatvv(format, std::forward<Args>(args)...));
}
template <typename... Args>
@@ -245,8 +245,8 @@ class Log final {
llvm::StringRef function, const char *format,
Args &&... args) {
Format(file, function,
- llvm::formatv(format, llvm::toString(std::move(error)),
- std::forward<Args>(args)...));
+ llvm::formatvv(format, llvm::toString(std::move(error)),
+ std::forward<Args>(args)...));
}
void Formatf(llvm::StringRef file, llvm::StringRef function,
diff --git a/lldb/include/lldb/Utility/Status.h b/lldb/include/lldb/Utility/Status.h
index fa5768141fa45d..2a9ff15cc9f76c 100644
--- a/lldb/include/lldb/Utility/Status.h
+++ b/lldb/include/lldb/Utility/Status.h
@@ -66,7 +66,7 @@ class Status {
template <typename... Args>
static Status createWithFormat(const char *format, Args &&...args) {
- return Status(llvm::formatv(format, std::forward<Args>(args)...));
+ return Status(llvm::formatvv(format, std::forward<Args>(args)...));
}
~Status();
@@ -167,7 +167,7 @@ class Status {
template <typename... Args>
void SetErrorStringWithFormatv(const char *format, Args &&... args) {
- SetErrorString(llvm::formatv(format, std::forward<Args>(args)...).str());
+ SetErrorString(llvm::formatvv(format, std::forward<Args>(args)...).str());
}
/// Test for success condition.
diff --git a/lldb/include/lldb/Utility/Stream.h b/lldb/include/lldb/Utility/Stream.h
index 37bcdc99241715..9277882bb3cdaf 100644
--- a/lldb/include/lldb/Utility/Stream.h
+++ b/lldb/include/lldb/Utility/Stream.h
@@ -351,7 +351,7 @@ class Stream {
size_t PrintfVarArg(const char *format, va_list args);
template <typename... Args> void Format(const char *format, Args &&... args) {
- PutCString(llvm::formatv(format, std::forward<Args>(args)...).str());
+ PutCString(llvm::formatvv(format, std::forward<Args>(args)...).str());
}
/// Output a quoted C string value to the stream.
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index 4e1f37099148b4..33924f17898805 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -674,12 +674,12 @@ static bool DumpValueWithLLVMFormat(Stream &s, llvm::StringRef options,
bool success = false;
int64_t integer = valobj.GetValueAsSigned(0, &success);
if (success)
- formatted = llvm::formatv(llvm_format.data(), integer);
+ formatted = llvm::formatvv(llvm_format.data(), integer);
} else {
bool success = false;
uint64_t integer = valobj.GetValueAsUnsigned(0, &success);
if (success)
- formatted = llvm::formatv(llvm_format.data(), integer);
+ formatted = llvm::formatvv(llvm_format.data(), integer);
}
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index e2660735ea7dec..16d9f5ad4ce163 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -49,7 +49,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
unit.GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
"[{0:x16}]: {1}, please file a bug and "
"attach the file at the start of this error message",
- static_cast<uint64_t>(m_offset), llvm::formatv(fmt, vals...));
+ static_cast<uint64_t>(m_offset), llvm::formatvv(fmt, vals...));
*offset_ptr = std::numeric_limits<lldb::offset_t>::max();
return false;
};
diff --git a/lldb/source/Utility/Log.cpp b/lldb/source/Utility/Log.cpp
index 6713a5bd758204..c55c8cf585b7ff 100644
--- a/lldb/source/Utility/Log.cpp
+++ b/lldb/source/Utility/Log.cpp
@@ -343,7 +343,7 @@ void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file,
llvm::SmallString<12> format_str;
llvm::raw_svector_ostream format_os(format_str);
format_os << "{0,-" << llvm::alignTo<16>(thread_name.size()) << "} ";
- OS << llvm::formatv(format_str.c_str(), thread_name);
+ OS << llvm::formatvv(format_str.c_str(), thread_name);
}
if (options.Test(LLDB_LOG_OPTION_BACKTRACE))
diff --git a/lldb/tools/lldb-test/FormatUtil.h b/lldb/tools/lldb-test/FormatUtil.h
index 2b2266e8dfbd6b..657931de6c05d9 100644
--- a/lldb/tools/lldb-test/FormatUtil.h
+++ b/lldb/tools/lldb-test/FormatUtil.h
@@ -46,7 +46,7 @@ class LinePrinter {
void printLine(const llvm::Twine &T) { line() << T; }
template <typename... Ts> void formatLine(const char *Fmt, Ts &&... Items) {
- printLine(llvm::formatv(Fmt, std::forward<Ts>(Items)...));
+ printLine(llvm::formatvv(Fmt, std::forward<Ts>(Items)...));
}
void formatBinary(llvm::StringRef Label, llvm::ArrayRef<uint8_t> Data,
diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index 535422a6d827be..df3a8f3c373925 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/tools/lldb-test/lldb-test.cpp
@@ -337,7 +337,7 @@ llvm::SmallVector<CompilerContext, 4> parseCompilerContext() {
template <typename... Args>
static Error make_string_error(const char *Format, Args &&... args) {
return llvm::make_error<llvm::StringError>(
- llvm::formatv(Format, std::forward<Args>(args)...).str(),
+ llvm::formatvv(Format, std::forward<Args>(args)...).str(),
llvm::inconvertibleErrorCode());
}
diff --git a/lldb/unittests/tools/lldb-server/tests/MessageObjects.h b/lldb/unittests/tools/lldb-server/tests/MessageObjects.h
index 0e0a3b2a927266..1c493282f2da6f 100644
--- a/lldb/unittests/tools/lldb-server/tests/MessageObjects.h
+++ b/lldb/unittests/tools/lldb-server/tests/MessageObjects.h
@@ -172,7 +172,7 @@ template <typename... Args>
llvm::Error make_parsing_error(llvm::StringRef format, Args &&... args) {
std::string error =
"Unable to parse " +
- llvm::formatv(format.data(), std::forward<Args>(args)...).str();
+ llvm::formatvv(format.data(), std::forward<Args>(args)...).str();
return llvm::make_error<llvm::StringError>(error,
llvm::inconvertibleErrorCode());
}
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h b/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h
index bb029e534c74e0..9b443948506517 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/LinePrinter.h
@@ -61,10 +61,10 @@ class LinePrinter {
void printLine(const Twine &T);
void print(const Twine &T);
template <typename... Ts> void formatLine(const char *Fmt, Ts &&...Items) {
- printLine(formatv(Fmt, std::forward<Ts>(Items)...));
+ printLine(formatvv(Fmt, std::forward<Ts>(Items)...));
}
template <typename... Ts> void format(const char *Fmt, Ts &&...Items) {
- print(formatv(Fmt, std::forward<Ts>(Items)...));
+ print(formatvv(Fmt, std::forward<Ts>(Items)...));
}
void formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
diff --git a/llvm/include/llvm/Support/FormatVariadic.h b/llvm/include/llvm/Support/FormatVariadic.h
index c0c931b3541040..dbac5816782ffd 100644
--- a/llvm/include/llvm/Support/FormatVariadic.h
+++ b/llvm/include/llvm/Support/FormatVariadic.h
@@ -66,6 +66,7 @@ struct ReplacementItem {
class formatv_object_base {
protected:
StringRef Fmt;
+ bool ValidateNumArgs;
ArrayRef<support::detail::format_adapter *> Adapters;
static bool consumeFieldLayout(StringRef &Spec, AlignStyle &Where,
@@ -74,9 +75,9 @@ class formatv_object_base {
static std::pair<ReplacementItem, StringRef>
splitLiteralAndReplacement(StringRef Fmt);
- formatv_object_base(StringRef Fmt,
+ formatv_object_base(StringRef Fmt, bool ValidateNumArgs,
ArrayRef<support::detail::format_adapter *> Adapters)
- : Fmt(Fmt), Adapters(Adapters) {}
+ : Fmt(Fmt), ValidateNumArgs(ValidateNumArgs), Adapters(Adapters) {}
formatv_object_base(formatv_object_base const &rhs) = delete;
formatv_object_base(formatv_object_base &&rhs) = default;
@@ -87,9 +88,11 @@ class formatv_object_base {
// Fail formatv() call if the number of replacement parameters provided
// does not match the expected number after parsing the format string.
// Assert in debug builds.
- assert(NumExpectedParams == Adapters.size() &&
- "Mismatch between replacement parameters expected and provided");
- if (NumExpectedParams != Adapters.size()) {
+ if (ValidateNumArgs && NumExpectedParams != Adapters.size()) {
+ errs() << "Invalid format() in formatv: " << Fmt << "\n";
+ assert(0 &&
+ "Mismatch between replacement parameters expected and provided");
+
S << "formatv() error: " << NumExpectedParams
<< " replacement parameters expected, but " << Adapters.size()
<< " provided";
@@ -166,8 +169,8 @@ template <typename Tuple> class formatv_object : public formatv_object_base {
};
public:
- formatv_object(StringRef Fmt, Tuple &&Params)
- : formatv_object_base(Fmt, ParameterPointers),
+ formatv_object(StringRef Fmt, bool ValidateNumArgs, Tuple &&Params)
+ : formatv_object_base(Fmt, ValidateNumArgs, ParameterPointers),
Parameters(std::move(Params)) {
ParameterPointers = std::apply(create_adapters(), Parameters);
}
@@ -264,15 +267,31 @@ template <typename Tuple> class formatv_object : public formatv_object_base {
// assertion. Otherwise, it will try to do something reasonable, but in general
// the details of what that is are undefined.
//
+
+// formatv() with a literal string as as the format.
+template <size_t N, typename... Ts>
+inline auto formatv(const char (&Fmt)[N], Ts &&...Vals)
+ -> formatv_object<decltype(std::make_tuple(
+ support::detail::build_format_adapter(std::forward<Ts>(Vals))...))> {
+ using ParamTuple = decltype(std::make_tuple(
+ support::detail::build_format_adapter(std::forward<Ts>(Vals))...));
+ return formatv_object<ParamTuple>(
+ Fmt, /*ValidateNumArgs=*/true,
+ std::make_tuple(
+ support::detail::build_format_adapter(std::forward<Ts>(Vals))...));
+}
+
+// formatvv() with a variable string as as the format.
template <typename... Ts>
-inline auto formatv(const char *Fmt, Ts &&...Vals)
+inline auto formatvv(const char *Fmt, Ts &&...Vals)
-> formatv_object<decltype(std::make_tuple(
support::detail::build_format_adapter(std::forward<Ts>(Vals))...))> {
using ParamTuple = decltype(std::make_tuple(
support::detail::build_format_adapter(std::forward<Ts>(Vals))...));
return formatv_object<ParamTuple>(
- Fmt, std::make_tuple(support::detail::build_format_adapter(
- std::forward<Ts>(Vals))...));
+ Fmt, /*ValidateNumArgs=*/false,
+ std::make_tuple(
+ support::detail::build_format_adapter(std::forward<Ts>(Vals))...));
}
} // end namespace llvm
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 280d3f1861ff00..8ad45d1e6f07be 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -2986,7 +2986,7 @@ Error DWARFLinker::link() {
int64_t InputTotal = 0;
int64_t OutputTotal = 0;
- const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
+ const char FormatStr[] = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
// Print header.
outs() << ".debug_info section size (in bytes)\n";
diff --git a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
index 6d9e3319db7e5e..2dd56f779eabfd 100644
--- a/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/DWARFLinkerImpl.cpp
@@ -915,7 +915,7 @@ void DWARFLinkerImpl::printStatistic() {
int64_t InputTotal = 0;
int64_t OutputTotal = 0;
- const char *FormatStr = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
+ const char FormatStr[] = "{0,-45} {1,10}b {2,10}b {3,8:P}\n";
// Print header.
outs() << ".debug_info section size (in bytes)\n";
diff --git a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
index 6448adaa0ceb36..48ee16e7574fd7 100644
--- a/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
@@ -348,10 +348,10 @@ void CompileOnDemandLayer::emitPartition(
HC = hash_combine(HC, hash_combine_range(GVName.begin(), GVName.end()));
}
raw_string_ostream(SubModuleName)
- << ".submodule."
- << formatv(sizeof(size_t) == 8 ? "{0:x16}" : "{0:x8}",
- static_cast<size_t>(HC))
- << ".ll";
+ << ".submodule."
+ << formatvv(sizeof(size_t) == 8 ? "{0:x16}" : "{0:x8}",
+ static_cast<size_t>(HC))
+ << ".ll";
}
// Extract the requested partiton (plus any necessary aliases) and
diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
index be10c32cf08d56..96d73b50dd934d 100644
--- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp
@@ -94,7 +94,7 @@ static void writeMeasurementValue(raw_ostream &OS, const double Value) {
static constexpr StringLiteral SimpleFloatFormat = StringLiteral("{0:F}");
writeEscaped<Tag>(
- OS, formatv(SimpleFloatFormat.data(), Value).sstr<SerializationLen>());
+ OS, formatvv(SimpleFloatFormat.data(), Value).sstr<SerializationLen>());
}
template <typename EscapeTag, EscapeTag Tag>
diff --git a/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp b/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
index f36d3ba99775b4..f214122366c2e1 100644
--- a/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
+++ b/llvm/unittests/Analysis/ProfileSummaryInfoTest.cpp
@@ -51,7 +51,7 @@ class ProfileSummaryInfoTest : public testing::Test {
double PartialProfileRatio = 0.0,
uint64_t HotNumCounts = 3,
uint64_t ColdNumCounts = 10) {
- const char *ModuleString =
+ const char ModuleString[] =
"define i32 @g(i32 %x) !prof !21 {{\n"
" ret i32 0\n"
"}\n"
@@ -91,7 +91,7 @@ class ProfileSummaryInfoTest : public testing::Test {
"!22 = !{{!\"function_entry_count\", i64 100}\n"
"!23 = !{{!\"branch_weights\", i32 64, i32 4}\n"
"{0}";
- const char *SummaryString =
+ const char SummaryString[] =
"!llvm.module.flags = !{{!1}\n"
"!1 = !{{i32 1, !\"ProfileSummary\", !2}\n"
"!2 = !{{!3, !4, !5, !6, !7, !8, !9, !10, !11, !12}\n"
diff --git a/llvm/unittests/Support/FormatVariadicTest.cpp b/llvm/unittests/Support/FormatVariadicTest.cpp
index b94c432f73b41a..a7e43ca47b685d 100644
--- a/llvm/unittests/Support/FormatVariadicTest.cpp
+++ b/llvm/unittests/Support/FormatVariadicTest.cpp
@@ -520,7 +520,7 @@ struct format_tuple {
explicit format_tuple(const char *Fmt) : Fmt(Fmt) {}
template <typename... Ts> auto operator()(Ts &&... Values) const {
- return formatv(Fmt, std::forward<Ts>(Values)...);
+ return formatvv(Fmt, std::forward<Ts>(Values)...);
}
};
@@ -536,12 +536,12 @@ TEST(FormatVariadicTest, BigTest) {
.08215f, (void *)nullptr, 0, 6.62E-34, -908234908423,
908234908422234, std::numeric_limits<double>::infinity(), 0x0)};
// Test long string formatting with many edge cases combined.
- const char *Intro =
+ const char Intro[] =
"There are {{{0}} items in the tuple, and {{{1}} tuple(s) in the array.";
- const char *Header =
+ const char Header[] =
"{0,6}|{1,8}|{2,=10}|{3,=10}|{4,=13}|{5,7}|{6,7}|{7,10}|{8,"
"-7}|{9,10}|{10,16}|{11,17}|{12,6}|{13,4}";
- const char *Line =
+ const char Line[] =
"{0,6}|{1,8:X}|{2,=10}|{3,=10:5}|{4,=13}|{5,7:3}|{6,7:P2}|{7,"
"10:X8}|{8,-7:N}|{9,10:E4}|{10,16:N}|{11,17:D}|{12,6}|{13,"
"4:X}";
@@ -719,7 +719,7 @@ TEST(FormatVariadicTest, FormatError) {
}
TEST(FormatVariadicTest, FormatErrorNumArgMismatch) {
-#ifndef NDEBUG
+#ifdef NDEBUG // Disable the test in debug builds where it will assert.
EXPECT_EQ(
formatv("{0}", 0, 1).str(),
"formatv() error: 1 replacement parameters expected, but 2 provided");
diff --git a/mlir/include/mlir/TableGen/CodeGenHelpers.h b/mlir/include/mlir/TableGen/CodeGenHelpers.h
index c263c69c53d1e3..4df4c5f375d85d 100644
--- a/mlir/include/mlir/TableGen/CodeGenHelpers.h
+++ b/mlir/include/mlir/TableGen/CodeGenHelpers.h
@@ -31,11 +31,16 @@ class Constraint;
class DagLeaf;
// Format into a std::string
-template <typename... Parameters>
-std::string strfmt(const char *fmt, Parameters &&...parameters) {
+template <size_t N, typename... Parameters>
+std::string strfmt(const char (&fmt)[N], Parameters &&...parameters) {
return llvm::formatv(fmt, std::forward<Parameters>(parameters)...).str();
}
+template <typename... Parameters>
+std::string strfmtv(const char *fmt, Parameters &&...parameters) {
+ return llvm::formatvv(fmt, std::forward<Parameters>(parameters)...).str();
+}
+
// Simple RAII helper for defining ifdef-undef-endif scopes.
class IfDefScope {
public:
diff --git a/mlir/include/mlir/Tools/lsp-server-support/Logging.h b/mlir/include/mlir/Tools/lsp-server-support/Logging.h
index 9b090d05f7fa47..aacc61b6098f2a 100644
--- a/mlir/include/mlir/Tools/lsp-server-support/Logging.h
+++ b/mlir/include/mlir/Tools/lsp-server-support/Logging.h
@@ -32,15 +32,15 @@ class Logger {
/// after a call to `initialize`.
template <typename... Ts>
static void debug(const char *fmt, Ts &&...vals) {
- log(Level::Debug, fmt, llvm::formatv(fmt, std::forward<Ts>(vals)...));
+ log(Level::Debug, fmt, llvm::formatvv(fmt, std::forward<Ts>(vals)...));
}
template <typename... Ts>
static void info(const char *fmt, Ts &&...vals) {
- log(Level::Info, fmt, llvm::formatv(fmt, std::forward<Ts>(vals)...));
+ log(Level::Info, fmt, llvm::formatvv(fmt, std::forward<Ts>(vals)...));
}
template <typename... Ts>
static void error(const char *fmt, Ts &&...vals) {
- log(Level::Error, fmt, llvm::formatv(fmt, std::forward<Ts>(vals)...));
+ log(Level::Error, fmt, llvm::formatvv(fmt, std::forward<Ts>(vals)...));
}
private:
diff --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp
index be4ab361083b9a..209abd092ec5df 100644
--- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp
+++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgMatchOps.cpp
@@ -333,7 +333,7 @@ static DiagnosedSilenceableFailure containsAll(ArrayRef<unsigned> reference,
})) {
continue;
}
- return emitSilenceableFailure(loc) << llvm::formatv(message, value);
+ return emitSilenceableFailure(loc) << llvm::formatvv(message, value);
}
return DiagnosedSilenceableFailure::success();
}
diff --git a/mlir/lib/Dialect/X86Vector/Transforms/AVXTranspose.cpp b/mlir/lib/Dialect/X86Vector/Transforms/AVXTranspose.cpp
index edd939eda7c599..523561b10cd253 100644
--- a/mlir/lib/Dialect/X86Vector/Transforms/AVXTranspose.cpp
+++ b/mlir/lib/Dialect/X86Vector/Transforms/AVXTranspose.cpp
@@ -33,7 +33,7 @@ Value mlir::x86vector::avx2::inline_asm::mm256BlendPsAsm(
ImplicitLocOpBuilder &b, Value v1, Value v2, uint8_t mask) {
auto asmDialectAttr =
LLVM::AsmDialectAttr::get(b.getContext(), LLVM::AsmDialect::AD_Intel);
- const auto *asmTp = "vblendps $0, $1, $2, {0}";
+ const char asmTp[] = "vblendps $0, $1, $2, {0}";
const auto *asmCstr =
"=x,x,x"; // Careful: constraint parser is very brittle: no ws!
SmallVector<Value> asmVals{v1, v2};
diff --git a/mlir/lib/TableGen/CodeGenHelpers.cpp b/mlir/lib/TableGen/CodeGenHelpers.cpp
index 718a8136944bdf..d366c2d2c80a4f 100644
--- a/mlir/lib/TableGen/CodeGenHelpers.cpp
+++ b/mlir/lib/TableGen/CodeGenHelpers.cpp
@@ -110,7 +110,7 @@ StringRef StaticVerifierFunctionEmitter::getRegionConstraintFn(
/// Code for a type constraint. These may be called on the type of either
/// operands or results.
-static const char *const typeConstraintCode = R"(
+static const char typeConstraintCode[] = R"(
static ::llvm::LogicalResult {0}(
::mlir::Operation *op, ::mlir::Type type, ::llvm::StringRef valueKind,
unsigned valueIndex) {
@@ -128,7 +128,7 @@ static ::llvm::LogicalResult {0}(
///
/// TODO: Unique constraints for adaptors. However, most Adaptor::verify
/// functions are stripped anyways.
-static const char *const attrConstraintCode = R"(
+static const char attrConstraintCode[] = R"(
static ::llvm::LogicalResult {0}(
::mlir::Attribute attr, ::llvm::StringRef attrName, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError) {{
if (attr && !({1}))
@@ -145,7 +145,7 @@ static ::llvm::LogicalResult {0}(
)";
/// Code for a successor constraint.
-static const char *const successorConstraintCode = R"(
+static const char successorConstraintCode[] = R"(
static ::llvm::LogicalResult {0}(
::mlir::Operation *op, ::mlir::Block *successor,
::llvm::StringRef successorName, unsigned successorIndex) {
@@ -159,7 +159,7 @@ static ::llvm::LogicalResult {0}(
/// Code for a region constraint. Callers will need to pass in the region's name
/// for emitting an error message.
-static const char *const regionConstraintCode = R"(
+static const char regionConstraintCode[] = R"(
static ::llvm::LogicalResult {0}(
::mlir::Operation *op, ::mlir::Region ®ion, ::llvm::StringRef regionName,
unsigned regionIndex) {
@@ -175,7 +175,7 @@ static ::llvm::LogicalResult {0}(
/// Code for a pattern type or attribute constraint.
///
/// {3}: "Type type" or "Attribute attr".
-static const char *const patternAttrOrTypeConstraintCode = R"(
+static const char patternAttrOrTypeConstraintCode[] = R"(
static ::llvm::LogicalResult {0}(
::mlir::PatternRewriter &rewriter, ::mlir::Operation *op, ::mlir::{3},
::llvm::StringRef failureStr) {
@@ -194,9 +194,9 @@ void StaticVerifierFunctionEmitter::emitConstraints(
FmtContext ctx;
ctx.addSubst("_op", "*op").withSelf(selfName);
for (auto &it : constraints) {
- os << formatv(codeTemplate, it.second,
- tgfmt(it.first.getConditionTemplate(), &ctx),
- escapeString(it.first.getSummary()));
+ os << formatvv(codeTemplate, it.second,
+ tgfmt(it.first.getConditionTemplate(), &ctx),
+ escapeString(it.first.getSummary()));
}
}
diff --git a/mlir/lib/TableGen/Pattern.cpp b/mlir/lib/TableGen/Pattern.cpp
index afb69e7cc55866..3a1bdac6dabe49 100644
--- a/mlir/lib/TableGen/Pattern.cpp
+++ b/mlir/lib/TableGen/Pattern.cpp
@@ -27,6 +27,7 @@ using namespace mlir;
using namespace tblgen;
using llvm::formatv;
+using llvm::formatvv;
//===----------------------------------------------------------------------===//
// DagLeaf
@@ -295,7 +296,7 @@ std::string SymbolInfoMap::SymbolInfo::getValueAndRangeUse(
switch (kind) {
case Kind::Attr: {
assert(index < 0);
- auto repl = formatv(fmt, name);
+ auto repl = formatvv(fmt, name);
LLVM_DEBUG(llvm::dbgs() << repl << " (Attr)\n");
return std::string(repl);
}
@@ -306,11 +307,11 @@ std::string SymbolInfoMap::SymbolInfo::getValueAndRangeUse(
// index, then return the full variadic operand_range. Otherwise, return
// the value itself.
if (operand->isVariableLength() && !getVariadicSubIndex().has_value()) {
- auto repl = formatv(fmt, name);
+ auto repl = formatvv(fmt, name);
LLVM_DEBUG(llvm::dbgs() << repl << " (VariadicOperand)\n");
return std::string(repl);
}
- auto repl = formatv(fmt, formatv("(*{0}.begin())", name));
+ auto repl = formatvv(fmt, formatv("(*{0}.begin())", name));
LLVM_DEBUG(llvm::dbgs() << repl << " (SingleOperand)\n");
return std::string(repl);
}
@@ -322,7 +323,7 @@ std::string SymbolInfoMap::SymbolInfo::getValueAndRangeUse(
std::string(formatv("{0}.getODSResults({1})", name, index));
if (!op->getResult(index).isVariadic())
v = std::string(formatv("(*{0}.begin())", v));
- auto repl = formatv(fmt, v);
+ auto repl = formatvv(fmt, v);
LLVM_DEBUG(llvm::dbgs() << repl << " (SingleResult)\n");
return std::string(repl);
}
@@ -331,7 +332,7 @@ std::string SymbolInfoMap::SymbolInfo::getValueAndRangeUse(
// means we want to capture the op itself.
if (op->getNumResults() == 0) {
LLVM_DEBUG(llvm::dbgs() << name << " (Op)\n");
- return formatv(fmt, name);
+ return formatvv(fmt, name);
}
// We are referencing all results of the multi-result op. A specific result
@@ -344,7 +345,7 @@ std::string SymbolInfoMap::SymbolInfo::getValueAndRangeUse(
if (!op->getResult(i).isVariadic()) {
v = std::string(formatv("(*{0}.begin())", v));
}
- values.push_back(std::string(formatv(fmt, v)));
+ values.push_back(std::string(formatvv(fmt, v)));
}
auto repl = llvm::join(values, separator);
LLVM_DEBUG(llvm::dbgs() << repl << " (VariadicResult)\n");
@@ -353,7 +354,7 @@ std::string SymbolInfoMap::SymbolInfo::getValueAndRangeUse(
case Kind::Value: {
assert(index < 0);
assert(op == nullptr);
- auto repl = formatv(fmt, name);
+ auto repl = formatvv(fmt, name);
LLVM_DEBUG(llvm::dbgs() << repl << " (Value)\n");
return std::string(repl);
}
@@ -362,13 +363,13 @@ std::string SymbolInfoMap::SymbolInfo::getValueAndRangeUse(
assert(index < getSize());
if (index >= 0) {
std::string repl =
- formatv(fmt, std::string(formatv("{0}[{1}]", name, index)));
+ formatvv(fmt, std::string(formatv("{0}[{1}]", name, index)));
LLVM_DEBUG(llvm::dbgs() << repl << " (MultipleValues)\n");
return repl;
}
// If it doesn't specify certain element, unpack them all.
auto repl =
- formatv(fmt, std::string(formatv("{0}.begin(), {0}.end()", name)));
+ formatvv(fmt, std::string(formatv("{0}.begin(), {0}.end()", name)));
LLVM_DEBUG(llvm::dbgs() << repl << " (MultipleValues)\n");
return std::string(repl);
}
@@ -383,13 +384,13 @@ std::string SymbolInfoMap::SymbolInfo::getAllRangeUse(
case Kind::Attr:
case Kind::Operand: {
assert(index < 0 && "only allowed for symbol bound to result");
- auto repl = formatv(fmt, name);
+ auto repl = formatvv(fmt, name);
LLVM_DEBUG(llvm::dbgs() << repl << " (Operand/Attr)\n");
return std::string(repl);
}
case Kind::Result: {
if (index >= 0) {
- auto repl = formatv(fmt, formatv("{0}.getODSResults({1})", name, index));
+ auto repl = formatvv(fmt, formatv("{0}.getODSResults({1})", name, index));
LLVM_DEBUG(llvm::dbgs() << repl << " (SingleResult)\n");
return std::string(repl);
}
@@ -401,7 +402,7 @@ std::string SymbolInfoMap::SymbolInfo::getAllRangeUse(
for (int i = 0, e = op->getNumResults(); i < e; ++i) {
values.push_back(std::string(
- formatv(fmt, formatv("{0}.getODSResults({1})", name, i))));
+ formatvv(fmt, formatv("{0}.getODSResults({1})", name, i))));
}
auto repl = llvm::join(values, separator);
LLVM_DEBUG(llvm::dbgs() << repl << " (VariadicResult)\n");
@@ -410,7 +411,7 @@ std::string SymbolInfoMap::SymbolInfo::getAllRangeUse(
case Kind::Value: {
assert(index < 0 && "only allowed for symbol bound to result");
assert(op == nullptr);
- auto repl = formatv(fmt, formatv("{{{0}}", name));
+ auto repl = formatvv(fmt, formatv("{{{0}}", name));
LLVM_DEBUG(llvm::dbgs() << repl << " (Value)\n");
return std::string(repl);
}
@@ -419,12 +420,12 @@ std::string SymbolInfoMap::SymbolInfo::getAllRangeUse(
assert(index < getSize());
if (index >= 0) {
std::string repl =
- formatv(fmt, std::string(formatv("{0}[{1}]", name, index)));
+ formatvv(fmt, std::string(formatv("{0}[{1}]", name, index)));
LLVM_DEBUG(llvm::dbgs() << repl << " (MultipleValues)\n");
return repl;
}
auto repl =
- formatv(fmt, std::string(formatv("{0}.begin(), {0}.end()", name)));
+ formatvv(fmt, std::string(formatv("{0}.begin(), {0}.end()", name)));
LLVM_DEBUG(llvm::dbgs() << repl << " (MultipleValues)\n");
return std::string(repl);
}
diff --git a/mlir/lib/Tools/PDLL/CodeGen/CPPGen.cpp b/mlir/lib/Tools/PDLL/CodeGen/CPPGen.cpp
index 611b734dc4b056..539548ea5c2d38 100644
--- a/mlir/lib/Tools/PDLL/CodeGen/CPPGen.cpp
+++ b/mlir/lib/Tools/PDLL/CodeGen/CPPGen.cpp
@@ -105,7 +105,7 @@ void CodeGen::generate(const ast::Module &astModule, ModuleOp module) {
void CodeGen::generate(pdl::PatternOp pattern, StringRef patternName,
StringSet<> &nativeFunctions) {
- const char *patternClassStartStr = R"(
+ const char patternClassStartStr[] = R"(
struct {0} : ::mlir::PDLPatternModule {{
template <typename... ConfigsT>
{0}(::mlir::MLIRContext *context, ConfigsT &&...configs)
diff --git a/mlir/lib/Tools/lsp-server-support/Transport.cpp b/mlir/lib/Tools/lsp-server-support/Transport.cpp
index ca7ffdf78d3a1b..82294df22da48b 100644
--- a/mlir/lib/Tools/lsp-server-support/Transport.cpp
+++ b/mlir/lib/Tools/lsp-server-support/Transport.cpp
@@ -230,7 +230,7 @@ llvm::Error JSONTransport::run(MessageHandler &handler) {
void JSONTransport::sendMessage(llvm::json::Value msg) {
outputBuffer.clear();
llvm::raw_svector_ostream os(outputBuffer);
- os << llvm::formatv(prettyOutput ? "{0:2}\n" : "{0}", msg);
+ os << llvm::formatvv(prettyOutput ? "{0:2}\n" : "{0}", msg);
out << "Content-Length: " << outputBuffer.size() << "\r\n\r\n"
<< outputBuffer;
out.flush();
diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp
index bf2990c257bad2..89828820d93565 100644
--- a/mlir/lib/Transforms/Utils/DialectConversion.cpp
+++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp
@@ -37,7 +37,8 @@ static void logSuccess(llvm::ScopedPrinter &os, StringRef fmt, Args &&...args) {
os.startLine() << "} -> SUCCESS";
if (!fmt.empty())
os.getOStream() << " : "
- << llvm::formatv(fmt.data(), std::forward<Args>(args)...);
+ << llvm::formatvv(fmt.data(),
+ std::forward<Args>(args)...);
os.getOStream() << "\n";
});
}
@@ -48,7 +49,7 @@ static void logFailure(llvm::ScopedPrinter &os, StringRef fmt, Args &&...args) {
LLVM_DEBUG({
os.unindent();
os.startLine() << "} -> FAILURE : "
- << llvm::formatv(fmt.data(), std::forward<Args>(args)...)
+ << llvm::formatvv(fmt.data(), std::forward<Args>(args)...)
<< "\n";
});
}
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
index eccd8029d950ff..a78b94407d94ed 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeDefGen.cpp
@@ -326,7 +326,7 @@ void DefGen::emitVerifierDecl() {
"emitError"}}));
}
-static const char *const patternParameterVerificationCode = R"(
+static const char patternParameterVerificationCode[] = R"(
if (!({0})) {
emitError() << "failed to verify '{1}': {2}";
return ::mlir::failure();
@@ -800,7 +800,7 @@ void DefGenerator::emitTypeDefList(ArrayRef<AttrOrTypeDef> defs) {
/// {0}: the dialect fully qualified class name.
/// {1}: the optional code for the dynamic attribute parser dispatch.
/// {2}: the optional code for the dynamic attribute printer dispatch.
-static const char *const dialectDefaultAttrPrinterParserDispatch = R"(
+static const char dialectDefaultAttrPrinterParserDispatch[] = R"(
/// Parse an attribute registered to this dialect.
::mlir::Attribute {0}::parseAttribute(::mlir::DialectAsmParser &parser,
::mlir::Type type) const {{
@@ -827,7 +827,7 @@ void {0}::printAttribute(::mlir::Attribute attr,
)";
/// The code block for dynamic attribute parser dispatch boilerplate.
-static const char *const dialectDynamicAttrParserDispatch = R"(
+static const char dialectDynamicAttrParserDispatch[] = R"(
{
::mlir::Attribute genAttr;
auto parseResult = parseOptionalDynamicAttr(attrTag, parser, genAttr);
@@ -840,7 +840,7 @@ static const char *const dialectDynamicAttrParserDispatch = R"(
)";
/// The code block for dynamic type printer dispatch boilerplate.
-static const char *const dialectDynamicAttrPrinterDispatch = R"(
+static const char dialectDynamicAttrPrinterDispatch[] = R"(
if (::mlir::succeeded(printIfDynamicAttr(attr, printer)))
return;
)";
@@ -849,7 +849,7 @@ static const char *const dialectDynamicAttrPrinterDispatch = R"(
/// {0}: the dialect fully qualified class name.
/// {1}: the optional code for the dynamic type parser dispatch.
/// {2}: the optional code for the dynamic type printer dispatch.
-static const char *const dialectDefaultTypePrinterParserDispatch = R"(
+static const char dialectDefaultTypePrinterParserDispatch[] = R"(
/// Parse a type registered to this dialect.
::mlir::Type {0}::parseType(::mlir::DialectAsmParser &parser) const {{
::llvm::SMLoc typeLoc = parser.getCurrentLocation();
@@ -873,7 +873,7 @@ void {0}::printType(::mlir::Type type,
)";
/// The code block for dynamic type parser dispatch boilerplate.
-static const char *const dialectDynamicTypeParserDispatch = R"(
+static const char dialectDynamicTypeParserDispatch[] = R"(
{
auto parseResult = parseOptionalDynamicType(mnemonic, parser, genType);
if (parseResult.has_value()) {
@@ -885,7 +885,7 @@ static const char *const dialectDynamicTypeParserDispatch = R"(
)";
/// The code block for dynamic type printer dispatch boilerplate.
-static const char *const dialectDynamicTypePrinterDispatch = R"(
+static const char dialectDynamicTypePrinterDispatch[] = R"(
if (::mlir::succeeded(printIfDynamicType(type, printer)))
return;
)";
@@ -918,7 +918,7 @@ void DefGenerator::emitParsePrintDispatch(ArrayRef<AttrOrTypeDef> defs) {
parse.body() << " return "
"::mlir::AsmParser::KeywordSwitch<::mlir::"
"OptionalParseResult>(parser)\n";
- const char *const getValueForMnemonic =
+ static const char getValueForMnemonic[] =
R"( .Case({0}::getMnemonic(), [&](llvm::StringRef, llvm::SMLoc) {{
value = {0}::{1};
return ::mlir::success(!!value);
@@ -929,7 +929,7 @@ void DefGenerator::emitParsePrintDispatch(ArrayRef<AttrOrTypeDef> defs) {
// printer.
printer.body() << " return ::llvm::TypeSwitch<::mlir::" << valueType
<< ", ::llvm::LogicalResult>(def)";
- const char *const printValue = R"( .Case<{0}>([&](auto t) {{
+ static const char printValue[] = R"( .Case<{0}>([&](auto t) {{
printer << {0}::getMnemonic();{1}
return ::mlir::success();
})
@@ -1048,7 +1048,7 @@ getAllTypeConstraints(const llvm::RecordKeeper &records) {
static void emitTypeConstraintDecls(const llvm::RecordKeeper &records,
raw_ostream &os) {
- static const char *const typeConstraintDecl = R"(
+ static const char typeConstraintDecl[] = R"(
bool {0}(::mlir::Type type);
)";
@@ -1058,7 +1058,7 @@ bool {0}(::mlir::Type type);
static void emitTypeConstraintDefs(const llvm::RecordKeeper &records,
raw_ostream &os) {
- static const char *const typeConstraintDef = R"(
+ static const char typeConstraintDef[] = R"(
bool {0}(::mlir::Type type) {
return ({1});
}
diff --git a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
index a4ae271edb6bd2..ab19f5b3f446c5 100644
--- a/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/AttrOrTypeFormatGen.cpp
@@ -138,21 +138,21 @@ class StructDirective : public ParamsDirectiveBase<DirectiveElement::Struct> {
//===----------------------------------------------------------------------===//
/// Default parser for attribute or type parameters.
-static const char *const defaultParameterParser =
+static const char defaultParameterParser[] =
"::mlir::FieldParser<$0>::parse($_parser)";
/// Default printer for attribute or type parameters.
-static const char *const defaultParameterPrinter =
+static const char defaultParameterPrinter[] =
"$_printer.printStrippedAttrOrType($_self)";
/// Qualified printer for attribute or type parameters: it does not elide
/// dialect and mnemonic.
-static const char *const qualifiedParameterPrinter = "$_printer << $_self";
+static const char qualifiedParameterPrinter[] = "$_printer << $_self";
/// Print an error when failing to parse an element.
///
/// $0: The parameter C++ class name.
-static const char *const parserErrorStr =
+static const char parserErrorStr[] =
"$_parser.emitError($_parser.getCurrentLocation(), ";
/// Code format to parse a variable. Separate by lines because variable parsers
@@ -164,7 +164,7 @@ static const char *const parserErrorStr =
/// {3}: Name of the attribute or type.
/// {4}: C++ class of the parameter.
/// {5}: Optional code to preload the dialect for this variable.
-static const char *const variableParser = R"(
+static const char variableParser[] = R"(
// Parse variable '{0}'{5}
_result_{0} = {1};
if (::mlir::failed(_result_{0})) {{
@@ -500,12 +500,12 @@ void DefFormat::genStructParser(StructDirective *el, FmtContext &ctx,
// Loop declaration for struct parser with only required parameters.
//
// $0: Number of expected parameters.
- const char *const loopHeader = R"(
+ static const char loopHeader[] = R"(
for (unsigned odsStructIndex = 0; odsStructIndex < $0; ++odsStructIndex) {
)";
// Loop body start for struct parser.
- const char *const loopStart = R"(
+ static const char loopStart[] = R"(
::llvm::StringRef _paramKey;
if ($_parser.parseKeyword(&_paramKey)) {
$_parser.emitError($_parser.getCurrentLocation(),
@@ -518,7 +518,7 @@ void DefFormat::genStructParser(StructDirective *el, FmtContext &ctx,
// Struct parser loop end. Check for duplicate or unknown struct parameters.
//
// {0}: Code template for printing an error.
- const char *const loopEnd = R"({{
+ static const char loopEnd[] = R"({{
{0}"duplicate or unknown struct parameter name: ") << _paramKey;
return {{};
}
@@ -527,7 +527,7 @@ void DefFormat::genStructParser(StructDirective *el, FmtContext &ctx,
// Struct parser loop terminator. Parse a comma except on the last element.
//
// {0}: Number of elements in the struct.
- const char *const loopTerminator = R"(
+ static const char loopTerminator[] = R"(
if ((odsStructIndex != {0} - 1) && odsParser.parseComma())
return {{};
}
@@ -536,7 +536,7 @@ void DefFormat::genStructParser(StructDirective *el, FmtContext &ctx,
// Check that a mandatory parameter was parse.
//
// {0}: Name of the parameter.
- const char *const checkParam = R"(
+ static const char checkParam[] = R"(
if (!_seen_{0}) {
{1}"struct is missing required parameter: ") << "{0}";
return {{};
@@ -544,7 +544,7 @@ void DefFormat::genStructParser(StructDirective *el, FmtContext &ctx,
)";
// First iteration of the loop parsing an optional struct.
- const char *const optionalStructFirst = R"(
+ static const char optionalStructFirst[] = R"(
::llvm::StringRef _paramKey;
if (!$_parser.parseOptionalKeyword(&_paramKey)) {
if (!_loop_body(_paramKey)) return {};
diff --git a/mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp b/mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp
index 66a3750d7c8266..0f90f9721fdc22 100644
--- a/mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp
+++ b/mlir/tools/mlir-tblgen/BytecodeDialectGen.cpp
@@ -87,14 +87,14 @@ static std::string getCType(Record *def) {
if (def->isAnonymous())
PrintFatalError(def->getLoc(), "Unable to determine cType");
- return formatv(format.c_str(), def->getName().str());
+ return formatvv(format.c_str(), def->getName().str());
}
- return formatv(format.c_str(), cType.str());
+ return formatvv(format.c_str(), cType.str());
}
void Generator::emitParseDispatch(StringRef kind, ArrayRef<Record *> vec) {
mlir::raw_indented_ostream os(output);
- char const *head =
+ char const head[] =
R"(static {0} read{0}(MLIRContext* context, DialectBytecodeReader &reader))";
os << formatv(head, capitalize(kind));
auto funScope = os.scope(" {\n", "}\n\n");
@@ -130,7 +130,7 @@ void Generator::emitParse(StringRef kind, Record &x) {
if (x.getNameInitAsString() == "ReservedOrDead")
return;
- char const *head =
+ char const head[] =
R"(static {0} read{1}(MLIRContext* context, DialectBytecodeReader &reader) )";
mlir::raw_indented_ostream os(output);
std::string returnType = getCType(&x);
@@ -297,7 +297,7 @@ void Generator::emitPrint(StringRef kind, StringRef type,
if (type == "ReservedOrDead")
return;
- char const *head =
+ char const head[] =
R"(static void write({0} {1}, DialectBytecodeWriter &writer) )";
mlir::raw_indented_ostream os(output);
os << formatv(head, type, kind);
@@ -401,7 +401,7 @@ void Generator::emitPrintHelper(Record *memberRec, StringRef kind,
void Generator::emitPrintDispatch(StringRef kind, ArrayRef<std::string> vec) {
mlir::raw_indented_ostream os(output);
- char const *head = R"(static LogicalResult write{0}({0} {1},
+ char const head[] = R"(static LogicalResult write{0}({0} {1},
DialectBytecodeWriter &writer))";
os << formatv(head, capitalize(kind), kind);
auto funScope = os.scope(" {\n", "}\n\n");
diff --git a/mlir/tools/mlir-tblgen/DialectGen.cpp b/mlir/tools/mlir-tblgen/DialectGen.cpp
index 2412876958a0c9..3560611fadf035 100644
--- a/mlir/tools/mlir-tblgen/DialectGen.cpp
+++ b/mlir/tools/mlir-tblgen/DialectGen.cpp
@@ -106,7 +106,7 @@ tblgen::findDialectToGenerate(ArrayRef<Dialect> dialects) {
/// {0}: The name of the dialect class.
/// {1}: The dialect namespace.
/// {2}: The dialect parent class.
-static const char *const dialectDeclBeginStr = R"(
+static const char dialectDeclBeginStr[] = R"(
class {0} : public ::mlir::{2} {
explicit {0}(::mlir::MLIRContext *context);
@@ -121,11 +121,11 @@ class {0} : public ::mlir::{2} {
/// Registration for a single dependent dialect: to be inserted in the ctor
/// above for each dependent dialect.
-const char *const dialectRegistrationTemplate =
+static const char dialectRegistrationTemplate[] =
"getContext()->loadDialect<{0}>();";
/// The code block for the attribute parser/printer hooks.
-static const char *const attrParserDecl = R"(
+static const char attrParserDecl[] = R"(
/// Parse an attribute registered to this dialect.
::mlir::Attribute parseAttribute(::mlir::DialectAsmParser &parser,
::mlir::Type type) const override;
@@ -136,7 +136,7 @@ static const char *const attrParserDecl = R"(
)";
/// The code block for the type parser/printer hooks.
-static const char *const typeParserDecl = R"(
+static const char typeParserDecl[] = R"(
/// Parse a type registered to this dialect.
::mlir::Type parseType(::mlir::DialectAsmParser &parser) const override;
@@ -146,14 +146,14 @@ static const char *const typeParserDecl = R"(
)";
/// The code block for the canonicalization pattern registration hook.
-static const char *const canonicalizerDecl = R"(
+static const char canonicalizerDecl[] = R"(
/// Register canonicalization patterns.
void getCanonicalizationPatterns(
::mlir::RewritePatternSet &results) const override;
)";
/// The code block for the constant materializer hook.
-static const char *const constantMaterializerDecl = R"(
+static const char constantMaterializerDecl[] = R"(
/// Materialize a single constant operation from a given attribute value with
/// the desired resultant type.
::mlir::Operation *materializeConstant(::mlir::OpBuilder &builder,
@@ -163,7 +163,7 @@ static const char *const constantMaterializerDecl = R"(
)";
/// The code block for the operation attribute verifier hook.
-static const char *const opAttrVerifierDecl = R"(
+static const char opAttrVerifierDecl[] = R"(
/// Provides a hook for verifying dialect attributes attached to the given
/// op.
::llvm::LogicalResult verifyOperationAttribute(
@@ -171,7 +171,7 @@ static const char *const opAttrVerifierDecl = R"(
)";
/// The code block for the region argument attribute verifier hook.
-static const char *const regionArgAttrVerifierDecl = R"(
+static const char regionArgAttrVerifierDecl[] = R"(
/// Provides a hook for verifying dialect attributes attached to the given
/// op's region argument.
::llvm::LogicalResult verifyRegionArgAttribute(
@@ -180,7 +180,7 @@ static const char *const regionArgAttrVerifierDecl = R"(
)";
/// The code block for the region result attribute verifier hook.
-static const char *const regionResultAttrVerifierDecl = R"(
+static const char regionResultAttrVerifierDecl[] = R"(
/// Provides a hook for verifying dialect attributes attached to the given
/// op's region result.
::llvm::LogicalResult verifyRegionResultAttribute(
@@ -189,14 +189,14 @@ static const char *const regionResultAttrVerifierDecl = R"(
)";
/// The code block for the op interface fallback hook.
-static const char *const operationInterfaceFallbackDecl = R"(
+static const char operationInterfaceFallbackDecl[] = R"(
/// Provides a hook for op interface.
void *getRegisteredInterfaceForOp(mlir::TypeID interfaceID,
mlir::OperationName opName) override;
)";
/// The code block for the discardable attribute helper.
-static const char *const discardableAttrHelperDecl = R"(
+static const char discardableAttrHelperDecl[] = R"(
/// Helper to manage the discardable attribute `{1}`.
class {0}AttrHelper {{
::mlir::StringAttr name;
@@ -322,7 +322,7 @@ static bool emitDialectDecls(const llvm::RecordKeeper &recordKeeper,
/// initialize(), such as dependent dialect registration.
/// {2}: The dialect parent class.
/// {3}: Extra members to initialize
-static const char *const dialectConstructorStr = R"(
+static const char dialectConstructorStr[] = R"(
{0}::{0}(::mlir::MLIRContext *context)
: ::mlir::{2}(getDialectNamespace(), context, ::mlir::TypeID::get<{0}>())
{3}
@@ -335,7 +335,7 @@ static const char *const dialectConstructorStr = R"(
/// The code block to generate a default destructor definition.
///
/// {0}: The name of the dialect class.
-static const char *const dialectDestructorStr = R"(
+static const char dialectDestructorStr[] = R"(
{0}::~{0}() = default;
)";
diff --git a/mlir/tools/mlir-tblgen/EnumsGen.cpp b/mlir/tools/mlir-tblgen/EnumsGen.cpp
index f1d7a233b66a9a..0d9537872ddabf 100644
--- a/mlir/tools/mlir-tblgen/EnumsGen.cpp
+++ b/mlir/tools/mlir-tblgen/EnumsGen.cpp
@@ -81,7 +81,7 @@ static void emitParserPrinter(const EnumAttr &enumAttr, StringRef qualName,
nonKeywordCases.set(index);
// Generate the parser and the start of the printer for the enum.
- const char *parsedAndPrinterStart = R"(
+ static const char parsedAndPrinterStart[] = R"(
namespace mlir {
template <typename T, typename>
struct FieldParser;
@@ -177,7 +177,7 @@ static void emitDenseMapInfo(StringRef qualName, std::string underlyingType,
underlyingType =
std::string(formatv("std::underlying_type_t<{0}>", qualName));
- const char *const mapInfo = R"(
+ static const char mapInfo[] = R"(
namespace llvm {
template<> struct DenseMapInfo<{0}> {{
using StorageInfo = ::llvm::DenseMapInfo<{1}>;
@@ -252,7 +252,7 @@ static void emitOperators(const Record &enumDef, raw_ostream &os) {
StringRef enumName = enumAttr.getEnumClassName();
std::string underlyingType = std::string(enumAttr.getUnderlyingType());
int64_t validBits = enumDef.getValueAsInt("validBits");
- const char *const operators = R"(
+ static const char operators[] = R"(
inline constexpr {0} operator|({0} a, {0} b) {{
return static_cast<{0}>(static_cast<{1}>(a) | static_cast<{1}>(b));
}
@@ -331,7 +331,7 @@ static void emitSymToStrFnForBitEnum(const Record &enumDef, raw_ostream &os) {
// Add case string if the value has all case bits, and remove them to avoid
// printing again. Used only for groups, when printBitEnumPrimaryGroups is 1.
- const char *const formatCompareRemove = R"(
+ static const char formatCompareRemove[] = R"(
if ({0}u == ({0}u & val)) {{
strs.push_back("{1}");
val &= ~static_cast<{2}>({0});
@@ -339,7 +339,7 @@ static void emitSymToStrFnForBitEnum(const Record &enumDef, raw_ostream &os) {
)";
// Add case string if the value has all case bits. Used for individual bit
// cases, and for groups when printBitEnumPrimaryGroups is 0.
- const char *const formatCompare = R"(
+ static const char formatCompare[] = R"(
if ({0}u == ({0}u & val))
strs.push_back("{1}");
)";
@@ -594,7 +594,7 @@ static void emitEnumDecl(const Record &enumDef, raw_ostream &os) {
// Generate a generic `stringifyEnum` function that forwards to the method
// specified by the user.
- const char *const stringifyEnumStr = R"(
+ static const char stringifyEnumStr[] = R"(
inline {0} stringifyEnum({1} enumValue) {{
return {2}(enumValue);
}
@@ -603,7 +603,7 @@ inline {0} stringifyEnum({1} enumValue) {{
// Generate a generic `symbolizeEnum` function that forwards to the method
// specified by the user.
- const char *const symbolizeEnumStr = R"(
+ static const char symbolizeEnumStr[] = R"(
template <typename EnumType>
::std::optional<EnumType> symbolizeEnum(::llvm::StringRef);
@@ -614,7 +614,7 @@ inline ::std::optional<{0}> symbolizeEnum<{0}>(::llvm::StringRef str) {
)";
os << formatv(symbolizeEnumStr, enumName, strToSymFnName);
- const char *const attrClassDecl = R"(
+ static const char attrClassDecl[] = R"(
class {1} : public ::mlir::{2} {
public:
using ValueType = {0};
diff --git a/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp b/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
index ebadfe4499a54d..5560298831865f 100644
--- a/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
+++ b/mlir/tools/mlir-tblgen/LLVMIRConversionGen.cpp
@@ -519,7 +519,7 @@ static void emitOneCEnumFromConversion(const llvm::Record *record,
os << formatv(
"inline LLVM_ATTRIBUTE_UNUSED {0}::{1} convert{1}FromLLVM(int64_t "
"value) {{\n",
- cppNamespace, cppClassName, llvmClass);
+ cppNamespace, cppClassName);
os << " switch (value) {\n";
for (const auto &enumerant : enumAttr.getAllCases()) {
diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
index 66dbb16760ebb0..2017ce60e54073 100644
--- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp
@@ -67,7 +67,7 @@ static const char *const resultSegmentAttrName = "resultSegmentSizes";
/// {2}: The upper bound on the sorted subrange.
/// {3}: Code snippet to get the array of named attributes.
/// {4}: "Named" to get the named attribute.
-static const char *const subrangeGetAttr =
+static const char subrangeGetAttr[] =
"::mlir::impl::get{4}AttrFromSortedRange({3}.begin() + {1}, {3}.end() - "
"{2}, {0})";
@@ -81,7 +81,7 @@ static const char *const subrangeGetAttr =
/// {2}: The total number of variadic operands/results.
/// {3}: The total number of actual values.
/// {4}: "operand" or "result".
-static const char *const sameVariadicSizeValueRangeCalcCode = R"(
+static const char sameVariadicSizeValueRangeCalcCode[] = R"(
bool isVariadic[] = {{{0}};
int prevVariadicCount = 0;
for (unsigned i = 0; i < index; ++i)
@@ -103,7 +103,7 @@ static const char *const sameVariadicSizeValueRangeCalcCode = R"(
/// of an op with variadic operands/results. Note that this logic is assumes
/// the op has an attribute specifying the size of each operand/result segment
/// (variadic or not).
-static const char *const attrSizedSegmentValueRangeCalcCode = R"(
+static const char attrSizedSegmentValueRangeCalcCode[] = R"(
unsigned start = 0;
for (unsigned i = 0; i < index; ++i)
start += sizeAttr[i];
@@ -112,18 +112,18 @@ static const char *const attrSizedSegmentValueRangeCalcCode = R"(
/// The code snippet to initialize the sizes for the value range calculation.
///
/// {0}: The code to get the attribute.
-static const char *const adapterSegmentSizeAttrInitCode = R"(
+static const char adapterSegmentSizeAttrInitCode[] = R"(
assert({0} && "missing segment size attribute for op");
auto sizeAttr = ::llvm::cast<::mlir::DenseI32ArrayAttr>({0});
)";
-static const char *const adapterSegmentSizeAttrInitCodeProperties = R"(
+static const char adapterSegmentSizeAttrInitCodeProperties[] = R"(
::llvm::ArrayRef<int32_t> sizeAttr = {0};
)";
/// The code snippet to initialize the sizes for the value range calculation.
///
/// {0}: The code to get the attribute.
-static const char *const opSegmentSizeAttrInitCode = R"(
+static const char opSegmentSizeAttrInitCode[] = R"(
auto sizeAttr = ::llvm::cast<::mlir::DenseI32ArrayAttr>({0});
)";
@@ -133,7 +133,7 @@ static const char *const opSegmentSizeAttrInitCode = R"(
/// {0}: The name of the segment attribute.
/// {1}: The index of the main operand.
/// {2}: The range type of adaptor.
-static const char *const variadicOfVariadicAdaptorCalcCode = R"(
+static const char variadicOfVariadicAdaptorCalcCode[] = R"(
auto tblgenTmpOperands = getODSOperands({1});
auto sizes = {0}();
@@ -149,7 +149,7 @@ static const char *const variadicOfVariadicAdaptorCalcCode = R"(
///
/// {0}: The begin iterator of the actual values.
/// {1}: The call to generate the start and length of the value range.
-static const char *const valueRangeReturnCode = R"(
+static const char valueRangeReturnCode[] = R"(
auto valueRange = {1};
return {{std::next({0}, valueRange.first),
std::next({0}, valueRange.first + valueRange.second)};
@@ -157,7 +157,7 @@ static const char *const valueRangeReturnCode = R"(
/// Parse operand/result segment_size property.
/// {0}: Number of elements in the segment array
-static const char *const parseTextualSegmentSizeFormat = R"(
+static const char parseTextualSegmentSizeFormat[] = R"(
size_t i = 0;
auto parseElem = [&]() -> ::mlir::ParseResult {
if (i >= {0})
@@ -177,7 +177,7 @@ static const char *const parseTextualSegmentSizeFormat = R"(
return success();
)";
-static const char *const printTextualSegmentSize = R"(
+static const char printTextualSegmentSize[] = R"(
[&]() {
$_printer << '[';
::llvm::interleaveComma($_storage, $_printer);
@@ -186,12 +186,12 @@ static const char *const printTextualSegmentSize = R"(
)";
/// Read operand/result segment_size from bytecode.
-static const char *const readBytecodeSegmentSizeNative = R"(
+static const char readBytecodeSegmentSizeNative[] = R"(
if ($_reader.getBytecodeVersion() >= /*kNativePropertiesODSSegmentSize=*/6)
return $_reader.readSparseArray(::llvm::MutableArrayRef($_storage));
)";
-static const char *const readBytecodeSegmentSizeLegacy = R"(
+static const char readBytecodeSegmentSizeLegacy[] = R"(
if ($_reader.getBytecodeVersion() < /*kNativePropertiesODSSegmentSize=*/6) {
auto &$_storage = prop.$_propName;
::mlir::DenseI32ArrayAttr attr;
@@ -205,13 +205,13 @@ static const char *const readBytecodeSegmentSizeLegacy = R"(
)";
/// Write operand/result segment_size to bytecode.
-static const char *const writeBytecodeSegmentSizeNative = R"(
+static const char writeBytecodeSegmentSizeNative[] = R"(
if ($_writer.getBytecodeVersion() >= /*kNativePropertiesODSSegmentSize=*/6)
$_writer.writeSparseArray(::llvm::ArrayRef($_storage));
)";
/// Write operand/result segment_size to bytecode.
-static const char *const writeBytecodeSegmentSizeLegacy = R"(
+static const char writeBytecodeSegmentSizeLegacy[] = R"(
if ($_writer.getBytecodeVersion() < /*kNativePropertiesODSSegmentSize=*/6) {
auto &$_storage = prop.$_propName;
$_writer.writeAttribute(::mlir::DenseI32ArrayAttr::get($_ctxt, $_storage));
@@ -222,7 +222,7 @@ if ($_writer.getBytecodeVersion() < /*kNativePropertiesODSSegmentSize=*/6) {
///
/// {0}: Some text, or a class name.
/// {1}: Some text.
-static const char *const opCommentHeader = R"(
+static const char opCommentHeader[] = R"(
//===----------------------------------------------------------------------===//
// {0} {1}
//===----------------------------------------------------------------------===//
@@ -375,10 +375,10 @@ class OpOrAdaptorHelper {
// Get the call to get an operand or segment of operands.
Formatter getOperand(unsigned index) const {
return [this, index](raw_ostream &os) -> raw_ostream & {
- return os << formatv(op.getOperand(index).isVariadic()
- ? "this->getODSOperands({0})"
- : "(*this->getODSOperands({0}).begin())",
- index);
+ return os << formatvv(op.getOperand(index).isVariadic()
+ ? "this->getODSOperands({0})"
+ : "(*this->getODSOperands({0}).begin())",
+ index);
};
}
@@ -387,10 +387,10 @@ class OpOrAdaptorHelper {
return [this, index](raw_ostream &os) -> raw_ostream & {
if (!emitForOp)
return os << "<no results should be generated>";
- return os << formatv(op.getResult(index).isVariadic()
- ? "this->getODSResults({0})"
- : "(*this->getODSResults({0}).begin())",
- index);
+ return os << formatvv(op.getResult(index).isVariadic()
+ ? "this->getODSResults({0})"
+ : "(*this->getODSResults({0}).begin())",
+ index);
};
}
@@ -822,7 +822,7 @@ static void genNativeTraitAttrVerifier(MethodBody &body,
// {1}: Expected number of elements.
// {2}: "operand" or "result".
// {3}: Emit error prefix.
- const char *const checkAttrSizedValueSegmentsCode = R"(
+ const char checkAttrSizedValueSegmentsCode[] = R"(
{
auto sizeAttr = ::llvm::cast<::mlir::DenseI32ArrayAttr>(tblgen_{0});
auto numElements = sizeAttr.asArrayRef().size();
@@ -893,7 +893,7 @@ genAttributeVerifier(const OpOrAdaptorHelper &emitHelper, FmtContext &ctx,
// {2}: Emit error prefix.
// {3}: Attribute name.
// {4}: Attribute/constraint description.
- const char *const verifyAttrInline = R"(
+ const char verifyAttrInline[] = R"(
if ({0} && !({1}))
return {2}"attribute '{3}' failed to satisfy constraint: {4}");
)";
@@ -903,7 +903,7 @@ genAttributeVerifier(const OpOrAdaptorHelper &emitHelper, FmtContext &ctx,
// {0}: Unique constraint name.
// {1}: Attribute variable name.
// {2}: Attribute name.
- const char *const verifyAttrUnique = R"(
+ const char verifyAttrUnique[] = R"(
if (::mlir::failed({0}(*this, {1}, "{2}")))
return ::mlir::failure();
)";
@@ -914,7 +914,7 @@ genAttributeVerifier(const OpOrAdaptorHelper &emitHelper, FmtContext &ctx,
// {0}: Code to get the name of the attribute.
// {1}: The emit error prefix.
// {2}: The name of the attribute.
- const char *const findRequiredAttr = R"(
+ const char findRequiredAttr[] = R"(
while (true) {{
if (namedAttrIt == namedAttrRange.end())
return {1}"requires attribute '{2}'");
@@ -927,13 +927,13 @@ while (true) {{
//
// {0}: Code to get the name of the attribute.
// {1}: The name of the attribute.
- const char *const checkOptionalAttr = R"(
+ const char checkOptionalAttr[] = R"(
else if (namedAttrIt->getName() == {0}) {{
tblgen_{1} = namedAttrIt->getValue();
})";
// Emit the start of the loop for checking trailing attributes.
- const char *const checkTrailingAttrs = R"(while (true) {
+ const char checkTrailingAttrs[] = R"(while (true) {
if (namedAttrIt == namedAttrRange.end()) {
break;
})";
@@ -1192,7 +1192,7 @@ void OpEmitter::genAttrNameGetters() {
if (attributes.empty()) {
method->body() << " return {};";
} else {
- const char *const getAttrName = R"(
+ const char getAttrName[] = R"(
assert(index < {0} && "invalid attribute index");
assert(name.getStringRef() == getOperationName() && "invalid operation name");
assert(name.isRegistered() && "Operation isn't registered, missing a "
@@ -1205,7 +1205,7 @@ void OpEmitter::genAttrNameGetters() {
// Generate the <attr>AttrName methods, that expose the attribute names to
// users.
- const char *attrNameMethodBody = " return getAttributeNameForIndex({0});";
+ const char attrNameMethodBody[] = " return getAttributeNameForIndex({0});";
for (auto [index, attr] :
llvm::enumerate(llvm::make_first_range(attributes))) {
std::string name = op.getGetterName(attr);
@@ -1373,18 +1373,18 @@ void OpEmitter::genPropertiesSupport() {
return ::mlir::failure();
}
)decl";
- const char *propFromAttrFmt = R"decl(
+ const char propFromAttrFmt[] = R"decl(
auto setFromAttr = [] (auto &propStorage, ::mlir::Attribute propAttr,
::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError) -> ::mlir::LogicalResult {{
{0}
};
{2};
)decl";
- const char *attrGetNoDefaultFmt = R"decl(;
+ const char attrGetNoDefaultFmt[] = R"decl(;
if (attr && ::mlir::failed(setFromAttr(prop.{0}, attr, emitError)))
return ::mlir::failure();
)decl";
- const char *attrGetDefaultFmt = R"decl(;
+ const char attrGetDefaultFmt[] = R"decl(;
if (attr) {{
if (::mlir::failed(setFromAttr(prop.{0}, attr, emitError)))
return ::mlir::failure();
@@ -1471,7 +1471,7 @@ void OpEmitter::genPropertiesSupport() {
getPropMethod << " ::mlir::SmallVector<::mlir::NamedAttribute> attrs;\n"
<< " ::mlir::Builder odsBuilder{ctx};\n";
- const char *propToAttrFmt = R"decl(
+ const char propToAttrFmt[] = R"decl(
{
const auto &propStorage = prop.{0};
auto attr = [&]() -> ::mlir::Attribute {{
@@ -1514,7 +1514,7 @@ void OpEmitter::genPropertiesSupport() {
// Hashing for the property
- const char *propHashFmt = R"decl(
+ const char propHashFmt[] = R"decl(
auto hash_{0} = [] (const auto &propStorage) -> llvm::hash_code {
return {1};
};
@@ -1555,17 +1555,18 @@ void OpEmitter::genPropertiesSupport() {
});
hashMethod << ");\n";
- const char *getInherentAttrMethodFmt = R"decl(
+ const char getInherentAttrMethodFmt[] = R"decl(
if (name == "{0}")
return prop.{0};
)decl";
- const char *setInherentAttrMethodFmt = R"decl(
+ const char setInherentAttrMethodFmt[] = R"decl(
if (name == "{0}") {{
- prop.{0} = ::llvm::dyn_cast_or_null<std::remove_reference_t<decltype(prop.{0})>>(value);
+ prop.{0} = ::llvm::dyn_cast_or_null<
+ std::remove_reference_t<decltype(prop.{0})>>(value);
return;
}
)decl";
- const char *populateInherentAttrsMethodFmt = R"decl(
+ const char populateInherentAttrsMethodFmt[] = R"decl(
if (prop.{0}) attrs.append("{0}", prop.{0});
)decl";
for (const auto &attrOrProp : attrOrProperties) {
@@ -1980,7 +1981,7 @@ void OpEmitter::genAttrSetters() {
// std::optional<>).
StringRef paramStr = isUnitAttr ? "attrValue" : "*attrValue";
if (!useProperties) {
- const char *optionalCodeBody = R"(
+ const char optionalCodeBody[] = R"(
if (attrValue)
return (*this)->setAttr({0}AttrName(), {1});
(*this)->removeAttr({0}AttrName());)";
@@ -1988,7 +1989,7 @@ void OpEmitter::genAttrSetters() {
optionalCodeBody, getterName,
constBuildAttrFromParam(baseAttr, fctx, paramStr));
} else {
- const char *optionalCodeBody = R"(
+ const char optionalCodeBody[] = R"(
auto &odsProp = getProperties().{0};
if (attrValue)
odsProp = {1};
@@ -2768,11 +2769,10 @@ void OpEmitter::genInferredTypeCollectiveParamBuilder() {
<< "u && \"mismatched number of return types\");";
body << "\n " << builderOpState << ".addTypes(inferredReturnTypes);";
- body << formatv(R"(
- } else {{
+ body << R"(
+ } else {
::llvm::report_fatal_error("Failed to infer result type(s).");
- })",
- opClass.getClassName(), builderOpState);
+ })";
}
void OpEmitter::genUseOperandAsResultTypeSeparateParamBuilder() {
@@ -3502,7 +3502,7 @@ void OpEmitter::genSideEffectInterfaceMethods() {
// {2}: The side effect stage.
// {3}: Does this side effect act on every single value of resource.
// {4}: The resource class.
- const char *addEffectCode =
+ const char addEffectCode[] =
" effects.emplace_back({0}::get(), {1}{2}, {3}, {4}::get());\n";
for (auto &it : interfaceEffects) {
@@ -3745,7 +3745,7 @@ void OpEmitter::genOperandResultVerifier(MethodBody &body,
//
// {0}: Value index.
// {1}: "operand" or "result"
- const char *const verifyOptional = R"(
+ const char verifyOptional[] = R"(
if (valueGroup{0}.size() > 1) {
return emitOpError("{1} group starting at #") << index
<< " requires 0 or 1 element, but found " << valueGroup{0}.size();
@@ -3756,7 +3756,7 @@ void OpEmitter::genOperandResultVerifier(MethodBody &body,
// {0}: Value index.
// {1}: Type constraint function.
// {2}: "operand" or "result"
- const char *const verifyValues = R"(
+ const char verifyValues[] = R"(
for (auto v : valueGroup{0}) {
if (::mlir::failed({1}(*this, v.getType(), "{2}", index++)))
return ::mlir::failure();
@@ -3819,7 +3819,7 @@ void OpEmitter::genRegionVerifier(MethodBody &body) {
/// {1}: The region constraint.
/// {2}: The region's name.
/// {3}: The region description.
- const char *const verifyRegion = R"(
+ const char verifyRegion[] = R"(
for (auto ®ion : {0})
if (::mlir::failed({1}(*this, region, "{2}", index++)))
return ::mlir::failure();
@@ -3827,7 +3827,7 @@ void OpEmitter::genRegionVerifier(MethodBody &body) {
/// Get a single region.
///
/// {0}: The region's index.
- const char *const getSingleRegion =
+ const char getSingleRegion[] =
"::llvm::MutableArrayRef((*this)->getRegion({0}))";
// If we have no regions, there is nothing more to do.
@@ -3855,7 +3855,7 @@ void OpEmitter::genRegionVerifier(MethodBody &body) {
}
void OpEmitter::genSuccessorVerifier(MethodBody &body) {
- const char *const verifySuccessor = R"(
+ const char verifySuccessor[] = R"(
for (auto *successor : {0})
if (::mlir::failed({1}(*this, successor, "{2}", index++)))
return ::mlir::failure();
@@ -3863,7 +3863,7 @@ void OpEmitter::genSuccessorVerifier(MethodBody &body) {
/// Get a single successor.
///
/// {0}: The successor's name.
- const char *const getSingleSuccessor = "::llvm::MutableArrayRef({0}())";
+ const char getSingleSuccessor[] = "::llvm::MutableArrayRef({0}())";
// If we have no successors, there is nothing more to do.
const auto canSkip = [](const NamedSuccessor &successor) {
@@ -3881,8 +3881,8 @@ void OpEmitter::genSuccessorVerifier(MethodBody &body) {
continue;
auto getSuccessor =
- formatv(successor.isVariadic() ? "{0}()" : getSingleSuccessor,
- successor.name, it.index())
+ formatvv(successor.isVariadic() ? "{0}()" : getSingleSuccessor,
+ successor.name, it.index())
.str();
auto constraintFn =
staticVerifierEmitter.getSuccessorConstraintFn(successor.constraint);
@@ -4123,7 +4123,7 @@ OpOperandAdaptorEmitter::OpOperandAdaptorEmitter(
comparatorOs << " rhs." << name << " == this->" << name
<< " &&\n";
// Emit accessors using the interface type.
- const char *accessorFmt = R"decl(;
+ const char accessorFmt[] = R"decl(;
{0} get{1}() const {
auto &propStorage = this->{2};
return {3};
@@ -4169,7 +4169,7 @@ OpOperandAdaptorEmitter::OpOperandAdaptorEmitter(
// Emit accessors using the interface type.
if (attr) {
- const char *accessorFmt = R"decl(
+ const char accessorFmt[] = R"decl(
auto get{0}() {
auto &propStorage = this->{1};
return ::llvm::{2}<{3}>(propStorage);
@@ -4597,7 +4597,7 @@ static bool emitOpDecls(const RecordKeeper &recordKeeper, raw_ostream &os) {
Dialect dialect = Operator(defs.front()).getDialect();
NamespaceEmitter ns(os, dialect);
- const char *const opRegistrationHook =
+ const char opRegistrationHook[] =
"void register{0}Operations{1}({2}::{0} *dialect);\n";
os << formatv(opRegistrationHook, dialect.getCppClassName(), "",
dialect.getCppNamespace());
@@ -4621,7 +4621,7 @@ static void emitOpDefShard(const RecordKeeper &recordKeeper,
IfDefScope scope(shardGuard, os);
// Emit the op registration hook in the first shard.
- const char *const opRegistrationHook =
+ const char opRegistrationHook[] =
"void {0}::register{1}Operations{2}({0}::{1} *dialect) {{\n";
if (shardIndex == 0) {
os << formatv(opRegistrationHook, dialect.getCppNamespace(),
diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
index 9a95f495b77658..a3cd3388ed37a1 100644
--- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp
@@ -443,7 +443,7 @@ static bool shouldFormatSymbolNameAttr(const NamedAttribute *attr) {
///
/// {0}: The name of the attribute.
/// {1}: The type for the attribute.
-const char *const attrParserCode = R"(
+const char attrParserCode[] = R"(
if (parser.parseCustomAttributeWithFallback({0}Attr, {1})) {{
return ::mlir::failure();
}
@@ -453,12 +453,12 @@ const char *const attrParserCode = R"(
///
/// {0}: The name of the attribute.
/// {1}: The type for the attribute.
-const char *const genericAttrParserCode = R"(
+const char genericAttrParserCode[] = R"(
if (parser.parseAttribute({0}Attr, {1}))
return ::mlir::failure();
)";
-const char *const optionalAttrParserCode = R"(
+const char optionalAttrParserCode[] = R"(
::mlir::OptionalParseResult parseResult{0}Attr =
parser.parseOptionalAttribute({0}Attr, {1});
if (parseResult{0}Attr.has_value() && failed(*parseResult{0}Attr))
@@ -469,11 +469,11 @@ const char *const optionalAttrParserCode = R"(
/// The code snippet used to generate a parser call for a symbol name attribute.
///
/// {0}: The name of the attribute.
-const char *const symbolNameAttrParserCode = R"(
+const char symbolNameAttrParserCode[] = R"(
if (parser.parseSymbolName({0}Attr))
return ::mlir::failure();
)";
-const char *const optionalSymbolNameAttrParserCode = R"(
+const char optionalSymbolNameAttrParserCode[] = R"(
// Parsing an optional symbol name doesn't fail, so no need to check the
// result.
(void)parser.parseOptionalSymbolName({0}Attr);
@@ -488,7 +488,7 @@ const char *const optionalSymbolNameAttrParserCode = R"(
/// {4}: The set of allowed enum keywords.
/// {5}: The error message on failure when the enum isn't present.
/// {6}: The attribute assignment expression
-const char *const enumAttrParserCode = R"(
+const char enumAttrParserCode[] = R"(
{
::llvm::StringRef attrStr;
::mlir::NamedAttrList attrStorage;
@@ -524,7 +524,7 @@ const char *const enumAttrParserCode = R"(
/// {1}: The C++ class name of the operation
/// {2}: The property's parser code with appropriate substitutions performed
/// {3}: The description of the expected property for the error message.
-const char *const propertyParserCode = R"(
+const char propertyParserCode[] = R"(
auto {0}PropLoc = parser.getCurrentLocation();
auto {0}PropParseResult = [&](auto& propStorage) -> ::mlir::ParseResult {{
{2}
@@ -539,7 +539,7 @@ const char *const propertyParserCode = R"(
/// {0}: The name of the property
/// {1}: The C++ class name of the operation
/// {2}: The property's parser code with appropriate substitutions performed
-const char *const optionalPropertyParserCode = R"(
+const char optionalPropertyParserCode[] = R"(
auto {0}PropParseResult = [&](auto& propStorage) -> ::mlir::OptionalParseResult {{
{2}
return ::mlir::success();
@@ -552,12 +552,12 @@ const char *const optionalPropertyParserCode = R"(
/// The code snippet used to generate a parser call for an operand.
///
/// {0}: The name of the operand.
-const char *const variadicOperandParserCode = R"(
+const char variadicOperandParserCode[] = R"(
{0}OperandsLoc = parser.getCurrentLocation();
if (parser.parseOperandList({0}Operands))
return ::mlir::failure();
)";
-const char *const optionalOperandParserCode = R"(
+const char optionalOperandParserCode[] = R"(
{
{0}OperandsLoc = parser.getCurrentLocation();
::mlir::OpAsmParser::UnresolvedOperand operand;
@@ -570,7 +570,7 @@ const char *const optionalOperandParserCode = R"(
}
}
)";
-const char *const operandParserCode = R"(
+const char operandParserCode[] = R"(
{0}OperandsLoc = parser.getCurrentLocation();
if (parser.parseOperand({0}RawOperand))
return ::mlir::failure();
@@ -579,8 +579,7 @@ const char *const operandParserCode = R"(
/// operand.
///
/// {0}: The name of the operand.
-/// {1}: The name of segment size attribute.
-const char *const variadicOfVariadicOperandParserCode = R"(
+const char variadicOfVariadicOperandParserCode[] = R"(
{
{0}OperandsLoc = parser.getCurrentLocation();
int32_t curSize = 0;
@@ -598,7 +597,7 @@ const char *const variadicOfVariadicOperandParserCode = R"(
/// The code snippet used to generate a parser call for a type list.
///
/// {0}: The name for the type list.
-const char *const variadicOfVariadicTypeParserCode = R"(
+const char variadicOfVariadicTypeParserCode[] = R"(
do {
if (parser.parseOptionalLParen())
break;
@@ -607,11 +606,11 @@ const char *const variadicOfVariadicTypeParserCode = R"(
return ::mlir::failure();
} while (succeeded(parser.parseOptionalComma()));
)";
-const char *const variadicTypeParserCode = R"(
+const char variadicTypeParserCode[] = R"(
if (parser.parseTypeList({0}Types))
return ::mlir::failure();
)";
-const char *const optionalTypeParserCode = R"(
+const char optionalTypeParserCode[] = R"(
{
::mlir::Type optionalType;
::mlir::OptionalParseResult parseResult =
@@ -623,7 +622,7 @@ const char *const optionalTypeParserCode = R"(
}
}
)";
-const char *const typeParserCode = R"(
+const char typeParserCode[] = R"(
{
{0} type;
if (parser.parseCustomTypeWithFallback(type))
@@ -631,7 +630,7 @@ const char *const typeParserCode = R"(
{1}RawType = type;
}
)";
-const char *const qualifiedTypeParserCode = R"(
+const char qualifiedTypeParserCode[] = R"(
if (parser.parseType({1}RawType))
return ::mlir::failure();
)";
@@ -640,7 +639,7 @@ const char *const qualifiedTypeParserCode = R"(
///
/// {0}: The name for the input type list.
/// {1}: The name for the result type list.
-const char *const functionalTypeParserCode = R"(
+const char functionalTypeParserCode[] = R"(
::mlir::FunctionType {0}__{1}_functionType;
if (parser.parseType({0}__{1}_functionType))
return ::mlir::failure();
@@ -651,7 +650,7 @@ const char *const functionalTypeParserCode = R"(
/// The code snippet used to generate a parser call to infer return types.
///
/// {0}: The operation class name
-const char *const inferReturnTypesParserCode = R"(
+const char inferReturnTypesParserCode[] = R"(
::llvm::SmallVector<::mlir::Type> inferredReturnTypes;
if (::mlir::failed({0}::inferReturnTypes(parser.getContext(),
result.location, result.operands,
@@ -665,7 +664,7 @@ const char *const inferReturnTypesParserCode = R"(
/// The code snippet used to generate a parser call for a region list.
///
/// {0}: The name for the region list.
-const char *regionListParserCode = R"(
+const char regionListParserCode[] = R"(
{
std::unique_ptr<::mlir::Region> region;
auto firstRegionResult = parser.parseOptionalRegion(region);
@@ -688,7 +687,7 @@ const char *regionListParserCode = R"(
/// The code snippet used to ensure a list of regions have terminators.
///
/// {0}: The name of the region list.
-const char *regionListEnsureTerminatorParserCode = R"(
+const char regionListEnsureTerminatorParserCode[] = R"(
for (auto ®ion : {0}Regions)
ensureTerminator(*region, parser.getBuilder(), result.location);
)";
@@ -696,7 +695,7 @@ const char *regionListEnsureTerminatorParserCode = R"(
/// The code snippet used to ensure a list of regions have a block.
///
/// {0}: The name of the region list.
-const char *regionListEnsureSingleBlockParserCode = R"(
+const char regionListEnsureSingleBlockParserCode[] = R"(
for (auto ®ion : {0}Regions)
if (region->empty()) region->emplaceBlock();
)";
@@ -704,7 +703,7 @@ const char *regionListEnsureSingleBlockParserCode = R"(
/// The code snippet used to generate a parser call for an optional region.
///
/// {0}: The name of the region.
-const char *optionalRegionParserCode = R"(
+const char optionalRegionParserCode[] = R"(
{
auto parseResult = parser.parseOptionalRegion(*{0}Region);
if (parseResult.has_value() && failed(*parseResult))
@@ -715,7 +714,7 @@ const char *optionalRegionParserCode = R"(
/// The code snippet used to generate a parser call for a region.
///
/// {0}: The name of the region.
-const char *regionParserCode = R"(
+const char regionParserCode[] = R"(
if (parser.parseRegion(*{0}Region))
return ::mlir::failure();
)";
@@ -723,21 +722,21 @@ const char *regionParserCode = R"(
/// The code snippet used to ensure a region has a terminator.
///
/// {0}: The name of the region.
-const char *regionEnsureTerminatorParserCode = R"(
+const char regionEnsureTerminatorParserCode[] = R"(
ensureTerminator(*{0}Region, parser.getBuilder(), result.location);
)";
/// The code snippet used to ensure a region has a block.
///
/// {0}: The name of the region.
-const char *regionEnsureSingleBlockParserCode = R"(
+const char regionEnsureSingleBlockParserCode[] = R"(
if ({0}Region->empty()) {0}Region->emplaceBlock();
)";
/// The code snippet used to generate a parser call for a successor list.
///
/// {0}: The name for the successor list.
-const char *successorListParserCode = R"(
+const char successorListParserCode[] = R"(
{
::mlir::Block *succ;
auto firstSucc = parser.parseOptionalSuccessor(succ);
@@ -759,7 +758,7 @@ const char *successorListParserCode = R"(
/// The code snippet used to generate a parser call for a successor.
///
/// {0}: The name of the successor.
-const char *successorParserCode = R"(
+const char successorParserCode[] = R"(
if (parser.parseSuccessor({0}Successor))
return ::mlir::failure();
)";
@@ -767,7 +766,7 @@ const char *successorParserCode = R"(
/// The code snippet used to generate a parser for OIList
///
/// {0}: literal keyword corresponding to a case for oilist
-const char *oilistParserCode = R"(
+const char oilistParserCode[] = R"(
if ({0}Clause) {
return parser.emitError(parser.getNameLoc())
<< "`{0}` clause can appear at most once in the expansion of the "
@@ -1122,7 +1121,7 @@ static void genCustomDirectiveParser(CustomDirective *dir, MethodBody &body,
" {0}Operands.append(subRange.begin(), subRange.end());\n"
" {0}OperandGroupSizes.push_back(subRange.size());\n"
" }\n",
- var->name, var->constraint.getVariadicOfVariadicSegmentSizeAttr());
+ var->name);
}
} else if (auto *dir = dyn_cast<TypeDirective>(param)) {
ArgumentLengthKind lengthKind;
@@ -1233,9 +1232,9 @@ static void genAttrParser(AttributeVariable *attr, MethodBody &body,
// Check to see if we should parse this as a symbol name attribute.
if (shouldFormatSymbolNameAttr(var)) {
- body << formatv(parseAsOptional ? optionalSymbolNameAttrParserCode
- : symbolNameAttrParserCode,
- var->name);
+ body << formatvv(parseAsOptional ? optionalSymbolNameAttrParserCode
+ : symbolNameAttrParserCode,
+ var->name);
} else {
// If this attribute has a buildable type, use that when parsing the
@@ -1299,7 +1298,7 @@ if (!dict) {
// {0}: fromAttribute call
// {1}: property name
// {2}: isRequired
- const char *propFromAttrFmt = R"decl(
+ const char propFromAttrFmt[] = R"decl(
auto setFromAttr = [] (auto &propStorage, ::mlir::Attribute propAttr,
::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError) -> ::mlir::LogicalResult {{
{0};
@@ -1575,9 +1574,7 @@ void OperationFormat::genElementParser(FormatElement *element, MethodBody &body,
ArgumentLengthKind lengthKind = getArgumentLengthKind(operand->getVar());
StringRef name = operand->getVar()->name;
if (lengthKind == ArgumentLengthKind::VariadicOfVariadic)
- body << llvm::formatv(
- variadicOfVariadicOperandParserCode, name,
- operand->getVar()->constraint.getVariadicOfVariadicSegmentSizeAttr());
+ body << llvm::formatv(variadicOfVariadicOperandParserCode, name);
else if (lengthKind == ArgumentLengthKind::Variadic)
body << llvm::formatv(variadicOperandParserCode, name);
else if (lengthKind == ArgumentLengthKind::Optional)
@@ -1587,21 +1584,21 @@ void OperationFormat::genElementParser(FormatElement *element, MethodBody &body,
} else if (auto *region = dyn_cast<RegionVariable>(element)) {
bool isVariadic = region->getVar()->isVariadic();
- body << llvm::formatv(isVariadic ? regionListParserCode : regionParserCode,
- region->getVar()->name);
+ body << llvm::formatvv(isVariadic ? regionListParserCode : regionParserCode,
+ region->getVar()->name);
if (hasImplicitTermTrait)
- body << llvm::formatv(isVariadic ? regionListEnsureTerminatorParserCode
- : regionEnsureTerminatorParserCode,
- region->getVar()->name);
+ body << llvm::formatvv(isVariadic ? regionListEnsureTerminatorParserCode
+ : regionEnsureTerminatorParserCode,
+ region->getVar()->name);
else if (hasSingleBlockTrait)
- body << llvm::formatv(isVariadic ? regionListEnsureSingleBlockParserCode
- : regionEnsureSingleBlockParserCode,
- region->getVar()->name);
+ body << llvm::formatvv(isVariadic ? regionListEnsureSingleBlockParserCode
+ : regionEnsureSingleBlockParserCode,
+ region->getVar()->name);
} else if (auto *successor = dyn_cast<SuccessorVariable>(element)) {
bool isVariadic = successor->getVar()->isVariadic();
- body << formatv(isVariadic ? successorListParserCode : successorParserCode,
- successor->getVar()->name);
+ body << formatvv(isVariadic ? successorListParserCode : successorParserCode,
+ successor->getVar()->name);
/// Directives.
} else if (auto *attrDict = dyn_cast<AttrDictDirective>(element)) {
@@ -1656,12 +1653,12 @@ void OperationFormat::genElementParser(FormatElement *element, MethodBody &body,
dir->shouldBeQualified() ? qualifiedTypeParserCode : typeParserCode;
TypeSwitch<FormatElement *>(dir->getArg())
.Case<OperandVariable, ResultVariable>([&](auto operand) {
- body << formatv(parserCode,
- operand->getVar()->constraint.getCppType(),
- listName);
+ body << formatvv(parserCode,
+ operand->getVar()->constraint.getCppType(),
+ listName);
})
.Default([&](auto operand) {
- body << formatv(parserCode, "::mlir::Type", listName);
+ body << formatvv(parserCode, "::mlir::Type", listName);
});
}
} else if (auto *dir = dyn_cast<FunctionalTypeDirective>(element)) {
@@ -1954,7 +1951,7 @@ void OperationFormat::genParserVariadicSegmentResolution(Operator &op,
// operation that has the SingleBlockImplicitTerminator trait.
///
/// {0}: The name of the region.
-const char *regionSingleBlockImplicitTerminatorPrinterCode = R"(
+const char regionSingleBlockImplicitTerminatorPrinterCode[] = R"(
{
bool printTerminator = true;
if (auto *term = {0}.empty() ? nullptr : {0}.begin()->getTerminator()) {{
@@ -1972,7 +1969,7 @@ const char *regionSingleBlockImplicitTerminatorPrinterCode = R"(
///
/// {0}: The name of the enum attribute.
/// {1}: The name of the enum attributes symbolToString function.
-const char *enumAttrBeginPrinterCode = R"(
+const char enumAttrBeginPrinterCode[] = R"(
{
auto caseValue = {0}();
auto caseValueStr = {1}(caseValue);
diff --git a/mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp b/mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp
index 052020acdcb764..2637e2b2dada3d 100644
--- a/mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp
+++ b/mlir/tools/mlir-tblgen/OpPythonBindingGen.cpp
@@ -26,7 +26,7 @@ using namespace mlir::tblgen;
/// File header and includes.
/// {0} is the dialect namespace.
-constexpr const char *fileHeader = R"Py(
+constexpr const char fileHeader[] = R"Py(
# Autogenerated by mlir-tblgen; don't manually edit.
from ._ods_common import _cext as _ods_cext
@@ -47,20 +47,20 @@ from typing import Sequence as _Sequence, Union as _Union
/// Template for dialect class:
/// {0} is the dialect namespace.
-constexpr const char *dialectClassTemplate = R"Py(
+constexpr const char dialectClassTemplate[] = R"Py(
@_ods_cext.register_dialect
class _Dialect(_ods_ir.Dialect):
DIALECT_NAMESPACE = "{0}"
)Py";
-constexpr const char *dialectExtensionTemplate = R"Py(
+constexpr const char dialectExtensionTemplate[] = R"Py(
from ._{0}_ops_gen import _Dialect
)Py";
/// Template for operation class:
/// {0} is the Python class name;
/// {1} is the operation name.
-constexpr const char *opClassTemplate = R"Py(
+constexpr const char opClassTemplate[] = R"Py(
@_ods_cext.register_operation(_Dialect)
class {0}(_ods_ir.OpView):
OPERATION_NAME = "{1}"
@@ -75,14 +75,14 @@ class {0}(_ods_ir.OpView):
/// 1 = single element (expect non sequence operand/result)
/// 0 = optional element (expect a value or std::nullopt)
/// -1 = operand/result is a sequence corresponding to a variadic
-constexpr const char *opClassSizedSegmentsTemplate = R"Py(
+constexpr const char opClassSizedSegmentsTemplate[] = R"Py(
_ODS_{0}_SEGMENTS = {1}
)Py";
/// Template for class level declarations of the _ODS_REGIONS spec:
/// {0} is the minimum number of regions
/// {1} is the Python bool literal for hasNoVariadicRegions
-constexpr const char *opClassRegionSpecTemplate = R"Py(
+constexpr const char opClassRegionSpecTemplate[] = R"Py(
_ODS_REGIONS = ({0}, {1})
)Py";
@@ -90,7 +90,7 @@ constexpr const char *opClassRegionSpecTemplate = R"Py(
/// {0} is the name of the accessor;
/// {1} is either 'operand' or 'result';
/// {2} is the position in the element list.
-constexpr const char *opSingleTemplate = R"Py(
+constexpr const char opSingleTemplate[] = R"Py(
@builtins.property
def {0}(self):
return self.operation.{1}s[{2}]
@@ -103,7 +103,7 @@ constexpr const char *opSingleTemplate = R"Py(
/// {3} is the position of the current group in the group list.
/// This works for both a single variadic group (non-negative length) and an
/// single optional element (zero length if the element is absent).
-constexpr const char *opSingleAfterVariableTemplate = R"Py(
+constexpr const char opSingleAfterVariableTemplate[] = R"Py(
@builtins.property
def {0}(self):
_ods_variadic_group_length = len(self.operation.{1}s) - {2} + 1
@@ -118,7 +118,7 @@ constexpr const char *opSingleAfterVariableTemplate = R"Py(
/// This works if we have only one variable-length group (and it's the optional
/// operand/result): we can deduce it's absent if the `len(operation.{1}s)` is
/// smaller than the total number of groups.
-constexpr const char *opOneOptionalTemplate = R"Py(
+constexpr const char opOneOptionalTemplate[] = R"Py(
@builtins.property
def {0}(self):
return None if len(self.operation.{1}s) < {2} else self.operation.{1}s[{3}]
@@ -129,7 +129,7 @@ constexpr const char *opOneOptionalTemplate = R"Py(
/// {1} is either 'operand' or 'result';
/// {2} is the total number of element groups;
/// {3} is the position of the current group in the group list.
-constexpr const char *opOneVariadicTemplate = R"Py(
+constexpr const char opOneVariadicTemplate[] = R"Py(
@builtins.property
def {0}(self):
_ods_variadic_group_length = len(self.operation.{1}s) - {2} + 1
@@ -142,7 +142,7 @@ constexpr const char *opOneVariadicTemplate = R"Py(
/// {2} is the total number of variadic groups;
/// {3} is the number of non-variadic groups preceding the current group;
/// {3} is the number of variadic groups preceding the current group.
-constexpr const char *opVariadicEqualPrefixTemplate = R"Py(
+constexpr const char opVariadicEqualPrefixTemplate[] = R"Py(
@builtins.property
def {0}(self):
start, pg = _ods_equally_sized_accessor(operation.{1}s, {2}, {3}, {4}))Py";
@@ -150,14 +150,14 @@ constexpr const char *opVariadicEqualPrefixTemplate = R"Py(
/// Second part of the template for equally-sized case, accessing a single
/// element:
/// {0} is either 'operand' or 'result'.
-constexpr const char *opVariadicEqualSimpleTemplate = R"Py(
+constexpr const char opVariadicEqualSimpleTemplate[] = R"Py(
return self.operation.{0}s[start]
)Py";
/// Second part of the template for equally-sized case, accessing a variadic
/// group:
/// {0} is either 'operand' or 'result'.
-constexpr const char *opVariadicEqualVariadicTemplate = R"Py(
+constexpr const char opVariadicEqualVariadicTemplate[] = R"Py(
return self.operation.{0}s[start:start + pg]
)Py";
@@ -167,7 +167,7 @@ constexpr const char *opVariadicEqualVariadicTemplate = R"Py(
/// {2} is the position of the group in the group list;
/// {3} is a return suffix (expected [0] for single-element, empty for
/// variadic, and opVariadicSegmentOptionalTrailingTemplate for optional).
-constexpr const char *opVariadicSegmentTemplate = R"Py(
+constexpr const char opVariadicSegmentTemplate[] = R"Py(
@builtins.property
def {0}(self):
{1}_range = _ods_segmented_accessor(
@@ -179,13 +179,13 @@ constexpr const char *opVariadicSegmentTemplate = R"Py(
/// Template for a suffix when accessing an optional element in the
/// attribute-sized case:
/// {0} is either 'operand' or 'result';
-constexpr const char *opVariadicSegmentOptionalTrailingTemplate =
+constexpr const char opVariadicSegmentOptionalTrailingTemplate[] =
R"Py([0] if len({0}_range) > 0 else None)Py";
/// Template for an operation attribute getter:
/// {0} is the name of the attribute sanitized for Python;
/// {1} is the original name of the attribute.
-constexpr const char *attributeGetterTemplate = R"Py(
+constexpr const char attributeGetterTemplate[] = R"Py(
@builtins.property
def {0}(self):
return self.operation.attributes["{1}"]
@@ -194,7 +194,7 @@ constexpr const char *attributeGetterTemplate = R"Py(
/// Template for an optional operation attribute getter:
/// {0} is the name of the attribute sanitized for Python;
/// {1} is the original name of the attribute.
-constexpr const char *optionalAttributeGetterTemplate = R"Py(
+constexpr const char optionalAttributeGetterTemplate[] = R"Py(
@builtins.property
def {0}(self):
if "{1}" not in self.operation.attributes:
@@ -207,7 +207,7 @@ constexpr const char *optionalAttributeGetterTemplate = R"Py(
/// by mere presence):
/// {0} is the name of the attribute sanitized for Python,
/// {1} is the original name of the attribute.
-constexpr const char *unitAttributeGetterTemplate = R"Py(
+constexpr const char unitAttributeGetterTemplate[] = R"Py(
@builtins.property
def {0}(self):
return "{1}" in self.operation.attributes
@@ -216,7 +216,7 @@ constexpr const char *unitAttributeGetterTemplate = R"Py(
/// Template for an operation attribute setter:
/// {0} is the name of the attribute sanitized for Python;
/// {1} is the original name of the attribute.
-constexpr const char *attributeSetterTemplate = R"Py(
+constexpr const char attributeSetterTemplate[] = R"Py(
@{0}.setter
def {0}(self, value):
if value is None:
@@ -228,7 +228,7 @@ constexpr const char *attributeSetterTemplate = R"Py(
/// removes the attribute:
/// {0} is the name of the attribute sanitized for Python;
/// {1} is the original name of the attribute.
-constexpr const char *optionalAttributeSetterTemplate = R"Py(
+constexpr const char optionalAttributeSetterTemplate[] = R"Py(
@{0}.setter
def {0}(self, value):
if value is not None:
@@ -241,7 +241,7 @@ constexpr const char *optionalAttributeSetterTemplate = R"Py(
/// False removes the attribute:
/// {0} is the name of the attribute sanitized for Python;
/// {1} is the original name of the attribute.
-constexpr const char *unitAttributeSetterTemplate = R"Py(
+constexpr const char unitAttributeSetterTemplate[] = R"Py(
@{0}.setter
def {0}(self, value):
if bool(value):
@@ -254,19 +254,19 @@ constexpr const char *unitAttributeSetterTemplate = R"Py(
/// the attribute from the operation:
/// {0} is the name of the attribute sanitized for Python;
/// {1} is the original name of the attribute.
-constexpr const char *attributeDeleterTemplate = R"Py(
+constexpr const char attributeDeleterTemplate[] = R"Py(
@{0}.deleter
def {0}(self):
del self.operation.attributes["{1}"]
)Py";
-constexpr const char *regionAccessorTemplate = R"Py(
+constexpr const char regionAccessorTemplate[] = R"Py(
@builtins.property
def {0}(self):
return self.regions[{1}]
)Py";
-constexpr const char *valueBuilderTemplate = R"Py(
+constexpr const char valueBuilderTemplate[] = R"Py(
def {0}({2}) -> {4}:
return _get_op_result_or_op_results({1}({3}))
)Py";
@@ -353,10 +353,10 @@ static void emitElementAccessors(
if (element.name.empty())
continue;
if (element.isVariableLength()) {
- os << llvm::formatv(element.isOptional() ? opOneOptionalTemplate
- : opOneVariadicTemplate,
- sanitizeName(element.name), kind,
- getNumElements(op), i);
+ os << llvm::formatvv(element.isOptional() ? opOneOptionalTemplate
+ : opOneVariadicTemplate,
+ sanitizeName(element.name), kind,
+ getNumElements(op), i);
} else if (seenVariableLength) {
os << llvm::formatv(opSingleAfterVariableTemplate,
sanitizeName(element.name), kind,
@@ -379,10 +379,10 @@ static void emitElementAccessors(
os << llvm::formatv(opVariadicEqualPrefixTemplate,
sanitizeName(element.name), kind, numVariableLength,
numPrecedingSimple, numPrecedingVariadic);
- os << llvm::formatv(element.isVariableLength()
- ? opVariadicEqualVariadicTemplate
- : opVariadicEqualSimpleTemplate,
- kind);
+ os << llvm::formatvv(element.isVariableLength()
+ ? opVariadicEqualVariadicTemplate
+ : opVariadicEqualSimpleTemplate,
+ kind);
}
if (element.isVariableLength())
++numPrecedingVariadic;
@@ -489,7 +489,7 @@ static void emitAttributeAccessors(const Operator &op, raw_ostream &os) {
/// `loc` and `ip`;
/// {1} is the code populating `operands`, `results` and `attributes`,
/// `successors` fields.
-constexpr const char *initTemplate = R"Py(
+constexpr const char initTemplate[] = R"Py(
def __init__(self, {0}):
operands = []
results = []
@@ -501,27 +501,27 @@ constexpr const char *initTemplate = R"Py(
/// Template for appending a single element to the operand/result list.
/// {0} is the field name.
-constexpr const char *singleOperandAppendTemplate =
+constexpr const char singleOperandAppendTemplate[] =
"operands.append(_get_op_result_or_value({0}))";
constexpr const char *singleResultAppendTemplate = "results.append({0})";
/// Template for appending an optional element to the operand/result list.
/// {0} is the field name.
-constexpr const char *optionalAppendOperandTemplate =
+constexpr const char optionalAppendOperandTemplate[] =
"if {0} is not None: operands.append(_get_op_result_or_value({0}))";
-constexpr const char *optionalAppendAttrSizedOperandsTemplate =
+constexpr const char optionalAppendAttrSizedOperandsTemplate[] =
"operands.append(_get_op_result_or_value({0}) if {0} is not None else "
"None)";
-constexpr const char *optionalAppendResultTemplate =
+constexpr const char optionalAppendResultTemplate[] =
"if {0} is not None: results.append({0})";
/// Template for appending a list of elements to the operand/result list.
/// {0} is the field name.
-constexpr const char *multiOperandAppendTemplate =
+constexpr const char multiOperandAppendTemplate[] =
"operands.extend(_get_op_results_or_values({0}))";
-constexpr const char *multiOperandAppendPackTemplate =
+constexpr const char multiOperandAppendPackTemplate[] =
"operands.append(_get_op_results_or_values({0}))";
-constexpr const char *multiResultAppendTemplate = "results.extend({0})";
+constexpr const char multiResultAppendTemplate[] = "results.extend({0})";
/// Template for attribute builder from raw input in the operation builder.
/// {0} is the builder argument name;
@@ -529,7 +529,7 @@ constexpr const char *multiResultAppendTemplate = "results.extend({0})";
/// {2} is the attribute builder from raw.
/// Use the value the user passed in if either it is already an Attribute or
/// there is no method registered to make it an Attribute.
-constexpr const char *initAttributeWithBuilderTemplate =
+constexpr const char initAttributeWithBuilderTemplate[] =
R"Py(attributes["{1}"] = ({0} if (
isinstance({0}, _ods_ir.Attribute) or
not _ods_ir.AttrBuilder.contains('{2}')) else
@@ -542,25 +542,25 @@ constexpr const char *initAttributeWithBuilderTemplate =
/// {2} is the attribute builder from raw.
/// Use the value the user passed in if either it is already an Attribute or
/// there is no method registered to make it an Attribute.
-constexpr const char *initOptionalAttributeWithBuilderTemplate =
+constexpr const char initOptionalAttributeWithBuilderTemplate[] =
R"Py(if {0} is not None: attributes["{1}"] = ({0} if (
isinstance({0}, _ods_ir.Attribute) or
not _ods_ir.AttrBuilder.contains('{2}')) else
_ods_ir.AttrBuilder.get('{2}')({0}, context=_ods_context)))Py";
-constexpr const char *initUnitAttributeTemplate =
+constexpr const char initUnitAttributeTemplate[] =
R"Py(if bool({1}): attributes["{0}"] = _ods_ir.UnitAttr.get(
_ods_get_default_loc_context(loc)))Py";
/// Template to initialize the successors list in the builder if there are any
/// successors.
/// {0} is the value to initialize the successors list to.
-constexpr const char *initSuccessorsTemplate = R"Py(_ods_successors = {0})Py";
+constexpr const char initSuccessorsTemplate[] = R"Py(_ods_successors = {0})Py";
/// Template to append or extend the list of successors in the builder.
/// {0} is the list method ('append' or 'extend');
/// {1} is the value to add.
-constexpr const char *addSuccessorTemplate = R"Py(_ods_successors.{0}({1}))Py";
+constexpr const char addSuccessorTemplate[] = R"Py(_ods_successors.{0}({1}))Py";
/// Returns true if the SameArgumentAndResultTypes trait can be used to infer
/// result types of the given operation.
@@ -674,7 +674,7 @@ populateBuilderLinesAttr(const Operator &op,
continue;
}
- builderLines.push_back(llvm::formatv(
+ builderLines.push_back(llvm::formatvv(
attribute->attr.isOptional() || attribute->attr.hasDefaultValue()
? initOptionalAttributeWithBuilderTemplate
: initAttributeWithBuilderTemplate,
@@ -737,14 +737,14 @@ populateBuilderLinesOperand(const Operator &op,
}
}
- builderLines.push_back(llvm::formatv(formatString.data(), name));
+ builderLines.push_back(llvm::formatvv(formatString.data(), name));
}
}
/// Python code template for deriving the operation result types from its
/// attribute:
/// - {0} is the name of the attribute from which to derive the types.
-constexpr const char *deriveTypeFromAttrTemplate =
+constexpr const char deriveTypeFromAttrTemplate[] =
R"Py(_ods_result_type_source_attr = attributes["{0}"]
_ods_derived_result_type = (
_ods_ir.TypeAttr(_ods_result_type_source_attr).value
@@ -752,7 +752,8 @@ _ods_derived_result_type = (
_ods_result_type_source_attr.type))Py";
/// Python code template appending {0} type {1} times to the results list.
-constexpr const char *appendSameResultsTemplate = "results.extend([{0}] * {1})";
+constexpr const char appendSameResultsTemplate[] =
+ "results.extend([{0}] * {1})";
/// Appends the given multiline string as individual strings into
/// `builderLines`.
@@ -818,7 +819,7 @@ populateBuilderLinesResult(const Operator &op,
}
}
- builderLines.push_back(llvm::formatv(formatString.data(), name));
+ builderLines.push_back(llvm::formatvv(formatString.data(), name));
}
}
diff --git a/mlir/tools/mlir-tblgen/PassCAPIGen.cpp b/mlir/tools/mlir-tblgen/PassCAPIGen.cpp
index 9f33a4129aacca..d7bbb1f759903b 100644
--- a/mlir/tools/mlir-tblgen/PassCAPIGen.cpp
+++ b/mlir/tools/mlir-tblgen/PassCAPIGen.cpp
@@ -30,14 +30,14 @@ static llvm::cl::opt<std::string>
"prefix can avoid conflicts across libraries."),
llvm::cl::cat(passGenCat));
-const char *const passDecl = R"(
+const char passDecl[] = R"(
/* Create {0} Pass. */
MLIR_CAPI_EXPORTED MlirPass mlirCreate{0}{1}(void);
MLIR_CAPI_EXPORTED void mlirRegister{0}{1}(void);
)";
-const char *const fileHeader = R"(
+const char fileHeader[] = R"(
/* Autogenerated by mlir-tblgen; don't manually edit. */
#include "mlir-c/Pass.h"
@@ -48,7 +48,7 @@ extern "C" {
)";
-const char *const fileFooter = R"(
+const char fileFooter[] = R"(
#ifdef __cplusplus
}
@@ -70,7 +70,7 @@ static bool emitCAPIHeader(const llvm::RecordKeeper &records, raw_ostream &os) {
return false;
}
-const char *const passCreateDef = R"(
+const char passCreateDef[] = R"(
MlirPass mlirCreate{0}{1}(void) {
return wrap({2}.release());
}
@@ -81,7 +81,7 @@ void mlirRegister{0}{1}(void) {
)";
/// {0}: The name of the pass group.
-const char *const passGroupRegistrationCode = R"(
+const char passGroupRegistrationCode[] = R"(
//===----------------------------------------------------------------------===//
// {0} Group Registration
//===----------------------------------------------------------------------===//
diff --git a/mlir/tools/mlir-tblgen/PassGen.cpp b/mlir/tools/mlir-tblgen/PassGen.cpp
index 90aa67115a4007..da128bf050a356 100644
--- a/mlir/tools/mlir-tblgen/PassGen.cpp
+++ b/mlir/tools/mlir-tblgen/PassGen.cpp
@@ -37,7 +37,7 @@ static std::vector<Pass> getPasses(const llvm::RecordKeeper &recordKeeper) {
return passes;
}
-const char *const passHeader = R"(
+const char passHeader[] = R"(
//===----------------------------------------------------------------------===//
// {0}
//===----------------------------------------------------------------------===//
@@ -51,7 +51,7 @@ const char *const passHeader = R"(
///
/// {0}: The def name of the pass record.
/// {1}: The pass constructor call.
-const char *const passRegistrationCode = R"(
+const char passRegistrationCode[] = R"(
//===----------------------------------------------------------------------===//
// {0} Registration
//===----------------------------------------------------------------------===//
@@ -74,7 +74,7 @@ inline void register{0}Pass() {{
/// group.
///
/// {0}: The name of the pass group.
-const char *const passGroupRegistrationCode = R"(
+const char passGroupRegistrationCode[] = R"(
//===----------------------------------------------------------------------===//
// {0} Registration
//===----------------------------------------------------------------------===//
@@ -175,7 +175,7 @@ static void emitRegistrations(llvm::ArrayRef<Pass> passes, raw_ostream &os) {
/// {2): The command line argument for the pass.
/// {3}: The summary for the pass.
/// {4}: The dependent dialects registration.
-const char *const baseClassBegin = R"(
+const char baseClassBegin[] = R"(
template <typename DerivedT>
class {0}Base : public {1} {
public:
@@ -226,39 +226,39 @@ class {0}Base : public {1} {
/// Registration for a single dependent dialect, to be inserted for each
/// dependent dialect in the `getDependentDialects` above.
-const char *const dialectRegistrationTemplate = "registry.insert<{0}>();";
+const char dialectRegistrationTemplate[] = "registry.insert<{0}>();";
-const char *const friendDefaultConstructorDeclTemplate = R"(
+const char friendDefaultConstructorDeclTemplate[] = R"(
namespace impl {{
std::unique_ptr<::mlir::Pass> create{0}();
} // namespace impl
)";
-const char *const friendDefaultConstructorWithOptionsDeclTemplate = R"(
+const char friendDefaultConstructorWithOptionsDeclTemplate[] = R"(
namespace impl {{
std::unique_ptr<::mlir::Pass> create{0}(const {0}Options &options);
} // namespace impl
)";
-const char *const friendDefaultConstructorDefTemplate = R"(
+const char friendDefaultConstructorDefTemplate[] = R"(
friend std::unique_ptr<::mlir::Pass> create{0}() {{
return std::make_unique<DerivedT>();
}
)";
-const char *const friendDefaultConstructorWithOptionsDefTemplate = R"(
+const char friendDefaultConstructorWithOptionsDefTemplate[] = R"(
friend std::unique_ptr<::mlir::Pass> create{0}(const {0}Options &options) {{
return std::make_unique<DerivedT>(options);
}
)";
-const char *const defaultConstructorDefTemplate = R"(
+const char defaultConstructorDefTemplate[] = R"(
std::unique_ptr<::mlir::Pass> create{0}() {{
return impl::create{0}();
}
)";
-const char *const defaultConstructorWithOptionsDefTemplate = R"(
+const char defaultConstructorWithOptionsDefTemplate[] = R"(
std::unique_ptr<::mlir::Pass> create{0}(const {0}Options &options) {{
return impl::create{0}(options);
}
@@ -376,7 +376,7 @@ static void emitPass(const Pass &pass, raw_ostream &os) {
// TODO: Drop old pass declarations.
// The old pass base class is being kept until all the passes have switched to
// the new decls/defs design.
-const char *const oldPassDeclBegin = R"(
+const char oldPassDeclBegin[] = R"(
template <typename DerivedT>
class {0}Base : public {1} {
public:
diff --git a/mlir/tools/mlir-tblgen/RewriterGen.cpp b/mlir/tools/mlir-tblgen/RewriterGen.cpp
index 2c79ba2cd6353e..5ea6cd93910b3f 100644
--- a/mlir/tools/mlir-tblgen/RewriterGen.cpp
+++ b/mlir/tools/mlir-tblgen/RewriterGen.cpp
@@ -1797,7 +1797,7 @@ void PatternEmitter::createAggregateLocalVarsForOpArgs(
os << formatv("::llvm::SmallVector<::mlir::NamedAttribute, 4> "
"tblgen_attrs; (void)tblgen_attrs;\n");
- const char *addAttrCmd =
+ const char addAttrCmd[] =
"if (auto tmpAttr = {1}) {\n"
" tblgen_attrs.emplace_back(rewriter.getStringAttr(\"{0}\"), "
"tmpAttr);\n}\n";
@@ -1876,7 +1876,7 @@ void PatternEmitter::createAggregateLocalVarsForOpArgs(
const auto *sameVariadicSize =
resultOp.getTrait("::mlir::OpTrait::SameVariadicOperandSize");
if (!sameVariadicSize) {
- const char *setSizes = R"(
+ const char setSizes[] = R"(
tblgen_attrs.emplace_back(rewriter.getStringAttr("operandSegmentSizes"),
rewriter.getDenseI32ArrayAttr({{ {0} }));
)";
More information about the Mlir-commits
mailing list