@@ -513,14 +513,57 @@ getCustomBuilderParams(std::initializer_list<MethodParameter> prefix,
513
513
return builderParams;
514
514
}
515
515
516
+ static std::string getSignature (const Method &m) {
517
+ std::string signature;
518
+ llvm::raw_string_ostream os (signature);
519
+ raw_indented_ostream indentedOs (os);
520
+ m.writeDeclTo (indentedOs);
521
+ return signature;
522
+ }
523
+
524
+ static void emitDuplicatedBuilderError (const Method ¤tMethod,
525
+ StringRef methodName,
526
+ const Class &defCls,
527
+ const AttrOrTypeDef &def) {
528
+
529
+ // Try to search for method that makes `get` redundant.
530
+ auto loc = def.getDef ()->getFieldLoc (" builders" );
531
+ for (auto &method : defCls.getMethods ()) {
532
+ if (method->getName () == methodName &&
533
+ method->makesRedundant (currentMethod)) {
534
+ PrintError (loc, llvm::Twine (" builder `" ) + methodName +
535
+ " ` conflicts with an existing builder. " );
536
+ PrintFatalNote (llvm::Twine (" A new builder with signature:\n " ) +
537
+ getSignature (currentMethod) +
538
+ " \n is shadowed by an existing builder with signature:\n " +
539
+ getSignature (*method) +
540
+ " \n Please remove one of the conflicting "
541
+ " definitions." );
542
+ }
543
+ }
544
+
545
+ // This code shouldn't be reached, but leaving this here for potential future
546
+ // use.
547
+ PrintFatalError (loc, " Failed to generate builder " + methodName);
548
+ }
549
+
516
550
void DefGen::emitCustomBuilder (const AttrOrTypeBuilder &builder) {
517
551
// Don't emit a body if there isn't one.
518
552
auto props = builder.getBody () ? Method::Static : Method::StaticDeclaration;
519
553
StringRef returnType = def.getCppClassName ();
520
554
if (std::optional<StringRef> builderReturnType = builder.getReturnType ())
521
555
returnType = *builderReturnType;
522
- Method *m = defCls.addMethod (returnType, " get" , props,
523
- getCustomBuilderParams ({}, builder));
556
+
557
+ llvm::StringRef methodName = " get" ;
558
+ const auto parameters = getCustomBuilderParams ({}, builder);
559
+ Method *m = defCls.addMethod (returnType, methodName, props, parameters);
560
+
561
+ // If method is pruned, report error and terminate.
562
+ if (!m) {
563
+ auto curMethod = Method (returnType, methodName, props, parameters);
564
+ emitDuplicatedBuilderError (curMethod, methodName, defCls, def);
565
+ }
566
+
524
567
if (!builder.getBody ())
525
568
return ;
526
569
@@ -547,11 +590,19 @@ void DefGen::emitCheckedCustomBuilder(const AttrOrTypeBuilder &builder) {
547
590
StringRef returnType = def.getCppClassName ();
548
591
if (std::optional<StringRef> builderReturnType = builder.getReturnType ())
549
592
returnType = *builderReturnType;
550
- Method *m = defCls.addMethod (
551
- returnType, " getChecked" , props,
552
- getCustomBuilderParams (
553
- {{" ::llvm::function_ref<::mlir::InFlightDiagnostic()>" , " emitError" }},
554
- builder));
593
+
594
+ llvm::StringRef methodName = " getChecked" ;
595
+ auto parameters = getCustomBuilderParams (
596
+ {{" ::llvm::function_ref<::mlir::InFlightDiagnostic()>" , " emitError" }},
597
+ builder);
598
+ Method *m = defCls.addMethod (returnType, methodName, props, parameters);
599
+
600
+ // If method is pruned, report error and terminate.
601
+ if (!m) {
602
+ auto curMethod = Method (returnType, methodName, props, parameters);
603
+ emitDuplicatedBuilderError (curMethod, methodName, defCls, def);
604
+ }
605
+
555
606
if (!builder.getBody ())
556
607
return ;
557
608
0 commit comments