Implement method friends in class templates and fix a few related problems.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99708 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index e9f004d..d5913e2 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -452,15 +452,23 @@
   /// same entity may not (and probably don't) share this property.
   void setObjectOfFriendDecl(bool PreviouslyDeclared) {
     unsigned OldNS = IdentifierNamespace;
-    assert((OldNS == IDNS_Tag || OldNS == IDNS_Ordinary ||
-            OldNS == (IDNS_Tag | IDNS_Ordinary))
-           && "unsupported namespace for undeclared friend");
-    if (!PreviouslyDeclared) IdentifierNamespace = 0;
+    assert((OldNS & (IDNS_Tag | IDNS_Ordinary |
+                     IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+           "namespace includes neither ordinary nor tag");
+    assert(!(OldNS & ~(IDNS_Tag | IDNS_Ordinary |
+                       IDNS_TagFriend | IDNS_OrdinaryFriend)) &&
+           "namespace includes other than ordinary or tag");
 
-    if (OldNS == IDNS_Tag)
+    IdentifierNamespace = 0;
+    if (OldNS & (IDNS_Tag | IDNS_TagFriend)) {
       IdentifierNamespace |= IDNS_TagFriend;
-    else
+      if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Tag;
+    }
+
+    if (OldNS & (IDNS_Ordinary | IDNS_OrdinaryFriend)) {
       IdentifierNamespace |= IDNS_OrdinaryFriend;
+      if (PreviouslyDeclared) IdentifierNamespace |= IDNS_Ordinary;
+    }
   }
 
   enum FriendObjectKind {