@@ -789,6 +789,14 @@ class OpEmitter {
789789 Method *genOpInterfaceMethod (const tblgen::InterfaceMethod &method,
790790 bool declaration = true );
791791
792+ // Generate a `using` declaration for the op interface method to include
793+ // the default implementation from the interface trait.
794+ // This is needed when the interface defines multiple methods with the same
795+ // name, but some have a default implementation and some don't.
796+ UsingDeclaration *
797+ genOpInterfaceMethodUsingDecl (const tblgen::InterfaceTrait *opTrait,
798+ const tblgen::InterfaceMethod &method);
799+
792800 // Generate the side effect interface methods.
793801 void genSideEffectInterfaceMethods ();
794802
@@ -815,6 +823,10 @@ class OpEmitter {
815823
816824 // Helper for emitting op code.
817825 OpOrAdaptorHelper emitHelper;
826+
827+ // Keep track of the interface using declarations that have been generated to
828+ // avoid duplicates.
829+ llvm::StringSet<> interfaceUsingNames;
818830};
819831
820832} // namespace
@@ -3672,8 +3684,10 @@ void OpEmitter::genOpInterfaceMethods(const tblgen::InterfaceTrait *opTrait) {
36723684 // Don't declare if the method has a default implementation and the op
36733685 // didn't request that it always be declared.
36743686 if (method.getDefaultImplementation () &&
3675- !alwaysDeclaredMethods.count (method.getName ()))
3687+ !alwaysDeclaredMethods.count (method.getName ())) {
3688+ genOpInterfaceMethodUsingDecl (opTrait, method);
36763689 continue ;
3690+ }
36773691 // Interface methods are allowed to overlap with existing methods, so don't
36783692 // check if pruned.
36793693 (void )genOpInterfaceMethod (method);
@@ -3692,6 +3706,17 @@ Method *OpEmitter::genOpInterfaceMethod(const InterfaceMethod &method,
36923706 std::move (paramList));
36933707}
36943708
3709+ UsingDeclaration *
3710+ OpEmitter::genOpInterfaceMethodUsingDecl (const tblgen::InterfaceTrait *opTrait,
3711+ const InterfaceMethod &method) {
3712+ std::string name = (llvm::Twine (opTrait->getFullyQualifiedTraitName ()) + " <" +
3713+ op.getQualCppClassName () + " >::" + method.getName ())
3714+ .str ();
3715+ if (interfaceUsingNames.insert (name).second )
3716+ return opClass.declare <UsingDeclaration>(std::move (name));
3717+ return nullptr ;
3718+ }
3719+
36953720void OpEmitter::genOpInterfaceMethods () {
36963721 for (const auto &trait : op.getTraits ()) {
36973722 if (const auto *opTrait = dyn_cast<tblgen::InterfaceTrait>(&trait))
0 commit comments