<div dir="ltr">On Thu, Aug 15, 2013 at 8:04 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div class="h5">On Thu, Aug 15, 2013 at 6:15 PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br>
<div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>On Thu, Aug 15, 2013 at 5:29 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></span> wrote:<br>

<div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>On Thu, Aug 15, 2013 at 4:59 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></span> wrote:<br>


</div></div><div class="gmail_extra"><div><div><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: efriedma<br>
Date: Thu Aug 15 18:59:20 2013<br>
New Revision: 188510<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=188510&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=188510&view=rev</a><br>
Log:<br>
Fix for dependent contexts in alias templates.<br>
<br>
When we are parsing a type for an alias template, we are not entering<br>
the context, so we can't look into dependent classes.  Make sure the<br>
parser handles this correctly.<br>
<br>
PR16904.<br>
<br>
Modified:<br>
    cfe/trunk/lib/Parse/ParseDecl.cpp<br>
    cfe/trunk/test/SemaTemplate/alias-templates.cpp<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=188510&r1=188509&r2=188510&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=188510&r1=188509&r2=188510&view=diff</a><br>




==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Aug 15 18:59:20 2013<br>
@@ -2436,7 +2436,7 @@ void Parser::ParseDeclarationSpecifiers(<br>
<br>
     case tok::coloncolon: // ::foo::bar<br>
       // C++ scope specifier.  Annotate and loop, or bail out on error.<br>
-      if (TryAnnotateCXXScopeToken(true)) {<br>
+      if (TryAnnotateCXXScopeToken(EnteringContext)) {<br>
         if (!DS.hasTypeSpecifier())<br>
           DS.SetTypeSpecError();<br>
         goto DoneWithDeclSpec;<br>
@@ -2632,7 +2632,7 @@ void Parser::ParseDeclarationSpecifiers(<br>
       // In C++, check to see if this is a scope specifier like foo::bar::, if<br>
       // so handle it as such.  This is important for ctor parsing.<br>
       if (getLangOpts().CPlusPlus) {<br>
-        if (TryAnnotateCXXScopeToken(true)) {<br>
+        if (TryAnnotateCXXScopeToken(EnteringContext)) {<br>
           if (!DS.hasTypeSpecifier())<br>
             DS.SetTypeSpecError();<br>
           goto DoneWithDeclSpec;<br><br></blockquote><div><br></div><div> </div></div></div></div>Ugh... I just spent some more time thinking about this; while this fix doesn't break anything as far as I know, it isn't really complete.  Consider the following testcase:</div>



<div class="gmail_extra"><br></div><div class="gmail_extra"><p style="margin:0px;font-size:11px;font-family:Menlo">template <typename,typename></p>
<p style="margin:0px;font-size:11px;font-family:Menlo">struct base {</p>
<p style="margin:0px;font-size:11px;font-family:Menlo">  template <typename> struct derived;</p>
<p style="margin:0px;font-size:11px;font-family:Menlo">};</p>
<p style="margin:0px;font-size:11px;font-family:Menlo">template <typename T, typename U, typename V> base<T, U>::derived<V> foo();</p><div><br></div><div>There's a missing typename keyword, but clang fails to detect this.  Any suggestions? </div>


</div></div></blockquote></div><br></div></div></div><div class="gmail_extra">This looks closely related to PR15554. Perhaps we could introduce an 'unknown' value for EnteringContext (where '<' is known to introduce a template, but which is otherwise parsed as if we're not entering the context), and then once we've parsed far enough to know whether we're entering the context, either transform it to the concrete form or diagnose missing 'template' keywords.</div>


</div>
</blockquote></div><br></div></div></div><div class="gmail_extra">If we had infrastructure like that, we could use it here.  If we see an annotated scope which has a dependent type in the nested-name-specifier, we can assume we're looking at a constructor declaration (and we would get appropriate errors if it turns out to be something else, like a type).</div>

<div class="gmail_extra"><br></div><div class="gmail_extra">Actually, if we were going to go your suggested route, we might just want to change "EnteringContext" to "MaybeEnteringContext" instead of changing it to a tri-state; I'm not sure there are actually any cases where we want the current EnteringContext=true, and if there were it would be easy enough to emulate.<br>

</div><div class="gmail_extra"><br></div><div class="gmail_extra">Another related testcase (we don't diagnose the missing template keyword):</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">

<div class="gmail_extra">template<typename> struct S { </div><div class="gmail_extra">  template<typename> struct SS;</div><div class="gmail_extra">};</div><div class="gmail_extra">template<typename T> struct S2 {            </div>

<div class="gmail_extra">  template<typename U> enum S<T>::SS<U>::E foo();</div><div class="gmail_extra">};</div></div></div><div class="gmail_extra"><br><br></div></div></blockquote><div><br></div><div>
Filed <a href="http://llvm.org/bugs/show_bug.cgi?id=16908">http://llvm.org/bugs/show_bug.cgi?id=16908</a> and <a href="http://llvm.org/bugs/show_bug.cgi?id=16909">http://llvm.org/bugs/show_bug.cgi?id=16909</a>.<br></div><div>
<br>-Eli<br></div></div></div></div>