From: Douglas Gregor Date: Tue, 1 Mar 2011 16:44:30 +0000 (+0000) Subject: When building a type for a typename specifier, check specifically for X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ef24c4b85e354255240bbbc21772098e6c3f6ae8;p=clang When building a type for a typename specifier, check specifically for a dependent template name rather than (indirectly and incorrectly) trying to determine whether we can compute a context for the nested-name-specifier. Fixes a GCC testsuite regression, . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126749 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index fbb7246533..a710f94436 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -5950,62 +5950,56 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, translateTemplateArguments(TemplateArgsIn, TemplateArgs); TemplateName Template = TemplateIn.get(); - - if (computeDeclContext(SS, false)) { - // If we can compute a declaration context, then the "typename" - // keyword was superfluous. Just build an ElaboratedType to keep - // track of the nested-name-specifier. - - QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs); - if (T.isNull()) - return true; + if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { + // Construct a dependent template specialization type. + assert(DTN && "dependent template has non-dependent name?"); + assert(DTN->getQualifier() + == static_cast(SS.getScopeRep())); + QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename, + DTN->getQualifier(), + DTN->getIdentifier(), + TemplateArgs); - // Provide source-location information for the template specialization - // type. + // Create source-location information for this type. TypeLocBuilder Builder; - TemplateSpecializationTypeLoc SpecTL - = Builder.push(T); - - // FIXME: No place to set the location of the 'template' keyword! + DependentTemplateSpecializationTypeLoc SpecTL + = Builder.push(T); SpecTL.setLAngleLoc(LAngleLoc); SpecTL.setRAngleLoc(RAngleLoc); - SpecTL.setTemplateNameLoc(TemplateNameLoc); + SpecTL.setKeywordLoc(TypenameLoc); + SpecTL.setNameLoc(TemplateNameLoc); for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); - T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T); - ElaboratedTypeLoc TL = Builder.push(T); - TL.setKeywordLoc(TypenameLoc); - TL.setQualifierLoc(SS.getWithLocInContext(Context)); - - TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T); - return CreateParsedType(T, TSI); + // FIXME: Nested-name-specifier source locations. + SpecTL.setQualifierRange(SS.getRange()); + return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); } - // Construct a dependent template specialization type. - DependentTemplateName *DTN = Template.getAsDependentTemplateName(); - assert(DTN && "dependent template has non-dependent name?"); - assert(DTN->getQualifier() - == static_cast(SS.getScopeRep())); - QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename, - DTN->getQualifier(), - DTN->getIdentifier(), - TemplateArgs); + QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs); + if (T.isNull()) + return true; - // Create source-location information for this type. + // Provide source-location information for the template specialization + // type. TypeLocBuilder Builder; - DependentTemplateSpecializationTypeLoc SpecTL - = Builder.push(T); + TemplateSpecializationTypeLoc SpecTL + = Builder.push(T); + + // FIXME: No place to set the location of the 'template' keyword! SpecTL.setLAngleLoc(LAngleLoc); SpecTL.setRAngleLoc(RAngleLoc); - SpecTL.setKeywordLoc(TypenameLoc); - SpecTL.setNameLoc(TemplateNameLoc); + SpecTL.setTemplateNameLoc(TemplateNameLoc); for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); - // FIXME: Nested-name-specifier source locations. - SpecTL.setQualifierRange(SS.getRange()); - return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); + T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T); + ElaboratedTypeLoc TL = Builder.push(T); + TL.setKeywordLoc(TypenameLoc); + TL.setQualifierLoc(SS.getWithLocInContext(Context)); + + TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T); + return CreateParsedType(T, TSI); } diff --git a/test/SemaTemplate/typename-specifier-4.cpp b/test/SemaTemplate/typename-specifier-4.cpp index 38045e0a31..44cf966e33 100644 --- a/test/SemaTemplate/typename-specifier-4.cpp +++ b/test/SemaTemplate/typename-specifier-4.cpp @@ -154,3 +154,11 @@ namespace rdar8740998 { xi.f(); } } + +namespace rdar9068589 { + // From GCC PR c++/13950 + template struct Base {}; + template struct Derived: public Base { + typename Derived::template Base* p1; + }; +}