Omnibus friend decl refactoring.  Instead of cloning AST classes for friend
declarations of same, introduce a single AST class and add appropriate bits
(encoded in the namespace) for whether a decl is "real" or not.  Much hackery
about previously-declared / not-previously-declared, but it's essentially
mandated by the standard that friends alter lookup, and this is at least
fairly non-intrusive.

Refactor the Sema methods specific to friends for cleaner flow and less nesting.

Incidentally solve a few bugs, but I remain confident that we can put them back.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80353 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 70e4897..46acf67 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -777,20 +777,20 @@
   return !isa<OverloadedFunctionDecl>(D) || Iter == Other.Iter;
 }
 
-FriendFunctionDecl *FriendFunctionDecl::Create(ASTContext &C,
-                                               DeclContext *DC,
-                                               SourceLocation L,
-                                               DeclarationName N, QualType T,
-                                               DeclaratorInfo *DInfo,
-                                               bool isInline,
-                                               SourceLocation FriendL) {
-  return new (C) FriendFunctionDecl(DC, L, N, T, DInfo, isInline, FriendL);
-}
+FriendDecl *FriendDecl::Create(ASTContext &C, DeclContext *DC,
+                               SourceLocation L,
+                               FriendUnion Friend,
+                               SourceLocation FriendL) {
+  if (Friend.is<NamedDecl*>()) {
+    NamedDecl *D = Friend.get<NamedDecl*>();
+    assert(isa<FunctionDecl>(D) ||
+           isa<CXXRecordDecl>(D) ||
+           isa<FunctionTemplateDecl>(D) ||
+           isa<ClassTemplateDecl>(D));
+    assert(D->getFriendObjectKind());
+  }
 
-FriendClassDecl *FriendClassDecl::Create(ASTContext &C, DeclContext *DC,
-                                         SourceLocation L, QualType T,
-                                         SourceLocation FriendL) {
-  return new (C) FriendClassDecl(DC, L, T, FriendL);
+  return new (C) FriendDecl(DC, L, Friend, FriendL);
 }                                               
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,