]> granicus.if.org Git - llvm/commitdiff
Workaround MSVC bug when using TrailingObjects from a template.
authorJames Y Knight <jyknight@google.com>
Tue, 28 Feb 2017 18:05:41 +0000 (18:05 +0000)
committerJames Y Knight <jyknight@google.com>
Tue, 28 Feb 2017 18:05:41 +0000 (18:05 +0000)
MSVC appears to be getting confused as to whether OverloadToken is
supposed to be public or not.

This was discovered by code in Swift, and has been reported to
microsoft by hughbe:
https://connect.microsoft.com/VisualStudio/feedback/details/3116517

Differential Revision: https://reviews.llvm.org/D29880

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296497 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Support/TrailingObjects.h
unittests/Support/TrailingObjectsTest.cpp

index 4d355724149c271861165d7f18aa35dce0074dd3..cb5a52b0d861b121e7312e462fef8f9cf88c8365 100644 (file)
@@ -294,7 +294,14 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
 
 public:
   // Make this (privately inherited) member public.
+#ifndef _MSC_VER
   using ParentType::OverloadToken;
+#else
+  // MSVC bug prevents the above from working, at least up through CL
+  // 19.10.24629.
+  template <typename T>
+  using OverloadToken = typename ParentType::template OverloadToken<T>;
+#endif
 
   /// Returns a pointer to the trailing object array of the given type
   /// (which must be one of those specified in the class template). The
index cb5c47d1b25be444b7117912a102ddfb204ddf25..23acc54d23761149e0a7af1bd8e7d38fb30e70d7 100644 (file)
@@ -236,3 +236,24 @@ TEST(TrailingObjects, Realignment) {
                 reinterpret_cast<char *>(C + 1) + 1, alignof(long))));
 }
 }
+
+// Test the use of TrailingObjects with a template class. This
+// previously failed to compile due to a bug in MSVC's member access
+// control/lookup handling for OverloadToken.
+template <typename Derived>
+class Class5Tmpl : private llvm::TrailingObjects<Derived, float, int> {
+  using TrailingObjects = typename llvm::TrailingObjects<Derived, float>;
+  friend TrailingObjects;
+
+  size_t numTrailingObjects(
+      typename TrailingObjects::template OverloadToken<float>) const {
+    return 1;
+  }
+
+  size_t numTrailingObjects(
+      typename TrailingObjects::template OverloadToken<int>) const {
+    return 2;
+  }
+};
+
+class Class5 : public Class5Tmpl<Class5> {};