This is an archive of the discontinued LLVM Phabricator instance.

Add support for unique_ptr<T> to dyn_cast<>
ClosedPublic

Authored by zturner on Apr 10 2017, 10:14 AM.

Details

Summary

Currently it's possible to take a T* and cast it to a U* using llvm's casting mechanics, but it's not possible to take a std::unique_ptr<T> and cast it to a std::unique_ptr<U> even if they are compatible. This patch adds this functionality.

I tried to modify the cast macros as well as the dyn_cast macros, but honestly the template mechanics started getting a little hairy and I wasn't able to get it working. Upon further reflection, I decided that maybe we don't even want that behavior anyway, since if T is not a U, then no good can possibly come of casting it to one in the face of unique_ptr's RAII semantics. So hopefully I can get this in without adding cast<>() functionality, and then if/when someone actually needs cast functionality in the future, they can revisit this.

Diff Detail

Event Timeline

zturner created this revision.Apr 10 2017, 10:14 AM
zturner updated this revision to Diff 94746.Apr 10 2017, 2:53 PM
zturner added a reviewer: rsmith.

Discussed this with rsmith@ some, and we came to the conclusion that it's actually the other way around. We should support this only for cast, and not for dyn_cast. The reason being that you would need to declare the function as dyn_cast(unique_ptr<T> &&Value), and so to invoke it you would need to write dyn_cast<To>(std::move(From)). So even though you're writing this as an unconditional move, it's actually a conditional move, because if it's not actually convertible to To then you would want to return nullptr and leave the source unchanged. The code would still work, but it would just be confusing because std::move(From) sometimes doesn't actually move anything.

This patch removes the implementation of dyn_cast<> and adds a version of cast<> which has expected semantics. It moves unconditionally, and just asserts if it's the wrong type.

chandlerc accepted this revision.Apr 10 2017, 3:08 PM

LGTM from me, and thanks for the update around dyn_cast. Maybe wait for Mehdi or some second pair of eyes just to be sure I'm not missing anything.

This revision is now accepted and ready to land.Apr 10 2017, 3:08 PM
zturner updated this revision to Diff 94759.Apr 10 2017, 5:15 PM

Updated this so that isa<B>(const unique_ptr<A>&) works. Will commit tomorrow afternoon if nobody has objections.

This revision was automatically updated to reflect the committed changes.