Hi all.
Please find patch in attachment for review.
I suppose that this check was not implemented yet, since I couldn't found it anywhere. The friend method availability check was inserted in Sema::ActOnFriendFunctionDecl. I also added "DeclContext *FromContext" to the AccessedEntity class. It allows to ask DelayedDiagnostic to use context that was "current" when this diagnostics was requested. It is usefull in our case, since we requested diagnostics when we're parsing class with "friend" declaration, but diagnostics is invoked for class with definition of friend member itself.

-Stepan.
Index: include/clang/Sema/DelayedDiagnostic.h
===================================================================
--- include/clang/Sema/DelayedDiagnostic.h	(revision 154259)
+++ include/clang/Sema/DelayedDiagnostic.h	(working copy)
@@ -44,10 +44,13 @@
                  MemberNonce _,
                  CXXRecordDecl *NamingClass,
                  DeclAccessPair FoundDecl,
-                 QualType BaseObjectType)
+                 QualType BaseObjectType,
+                 DeclContext *FromContext = 0)
     : Access(FoundDecl.getAccess()), IsMember(true),
       Target(FoundDecl.getDecl()), NamingClass(NamingClass),
-      BaseObjectType(BaseObjectType), Diag(0, Context.getDiagAllocator()) {
+      BaseObjectType(BaseObjectType),
+      FromContext(FromContext),
+      Diag(0, Context.getDiagAllocator()) {
   }
 
   AccessedEntity(ASTContext &Context,
@@ -58,7 +61,9 @@
     : Access(Access), IsMember(false),
       Target(BaseClass),
       NamingClass(DerivedClass),
-      Diag(0, Context.getDiagAllocator()) {
+      FromContext(0),
+      Diag(0, Context.getDiagAllocator())  
+      {
   }
 
   bool isQuiet() const { return Diag.getDiagID() == 0; }
@@ -78,6 +83,10 @@
   /// Retrieves the base object type, important when accessing
   /// an instance member.
   QualType getBaseObjectType() const { return BaseObjectType; }
+  
+  /// Retrieves the specified DeclarationContext from which
+  /// we want to access the target.
+  DeclContext *getFromContext() const { return FromContext; }
 
   /// Sets a diagnostic to be performed.  The diagnostic is given
   /// four (additional) arguments:
@@ -105,6 +114,7 @@
   NamedDecl *Target;
   CXXRecordDecl *NamingClass;
   QualType BaseObjectType;
+  DeclContext *FromContext;
   PartialDiagnostic Diag;
 };
 
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 154259)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -4127,7 +4127,7 @@
                                     unsigned DiagID,
                                     bool ForceCheck = false,
                                     bool ForceUnprivileged = false);
-  void CheckLookupAccess(const LookupResult &R);
+  void CheckLookupAccess(const LookupResult &R, bool UseCurContext = false);
   bool IsSimplyAccessible(NamedDecl *decl, DeclContext *Ctx);
 
   void HandleDependentAccessCheck(const DependentDiagnostic &DD,
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp	(revision 154259)
+++ lib/Sema/SemaDeclCXX.cpp	(working copy)
@@ -10334,6 +10334,10 @@
     }
   }
 
+  if (Previous.getResultKind() == LookupResult::Found &&
+      Previous.getFoundDecl()->isCXXClassMember())
+    CheckLookupAccess(Previous);
+  
   // FIXME: This is an egregious hack to cope with cases where the scope stack
   // does not contain the declaration context, i.e., in an out-of-line 
   // definition of a class.
Index: lib/Sema/SemaAccess.cpp
===================================================================
--- lib/Sema/SemaAccess.cpp	(revision 154259)
+++ lib/Sema/SemaAccess.cpp	(working copy)
@@ -151,8 +151,10 @@
                MemberNonce _,
                CXXRecordDecl *NamingClass,
                DeclAccessPair FoundDecl,
-               QualType BaseObjectType)
-    : AccessedEntity(Context, Member, NamingClass, FoundDecl, BaseObjectType) {
+               QualType BaseObjectType,
+               DeclContext *FromContext = 0)
+    : AccessedEntity(Context, Member, NamingClass, FoundDecl,
+                     BaseObjectType, FromContext) {
     initialize();
   }
 
@@ -1418,12 +1420,15 @@
   // of the declaration, just in case it's a friend of something.
   // However, this does not apply to local extern declarations.
 
-  DeclContext *DC = decl->getDeclContext();
-  if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
-    if (!DC->isFunctionOrMethod()) DC = fn;
-  } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
-    // Never a local declaration.
-    DC = fnt->getTemplatedDecl();
+  DeclContext *DC = DD.getAccessData().getFromContext();
+  if (!DC) {
+    DC = decl->getDeclContext();
+    if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
+      if (!DC->isFunctionOrMethod()) DC = fn;
+    } else if (FunctionTemplateDecl *fnt = dyn_cast<FunctionTemplateDecl>(decl)) {
+      // Never a local declaration.
+      DC = fnt->getTemplatedDecl();
+    }
   }
 
   EffectiveContext EC(DC);
@@ -1726,7 +1731,7 @@
 }
 
 /// Checks access to all the declarations in the given result set.
-void Sema::CheckLookupAccess(const LookupResult &R) {
+void Sema::CheckLookupAccess(const LookupResult &R, bool UseCurContext) {
   assert(getLangOpts().AccessControl
          && "performing access check without access control");
   assert(R.getNamingClass() && "performing access check without naming class");
@@ -1735,7 +1740,8 @@
     if (I.getAccess() != AS_public) {
       AccessTarget Entity(Context, AccessedEntity::Member,
                           R.getNamingClass(), I.getPair(),
-                          R.getBaseObjectType());
+                          R.getBaseObjectType(),
+                          UseCurContext ? CurContext : 0);
       Entity.setDiag(diag::err_access);
       CheckAccess(*this, R.getNameLoc(), Entity);
     }
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to