Add an extension to avoid an error when a global template has the same name as
a member template, and you try to call the member template with an explicit
template argument.  See PR7247 

For example, this downgrades the error to a warning in:

template<typename T> struct set{};
struct Value {
    template<typename T>
    void set(T value) {
    }
};
void foo() {
    Value v;
    v.set<double>(3.2);  // Warning here.
}



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105518 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/docs/UsersManual.html b/docs/UsersManual.html
index 5bff1af..a53a1af 100644
--- a/docs/UsersManual.html
+++ b/docs/UsersManual.html
@@ -386,6 +386,30 @@
  and <a href="">-Wbaz</a>.</p>
 </dd>
 
+<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+<dt id="opt_Wambiguous-member-template"><b>-Wambiguous-member-template</b>:
+Warn about unqualified uses of a member template whose name resolves
+to another template at the location of the use.</dt>
+<dd>This option, which defaults to on, enables a warning in the
+following code:</p>
+
+<pre>
+template&lt;typename T> struct set{};
+template&lt;typename T> struct trait { typedef const T& type; };
+struct Value {
+  template&lt;typename T> void set(typename trait&lt;T>::type value) {}
+};
+void foo() {
+  Value v;
+  v.set&lt;double>(3.2);
+}
+</pre>
+
+<p>C++ [basic.lookup.classref] requires this to be an error, but,
+because it's hard to work around, Clang downgrades it to a warning as
+an extension.</p>
+</dd>
+
 </dl>
 
 <!-- ======================================================================= -->
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 507ef1c..e507733 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -20,6 +20,7 @@
 def : DiagGroup<"address">;
 def AddressOfTemporary : DiagGroup<"address-of-temporary">;
 def : DiagGroup<"aggregate-return">;
+def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">;
 def : DiagGroup<"attributes">;
 def : DiagGroup<"bad-function-cast">;
 def : DiagGroup<"c++-compat">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 207b081..ce28fd6 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -549,6 +549,9 @@
   "parameter">;
 def err_nested_name_member_ref_lookup_ambiguous : Error<
   "lookup of %0 in member access expression is ambiguous">;
+def ext_nested_name_member_ref_lookup_ambiguous : ExtWarn<
+  "lookup of %0 in member access expression is ambiguous; using member of %1">,
+  InGroup<AmbigMemberTemplate>;
 def note_ambig_member_ref_object_type : Note<
   "lookup in the object type %0 refers here">;
 def note_ambig_member_ref_scope : Note<
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 08f2616..f77454b 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -311,8 +311,9 @@
           Found.getFoundDecl()->getCanonicalDecl()
             != FoundOuter.getFoundDecl()->getCanonicalDecl()) {
         Diag(Found.getNameLoc(), 
-             diag::err_nested_name_member_ref_lookup_ambiguous)
-          << Found.getLookupName();
+             diag::ext_nested_name_member_ref_lookup_ambiguous)
+          << Found.getLookupName()
+          << ObjectType;
         Diag(Found.getRepresentativeDecl()->getLocation(),
              diag::note_ambig_member_ref_object_type)
           << ObjectType;
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp b/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
new file mode 100644
index 0000000..3fde0da
--- /dev/null
+++ b/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -fdiagnostics-show-option -verify %s
+
+// C++98 [basic.lookup.classref]p1:
+//   In a class member access expression (5.2.5), if the . or -> token is
+//   immediately followed by an identifier followed by a <, the identifier must
+//   be looked up to determine whether the < is the beginning of a template
+//   argument list (14.2) or a less-than operator. The identifier is first
+//   looked up in the class of the object expression. If the identifier is not
+//   found, it is then looked up in the context of the entire postfix-expression
+//   and shall name a class or function template. If the lookup in the class of
+//   the object expression finds a template, the name is also looked up in the
+//   context of the entire postfix-expression and
+//    -- if the name is not found, the name found in the class of the object
+//       expression is used, otherwise
+//    -- if the name is found in the context of the entire postfix-expression
+//       and does not name a class template, the name found in the class of the
+//       object expression is used, otherwise
+//    -- if the name found is a class template, it must refer to the same
+//       entity as the one found in the class of the object expression,
+//       otherwise the program is ill-formed.
+
+// From PR 7247
+template<typename T>
+struct set{};  // expected-note{{lookup from the current scope refers here}}
+struct Value {
+  template<typename T>
+  void set(T value) {}  // expected-note{{lookup in the object type 'Value' refers here}}
+
+  void resolves_to_same() {
+    Value v;
+    v.set<double>(3.2);
+  }
+};
+void resolves_to_different() {
+  {
+    Value v;
+    // The fact that the next line is a warning rather than an error is an
+    // extension.
+    v.set<double>(3.2);  // expected-warning{{lookup of 'set' in member access expression is ambiguous; using member of 'Value' [-Wambiguous-member-template]}}
+  }
+  {
+    int set;  // Non-template.
+    Value v;
+    v.set<double>(3.2);
+  }
+}