<div dir="ltr">Committed as r180707.<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Apr 26, 2013 at 3:31 PM, Ismail Pazarbasi <span dir="ltr"><<a href="mailto:ismail.pazarbasi@gmail.com" target="_blank">ismail.pazarbasi@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Thank you Richard,<br><br>could you please commit this?<br></div></div><div class="HOEnZb"><div class="h5">
<div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Apr 26, 2013 at 5:14 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">LGTM<div><div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Apr 22, 2013 at 2:10 PM, Ismail Pazarbasi <span dir="ltr"><<a href="mailto:ismail.pazarbasi@gmail.com" target="_blank">ismail.pazarbasi@gmail.com</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">  I have added a few test cases for alias templates, a function template - to ensure I didn't break it - and extended previous one slightly. I initially had a FIXME for alias templates, but removed it right before I submitted the patch. I can't find a way to access a private variable/field from an alias template context.<br>



<div><br>
Hi rsmith,<br>
<br>
<a href="http://llvm-reviews.chandlerc.com/D696" target="_blank">http://llvm-reviews.chandlerc.com/D696</a><br>
<br>
CHANGE SINCE LAST DIFF<br>
</div>  <a href="http://llvm-reviews.chandlerc.com/D696?vs=1703&id=1718#toc" target="_blank">http://llvm-reviews.chandlerc.com/D696?vs=1703&id=1718#toc</a><br>
<div><br>
Files:<br>
  lib/Sema/SemaAccess.cpp<br>
  test/SemaCXX/access.cpp<br>
<br>
Index: lib/Sema/SemaAccess.cpp<br>
===================================================================<br>
--- lib/Sema/SemaAccess.cpp<br>
+++ lib/Sema/SemaAccess.cpp<br>
</div>@@ -1487,7 +1487,7 @@<br>
<div>     if (!DC->isFunctionOrMethod())<br>
       DC = FN;<br>
</div><div>   } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {<br>
-    DC = dyn_cast<DeclContext>(TD->getTemplatedDecl());<br>
</div>+    DC = cast<DeclContext>(TD->getTemplatedDecl());<br>
<div>   }<br>
<br>
   EffectiveContext EC(DC);<br>
Index: test/SemaCXX/access.cpp<br>
===================================================================<br>
--- test/SemaCXX/access.cpp<br>
+++ test/SemaCXX/access.cpp<br>
</div>@@ -35,24 +35,74 @@<br>
<br>
 // PR15209<br>
<div> namespace PR15209 {<br>
-  class A {<br>
-    typedef int I;  // expected-note {{implicitly declared private here}}<br>
-    template<int> friend struct B;<br>
-    template<int> struct C;<br>
-    template<int, typename T> friend struct E;<br>
-    template<template<int> class T> friend struct TT;<br>
-    static constexpr int x = 0;<br>
-  };<br>
-  template<A::I> struct B { };<br>
</div>+  namespace alias_templates {<br>
+    template<typename T1, typename T2> struct U { };<br>
+    template<typename T1> using W = U<T1, float>;<br>
<div><br>
-  template<A::I> struct A::C { };<br>
</div><div>+    class A {<br>
+      typedef int I;<br>
</div>+      static constexpr I x = 0; // expected-note {{implicitly declared private here}}<br>
+      static constexpr I y = 42; // expected-note {{implicitly declared private here}}<br>
+      friend W<int>;<br>
+    };<br>
<div><br>
-  template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::A'}}<br>
</div>+    template<typename T1><br>
+    struct U<T1, float>  {<br>
+      int v_;<br>
+      // the following will trigger for U<float, float> instantiation, via W<float><br>
+      U() : v_(A::x) { } // expected-error {{'x' is a private member of 'PR15209::alias_templates::A'}}<br>
+    };<br>
<div><br>
-  template<A::I, typename T> struct E { };<br>
</div>+    template<typename T1><br>
+    struct U<T1, int> {<br>
+      int v_;<br>
+      U() : v_(A::y) { } // expected-error {{'y' is a private member of 'PR15209::alias_templates::A'}}<br>
+    };<br>
<div><br>
-  template<template<A::I> class T> struct TT {<br>
-    T<A::I(0)> t;<br>
-  };<br>
-  template struct TT<B>;<br>
</div>+    template struct U<int, int>; // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<int, int>::U' requested here}}<br>
+<br>
+    void f()<br>
+    {<br>
+      W<int>();<br>
+      // we should issue diagnostics for the following<br>
+      W<float>(); // expected-note {{in instantiation of member function 'PR15209::alias_templates::U<float, float>::U' requested here}}<br>
+    }<br>
+  }<br>
+<br>
+  namespace templates {<br>
<div>+    class A {<br>
+      typedef int I;  // expected-note {{implicitly declared private here}}<br>
</div>+      static constexpr I x = 0; // expected-note {{implicitly declared private here}}<br>
<div>+<br>
+      template<int> friend struct B;<br>
+      template<int> struct C;<br>
</div><div>+      template<template<int> class T> friend struct TT;<br>
</div>+      template<typename T> friend void funct(T);<br>
<div>+    };<br>
+    template<A::I> struct B { };<br>
+<br>
+    template<A::I> struct A::C { };<br>
+<br>
</div><div>+    template<template<A::I> class T> struct TT {<br>
</div>+      T<A::x> t;<br>
+    };<br>
<div>+<br>
+    template struct TT<B>;<br>
</div>+    template<A::I> struct D { };  // expected-error {{'I' is a private member of 'PR15209::templates::A'}}<br>
+    template struct TT<D>;<br>
+<br>
+    // function template case<br>
+    template<typename T><br>
+    void funct(T)<br>
+    {<br>
+      (void)A::x;<br>
+    }<br>
+<br>
+    template void funct<int>(int);<br>
+<br>
+    void f()<br>
+    {<br>
+      (void)A::x;  // expected-error {{'x' is a private member of 'PR15209::templates::A'}}<br>
+    }<br>
+  }<br>
 }<br>
</blockquote></div><br></div></div></div></div>
</blockquote></div><br></div>
</div></div></blockquote></div><br></div>