Argument-dependent lookup for friend declarations.  Add a new decl type,
FriendFunctionDecl, and create instances as appropriate.

The design of FriendFunctionDecl is still somewhat up in the air;  you can
befriend arbitrary types of functions --- methods, constructors, etc. ---
and it's not clear that this representation captures that very well.
We'll have a better picture when we start consuming this data in access
control.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78653 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 2d27661..0f7c4dc 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -198,6 +198,9 @@
     case ObjCProperty:
     case ObjCCompatibleAlias:
       return IDNS_Ordinary;
+
+    case FriendFunction:
+      return IDNS_Friend;
       
     case ObjCProtocol:
       return IDNS_ObjCProtocol;
@@ -583,7 +586,7 @@
   return !FirstDecl;
 }
 
-void DeclContext::addDecl(Decl *D) {
+void DeclContext::addHiddenDecl(Decl *D) {
   assert(D->getLexicalDeclContext() == this &&
          "Decl inserted into wrong lexical context");
   assert(!D->getNextDeclInContext() && D != LastDecl && 
@@ -595,6 +598,10 @@
   } else {
     FirstDecl = LastDecl = D;
   }
+}
+
+void DeclContext::addDecl(Decl *D) {
+  addHiddenDecl(D);
 
   if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
     ND->getDeclContext()->makeDeclVisibleInContext(ND);
@@ -608,9 +615,12 @@
     for (decl_iterator D = DCtx->decls_begin(), 
                     DEnd = DCtx->decls_end(); 
          D != DEnd; ++D) {
-      // Insert this declaration into the lookup structure
+      // Insert this declaration into the lookup structure, but only
+      // if it's semantically in its decl context.  During non-lazy
+      // lookup building, this is implicitly enforced by addDecl.
       if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
-        makeDeclVisibleInContextImpl(ND);
+        if (D->getDeclContext() == DCtx)
+          makeDeclVisibleInContextImpl(ND);
 
       // If this declaration is itself a transparent declaration context,
       // add its members (recursively).