<div dir="ltr"><br><br>On Tue, May 7, 2019 at 7:27 AM via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br>><br>> Hi all!<br>> I found that in clang sources, in Sema.h in particular,<br>> it is required to add class predeclaration before friending it, like this:<br>><br>>   class DelayedDiagnostics; // predeclaration is required here, otherwise it won't compiled<br>><br>>   class DelayedDiagnosticsState {<br>>     sema::DelayedDiagnosticPool *SavedPool;<br>>     friend class Sema::DelayedDiagnostics;<br>>   };<br>>   // ...<br>>   class DelayedDiagnostics {<br>>   // ...<br>>     DelayedDiagnosticsState push(sema::DelayedDiagnosticPool &pool) {<br>>       DelayedDiagnosticsState state;<br>>       state.SavedPool = CurPool; // Private access.<br>>       // ...<br>>     }<br>>   };<br>><br>> And yet it contradicts standard, which states that the name of the class that is used in this friend declaration does not need to be previously declared.<br>><br>> Honestly I didn't try to debug it. I tried to reproduce it though, but failed. The example below compiled with no errors:<br>><br>> namespace clang {<br>> class Sema {<br>>   public:<br>>   class A {<br>>     int x;<br>>     friend class B;<br>>   };<br>><br>>   class B {<br>>     A a;<br>>     void f() {<br>>       a.x = 1; // access private member of A, no error!<br>>     }<br>>   };<br>> };<br>> } // namespace clang<br>><br>> It looks like I'm missing something... Anybody knows why we should predeclare friend classes in clang::Sema?<br><br>I can't reproduce your minimized test case - when I try to compile the example you gave, I get an error:<br><br><font face="monospace, monospace">delay.cpp:12:9: error: 'x' is a private member of 'clang::Sema::A'<br>      a.x = 1;  // access private member of A, no error!<br>        ^<br>delay.cpp:5:9: note: implicitly declared private here<br>    int x;<br>        ^<br>1 error generated.</font><br><br>But if you make 'B' not a member of 'Sema', but instead just a member of the 'clang' namespace, then it compiles - which shows the difference between your example and the original. In the original code, it says "friend class Sema::B", whereas your example is "friend class B" - in the latter case, that unqualified 'class B' (in the absence of a prior declaration of 'class B' inside class Sema) refers to/injects a declaration of 'B' into the clang namespace, not into the Sema class.<br><br>><br>> Thanks!<br>> Stepan Dyatkovskiy<br>><br>> _______________________________________________<br>> cfe-dev mailing list<br>> <a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a><br>> <a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev">https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a></div>