]> granicus.if.org Git - clang/commitdiff
Apparently that didn't work. Reverting for now.
authorJohn McCall <rjmccall@apple.com>
Fri, 26 Mar 2010 02:38:45 +0000 (02:38 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 26 Mar 2010 02:38:45 +0000 (02:38 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99601 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaAccess.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/CXX/temp/temp.decls/temp.friend/p1.cpp

index 4cfd99d5c5230905e71bb8b1a5fc0b8c2944642e..a92989696e3101982144faa0470e9fcee536997f 100644 (file)
@@ -319,7 +319,7 @@ static Sema::AccessResult MatchesFriend(Sema &S,
   if (Friend == FTD->getCanonicalDecl())
     return Sema::AR_accessible;
 
-  if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
+  if (MightInstantiateTo(S, FTD, Friend))
     return Sema::AR_dependent;
 
   return Sema::AR_inaccessible;
index d929b5a370109b1a01f2bf6bf81dcaafac1737e4..cbd9086dfb272df5124b7ade25631356841cd14d 100644 (file)
@@ -904,15 +904,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
   // Check whether there is already a function template specialization for
   // this declaration.
   FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
-
-  bool isFriend;
-  if (FunctionTemplate)
-    isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None);
-  else
-    isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
-
   void *InsertPos = 0;
-  if (!isFriend && FunctionTemplate && !TemplateParams) {
+  if (FunctionTemplate && !TemplateParams) {
     llvm::FoldingSetNodeID ID;
     FunctionTemplateSpecializationInfo::Profile(ID,
                              TemplateArgs.getInnermost().getFlatArgumentList(),
@@ -940,29 +933,14 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
     return 0;
   QualType T = TInfo->getType();
 
-  NestedNameSpecifier *Qualifier = D->getQualifier();
-  if (Qualifier) {
-    Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
-                                                 D->getQualifierRange(),
-                                                 TemplateArgs);
-    if (!Qualifier) return 0;
-  }
-
   // If we're instantiating a local function declaration, put the result
   // in the owner;  otherwise we need to find the instantiated context.
   DeclContext *DC;
   if (D->getDeclContext()->isFunctionOrMethod())
     DC = Owner;
-  else if (isFriend && Qualifier) {
-    CXXScopeSpec SS;
-    SS.setScopeRep(Qualifier);
-    SS.setRange(D->getQualifierRange());
-    DC = SemaRef.computeDeclContext(SS);
-    if (!DC) return 0;
-  } else {
+  else
     DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(), 
                                          TemplateArgs);
-  }
 
   FunctionDecl *Function =
       FunctionDecl::Create(SemaRef.Context, DC, D->getLocation(),
@@ -970,8 +948,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
                            D->getStorageClass(),
                            D->isInlineSpecified(), D->hasWrittenPrototype());
 
-  if (Qualifier)
-    Function->setQualifierInfo(Qualifier, D->getQualifierRange());
+  // Substitute the nested name specifier, if any.
+  if (SubstQualifier(D, Function))
+    return 0;
 
   Function->setLexicalDeclContext(Owner);
 
@@ -995,7 +974,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
     // which means substituting int for T, but leaving "f" as a friend function
     // template.
     // Build the function template itself.
-    FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, DC,
+    FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, Owner,
                                                     Function->getLocation(),
                                                     Function->getDeclName(),
                                                     TemplateParams, Function);
@@ -1037,7 +1016,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
 
   // If the original function was part of a friend declaration,
   // inherit its namespace state and add it to the owner.
-  if (isFriend) {
+  NamedDecl *FromFriendD 
+      = TemplateParams? cast<NamedDecl>(D->getDescribedFunctionTemplate()) : D;
+  if (FromFriendD->getFriendObjectKind()) {
     NamedDecl *ToFriendD = 0;
     NamedDecl *PrevDecl;
     if (TemplateParams) {
@@ -1048,7 +1029,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
       PrevDecl = Function->getPreviousDeclaration();
     }
     ToFriendD->setObjectOfFriendDecl(PrevDecl != NULL);
-    DC->makeDeclVisibleInContext(ToFriendD, /*Recoverable=*/ false);
+    if (!Owner->isDependentContext() && !PrevDecl)
+      DC->makeDeclVisibleInContext(ToFriendD, /* Recoverable = */ false);
+
+    if (!TemplateParams)
+      Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
   }
 
   return Function;
index 0e41e5f8322bde2cad0c0bc4312fb84649025b6d..39818028bbad2dd3c43e62ec0e5b001598d8b23d 100644 (file)
@@ -178,16 +178,3 @@ namespace test7 {
   };
   template class D<int>;
 }
-
-namespace test8 {
-  template <class N> class A {
-    static int x;
-    template <class T> friend void foo();
-  };
-  template class A<int>;
-
-  template <class T> void foo() {
-    A<int>::x = 0;
-  }
-  template void foo<int>();
-}