On Thu, Aug 15, 2013 at 6:15 PM, Richard Smith <[email protected]>wrote:
> On Thu, Aug 15, 2013 at 5:29 PM, Eli Friedman <[email protected]>wrote: > >> On Thu, Aug 15, 2013 at 4:59 PM, Eli Friedman <[email protected]>wrote: >> >>> Author: efriedma >>> Date: Thu Aug 15 18:59:20 2013 >>> New Revision: 188510 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=188510&view=rev >>> Log: >>> Fix for dependent contexts in alias templates. >>> >>> When we are parsing a type for an alias template, we are not entering >>> the context, so we can't look into dependent classes. Make sure the >>> parser handles this correctly. >>> >>> PR16904. >>> >>> Modified: >>> cfe/trunk/lib/Parse/ParseDecl.cpp >>> cfe/trunk/test/SemaTemplate/alias-templates.cpp >>> >>> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=188510&r1=188509&r2=188510&view=diff >>> >>> ============================================================================== >>> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) >>> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Aug 15 18:59:20 2013 >>> @@ -2436,7 +2436,7 @@ void Parser::ParseDeclarationSpecifiers( >>> >>> case tok::coloncolon: // ::foo::bar >>> // C++ scope specifier. Annotate and loop, or bail out on error. >>> - if (TryAnnotateCXXScopeToken(true)) { >>> + if (TryAnnotateCXXScopeToken(EnteringContext)) { >>> if (!DS.hasTypeSpecifier()) >>> DS.SetTypeSpecError(); >>> goto DoneWithDeclSpec; >>> @@ -2632,7 +2632,7 @@ void Parser::ParseDeclarationSpecifiers( >>> // In C++, check to see if this is a scope specifier like >>> foo::bar::, if >>> // so handle it as such. This is important for ctor parsing. >>> if (getLangOpts().CPlusPlus) { >>> - if (TryAnnotateCXXScopeToken(true)) { >>> + if (TryAnnotateCXXScopeToken(EnteringContext)) { >>> if (!DS.hasTypeSpecifier()) >>> DS.SetTypeSpecError(); >>> goto DoneWithDeclSpec; >>> >>> >> >> 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: >> >> template <typename,typename> >> >> struct base { >> >> template <typename> struct derived; >> >> }; >> >> template <typename T, typename U, typename V> base<T, U>::derived<V> >> foo(); >> >> There's a missing typename keyword, but clang fails to detect this. Any >> suggestions? >> > > 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. > 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). 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. Another related testcase (we don't diagnose the missing template keyword): template<typename> struct S { template<typename> struct SS; }; template<typename T> struct S2 { template<typename U> enum S<T>::SS<U>::E foo(); }; -Eli
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
