================ @@ -3906,14 +4028,50 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, CodeGenTypes &Types = CGM.getTypes(); llvm::FunctionType *MethodTy = Types.GetFunctionType(Types.arrangeObjCMethodDeclaration(OMD)); - std::string FunctionName = getSymbolNameForMethod(OMD); - - llvm::Function *Method - = llvm::Function::Create(MethodTy, - llvm::GlobalValue::InternalLinkage, - FunctionName, - &TheModule); - return Method; + + bool isDirect = OMD->isDirectMethod(); + std::string FunctionName = + getSymbolNameForMethod(OMD, /*include category*/ !isDirect); + + if (!isDirect) + return llvm::Function::Create(MethodTy, + llvm::GlobalVariable::InternalLinkage, + FunctionName, &TheModule); + + auto *COMD = OMD->getCanonicalDecl(); + auto I = DirectMethodDefinitions.find(COMD); + llvm::Function *OldFn = nullptr, *Fn = nullptr; + + if (I != DirectMethodDefinitions.end()) { + // Objective-C allows for the declaration and implementation types + // to differ slightly. + // + // If we're being asked for the Function associated for a method + // implementation, a previous value might have been cached + // based on the type of the canonical declaration. + // + // If these do not match, then we'll replace this function with + // a new one that has the proper type below. + if (!OMD->getBody() || COMD->getReturnType() == OMD->getReturnType()) + return I->second; + OldFn = I->second; + } + + if (OldFn) { + Fn = llvm::Function::Create(MethodTy, llvm::GlobalValue::ExternalLinkage, + "", &CGM.getModule()); + Fn->takeName(OldFn); + OldFn->replaceAllUsesWith(Fn); + OldFn->eraseFromParent(); + + // Replace the cached function in the map. + I->second = Fn; + } else { + Fn = llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage, + FunctionName, &TheModule); + DirectMethodDefinitions.insert(std::make_pair(COMD, Fn)); + } + return Fn; ---------------- compnerd wrote:
Feels like this would be clearer as: ```c++ if (I == DirectMethodDefinitions.end()) { auto *F = llvm::Function::Create(MethodTy, llvm::GlobalVariable::ExternalLinkage, FunctionName, &TheModule); DirectMethodDefinitions.insert(std::make_pair(COMD, F)); return F; } // Objective-C allows for ... ``` That will merge the block on L4061-4068, with L4046-4057. https://github.com/llvm/llvm-project/pull/78030 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits