<div>David, Thanks!</div><div>I have updated my toolchain, and now it also emits error. Which turned out to be a correct behavour.</div><div>I obviously missed this statement (taken from cppreference, for I don't have a draft yet):</div><div>"When a local class declares an unqualified function or class as a friend, only functions and classes in the innermost non-class scope are looked up".</div><div>So as you mentioned declaring unqualified friend class in Sema, means that such should be non-nested declaration of "clang" namespace.</div><div> </div><div>Now everything makes sense! Thanks!</div><div>Stepan Dyatkovskiy.</div><div> </div><div>07.05.2019, 19:03, "David Blaikie" <dblaikie@gmail.com>:</div><blockquote><div><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></blockquote>