diff options
| -rw-r--r-- | mlir/include/mlir/TableGen/CodeGenHelpers.h | 24 | ||||
| -rw-r--r-- | mlir/lib/TableGen/CodeGenHelpers.cpp | 90 | ||||
| -rw-r--r-- | mlir/test/mlir-tblgen/constraint-unique.td | 10 | ||||
| -rw-r--r-- | mlir/test/mlir-tblgen/op-attribute.td | 16 | ||||
| -rw-r--r-- | mlir/test/mlir-tblgen/op-properties-predicates.td | 2 | ||||
| -rw-r--r-- | mlir/test/mlir-tblgen/predicate.td | 16 | ||||
| -rw-r--r-- | mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp | 38 | ||||
| -rw-r--r-- | mlir/unittests/TableGen/CMakeLists.txt | 2 |
8 files changed, 150 insertions, 48 deletions
diff --git a/mlir/include/mlir/TableGen/CodeGenHelpers.h b/mlir/include/mlir/TableGen/CodeGenHelpers.h index 997aef2..b56172f 100644 --- a/mlir/include/mlir/TableGen/CodeGenHelpers.h +++ b/mlir/include/mlir/TableGen/CodeGenHelpers.h @@ -52,6 +52,15 @@ private: std::optional<llvm::NamespaceEmitter> nsEmitter; }; +/// This class represents how an error stream string being constructed will be +/// consumed. +enum class ErrorStreamType { + // Inside a string that's streamed into an InflightDiagnostic. + InString, + // Inside a string inside an OpError. + InsideOpError, +}; + /// This class deduplicates shared operation verification code by emitting /// static functions alongside the op definitions. These methods are local to /// the definition file, and are invoked within the operation verify methods. @@ -192,7 +201,8 @@ private: /// A generic function to emit constraints void emitConstraints(const ConstraintMap &constraints, StringRef selfName, - const char *codeTemplate); + const char *codeTemplate, + ErrorStreamType errorStreamType); /// Assign a unique name to a unique constraint. std::string getUniqueName(StringRef kind, unsigned index); @@ -243,6 +253,18 @@ std::string stringify(T &&t) { apply(std::forward<T>(t)); } +/// Helper to generate a C++ streaming error message from a given message. +/// Message can contain '{{...}}' placeholders that are substituted with +/// C-expressions via tgfmt. It would effectively convert: +/// "failed to verify {{foo}}" +/// into: +/// "failed to verify " << bar +/// where bar is the result of evaluating 'tgfmt("foo", &ctx)' at compile +/// time. +std::string buildErrorStreamingString( + StringRef message, const FmtContext &ctx, + ErrorStreamType errorStreamType = ErrorStreamType::InString); + } // namespace tblgen } // namespace mlir diff --git a/mlir/lib/TableGen/CodeGenHelpers.cpp b/mlir/lib/TableGen/CodeGenHelpers.cpp index d52d5e7..9ad031e 100644 --- a/mlir/lib/TableGen/CodeGenHelpers.cpp +++ b/mlir/lib/TableGen/CodeGenHelpers.cpp @@ -12,12 +12,26 @@ //===----------------------------------------------------------------------===// #include "mlir/TableGen/CodeGenHelpers.h" +#include "mlir/Support/LLVM.h" +#include "mlir/TableGen/Argument.h" +#include "mlir/TableGen/Attribute.h" +#include "mlir/TableGen/Format.h" #include "mlir/TableGen/Operator.h" #include "mlir/TableGen/Pattern.h" +#include "mlir/TableGen/Property.h" +#include "mlir/TableGen/Region.h" +#include "mlir/TableGen/Successor.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/CodeGenHelpers.h" +#include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" +#include <cassert> +#include <optional> +#include <string> using namespace llvm; using namespace mlir; @@ -112,6 +126,55 @@ StringRef StaticVerifierFunctionEmitter::getRegionConstraintFn( // Constraint Emission //===----------------------------------------------------------------------===// +/// Helper to generate a C++ string expression from a given message. +/// Message can contain '{{...}}' placeholders that are substituted with +/// C-expressions via tgfmt. +std::string mlir::tblgen::buildErrorStreamingString( + StringRef message, const FmtContext &ctx, ErrorStreamType errorStreamType) { + std::string result; + raw_string_ostream os(result); + + std::string msgStr = escapeString(message); + StringRef msg = msgStr; + + // Split the message by '{{' and '}}' and build a streaming expression. + auto split = msg.split("{{"); + os << split.first; + if (split.second.empty()) { + return msgStr; + } + + if (errorStreamType == ErrorStreamType::InsideOpError) + os << "\")"; + else + os << '"'; + + msg = split.second; + while (!msg.empty()) { + split = msg.split("}}"); + StringRef var = split.first; + StringRef rest = split.second; + + os << " << " << tgfmt(var, &ctx); + + if (rest.empty()) + break; + + split = rest.split("{{"); + if (split.second.empty() && + errorStreamType == ErrorStreamType::InsideOpError) { + // To enable having part of string post, this adds a parenthesis before + // the last string segment to match the existing one. + os << " << (\"" << split.first; + } else { + os << " << \"" << split.first; + } + msg = split.second; + } + + return os.str(); +} + /// Code templates for emitting type, attribute, successor, and region /// constraints. Each of these templates require the following arguments: /// @@ -224,22 +287,24 @@ static ::llvm::LogicalResult {0}( void StaticVerifierFunctionEmitter::emitConstraints( const ConstraintMap &constraints, StringRef selfName, - const char *const codeTemplate) { + const char *const codeTemplate, ErrorStreamType errorStreamType) { 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())); + buildErrorStreamingString(it.first.getSummary(), ctx)); } } - void StaticVerifierFunctionEmitter::emitTypeConstraints() { - emitConstraints(typeConstraints, "type", typeConstraintCode); + emitConstraints(typeConstraints, "type", typeConstraintCode, + ErrorStreamType::InString); } void StaticVerifierFunctionEmitter::emitAttrConstraints() { - emitConstraints(attrConstraints, "attr", attrConstraintCode); + emitConstraints(attrConstraints, "attr", attrConstraintCode, + ErrorStreamType::InString); } /// Unlike with the other helpers, this one has to substitute in the interface @@ -251,17 +316,19 @@ void StaticVerifierFunctionEmitter::emitPropConstraints() { auto propConstraint = cast<PropConstraint>(it.first); os << formatv(propConstraintCode, it.second, tgfmt(propConstraint.getConditionTemplate(), &ctx), - escapeString(it.first.getSummary()), + buildErrorStreamingString(it.first.getSummary(), ctx), propConstraint.getInterfaceType()); } } void StaticVerifierFunctionEmitter::emitSuccessorConstraints() { - emitConstraints(successorConstraints, "successor", successorConstraintCode); + emitConstraints(successorConstraints, "successor", successorConstraintCode, + ErrorStreamType::InString); } void StaticVerifierFunctionEmitter::emitRegionConstraints() { - emitConstraints(regionConstraints, "region", regionConstraintCode); + emitConstraints(regionConstraints, "region", regionConstraintCode, + ErrorStreamType::InString); } void StaticVerifierFunctionEmitter::emitPatternConstraints() { @@ -270,13 +337,14 @@ void StaticVerifierFunctionEmitter::emitPatternConstraints() { for (auto &it : typeConstraints) { os << formatv(patternConstraintCode, it.second, tgfmt(it.first.getConditionTemplate(), &ctx), - escapeString(it.first.getSummary()), "::mlir::Type type"); + buildErrorStreamingString(it.first.getSummary(), ctx), + "::mlir::Type type"); } ctx.withSelf("attr"); for (auto &it : attrConstraints) { os << formatv(patternConstraintCode, it.second, tgfmt(it.first.getConditionTemplate(), &ctx), - escapeString(it.first.getSummary()), + buildErrorStreamingString(it.first.getSummary(), ctx), "::mlir::Attribute attr"); } ctx.withSelf("prop"); @@ -291,7 +359,7 @@ void StaticVerifierFunctionEmitter::emitPatternConstraints() { } os << formatv(patternConstraintCode, it.second, tgfmt(propConstraint.getConditionTemplate(), &ctx), - escapeString(propConstraint.getSummary()), + buildErrorStreamingString(propConstraint.getSummary(), ctx), Twine(interfaceType) + " prop"); } } diff --git a/mlir/test/mlir-tblgen/constraint-unique.td b/mlir/test/mlir-tblgen/constraint-unique.td index d51e1a5f..3f2e5cd 100644 --- a/mlir/test/mlir-tblgen/constraint-unique.td +++ b/mlir/test/mlir-tblgen/constraint-unique.td @@ -16,7 +16,7 @@ def AType : Type<ATypePred, "a type">; def OtherType : Type<ATypePred, "another type">; def AnAttrPred : CPred<"attrPred($_self, $_op)">; -def AnAttr : Attr<AnAttrPred, "an attribute">; +def AnAttr : Attr<AnAttrPred, "an attribute (got {{reformat($_self)}})">; def OtherAttr : Attr<AnAttrPred, "another attribute">; def ASuccessorPred : CPred<"successorPred($_self, $_op)">; @@ -24,7 +24,7 @@ def ASuccessor : Successor<ASuccessorPred, "a successor">; def OtherSuccessor : Successor<ASuccessorPred, "another successor">; def ARegionPred : CPred<"regionPred($_self, $_op)">; -def ARegion : Region<ARegionPred, "a region">; +def ARegion : Region<ARegionPred, "a region ({{find(foo)}})">; def OtherRegion : Region<ARegionPred, "another region">; // OpA and OpB have the same type, attribute, successor, and region constraints. @@ -71,10 +71,10 @@ def OpC : NS_Op<"op_c"> { // CHECK: static ::llvm::LogicalResult [[$A_ATTR_CONSTRAINT:__mlir_ods_local_attr_constraint.*]]( // CHECK: if (attr && !((attrPred(attr, *op)))) // CHECK-NEXT: return emitError() << "attribute '" << attrName -// CHECK-NEXT: << "' failed to satisfy constraint: an attribute"; +// CHECK-NEXT: << "' failed to satisfy constraint: an attribute (got " << reformat(attr) << ")"; /// Test that duplicate attribute constraint was not generated. -// CHECK-NOT: << "' failed to satisfy constraint: an attribute"; +// CHECK-NOT: << "' failed to satisfy constraint: an attribute /// Test that a attribute constraint with a different description was generated. // CHECK: static ::llvm::LogicalResult [[$O_ATTR_CONSTRAINT:__mlir_ods_local_attr_constraint.*]]( @@ -103,7 +103,7 @@ def OpC : NS_Op<"op_c"> { // CHECK: if (!((regionPred(region, *op)))) { // CHECK-NEXT: return op->emitOpError("region #") << regionIndex // CHECK-NEXT: << (regionName.empty() ? " " : " ('" + regionName + "') ") -// CHECK-NEXT: << "failed to verify constraint: a region"; +// CHECK-NEXT: << "failed to verify constraint: a region (" << find(foo) << ")"; /// Test that duplicate region constraint was not generated. // CHECK-NOT: << "failed to verify constraint: a region"; diff --git a/mlir/test/mlir-tblgen/op-attribute.td b/mlir/test/mlir-tblgen/op-attribute.td index 549830e..a3cb9a4 100644 --- a/mlir/test/mlir-tblgen/op-attribute.td +++ b/mlir/test/mlir-tblgen/op-attribute.td @@ -69,19 +69,19 @@ def AOp : NS_Op<"a_op", []> { // DEF: ::llvm::LogicalResult AOpAdaptor::verify // DEF-NEXT: auto tblgen_aAttr = getProperties().aAttr; (void)tblgen_aAttr; -// DEF-NEXT: if (!tblgen_aAttr) return emitError(loc, "'test.a_op' op ""requires attribute 'aAttr'"); +// DEF-NEXT: if (!tblgen_aAttr) return emitError(loc, "'test.a_op' op requires attribute 'aAttr'"); // DEF-NEXT: auto tblgen_bAttr = getProperties().bAttr; (void)tblgen_bAttr; // DEF-NEXT: auto tblgen_cAttr = getProperties().cAttr; (void)tblgen_cAttr; // DEF-NEXT: auto tblgen_dAttr = getProperties().dAttr; (void)tblgen_dAttr; // DEF: if (tblgen_aAttr && !((some-condition))) -// DEF-NEXT: return emitError(loc, "'test.a_op' op ""attribute 'aAttr' failed to satisfy constraint: some attribute kind"); +// DEF-NEXT: return emitError(loc, "'test.a_op' op attribute 'aAttr' failed to satisfy constraint: some attribute kind"); // DEF: if (tblgen_bAttr && !((some-condition))) -// DEF-NEXT: return emitError(loc, "'test.a_op' op ""attribute 'bAttr' failed to satisfy constraint: some attribute kind"); +// DEF-NEXT: return emitError(loc, "'test.a_op' op attribute 'bAttr' failed to satisfy constraint: some attribute kind"); // DEF: if (tblgen_cAttr && !((some-condition))) -// DEF-NEXT: return emitError(loc, "'test.a_op' op ""attribute 'cAttr' failed to satisfy constraint: some attribute kind"); +// DEF-NEXT: return emitError(loc, "'test.a_op' op attribute 'cAttr' failed to satisfy constraint: some attribute kind"); // DEF: if (tblgen_dAttr && !((some-condition))) -// DEF-NEXT: return emitError(loc, "'test.a_op' op ""attribute 'dAttr' failed to satisfy constraint: some attribute kind"); +// DEF-NEXT: return emitError(loc, "'test.a_op' op attribute 'dAttr' failed to satisfy constraint: some attribute kind"); // Test getter methods // --- @@ -219,13 +219,13 @@ def AgetOp : Op<Test2_Dialect, "a_get_op", []> { // DEF: ::llvm::LogicalResult AgetOpAdaptor::verify // DEF: auto tblgen_aAttr = getProperties().aAttr; (void)tblgen_aAttr; -// DEF: if (!tblgen_aAttr) return emitError(loc, "'test2.a_get_op' op ""requires attribute 'aAttr'"); +// DEF: if (!tblgen_aAttr) return emitError(loc, "'test2.a_get_op' op requires attribute 'aAttr'"); // DEF: auto tblgen_bAttr = getProperties().bAttr; (void)tblgen_bAttr; // DEF: auto tblgen_cAttr = getProperties().cAttr; (void)tblgen_cAttr; // DEF: if (tblgen_bAttr && !((some-condition))) -// DEF-NEXT: return emitError(loc, "'test2.a_get_op' op ""attribute 'bAttr' failed to satisfy constraint: some attribute kind"); +// DEF-NEXT: return emitError(loc, "'test2.a_get_op' op attribute 'bAttr' failed to satisfy constraint: some attribute kind"); // DEF: if (tblgen_cAttr && !((some-condition))) -// DEF-NEXT: return emitError(loc, "'test2.a_get_op' op ""attribute 'cAttr' failed to satisfy constraint: some attribute kind"); +// DEF-NEXT: return emitError(loc, "'test2.a_get_op' op attribute 'cAttr' failed to satisfy constraint: some attribute kind"); // Test getter methods // --- diff --git a/mlir/test/mlir-tblgen/op-properties-predicates.td b/mlir/test/mlir-tblgen/op-properties-predicates.td index af09ee7..7cc9633 100644 --- a/mlir/test/mlir-tblgen/op-properties-predicates.td +++ b/mlir/test/mlir-tblgen/op-properties-predicates.td @@ -74,7 +74,7 @@ def OpWithPredicates : NS_Op<"op_with_predicates"> { // Note: comprehensive emission of verifiers is tested in verifyINvariantsImpl() below // CHECK: int64_t tblgen_scalar = this->getScalar(); // CHECK: if (!((tblgen_scalar >= 0))) -// CHECK: return emitError(loc, "'test.op_with_predicates' op ""property 'scalar' failed to satisfy constraint: non-negative int64_t"); +// CHECK: return emitError(loc, "'test.op_with_predicates' op property 'scalar' failed to satisfy constraint: non-negative int64_t"); // CHECK-LABEL: OpWithPredicates::verifyInvariantsImpl() // Note: for test readability, we capture [[maybe_unused]] into the variable maybe_unused diff --git a/mlir/test/mlir-tblgen/predicate.td b/mlir/test/mlir-tblgen/predicate.td index c1fcd3f..41e041f 100644 --- a/mlir/test/mlir-tblgen/predicate.td +++ b/mlir/test/mlir-tblgen/predicate.td @@ -55,7 +55,7 @@ def OpF : NS_Op<"op_for_int_min_val", []> { // CHECK-LABEL: OpFAdaptor::verify // CHECK: (::llvm::cast<::mlir::IntegerAttr>(tblgen_attr).getInt() >= 10) -// CHECK-NEXT: "attribute 'attr' failed to satisfy constraint: 32-bit signless integer attribute whose minimum value is 10" +// CHECK-NEXT: attribute 'attr' failed to satisfy constraint: 32-bit signless integer attribute whose minimum value is 10" def OpFX : NS_Op<"op_for_int_max_val", []> { let arguments = (ins ConfinedAttr<I32Attr, [IntMaxValue<10>]>:$attr); @@ -63,7 +63,7 @@ def OpFX : NS_Op<"op_for_int_max_val", []> { // CHECK-LABEL: OpFXAdaptor::verify // CHECK: (::llvm::cast<::mlir::IntegerAttr>(tblgen_attr).getInt() <= 10) -// CHECK-NEXT: "attribute 'attr' failed to satisfy constraint: 32-bit signless integer attribute whose maximum value is 10" +// CHECK-NEXT: attribute 'attr' failed to satisfy constraint: 32-bit signless integer attribute whose maximum value is 10" def OpG : NS_Op<"op_for_arr_min_count", []> { let arguments = (ins ConfinedAttr<ArrayAttr, [ArrayMinCount<8>]>:$attr); @@ -71,7 +71,7 @@ def OpG : NS_Op<"op_for_arr_min_count", []> { // CHECK-LABEL: OpGAdaptor::verify // CHECK: (::llvm::cast<::mlir::ArrayAttr>(tblgen_attr).size() >= 8) -// CHECK-NEXT: "attribute 'attr' failed to satisfy constraint: array attribute with at least 8 elements" +// CHECK-NEXT: attribute 'attr' failed to satisfy constraint: array attribute with at least 8 elements" def OpH : NS_Op<"op_for_arr_value_at_index", []> { let arguments = (ins ConfinedAttr<ArrayAttr, [IntArrayNthElemEq<0, 8>]>:$attr); @@ -79,7 +79,7 @@ def OpH : NS_Op<"op_for_arr_value_at_index", []> { // CHECK-LABEL: OpHAdaptor::verify // CHECK: (((::llvm::cast<::mlir::ArrayAttr>(tblgen_attr).size() > 0)) && ((::llvm::cast<::mlir::IntegerAttr>(::llvm::cast<::mlir::ArrayAttr>(tblgen_attr)[0]).getInt() == 8))))) -// CHECK-NEXT: "attribute 'attr' failed to satisfy constraint: array attribute whose 0-th element must be 8" +// CHECK-NEXT: attribute 'attr' failed to satisfy constraint: array attribute whose 0-th element must be 8" def OpI: NS_Op<"op_for_arr_min_value_at_index", []> { let arguments = (ins ConfinedAttr<ArrayAttr, [IntArrayNthElemMinValue<0, 8>]>:$attr); @@ -87,7 +87,7 @@ def OpI: NS_Op<"op_for_arr_min_value_at_index", []> { // CHECK-LABEL: OpIAdaptor::verify // CHECK: (((::llvm::cast<::mlir::ArrayAttr>(tblgen_attr).size() > 0)) && ((::llvm::cast<::mlir::IntegerAttr>(::llvm::cast<::mlir::ArrayAttr>(tblgen_attr)[0]).getInt() >= 8))))) -// CHECK-NEXT: "attribute 'attr' failed to satisfy constraint: array attribute whose 0-th element must be at least 8" +// CHECK-NEXT: attribute 'attr' failed to satisfy constraint: array attribute whose 0-th element must be at least 8" def OpJ: NS_Op<"op_for_arr_max_value_at_index", []> { let arguments = (ins ConfinedAttr<ArrayAttr, [IntArrayNthElemMaxValue<0, 8>]>:$attr); @@ -95,7 +95,7 @@ def OpJ: NS_Op<"op_for_arr_max_value_at_index", []> { // CHECK-LABEL: OpJAdaptor::verify // CHECK: (((::llvm::cast<::mlir::ArrayAttr>(tblgen_attr).size() > 0)) && ((::llvm::cast<::mlir::IntegerAttr>(::llvm::cast<::mlir::ArrayAttr>(tblgen_attr)[0]).getInt() <= 8))))) -// CHECK-NEXT: "attribute 'attr' failed to satisfy constraint: array attribute whose 0-th element must be at most 8" +// CHECK-NEXT: attribute 'attr' failed to satisfy constraint: array attribute whose 0-th element must be at most 8" def OpK: NS_Op<"op_for_arr_in_range_at_index", []> { let arguments = (ins ConfinedAttr<ArrayAttr, [IntArrayNthElemInRange<0, 4, 8>]>:$attr); @@ -103,7 +103,7 @@ def OpK: NS_Op<"op_for_arr_in_range_at_index", []> { // CHECK-LABEL: OpKAdaptor::verify // CHECK: (((::llvm::cast<::mlir::ArrayAttr>(tblgen_attr).size() > 0)) && ((::llvm::cast<::mlir::IntegerAttr>(::llvm::cast<::mlir::ArrayAttr>(tblgen_attr)[0]).getInt() >= 4)) && ((::llvm::cast<::mlir::IntegerAttr>(::llvm::cast<::mlir::ArrayAttr>(tblgen_attr)[0]).getInt() <= 8))))) -// CHECK-NEXT: "attribute 'attr' failed to satisfy constraint: array attribute whose 0-th element must be at least 4 and at most 8" +// CHECK-NEXT: attribute 'attr' failed to satisfy constraint: array attribute whose 0-th element must be at least 4 and at most 8" def OpL: NS_Op<"op_for_TCopVTEtAreSameAt", [ PredOpTrait<"operands indexed at 0, 2, 3 should all have " @@ -121,7 +121,7 @@ def OpL: NS_Op<"op_for_TCopVTEtAreSameAt", [ // CHECK: ::llvm::all_equal(::llvm::map_range( // CHECK-SAME: ::mlir::ArrayRef<unsigned>({0, 2, 3}), // CHECK-SAME: [this](unsigned i) { return getElementTypeOrSelf(this->getOperand(i)); })) -// CHECK: "failed to verify that operands indexed at 0, 2, 3 should all have the same type" +// CHECK: failed to verify that operands indexed at 0, 2, 3 should all have the same type" def OpM : NS_Op<"op_for_AnyTensorOf", []> { let arguments = (ins TensorOf<[F32, I32]>:$x); diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp index 4d9b1b2..3b10842 100644 --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -17,6 +17,7 @@ #include "OpGenHelpers.h" #include "mlir/TableGen/Argument.h" #include "mlir/TableGen/Attribute.h" +#include "mlir/TableGen/Builder.h" #include "mlir/TableGen/Class.h" #include "mlir/TableGen/CodeGenHelpers.h" #include "mlir/TableGen/Format.h" @@ -24,16 +25,24 @@ #include "mlir/TableGen/Interfaces.h" #include "mlir/TableGen/Operator.h" #include "mlir/TableGen/Property.h" +#include "mlir/TableGen/Region.h" #include "mlir/TableGen/SideEffects.h" +#include "mlir/TableGen/Successor.h" #include "mlir/TableGen/Trait.h" #include "llvm/ADT/BitVector.h" #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Sequence.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/CodeGenHelpers.h" @@ -380,9 +389,8 @@ public: Formatter emitErrorPrefix() const { return [this](raw_ostream &os) -> raw_ostream & { if (emitForOp) - return os << "emitOpError("; - return os << formatv("emitError(loc, \"'{0}' op \"", - op.getOperationName()); + return os << "emitOpError(\""; + return os << formatv("emitError(loc, \"'{0}' op ", op.getOperationName()); }; } @@ -940,7 +948,7 @@ genAttributeVerifier(const OpOrAdaptorHelper &emitHelper, FmtContext &ctx, // {4}: Attribute/constraint description. const char *const verifyAttrInline = R"( if ({0} && !({1})) - return {2}"attribute '{3}' failed to satisfy constraint: {4}"); + return {2}attribute '{3}' failed to satisfy constraint: {4}"); )"; // Verify the attribute using a uniqued constraint. Can only be used within // the context of an op. @@ -993,10 +1001,11 @@ while (true) {{ (constraintFn = staticVerifierEmitter.getAttrConstraintFn(attr))) { body << formatv(verifyAttrUnique, *constraintFn, varName, attrName); } else { - body << formatv(verifyAttrInline, varName, - tgfmt(condition, &ctx.withSelf(varName)), - emitHelper.emitErrorPrefix(), attrName, - escapeString(attr.getSummary())); + body << formatv( + verifyAttrInline, varName, tgfmt(condition, &ctx.withSelf(varName)), + emitHelper.emitErrorPrefix(), attrName, + buildErrorStreamingString(attr.getSummary(), ctx.withSelf(varName), + ErrorStreamType::InsideOpError)); } }; @@ -1017,7 +1026,7 @@ while (true) {{ it.first); if (metadata.isRequired) body << formatv( - "if (!tblgen_{0}) return {1}\"requires attribute '{0}'\");\n", + "if (!tblgen_{0}) return {1}requires attribute '{0}'\");\n", it.first, emitHelper.emitErrorPrefix()); } } else { @@ -1099,7 +1108,7 @@ static void genPropertyVerifier( // {3}: Property description. const char *const verifyPropertyInline = R"( if (!({0})) - return {1}"property '{2}' failed to satisfy constraint: {3}"); + return {1}property '{2}' failed to satisfy constraint: {3}"); )"; // Verify the property using a uniqued constraint. Can only be used @@ -1143,9 +1152,12 @@ static void genPropertyVerifier( if (uniquedFn.has_value() && emitHelper.isEmittingForOp()) body << formatv(verifyPropertyUniqued, *uniquedFn, varName, prop.name); else - body << formatv( - verifyPropertyInline, tgfmt(rawCondition, &ctx.withSelf(varName)), - emitHelper.emitErrorPrefix(), prop.name, prop.prop.getSummary()); + body << formatv(verifyPropertyInline, + tgfmt(rawCondition, &ctx.withSelf(varName)), + emitHelper.emitErrorPrefix(), prop.name, + buildErrorStreamingString( + prop.prop.getSummary(), ctx.withSelf(varName), + ErrorStreamType::InsideOpError)); } } diff --git a/mlir/unittests/TableGen/CMakeLists.txt b/mlir/unittests/TableGen/CMakeLists.txt index c51bda6..4d8e508 100644 --- a/mlir/unittests/TableGen/CMakeLists.txt +++ b/mlir/unittests/TableGen/CMakeLists.txt @@ -25,6 +25,6 @@ target_include_directories(MLIRTableGenTests ) target_link_libraries(MLIRTableGenTests - PRIVATE MLIRTableGen MLIRIR + PRIVATE LLVMTableGen MLIRTableGen MLIRIR PUBLIC MLIRTestDialect ) |
