[PM] Try to work-around what appears to be an MSVC SFINAE issue with
authorChandler Carruth <chandlerc@gmail.com>
Fri, 19 Aug 2016 09:26:00 +0000 (09:26 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Fri, 19 Aug 2016 09:26:00 +0000 (09:26 +0000)
r279217 where it fails to select the path that other compilers select.

The workaround won't be as careful to produce an error when an analysis
result is incorrect, but we can rely on non-MSVC builds to catch such
errors it seems and MSVC doesn't seem to support the alternative
techniques.

Hoping this brings the windows bots back to life. If not, will have to
revert all of this.

llvm-svn: 279225

llvm/include/llvm/IR/PassManagerInternal.h

index a498d39..2ffd552 100644 (file)
@@ -99,6 +99,15 @@ template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
     char a, b;
   };
 
+  // Purely to help out MSVC which fails to disable the below specialization,
+  // explicitly enable using the result type's invalidate routine if we can
+  // successfully call that routine.
+  template <typename T> struct Nonce { typedef EnabledType Type; };
+  template <typename T>
+  static typename Nonce<decltype(std::declval<T>().invalidate(
+      std::declval<IRUnitT &>(), std::declval<PreservedAnalyses>()))>::Type
+      check(rank<2>);
+
   // First we define an overload that can only be taken if there is no
   // invalidate member. We do this by taking the address of an invalidate
   // member in an adjacent base class of a derived class. This would be
@@ -115,7 +124,7 @@ template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
   static EnabledType check(rank<0>);
 
 public:
-  enum { Value = sizeof(check<ResultT>(rank<1>())) == sizeof(EnabledType) };
+  enum { Value = sizeof(check<ResultT>(rank<2>())) == sizeof(EnabledType) };
 };
 
 /// \brief Wrapper to model the analysis result concept.