r180571 - Put friend decls in the correct context.

Rafael Espindola rafael.espindola at gmail.com
Thu Apr 25 13:12:36 PDT 2013


Author: rafael
Date: Thu Apr 25 15:12:36 2013
New Revision: 180571

URL: http://llvm.org/viewvc/llvm-project?rev=180571&view=rev
Log:
Put friend decls in the correct context.

When we find a friend declaration we have to skip transparent contexts for doing
lookups, but we should not skip them when inserting the new decl if the lookup
found nothing.

Fixes PR15841.

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/linkage2.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=180571&r1=180570&r2=180571&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Apr 25 15:12:36 2013
@@ -11131,29 +11131,39 @@ NamedDecl *Sema::ActOnFriendFunctionDecl
 
     // Find the appropriate context according to the above.
     DC = CurContext;
-    while (true) {
-      // Skip class contexts.  If someone can cite chapter and verse
-      // for this behavior, that would be nice --- it's what GCC and
-      // EDG do, and it seems like a reasonable intent, but the spec
-      // really only says that checks for unqualified existing
-      // declarations should stop at the nearest enclosing namespace,
-      // not that they should only consider the nearest enclosing
-      // namespace.
-      while (DC->isRecord() || DC->isTransparentContext()) 
-        DC = DC->getParent();
 
-      LookupQualifiedName(Previous, DC);
+    // Skip class contexts.  If someone can cite chapter and verse
+    // for this behavior, that would be nice --- it's what GCC and
+    // EDG do, and it seems like a reasonable intent, but the spec
+    // really only says that checks for unqualified existing
+    // declarations should stop at the nearest enclosing namespace,
+    // not that they should only consider the nearest enclosing
+    // namespace.
+    while (DC->isRecord())
+      DC = DC->getParent();
+
+    DeclContext *LookupDC = DC;
+    while (LookupDC->isTransparentContext())
+      LookupDC = LookupDC->getParent();
+
+    while (true) {
+      LookupQualifiedName(Previous, LookupDC);
 
       // TODO: decide what we think about using declarations.
-      if (isLocal || !Previous.empty())
+      if (isLocal)
         break;
 
+      if (!Previous.empty()) {
+        DC = LookupDC;
+        break;
+      }
+
       if (isTemplateId) {
-        if (isa<TranslationUnitDecl>(DC)) break;
+        if (isa<TranslationUnitDecl>(LookupDC)) break;
       } else {
-        if (DC->isFileContext()) break;
+        if (LookupDC->isFileContext()) break;
       }
-      DC = DC->getParent();
+      LookupDC = LookupDC->getParent();
     }
 
     DCScope = getScopeForDeclContext(S, DC);

Modified: cfe/trunk/test/SemaCXX/linkage2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/linkage2.cpp?rev=180571&r1=180570&r2=180571&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/linkage2.cpp (original)
+++ cfe/trunk/test/SemaCXX/linkage2.cpp Thu Apr 25 15:12:36 2013
@@ -152,3 +152,15 @@ namespace test15 {
   const int a = 5; // expected-note {{previous definition is here}}
   static const int a; // expected-error {{redefinition of 'a'}}
 }
+
+namespace test16 {
+  extern "C" {
+    class Foo {
+      int x;
+      friend int bar(Foo *y);
+    };
+    int bar(Foo *y) {
+      return y->x;
+    }
+  }
+}





More information about the cfe-commits mailing list