Eliminate a 'default' case in template argument deduction, where we
were just punting on template argument deduction for a number of type
nodes. Most of them, obviously, didn't matter.

As a consequence of this, make extended vector types (via the
ext_vector_type attribute) actually work properly for several
important cases:
  - If the attribute appears in a type-id (i.e, not attached to a
  typedef), actually build a proper vector type
  - Build ExtVectorType whenever the size is constant; previously, we
  were building DependentSizedExtVectorType when the size was constant
  but the type was dependent, which makes no sense at all.
  - Teach template argument deduction to handle
  ExtVectorType/DependentSizedExtVectorType.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133060 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index 842c5fb..9011cdf 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -1053,10 +1053,39 @@
   }
 
   switch (Param->getTypeClass()) {
-    // No deduction possible for these types
+    // Non-canonical types cannot appear here.
+#define NON_CANONICAL_TYPE(Class, Base) \
+  case Type::Class: llvm_unreachable("deducing non-canonical type: " #Class);
+#define TYPE(Class, Base)
+#include "clang/AST/TypeNodes.def"
+      
+    case Type::TemplateTypeParm:
+    case Type::SubstTemplateTypeParmPack:
+      llvm_unreachable("Type nodes handled above");
+      
+    // These types cannot be used in templates or cannot be dependent, so
+    // deduction always fails.
     case Type::Builtin:
+    case Type::VariableArray:
+    case Type::Vector:
+    case Type::FunctionNoProto:
+    case Type::Record:
+    case Type::Enum:
+    case Type::ObjCObject:
+    case Type::ObjCInterface:
+    case Type::ObjCObjectPointer:
       return Sema::TDK_NonDeducedMismatch;
 
+    //     _Complex T   [placeholder extension]  
+    case Type::Complex:
+      if (const ComplexType *ComplexArg = Arg->getAs<ComplexType>())
+        return DeduceTemplateArguments(S, TemplateParams, 
+                                    cast<ComplexType>(Param)->getElementType(), 
+                                       ComplexArg->getElementType(),
+                                       Info, Deduced, TDF);
+
+      return Sema::TDK_NonDeducedMismatch;
+      
     //     T *
     case Type::Pointer: {
       QualType PointeeType;
@@ -1360,14 +1389,105 @@
                                      Deduced, 0);
     }
 
+    //     (clang extension)
+    //
+    //     T __attribute__(((ext_vector_type(<integral constant>))))
+    case Type::ExtVector: {
+      const ExtVectorType *VectorParam = cast<ExtVectorType>(Param);
+      if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) {
+        // Make sure that the vectors have the same number of elements.
+        if (VectorParam->getNumElements() != VectorArg->getNumElements())
+          return Sema::TDK_NonDeducedMismatch;
+        
+        // Perform deduction on the element types.
+        return DeduceTemplateArguments(S, TemplateParams,
+                                       VectorParam->getElementType(),
+                                       VectorArg->getElementType(),
+                                       Info, Deduced,
+                                       TDF);
+      }
+      
+      if (const DependentSizedExtVectorType *VectorArg 
+                                = dyn_cast<DependentSizedExtVectorType>(Arg)) {
+        // We can't check the number of elements, since the argument has a
+        // dependent number of elements. This can only occur during partial
+        // ordering.
+
+        // Perform deduction on the element types.
+        return DeduceTemplateArguments(S, TemplateParams,
+                                       VectorParam->getElementType(),
+                                       VectorArg->getElementType(),
+                                       Info, Deduced,
+                                       TDF);
+      }
+      
+      return Sema::TDK_NonDeducedMismatch;
+    }
+      
+    //     (clang extension)
+    //
+    //     T __attribute__(((ext_vector_type(N))))
+    case Type::DependentSizedExtVector: {
+      const DependentSizedExtVectorType *VectorParam
+        = cast<DependentSizedExtVectorType>(Param);
+
+      if (const ExtVectorType *VectorArg = dyn_cast<ExtVectorType>(Arg)) {
+        // Perform deduction on the element types.
+        if (Sema::TemplateDeductionResult Result
+              = DeduceTemplateArguments(S, TemplateParams,
+                                        VectorParam->getElementType(),
+                                        VectorArg->getElementType(),
+                                        Info, Deduced,
+                                        TDF))
+          return Result;
+        
+        // Perform deduction on the vector size, if we can.
+        NonTypeTemplateParmDecl *NTTP
+          = getDeducedParameterFromExpr(VectorParam->getSizeExpr());
+        if (!NTTP)
+          return Sema::TDK_Success;
+
+        llvm::APSInt ArgSize(S.Context.getTypeSize(S.Context.IntTy), false);
+        ArgSize = VectorArg->getNumElements();
+        return DeduceNonTypeTemplateArgument(S, NTTP, ArgSize, S.Context.IntTy,
+                                             false, Info, Deduced);
+      }
+      
+      if (const DependentSizedExtVectorType *VectorArg 
+                                = dyn_cast<DependentSizedExtVectorType>(Arg)) {
+        // Perform deduction on the element types.
+        if (Sema::TemplateDeductionResult Result
+            = DeduceTemplateArguments(S, TemplateParams,
+                                      VectorParam->getElementType(),
+                                      VectorArg->getElementType(),
+                                      Info, Deduced,
+                                      TDF))
+          return Result;
+        
+        // Perform deduction on the vector size, if we can.
+        NonTypeTemplateParmDecl *NTTP
+          = getDeducedParameterFromExpr(VectorParam->getSizeExpr());
+        if (!NTTP)
+          return Sema::TDK_Success;
+        
+        return DeduceNonTypeTemplateArgument(S, NTTP, VectorArg->getSizeExpr(),
+                                             Info, Deduced);
+      }
+      
+      return Sema::TDK_NonDeducedMismatch;
+    }
+      
     case Type::TypeOfExpr:
     case Type::TypeOf:
     case Type::DependentName:
+    case Type::UnresolvedUsing:
+    case Type::Decltype:
+    case Type::UnaryTransform:
+    case Type::Auto:
+    case Type::DependentTemplateSpecialization:
+    case Type::PackExpansion:
       // No template argument deduction for these types
       return Sema::TDK_Success;
-
-    default:
-      break;
   }
 
   // FIXME: Many more cases to go (to go).