[PATCH] D73208: [objc_direct] fix codegen for mismatched Decl/Impl return types
Duncan P. N. Exon Smith via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Jan 30 12:58:01 PST 2020
dexonsmith added a comment.
In D73208#1837909 <https://reviews.llvm.org/D73208#1837909>, @MadCoder wrote:
> In D73208#1836789 <https://reviews.llvm.org/D73208#1836789>, @dexonsmith wrote:
>
> > I think we're talking across each other. The idea is check the type when generating the implementation; if it's not correct, you fix it (need to update existing uses to bitcast). So the type used for the implementation would match dynamic methods.
>
>
> ah I see, I don't know how to do that, I couldn't figure out how to fix the function declaration, if you want to give it a stab I'd love it.
I missed that question until now. This uses `llvm::Value::replaceAllUsesWith`, if you `git grep` through clang you'll find examples.
Here's one from `CodeGenFunction::AddInitializerToStaticVarDecl`:
// The initializer may differ in type from the global. Rewrite
// the global to match the initializer. (We have to do this
// because some types, like unions, can't be completely represented
// in the LLVM type system.)
if (GV->getType()->getElementType() != Init->getType()) {
llvm::GlobalVariable *OldGV = GV;
GV = new llvm::GlobalVariable(CGM.getModule(), Init->getType(),
OldGV->isConstant(),
OldGV->getLinkage(), Init, "",
/*InsertBefore*/ OldGV,
OldGV->getThreadLocalMode(),
CGM.getContext().getTargetAddressSpace(D.getType()));
GV->setVisibility(OldGV->getVisibility());
GV->setDSOLocal(OldGV->isDSOLocal());
GV->setComdat(OldGV->getComdat());
// Steal the name of the old global
GV->takeName(OldGV);
// Replace all uses of the old global with the new global
llvm::Constant *NewPtrForOldDecl =
llvm::ConstantExpr::getBitCast(GV, OldGV->getType());
OldGV->replaceAllUsesWith(NewPtrForOldDecl);
// Erase the old global, since it is no longer used.
OldGV->eraseFromParent();
}
This example is analogous to your case. The pattern is:
1. Create the new thing (with no name, or with a temporary/bad name).
2. Steal the name of the old thing.
3. Bitcast from the new thing to the old type.
4. RAUW to replace all uses of the old thing with the bitcast-of-new-thing from (3).
5. Delete the old thing.
The RAUW isn't going to fix up the `DenseMap` you have on the side though, so you'll need to handle that explicitly; likely during step (4) makes sense.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D73208/new/
https://reviews.llvm.org/D73208
More information about the cfe-commits
mailing list