After performing template argument deduction for a function template,
check deduced non-type template arguments and template template
arguments against the template parameters for which they were deduced,
performing conversions as appropriate so that deduced template
arguments get the same treatment as explicitly-specified template
arguments. This is the bulk of PR6723.

Also keep track of whether deduction of a non-type template argument
came from an array bound (vs. anywhere else). With this information,
we enforce C++ [temp.deduct.type]p17, which requires exact type
matches when deduction deduces a non-type template argument from
something that is not an array bound.

Finally, when in a SFINAE context, translate the "zero sized
arrays are an extension" extension diagnostic into a hard error (for
better standard conformance), which was a minor part of PR6723.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99734 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplate.h b/lib/Sema/SemaTemplate.h
index 2bfb25a..ca59e27 100644
--- a/lib/Sema/SemaTemplate.h
+++ b/lib/Sema/SemaTemplate.h
@@ -99,6 +99,40 @@
     /// template specialization to a function template.
     TPOC_Other
   };
+
+  /// \brief Captures a template argument whose value has been deduced
+  /// via c++ template argument deduction.
+  class DeducedTemplateArgument : public TemplateArgument {
+    /// \brief For a non-type template argument, whether the value was
+    /// deduced from an array bound.
+    bool DeducedFromArrayBound;
+
+  public:
+    DeducedTemplateArgument()
+      : TemplateArgument(), DeducedFromArrayBound(false) { }
+
+    DeducedTemplateArgument(const TemplateArgument &Arg,
+                            bool DeducedFromArrayBound = false)
+      : TemplateArgument(Arg), DeducedFromArrayBound(DeducedFromArrayBound) { }
+
+    /// \brief Construct an integral non-type template argument that
+    /// has been deduced, possible from an array bound.
+    DeducedTemplateArgument(const llvm::APSInt &Value,
+                            QualType ValueType,
+                            bool DeducedFromArrayBound)
+      : TemplateArgument(Value, ValueType), 
+        DeducedFromArrayBound(DeducedFromArrayBound) { }
+
+    /// \brief For a non-type template argument, determine whether the
+    /// template argument was deduced from an array bound.
+    bool wasDeducedFromArrayBound() const { return DeducedFromArrayBound; }
+
+    /// \brief Specify whether the given non-type template argument
+    /// was deduced from an array bound.
+    void setDeducedFromArrayBound(bool Deduced) {
+      DeducedFromArrayBound = Deduced;
+    }
+  };
 }
 
 #endif // LLVM_CLANG_SEMA_TEMPLATE_H