1212// ===----------------------------------------------------------------------===//
1313
1414#include " mlir/TableGen/CodeGenHelpers.h"
15+ #include " mlir/Support/LLVM.h"
16+ #include " mlir/TableGen/Argument.h"
17+ #include " mlir/TableGen/Attribute.h"
18+ #include " mlir/TableGen/Format.h"
1519#include " mlir/TableGen/Operator.h"
1620#include " mlir/TableGen/Pattern.h"
21+ #include " mlir/TableGen/Property.h"
22+ #include " mlir/TableGen/Region.h"
23+ #include " mlir/TableGen/Successor.h"
24+ #include " llvm/ADT/StringExtras.h"
25+ #include " llvm/ADT/StringRef.h"
1726#include " llvm/Support/FormatVariadic.h"
1827#include " llvm/Support/Path.h"
28+ #include " llvm/Support/raw_ostream.h"
1929#include " llvm/TableGen/CodeGenHelpers.h"
30+ #include " llvm/TableGen/Error.h"
2031#include " llvm/TableGen/Record.h"
32+ #include < cassert>
33+ #include < optional>
34+ #include < string>
2135
2236using namespace llvm ;
2337using namespace mlir ;
@@ -112,6 +126,55 @@ StringRef StaticVerifierFunctionEmitter::getRegionConstraintFn(
112126// Constraint Emission
113127// ===----------------------------------------------------------------------===//
114128
129+ // / Helper to generate a C++ string expression from a given message.
130+ // / Message can contain '{{...}}' placeholders that are substituted with
131+ // / C-expressions via tgfmt.
132+ std::string mlir::tblgen::buildErrorStreamingString (
133+ StringRef message, const FmtContext &ctx, ErrorStreamType errorStreamType) {
134+ std::string result;
135+ raw_string_ostream os (result);
136+
137+ std::string msgStr = escapeString (message);
138+ StringRef msg = msgStr;
139+
140+ // Split the message by '{{' and '}}' and build a streaming expression.
141+ auto split = msg.split (" {{" );
142+ os << split.first ;
143+ if (split.second .empty ()) {
144+ return msgStr;
145+ }
146+
147+ if (errorStreamType == ErrorStreamType::InsideOpError)
148+ os << " \" )" ;
149+ else
150+ os << ' "' ;
151+
152+ msg = split.second ;
153+ while (!msg.empty ()) {
154+ split = msg.split (" }}" );
155+ StringRef var = split.first ;
156+ StringRef rest = split.second ;
157+
158+ os << " << " << tgfmt (var, &ctx);
159+
160+ if (rest.empty ())
161+ break ;
162+
163+ split = rest.split (" {{" );
164+ if (split.second .empty () &&
165+ errorStreamType == ErrorStreamType::InsideOpError) {
166+ // To enable having part of string post, this adds a parenthesis before
167+ // the last string segment to match the existing one.
168+ os << " << (\" " << split.first ;
169+ } else {
170+ os << " << \" " << split.first ;
171+ }
172+ msg = split.second ;
173+ }
174+
175+ return os.str ();
176+ }
177+
115178// / Code templates for emitting type, attribute, successor, and region
116179// / constraints. Each of these templates require the following arguments:
117180// /
@@ -224,22 +287,24 @@ static ::llvm::LogicalResult {0}(
224287
225288void StaticVerifierFunctionEmitter::emitConstraints (
226289 const ConstraintMap &constraints, StringRef selfName,
227- const char *const codeTemplate) {
290+ const char *const codeTemplate, ErrorStreamType errorStreamType ) {
228291 FmtContext ctx;
229292 ctx.addSubst (" _op" , " *op" ).withSelf (selfName);
293+
230294 for (auto &it : constraints) {
231295 os << formatv (codeTemplate, it.second ,
232296 tgfmt (it.first .getConditionTemplate (), &ctx),
233- escapeString (it.first .getSummary ()));
297+ buildErrorStreamingString (it.first .getSummary (), ctx ));
234298 }
235299}
236-
237300void StaticVerifierFunctionEmitter::emitTypeConstraints () {
238- emitConstraints (typeConstraints, " type" , typeConstraintCode);
301+ emitConstraints (typeConstraints, " type" , typeConstraintCode,
302+ ErrorStreamType::InString);
239303}
240304
241305void StaticVerifierFunctionEmitter::emitAttrConstraints () {
242- emitConstraints (attrConstraints, " attr" , attrConstraintCode);
306+ emitConstraints (attrConstraints, " attr" , attrConstraintCode,
307+ ErrorStreamType::InString);
243308}
244309
245310// / Unlike with the other helpers, this one has to substitute in the interface
@@ -251,17 +316,19 @@ void StaticVerifierFunctionEmitter::emitPropConstraints() {
251316 auto propConstraint = cast<PropConstraint>(it.first );
252317 os << formatv (propConstraintCode, it.second ,
253318 tgfmt (propConstraint.getConditionTemplate (), &ctx),
254- escapeString (it.first .getSummary ()),
319+ buildErrorStreamingString (it.first .getSummary (), ctx ),
255320 propConstraint.getInterfaceType ());
256321 }
257322}
258323
259324void StaticVerifierFunctionEmitter::emitSuccessorConstraints () {
260- emitConstraints (successorConstraints, " successor" , successorConstraintCode);
325+ emitConstraints (successorConstraints, " successor" , successorConstraintCode,
326+ ErrorStreamType::InString);
261327}
262328
263329void StaticVerifierFunctionEmitter::emitRegionConstraints () {
264- emitConstraints (regionConstraints, " region" , regionConstraintCode);
330+ emitConstraints (regionConstraints, " region" , regionConstraintCode,
331+ ErrorStreamType::InString);
265332}
266333
267334void StaticVerifierFunctionEmitter::emitPatternConstraints () {
@@ -270,13 +337,14 @@ void StaticVerifierFunctionEmitter::emitPatternConstraints() {
270337 for (auto &it : typeConstraints) {
271338 os << formatv (patternConstraintCode, it.second ,
272339 tgfmt (it.first .getConditionTemplate (), &ctx),
273- escapeString (it.first .getSummary ()), " ::mlir::Type type" );
340+ buildErrorStreamingString (it.first .getSummary (), ctx),
341+ " ::mlir::Type type" );
274342 }
275343 ctx.withSelf (" attr" );
276344 for (auto &it : attrConstraints) {
277345 os << formatv (patternConstraintCode, it.second ,
278346 tgfmt (it.first .getConditionTemplate (), &ctx),
279- escapeString (it.first .getSummary ()),
347+ buildErrorStreamingString (it.first .getSummary (), ctx ),
280348 " ::mlir::Attribute attr" );
281349 }
282350 ctx.withSelf (" prop" );
@@ -291,7 +359,7 @@ void StaticVerifierFunctionEmitter::emitPatternConstraints() {
291359 }
292360 os << formatv (patternConstraintCode, it.second ,
293361 tgfmt (propConstraint.getConditionTemplate (), &ctx),
294- escapeString (propConstraint.getSummary ()),
362+ buildErrorStreamingString (propConstraint.getSummary (), ctx ),
295363 Twine (interfaceType) + " prop" );
296364 }
297365}
0 commit comments