<div dir="rtl"><div dir="ltr">Thanks, I will look into this.</div><div dir="ltr"><br></div><div style="direction:ltr"><br></div><div class="gmail_quote"><div dir="rtl" style="direction:ltr">‫בתאריך יום ג׳, 18 באפר׳ 2017 ב-0:11 מאת ‪Benjamin Kramer‬‏ <‪<a href="mailto:benny.kra@gmail.com">benny.kra@gmail.com</a>‬‏>:‬<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="direction:ltr">This broke our internal build of libc++ with modules. Reduced test</div><div style="direction:ltr">case attached, courtesy of Richard Smith!</div>
<div style="direction:ltr"><br></div><div style="direction:ltr">With your patch it doesn't compiler anymore:</div><div style="direction:ltr">While building module 'x':</div><div style="direction:ltr">In file included from <module-includes>:2:</div><div style="direction:ltr">In file included from ./c.h:1:</div><div style="direction:ltr">./a.h:3:32: error: inline declaration of 'f' follows non-inline definition</div><div style="direction:ltr">template<typename> inline void f() {}</div><div style="direction:ltr">                               ^</div><div style="direction:ltr">./a.h:3:32: note: previous definition is here</div><div style="direction:ltr">template<typename> inline void f() {}</div>
<div style="direction:ltr"><br></div>
<div style="direction:ltr"><br></div><div style="direction:ltr">I reverted this change in r300497.</div>
<div style="direction:ltr"><br></div><div style="direction:ltr">On Mon, Apr 17, 2017 at 10:51 AM, Yaron Keren via cfe-commits</div><div style="direction:ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>> wrote:</div><div style="direction:ltr">> Author: yrnkrn</div><div style="direction:ltr">> Date: Mon Apr 17 03:51:20 2017</div><div style="direction:ltr">> New Revision: 300443</div><div style="direction:ltr">></div><div style="direction:ltr">> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=300443&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=300443&view=rev</a></div><div style="direction:ltr">> Log:</div><div style="direction:ltr">> Address <a href="http://bugs.llvm.org/pr30994" rel="noreferrer" target="_blank">http://bugs.llvm.org/pr30994</a> so that a non-friend can properly replace a friend, and a visible friend can properly replace an invisible friend but not vice verse, and definitions are not replaced. This fixes the two FIXME in SemaTemplate/friend-template.cpp.</div><div style="direction:ltr">></div><div style="direction:ltr">> The code implements Richard Smith suggestion in comment 3 of the PR.</div><div style="direction:ltr">></div><div style="direction:ltr">> reviewer: Vassil Vassilev</div><div style="direction:ltr">></div><div style="direction:ltr">> Differential Revision: <a href="https://reviews.llvm.org/D31540" rel="noreferrer" target="_blank">https://reviews.llvm.org/D31540</a></div><div style="direction:ltr">></div><div style="direction:ltr">></div><div style="direction:ltr">> Modified:</div><div style="direction:ltr">>     cfe/trunk/include/clang/AST/DeclBase.h</div><div style="direction:ltr">>     cfe/trunk/lib/AST/Decl.cpp</div><div style="direction:ltr">>     cfe/trunk/lib/AST/DeclBase.cpp</div><div style="direction:ltr">>     cfe/trunk/test/SemaTemplate/friend-template.cpp</div><div style="direction:ltr">></div><div style="direction:ltr">> Modified: cfe/trunk/include/clang/AST/DeclBase.h</div><div style="direction:ltr">> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=300443&r1=300442&r2=300443&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=300443&r1=300442&r2=300443&view=diff</a></div><div style="direction:ltr">> ==============================================================================</div><div style="direction:ltr">> --- cfe/trunk/include/clang/AST/DeclBase.h (original)</div><div style="direction:ltr">> +++ cfe/trunk/include/clang/AST/DeclBase.h Mon Apr 17 03:51:20 2017</div><div style="direction:ltr">> @@ -417,6 +417,8 @@ public:</div><div style="direction:ltr">>      return const_cast<Decl*>(this)->getTranslationUnitDecl();</div><div style="direction:ltr">>    }</div><div style="direction:ltr">></div><div style="direction:ltr">> +  bool isThisDeclarationADefinition() const;</div><div style="direction:ltr">> +</div><div style="direction:ltr">>    bool isInAnonymousNamespace() const;</div><div style="direction:ltr">></div><div style="direction:ltr">>    bool isInStdNamespace() const;</div><div style="direction:ltr">></div><div style="direction:ltr">> Modified: cfe/trunk/lib/AST/Decl.cpp</div><div style="direction:ltr">> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300443&r1=300442&r2=300443&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300443&r1=300442&r2=300443&view=diff</a></div><div style="direction:ltr">> ==============================================================================</div><div style="direction:ltr">> --- cfe/trunk/lib/AST/Decl.cpp (original)</div><div style="direction:ltr">> +++ cfe/trunk/lib/AST/Decl.cpp Mon Apr 17 03:51:20 2017</div><div style="direction:ltr">> @@ -1536,6 +1536,10 @@ bool NamedDecl::declarationReplaces(Name</div><div style="direction:ltr">>    if (isa<ObjCMethodDecl>(this))</div><div style="direction:ltr">>      return false;</div><div style="direction:ltr">></div><div style="direction:ltr">> +  if (getFriendObjectKind() > OldD->getFriendObjectKind() &&</div><div style="direction:ltr">> +      !isThisDeclarationADefinition())</div><div style="direction:ltr">> +    return false;</div><div style="direction:ltr">> +</div><div style="direction:ltr">>    // For parameters, pick the newer one. This is either an error or (in</div><div style="direction:ltr">>    // Objective-C) permitted as an extension.</div><div style="direction:ltr">>    if (isa<ParmVarDecl>(this))</div><div style="direction:ltr">></div><div style="direction:ltr">> Modified: cfe/trunk/lib/AST/DeclBase.cpp</div><div style="direction:ltr">> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=300443&r1=300442&r2=300443&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=300443&r1=300442&r2=300443&view=diff</a></div><div style="direction:ltr">> ==============================================================================</div><div style="direction:ltr">> --- cfe/trunk/lib/AST/DeclBase.cpp (original)</div><div style="direction:ltr">> +++ cfe/trunk/lib/AST/DeclBase.cpp Mon Apr 17 03:51:20 2017</div><div style="direction:ltr">> @@ -861,6 +861,21 @@ const FunctionType *Decl::getFunctionTyp</div><div style="direction:ltr">>    return Ty->getAs<FunctionType>();</div><div style="direction:ltr">>  }</div><div style="direction:ltr">></div><div style="direction:ltr">> +bool Decl::isThisDeclarationADefinition() const {</div><div style="direction:ltr">> +  if (auto *TD = dyn_cast<TagDecl>(this))</div><div style="direction:ltr">> +    return TD->isThisDeclarationADefinition();</div><div style="direction:ltr">> +  if (auto *FD = dyn_cast<FunctionDecl>(this))</div><div style="direction:ltr">> +    return FD->isThisDeclarationADefinition();</div><div style="direction:ltr">> +  if (auto *VD = dyn_cast<VarDecl>(this))</div><div style="direction:ltr">> +    return VD->isThisDeclarationADefinition();</div><div style="direction:ltr">> +  if (auto *CTD = dyn_cast<ClassTemplateDecl>(this))</div><div style="direction:ltr">> +    return CTD->isThisDeclarationADefinition();</div><div style="direction:ltr">> +  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(this))</div><div style="direction:ltr">> +    return FTD->isThisDeclarationADefinition();</div><div style="direction:ltr">> +  if (auto *VTD = dyn_cast<VarTemplateDecl>(this))</div><div style="direction:ltr">> +    return VTD->isThisDeclarationADefinition();</div><div style="direction:ltr">> +  return false;</div><div style="direction:ltr">> +}</div><div style="direction:ltr">></div><div style="direction:ltr">>  /// Starting at a given context (a Decl or DeclContext), look for a</div><div style="direction:ltr">>  /// code context that is not a closure (a lambda, block, etc.).</div><div style="direction:ltr">></div><div style="direction:ltr">> Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp</div><div style="direction:ltr">> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=300443&r1=300442&r2=300443&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=300443&r1=300442&r2=300443&view=diff</a></div><div style="direction:ltr">> ==============================================================================</div><div style="direction:ltr">> --- cfe/trunk/test/SemaTemplate/friend-template.cpp (original)</div><div style="direction:ltr">> +++ cfe/trunk/test/SemaTemplate/friend-template.cpp Mon Apr 17 03:51:20 2017</div><div style="direction:ltr">> @@ -1,4 +1,4 @@</div><div style="direction:ltr">> -// RUN: %clang_cc1 -fsyntax-only -verify %s</div><div style="direction:ltr">> +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s</div><div style="direction:ltr">>  // PR5057</div><div style="direction:ltr">>  namespace test0 {</div><div style="direction:ltr">>    namespace std {</div><div style="direction:ltr">> @@ -68,17 +68,12 @@ namespace test3 {</div><div style="direction:ltr">>    Foo<int> foo;</div><div style="direction:ltr">></div><div style="direction:ltr">>    template<typename T, T Value> struct X2a;</div><div style="direction:ltr">> -</div><div style="direction:ltr">> -  template<typename T, int Size> struct X2b;</div><div style="direction:ltr">> +  template<typename T, int Size> struct X2b;    // expected-note {{previous non-type template parameter with type 'int' is here}}</div><div style="direction:ltr">></div><div style="direction:ltr">>    template<typename T></div><div style="direction:ltr">>    class X3 {</div><div style="direction:ltr">>      template<typename U, U Value> friend struct X2a;</div><div style="direction:ltr">> -</div><div style="direction:ltr">> -    // FIXME: the redeclaration note ends up here because redeclaration</div><div style="direction:ltr">> -    // lookup ends up finding the friend target from X3<int>.</div><div style="direction:ltr">> -    template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \</div><div style="direction:ltr">> -      // expected-note {{previous non-type template parameter with type 'int' is here}}</div><div style="direction:ltr">> +    template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}}</div><div style="direction:ltr">>    };</div><div style="direction:ltr">></div><div style="direction:ltr">>    X3<int> x3i; // okay</div><div style="direction:ltr">> @@ -297,14 +292,11 @@ namespace PR12585 {</div><div style="direction:ltr">>    int n = C::D<void*>().f();</div><div style="direction:ltr">></div><div style="direction:ltr">>    struct F {</div><div style="direction:ltr">> -    template<int> struct G;</div><div style="direction:ltr">> +    template<int> struct G; // expected-note {{previous}}</div><div style="direction:ltr">>    };</div><div style="direction:ltr">>    template<typename T> struct H {</div><div style="direction:ltr">> -    // FIXME: As with cases above, the note here is on an unhelpful declaration,</div><div style="direction:ltr">> -    // and should point to the declaration of G within F.</div><div style="direction:ltr">>      template<T> friend struct F::G; // \</div><div style="direction:ltr">> -      // expected-error {{different type 'char' in template redeclaration}} \</div><div style="direction:ltr">> -      // expected-note {{previous}}</div><div style="direction:ltr">> +      // expected-error {{different type 'char' in template redeclaration}}</div><div style="direction:ltr">>    };</div><div style="direction:ltr">>    H<int> h1; // ok</div><div style="direction:ltr">>    H<char> h2; // expected-note {{instantiation}}</div><div style="direction:ltr">> @@ -329,3 +321,11 @@ namespace rdar12350696 {</div><div style="direction:ltr">>      foo(b); // expected-note {{in instantiation}}</div><div style="direction:ltr">>    }</div><div style="direction:ltr">>  }</div><div style="direction:ltr">> +namespace PR30994 {</div><div style="direction:ltr">> +  void f();</div><div style="direction:ltr">> +  struct A {</div><div style="direction:ltr">> +    [[deprecated]] friend void f() {} // \</div><div style="direction:ltr">> +      expected-note {{has been explicitly marked deprecated here}}</div><div style="direction:ltr">> +  };</div><div style="direction:ltr">> +  void g() { f(); } // expected-warning {{is deprecated}}</div><div style="direction:ltr">> +}</div><div style="direction:ltr">></div><div style="direction:ltr">></div><div style="direction:ltr">> _______________________________________________</div><div style="direction:ltr">> cfe-commits mailing list</div><div style="direction:ltr">> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a></div><div style="direction:ltr">> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a></div>
</blockquote></div></div>