summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-08-19 20:17:23 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-08-19 20:17:23 +0000
commit11cb5385a9646d430cb712e4950f16b25ac44065 (patch)
tree4a2d84aa8ed802c0f9fa2a1d2e3c32251b4e6914
parentb16734fbaa1b0a70c8349414239d1484e99fd018 (diff)
downloadbcm5719-llvm-11cb5385a9646d430cb712e4950f16b25ac44065.tar.gz
bcm5719-llvm-11cb5385a9646d430cb712e4950f16b25ac44065.zip
Reapply "ADT: Tidy up ilist_traits static asserts, NFC"
This spiritually reapplies r279012 (reverted in r279052) without the r278974 parts. The differences: - Only the HasGetNext trait exists here, so I've only cleaned up (and tested) it. I still added HasObsoleteCustomization since I know this will be expanding when r278974 is reapplied. - I changed the unit tests to use static_assert to catch problems earlier in the build. - I added negative tests for the type traits. Original commit message follows. ---- Change the ilist traits to use decltype instead of sizeof, and add HasObsoleteCustomization so that additions to this list don't need to be added in two places. I suspect this will now work with MSVC, since the trait tested in r278991 seems to work. If for some reason it continues to fail on Windows I'll follow up by adding back the #ifndef _MSC_VER. llvm-svn: 279312
-rw-r--r--llvm/include/llvm/ADT/ilist.h24
-rw-r--r--llvm/unittests/ADT/ilistTest.cpp21
2 files changed, 34 insertions, 11 deletions
diff --git a/llvm/include/llvm/ADT/ilist.h b/llvm/include/llvm/ADT/ilist.h
index 3723039bbad..f64413d5869 100644
--- a/llvm/include/llvm/ADT/ilist.h
+++ b/llvm/include/llvm/ADT/ilist.h
@@ -85,12 +85,15 @@ template <class TraitsT, class NodeT> struct HasGetNext {
template <size_t N> struct SFINAE {};
template <class U>
- static Yes &hasGetNext(
- SFINAE<sizeof(static_cast<NodeT *>(make<U>().getNext(&make<NodeT>())))>
- * = 0);
- template <class U> static No &hasGetNext(...);
+ static Yes &test(U *I, decltype(I->getNext(&make<NodeT>())) * = 0);
+ template <class> static No &test(...);
- static const bool value = sizeof(hasGetNext<TraitsT>(nullptr)) == sizeof(Yes);
+public:
+ static const bool value = sizeof(test<TraitsT>(nullptr)) == sizeof(Yes);
+};
+
+template <class TraitsT, class NodeT> struct HasObsoleteCustomization {
+ static const bool value = HasGetNext<TraitsT, NodeT>::value;
};
} // end namespace ilist_detail
@@ -378,12 +381,11 @@ template<typename NodeTy> struct simplify_type<const ilist_iterator<NodeTy> > {
///
template <typename NodeTy, typename Traits = ilist_traits<NodeTy>>
class iplist : public Traits, ilist_node_access {
-#if !defined(_MSC_VER)
- // FIXME: This fails in MSVC, but it's worth keeping around to help
- // non-Windows users root out bugs in their ilist_traits.
- static_assert(!ilist_detail::HasGetNext<Traits, NodeTy>::value,
- "ilist next and prev links are not customizable!");
-#endif
+ // TODO: Drop this assertion and the transitive type traits anytime after
+ // v4.0 is branched (i.e,. keep them for one release to help out-of-tree code
+ // update).
+ static_assert(!ilist_detail::HasObsoleteCustomization<Traits, NodeTy>::value,
+ "ilist customization points have changed!");
mutable NodeTy *Head;
diff --git a/llvm/unittests/ADT/ilistTest.cpp b/llvm/unittests/ADT/ilistTest.cpp
index b63cfd6310c..c2ad3d0dce3 100644
--- a/llvm/unittests/ADT/ilistTest.cpp
+++ b/llvm/unittests/ADT/ilistTest.cpp
@@ -128,4 +128,25 @@ TEST(ilistTest, UnsafeClear) {
EXPECT_EQ(6, List.back().Value);
}
+struct Empty {};
+TEST(ilistTest, HasObsoleteCustomizationTrait) {
+ // Negative test for HasObsoleteCustomization.
+ static_assert(!ilist_detail::HasObsoleteCustomization<Empty, Node>::value,
+ "Empty has no customizations");
}
+
+struct GetNext {
+ Node *getNext(Node *);
+};
+TEST(ilistTest, HasGetNextTrait) {
+ static_assert(ilist_detail::HasGetNext<GetNext, Node>::value,
+ "GetNext has a getNext(Node*)");
+ static_assert(ilist_detail::HasObsoleteCustomization<GetNext, Node>::value,
+ "Empty should be obsolete because of getNext()");
+
+ // Negative test for HasGetNext.
+ static_assert(!ilist_detail::HasGetNext<Empty, Node>::value,
+ "Empty does not have a getNext(Node*)");
+}
+
+} // end namespace
OpenPOWER on IntegriCloud