This is an archive of the discontinued LLVM Phabricator instance.

[Support][NFC] Improve isa implementation
Needs ReviewPublic

Authored by dmitry on Jan 13 2018, 3:28 AM.

Details

Summary

This patch aimed to enhance isa utility by making it more generic and reducing code duplication in its implementation in the same time. It extends isa<T>(value) so that isa works with any dereferenceable and implicitly convertible to bool values (i.e. fancy pointer-like types). It supposed to be a part of the following changes that I propose:

Generalize semantics of isa, cast, dyn_cast to any pointer-like types (i.e. dereferenceable and implicitly convertible to bool) so that:

  • for each fancy_pointer<T> t: isa<G>(t) returns true iff current implementation of isa<G>(nonfancy_t) returns true where decltype(nonfancy_t) is T*
  • all old cast operations should return a raw pointer of type typename std::pointer_traits<fancy_pointer<T>>::element_type * and do not perform ownership transfer.
  • move_[dyn_]cast should do what unique_dyn_cast [ab480f45cd23c08cb9aa3f427aad072df249135f] is currently doing in a more generic manner: it move constructs an object of type typename std::pointer_traits<fancy_pointer<T>>::rebind<G>

N.B. the reference to std::pointer_traits is a conception that was used to explain the behaviour - not necessary the way it would be implemented.

Diff Detail

Event Timeline

dmitry created this revision.Jan 13 2018, 3:28 AM
dmitry edited the summary of this revision. (Show Details)
dmitry edited the summary of this revision. (Show Details)
dmitry edited the summary of this revision. (Show Details)Jan 13 2018, 3:55 AM
dmitry updated this revision to Diff 129758.Jan 13 2018, 4:26 AM
dmitry edited the summary of this revision. (Show Details)Jan 22 2018, 11:12 AM

ping

dmitry updated this revision to Diff 131096.Jan 23 2018, 9:41 AM

Removed dereferenced_type specialization for non-dereferenceable type. Thus we could use detection idiom (e.g. std::experimental:: detected_or) with it in future.

dblaikie added a subscriber: dblaikie.
dblaikie added inline comments.
unittests/Support/Casting.cpp
288–289

Does this change then mean that one could cast<T> from Optional<Derived> to Optional<Base>? Because that'd be problematic, owing to Optional being a value-type. (it'd slice the object)

dmitry added inline comments.Jan 23 2018, 10:50 PM
unittests/Support/Casting.cpp
288–289

This change doesn't modify casts behavior - just isa.
As for the plan, cast should return T*, so

Optional<Derived> DOpt;
Base *b = cast<Base>(DOpt); //Just cast pointer to underlying data to Base*, does not handle potential ownership issues.

should work, but it's ok.
Move cast would be indeed problematic for value-types. So I would probably restrict it.