r206442 - Refactor all the checking for missing 'template<>'s when a declaration has a
Richard Smith
richard at metafoo.co.uk
Thu Jan 29 18:43:31 PST 2015
On Thu, Jan 29, 2015 at 6:35 PM, Nico Weber <thakis at chromium.org> wrote:
> On Thu, Jan 29, 2015 at 5:51 PM, Nico Weber <thakis at chromium.org> wrote:
>
>> r227540, thanks. I'll look
>> through MatchTemplateParametersToScopeSpecifier() for places that need to
>> set Invalid.
>>
>
> I think it's all good. All but one of the `return nullptr`s
> call CheckExplicitSpecialization() (maybe
> through DiagnoseMissingExplicitSpecialization()), and that sets Invalid to
> true.
>
So it does, thanks!
On Thu, Jan 29, 2015 at 4:24 PM, Richard Smith <richard at metafoo.co.uk>
>> wrote:
>>
>>> It looks like there are paths through
>>> MatchTemplateParametersToScopeSpecifier that return nullptr on invalid
>>> inputs but don't set Invalid to true; I don't think this patch is
>>> sufficient, though it does seem correct as far as it goes.
>>>
>>> On Wed, Jan 28, 2015 at 8:14 PM, Nico Weber <thakis at chromium.org> wrote:
>>>
>>>> On Wed, Apr 16, 2014 at 8:29 PM, Richard Smith <
>>>> richard-llvm at metafoo.co.uk> wrote:
>>>>
>>>>> Author: rsmith
>>>>> Date: Wed Apr 16 22:29:33 2014
>>>>> New Revision: 206442
>>>>>
>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=206442&view=rev
>>>>> Log:
>>>>> Refactor all the checking for missing 'template<>'s when a declaration
>>>>> has a
>>>>> template-id after its scope specifier into a single place.
>>>>>
>>>>> Modified:
>>>>> cfe/trunk/include/clang/Sema/Sema.h
>>>>> cfe/trunk/lib/Parse/ParseDeclCXX.cpp
>>>>> cfe/trunk/lib/Sema/SemaDecl.cpp
>>>>> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>>>>> cfe/trunk/lib/Sema/SemaTemplate.cpp
>>>>> cfe/trunk/test/FixIt/fixit.cpp
>>>>>
>>>>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=206442&r1=206441&r2=206442&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>>>>> +++ cfe/trunk/include/clang/Sema/Sema.h Wed Apr 16 22:29:33 2014
>>>>> @@ -5197,7 +5197,8 @@ public:
>>>>> TemplateParamListContext TPC);
>>>>> TemplateParameterList *MatchTemplateParametersToScopeSpecifier(
>>>>> SourceLocation DeclStartLoc, SourceLocation DeclLoc,
>>>>> - const CXXScopeSpec &SS, ArrayRef<TemplateParameterList *>
>>>>> ParamLists,
>>>>> + const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId,
>>>>> + ArrayRef<TemplateParameterList *> ParamLists,
>>>>> bool IsFriend, bool &IsExplicitSpecialization, bool &Invalid);
>>>>>
>>>>> DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec,
>>>>> TagUseKind TUK,
>>>>> @@ -5279,12 +5280,7 @@ public:
>>>>> ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
>>>>> TagUseKind TUK,
>>>>> SourceLocation KWLoc,
>>>>> SourceLocation ModulePrivateLoc,
>>>>> - CXXScopeSpec &SS,
>>>>> - TemplateTy Template,
>>>>> - SourceLocation TemplateNameLoc,
>>>>> - SourceLocation LAngleLoc,
>>>>> - ASTTemplateArgsPtr TemplateArgs,
>>>>> - SourceLocation RAngleLoc,
>>>>> + TemplateIdAnnotation &TemplateId,
>>>>> AttributeList *Attr,
>>>>> MultiTemplateParamsArg
>>>>> TemplateParameterLists);
>>>>>
>>>>>
>>>>> Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=206442&r1=206441&r2=206442&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
>>>>> +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Apr 16 22:29:33 2014
>>>>> @@ -1541,18 +1541,11 @@ void Parser::ParseClassSpecifier(tok::To
>>>>> }
>>>>>
>>>>> // Build the class template specialization.
>>>>> - TagOrTempResult
>>>>> - = Actions.ActOnClassTemplateSpecialization(getCurScope(),
>>>>> TagType, TUK,
>>>>> - StartLoc, DS.getModulePrivateSpecLoc(), SS,
>>>>> - TemplateId->Template,
>>>>> - TemplateId->TemplateNameLoc,
>>>>> - TemplateId->LAngleLoc,
>>>>> - TemplateArgsPtr,
>>>>> - TemplateId->RAngleLoc,
>>>>> - attrs.getList(),
>>>>> - MultiTemplateParamsArg(
>>>>> - TemplateParams?
>>>>> &(*TemplateParams)[0] : 0,
>>>>> - TemplateParams?
>>>>> TemplateParams->size() : 0));
>>>>> + TagOrTempResult = Actions.ActOnClassTemplateSpecialization(
>>>>> + getCurScope(), TagType, TUK, StartLoc,
>>>>> DS.getModulePrivateSpecLoc(),
>>>>> + *TemplateId, attrs.getList(),
>>>>> + MultiTemplateParamsArg(TemplateParams ?
>>>>> &(*TemplateParams)[0] : 0,
>>>>> + TemplateParams ?
>>>>> TemplateParams->size() : 0));
>>>>> }
>>>>> } else if (TemplateInfo.Kind ==
>>>>> ParsedTemplateInfo::ExplicitInstantiation &&
>>>>> TUK == Sema::TUK_Declaration) {
>>>>>
>>>>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=206442&r1=206441&r2=206442&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>>>>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Apr 16 22:29:33 2014
>>>>> @@ -5228,29 +5228,13 @@ Sema::ActOnVariableDeclarator(Scope *S,
>>>>> // determine whether we have a template or a template
>>>>> specialization.
>>>>> TemplateParams = MatchTemplateParametersToScopeSpecifier(
>>>>> D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
>>>>> - D.getCXXScopeSpec(), TemplateParamLists,
>>>>> + D.getCXXScopeSpec(),
>>>>> + D.getName().getKind() == UnqualifiedId::IK_TemplateId
>>>>> + ? D.getName().TemplateId
>>>>> + : 0,
>>>>> + TemplateParamLists,
>>>>> /*never a friend*/ false, IsExplicitSpecialization, Invalid);
>>>>>
>>>>> - if (D.getName().getKind() == UnqualifiedId::IK_TemplateId &&
>>>>> - !TemplateParams) {
>>>>> - TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
>>>>> -
>>>>> - // We have encountered something that the user meant to be a
>>>>> - // specialization (because it has explicitly-specified template
>>>>> - // arguments) but that was not introduced with a "template<>"
>>>>> (or had
>>>>> - // too few of them).
>>>>> - // FIXME: Differentiate between attempts for explicit
>>>>> instantiations
>>>>> - // (starting with "template") and the rest.
>>>>> - Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header)
>>>>> - << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
>>>>> - << FixItHint::CreateInsertion(D.getDeclSpec().getLocStart(),
>>>>> - "template<> ");
>>>>> - IsExplicitSpecialization = true;
>>>>> - TemplateParams = TemplateParameterList::Create(Context,
>>>>> SourceLocation(),
>>>>> -
>>>>> SourceLocation(), 0, 0,
>>>>> -
>>>>> SourceLocation());
>>>>> - }
>>>>> -
>>>>> if (TemplateParams) {
>>>>> if (!TemplateParams->size() &&
>>>>> D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
>>>>> @@ -5283,6 +5267,9 @@ Sema::ActOnVariableDeclarator(Scope *S,
>>>>> : diag::ext_variable_template);
>>>>> }
>>>>> }
>>>>> + } else {
>>>>> + assert(D.getName().getKind() != UnqualifiedId::IK_TemplateId &&
>>>>> + "should have a 'template<>' for this decl");
>>>>>
>>>>
>>>> This assert fires on some invalid inputs, for example
>>>>
>>>> template <typename> struct CT2 {
>>>> template <class U> struct X;
>>>> };
>>>> template <typename T> int CT2<int>::X<>;
>>>>
>>>> Is the right fix just to change this to assert(Invalid || D.getNameā¦)?
>>>> (Also attached in patch form.)
>>>>
>>>>
>>>>> }
>>>>>
>>>>> if (IsVariableTemplateSpecialization) {
>>>>> @@ -6709,8 +6696,12 @@ Sema::ActOnFunctionDeclarator(Scope *S,
>>>>> if (TemplateParameterList *TemplateParams =
>>>>> MatchTemplateParametersToScopeSpecifier(
>>>>> D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
>>>>> - D.getCXXScopeSpec(), TemplateParamLists, isFriend,
>>>>> - isExplicitSpecialization, Invalid)) {
>>>>> + D.getCXXScopeSpec(),
>>>>> + D.getName().getKind() == UnqualifiedId::IK_TemplateId
>>>>> + ? D.getName().TemplateId
>>>>> + : 0,
>>>>> + TemplateParamLists, isFriend,
>>>>> isExplicitSpecialization,
>>>>> + Invalid)) {
>>>>> if (TemplateParams->size() > 0) {
>>>>> // This is a function template
>>>>>
>>>>> @@ -6751,9 +6742,10 @@ Sema::ActOnFunctionDeclarator(Scope *S,
>>>>> // This is a function template specialization.
>>>>> isFunctionTemplateSpecialization = true;
>>>>> // For source fidelity, store all the template param lists.
>>>>> - NewFD->setTemplateParameterListsInfo(Context,
>>>>> -
>>>>> TemplateParamLists.size(),
>>>>> -
>>>>> TemplateParamLists.data());
>>>>> + if (TemplateParamLists.size() > 0)
>>>>> + NewFD->setTemplateParameterListsInfo(Context,
>>>>> +
>>>>> TemplateParamLists.size(),
>>>>> +
>>>>> TemplateParamLists.data());
>>>>>
>>>>> // C++0x [temp.expl.spec]p20 forbids "template<> friend void
>>>>> foo(int);".
>>>>> if (isFriend) {
>>>>> @@ -7152,21 +7144,10 @@ Sema::ActOnFunctionDeclarator(Scope *S,
>>>>> << SourceRange(TemplateId->LAngleLoc,
>>>>> TemplateId->RAngleLoc);
>>>>>
>>>>> HasExplicitTemplateArgs = false;
>>>>> - } else if (!isFunctionTemplateSpecialization &&
>>>>> - !D.getDeclSpec().isFriendSpecified()) {
>>>>> - // We have encountered something that the user meant to be a
>>>>> - // specialization (because it has explicitly-specified
>>>>> template
>>>>> - // arguments) but that was not introduced with a "template<>"
>>>>> (or had
>>>>> - // too few of them).
>>>>> - // FIXME: Differentiate between attempts for explicit
>>>>> instantiations
>>>>> - // (starting with "template") and the rest.
>>>>> - Diag(D.getIdentifierLoc(),
>>>>> diag::err_template_spec_needs_header)
>>>>> - << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
>>>>> - << FixItHint::CreateInsertion(
>>>>> - D.getDeclSpec().getLocStart(),
>>>>> - "template<> ");
>>>>> - isFunctionTemplateSpecialization = true;
>>>>> } else {
>>>>> + assert((isFunctionTemplateSpecialization ||
>>>>> + D.getDeclSpec().isFriendSpecified()) &&
>>>>> + "should have a 'template<>' for this decl");
>>>>> // "friend void foo<>(int);" is an implicit specialization
>>>>> decl.
>>>>> isFunctionTemplateSpecialization = true;
>>>>> }
>>>>> @@ -7178,7 +7159,7 @@ Sema::ActOnFunctionDeclarator(Scope *S,
>>>>> // friend void foo<>(int);
>>>>> // Go ahead and fake up a template id.
>>>>> HasExplicitTemplateArgs = true;
>>>>> - TemplateArgs.setLAngleLoc(D.getIdentifierLoc());
>>>>> + TemplateArgs.setLAngleLoc(D.getIdentifierLoc());
>>>>> TemplateArgs.setRAngleLoc(D.getIdentifierLoc());
>>>>> }
>>>>>
>>>>> @@ -10569,8 +10550,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned
>>>>> (SS.isNotEmpty() && TUK != TUK_Reference)) {
>>>>> if (TemplateParameterList *TemplateParams =
>>>>> MatchTemplateParametersToScopeSpecifier(
>>>>> - KWLoc, NameLoc, SS, TemplateParameterLists, TUK ==
>>>>> TUK_Friend,
>>>>> - isExplicitSpecialization, Invalid)) {
>>>>> + KWLoc, NameLoc, SS, 0, TemplateParameterLists,
>>>>> + TUK == TUK_Friend, isExplicitSpecialization,
>>>>> Invalid)) {
>>>>> if (Kind == TTK_Enum) {
>>>>> Diag(KWLoc, diag::err_enum_template);
>>>>> return 0;
>>>>>
>>>>> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=206442&r1=206441&r2=206442&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
>>>>> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Apr 16 22:29:33 2014
>>>>> @@ -11370,7 +11370,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scop
>>>>>
>>>>> if (TemplateParameterList *TemplateParams =
>>>>> MatchTemplateParametersToScopeSpecifier(
>>>>> - TagLoc, NameLoc, SS, TempParamLists, /*friend*/ true,
>>>>> + TagLoc, NameLoc, SS, 0, TempParamLists, /*friend*/ true,
>>>>> isExplicitSpecialization, Invalid)) {
>>>>> if (TemplateParams->size() > 0) {
>>>>> // This is a declaration of a class template.
>>>>>
>>>>> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=206442&r1=206441&r2=206442&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
>>>>> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Apr 16 22:29:33 2014
>>>>> @@ -1593,6 +1593,9 @@ static SourceRange getRangeOfTypeInNeste
>>>>> /// parameter lists. This scope specifier precedes a qualified name
>>>>> that is
>>>>> /// being declared.
>>>>> ///
>>>>> +/// \param TemplateId The template-id following the scope specifier,
>>>>> if there
>>>>> +/// is one. Used to check for a missing 'template<>'.
>>>>> +///
>>>>> /// \param ParamLists the template parameter lists, from the
>>>>> outermost to the
>>>>> /// innermost template parameter lists.
>>>>> ///
>>>>> @@ -1611,6 +1614,7 @@ static SourceRange getRangeOfTypeInNeste
>>>>> /// itself a template).
>>>>> TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
>>>>> SourceLocation DeclStartLoc, SourceLocation DeclLoc, const
>>>>> CXXScopeSpec &SS,
>>>>> + TemplateIdAnnotation *TemplateId,
>>>>> ArrayRef<TemplateParameterList *> ParamLists, bool IsFriend,
>>>>> bool &IsExplicitSpecialization, bool &Invalid) {
>>>>> IsExplicitSpecialization = false;
>>>>> @@ -1830,6 +1834,7 @@ TemplateParameterList *Sema::MatchTempla
>>>>> else
>>>>> ExpectedTemplateLoc = DeclStartLoc;
>>>>>
>>>>> + // FIXME: Don't recover this way if we
>>>>> SawNonEmptyTemplateParameterList.
>>>>> Diag(DeclLoc, diag::err_template_spec_needs_header)
>>>>> << getRangeOfTypeInNestedNameSpecifier(Context, T, SS)
>>>>> << FixItHint::CreateInsertion(ExpectedTemplateLoc,
>>>>> "template<> ");
>>>>> @@ -1875,12 +1880,33 @@ TemplateParameterList *Sema::MatchTempla
>>>>> continue;
>>>>> }
>>>>> }
>>>>> -
>>>>> +
>>>>> // If there were at least as many template-ids as there were
>>>>> template
>>>>> // parameter lists, then there are no template parameter lists
>>>>> remaining for
>>>>> // the declaration itself.
>>>>> - if (ParamIdx >= ParamLists.size())
>>>>> + if (ParamIdx >= ParamLists.size()) {
>>>>> + if (TemplateId && !IsFriend) {
>>>>> + // FIXME: Don't recover this way if we
>>>>> SawNonEmptyTemplateParameterList.
>>>>> + // We don't have a template header for the declaration itself,
>>>>> but we
>>>>> + // should.
>>>>> + SourceLocation ExpectedTemplateLoc;
>>>>> + if (!ParamLists.empty())
>>>>> + ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc();
>>>>> + else
>>>>> + ExpectedTemplateLoc = DeclStartLoc;
>>>>> + Diag(DeclLoc, diag::err_template_spec_needs_header)
>>>>> + << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)
>>>>> + << FixItHint::CreateInsertion(ExpectedTemplateLoc,
>>>>> "template<> ");
>>>>> + IsExplicitSpecialization = true;
>>>>> +
>>>>> + // Fabricate an empty template parameter list for the invented
>>>>> header.
>>>>> + return TemplateParameterList::Create(Context, SourceLocation(),
>>>>> + SourceLocation(), 0, 0,
>>>>> + SourceLocation());
>>>>> + }
>>>>> +
>>>>> return 0;
>>>>> + }
>>>>>
>>>>> // If there were too many template parameter lists, complain about
>>>>> that now.
>>>>> if (ParamIdx < ParamLists.size() - 1) {
>>>>> @@ -2355,6 +2381,17 @@ static bool isSameAsPrimaryTemplate(Temp
>>>>> return true;
>>>>> }
>>>>>
>>>>> +/// Convert the parser's template argument list representation into
>>>>> our form.
>>>>> +static TemplateArgumentListInfo
>>>>> +makeTemplateArgumentListInfo(Sema &S, TemplateIdAnnotation
>>>>> &TemplateId) {
>>>>> + TemplateArgumentListInfo TemplateArgs(TemplateId.LAngleLoc,
>>>>> + TemplateId.RAngleLoc);
>>>>> + ASTTemplateArgsPtr TemplateArgsPtr(TemplateId.getTemplateArgs(),
>>>>> + TemplateId.NumArgs);
>>>>> + S.translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
>>>>> + return TemplateArgs;
>>>>> +}
>>>>> +
>>>>> DeclResult Sema::ActOnVarTemplateSpecialization(
>>>>> Scope *S, Declarator &D, TypeSourceInfo *DI, SourceLocation
>>>>> TemplateKWLoc,
>>>>> TemplateParameterList *TemplateParams, VarDecl::StorageClass SC,
>>>>> @@ -2364,13 +2401,12 @@ DeclResult Sema::ActOnVarTemplateSpecial
>>>>> "Variable template specialization is declared with a
>>>>> template it.");
>>>>>
>>>>> TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
>>>>> + TemplateArgumentListInfo TemplateArgs =
>>>>> + makeTemplateArgumentListInfo(*this, *TemplateId);
>>>>> SourceLocation TemplateNameLoc = D.getIdentifierLoc();
>>>>> SourceLocation LAngleLoc = TemplateId->LAngleLoc;
>>>>> SourceLocation RAngleLoc = TemplateId->RAngleLoc;
>>>>> - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
>>>>> - TemplateId->NumArgs);
>>>>> - TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
>>>>> - translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
>>>>> +
>>>>> TemplateName Name = TemplateId->Template.get();
>>>>>
>>>>> // The template-id must name a variable template.
>>>>> @@ -5840,23 +5876,23 @@ Sema::ActOnClassTemplateSpecialization(S
>>>>> TagUseKind TUK,
>>>>> SourceLocation KWLoc,
>>>>> SourceLocation
>>>>> ModulePrivateLoc,
>>>>> - CXXScopeSpec &SS,
>>>>> - TemplateTy TemplateD,
>>>>> - SourceLocation TemplateNameLoc,
>>>>> - SourceLocation LAngleLoc,
>>>>> - ASTTemplateArgsPtr
>>>>> TemplateArgsIn,
>>>>> - SourceLocation RAngleLoc,
>>>>> + TemplateIdAnnotation
>>>>> &TemplateId,
>>>>> AttributeList *Attr,
>>>>> MultiTemplateParamsArg
>>>>> TemplateParameterLists) {
>>>>> assert(TUK != TUK_Reference && "References are not
>>>>> specializations");
>>>>>
>>>>> + CXXScopeSpec &SS = TemplateId.SS;
>>>>> +
>>>>> // NOTE: KWLoc is the location of the tag keyword. This will instead
>>>>> // store the location of the outermost template keyword in the
>>>>> declaration.
>>>>> SourceLocation TemplateKWLoc = TemplateParameterLists.size() > 0
>>>>> - ? TemplateParameterLists[0]->getTemplateLoc() : SourceLocation();
>>>>> + ? TemplateParameterLists[0]->getTemplateLoc() : KWLoc;
>>>>> + SourceLocation TemplateNameLoc = TemplateId.TemplateNameLoc;
>>>>> + SourceLocation LAngleLoc = TemplateId.LAngleLoc;
>>>>> + SourceLocation RAngleLoc = TemplateId.RAngleLoc;
>>>>>
>>>>> // Find the class template we're specializing
>>>>> - TemplateName Name = TemplateD.get();
>>>>> + TemplateName Name = TemplateId.Template.get();
>>>>> ClassTemplateDecl *ClassTemplate
>>>>> = dyn_cast_or_null<ClassTemplateDecl>(Name.getAsTemplateDecl());
>>>>>
>>>>> @@ -5877,8 +5913,9 @@ Sema::ActOnClassTemplateSpecialization(S
>>>>> bool Invalid = false;
>>>>> TemplateParameterList *TemplateParams =
>>>>> MatchTemplateParametersToScopeSpecifier(
>>>>> - TemplateNameLoc, TemplateNameLoc, SS,
>>>>> TemplateParameterLists,
>>>>> - TUK == TUK_Friend, isExplicitSpecialization, Invalid);
>>>>> + KWLoc, TemplateNameLoc, SS, &TemplateId,
>>>>> + TemplateParameterLists, TUK == TUK_Friend,
>>>>> isExplicitSpecialization,
>>>>> + Invalid);
>>>>> if (Invalid)
>>>>> return true;
>>>>>
>>>>> @@ -5929,11 +5966,8 @@ Sema::ActOnClassTemplateSpecialization(S
>>>>> << SourceRange(LAngleLoc, RAngleLoc);
>>>>> else
>>>>> isExplicitSpecialization = true;
>>>>> - } else if (TUK != TUK_Friend) {
>>>>> - Diag(KWLoc, diag::err_template_spec_needs_header)
>>>>> - << FixItHint::CreateInsertion(KWLoc, "template<> ");
>>>>> - TemplateKWLoc = KWLoc;
>>>>> - isExplicitSpecialization = true;
>>>>> + } else {
>>>>> + assert(TUK == TUK_Friend && "should have a 'template<>' for this
>>>>> decl");
>>>>> }
>>>>>
>>>>> // Check that the specialization uses the same tag kind as the
>>>>> @@ -5953,10 +5987,8 @@ Sema::ActOnClassTemplateSpecialization(S
>>>>> }
>>>>>
>>>>> // Translate the parser's template argument list in our AST format.
>>>>> - TemplateArgumentListInfo TemplateArgs;
>>>>> - TemplateArgs.setLAngleLoc(LAngleLoc);
>>>>> - TemplateArgs.setRAngleLoc(RAngleLoc);
>>>>> - translateTemplateArguments(TemplateArgsIn, TemplateArgs);
>>>>> + TemplateArgumentListInfo TemplateArgs =
>>>>> + makeTemplateArgumentListInfo(*this, TemplateId);
>>>>>
>>>>> // Check for unexpanded parameter packs in any of the template
>>>>> arguments.
>>>>> for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
>>>>> @@ -7416,13 +7448,8 @@ DeclResult Sema::ActOnExplicitInstantiat
>>>>> }
>>>>>
>>>>> // Translate the parser's template argument list into our AST
>>>>> format.
>>>>> - TemplateArgumentListInfo TemplateArgs;
>>>>> - TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
>>>>> - TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
>>>>> - TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
>>>>> - ASTTemplateArgsPtr
>>>>> TemplateArgsPtr(TemplateId->getTemplateArgs(),
>>>>> - TemplateId->NumArgs);
>>>>> - translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
>>>>> + TemplateArgumentListInfo TemplateArgs =
>>>>> + makeTemplateArgumentListInfo(*this,
>>>>> *D.getName().TemplateId);
>>>>>
>>>>> DeclResult Res = CheckVarTemplateId(PrevTemplate, TemplateLoc,
>>>>> D.getIdentifierLoc(),
>>>>> TemplateArgs);
>>>>> @@ -7492,12 +7519,7 @@ DeclResult Sema::ActOnExplicitInstantiat
>>>>> bool HasExplicitTemplateArgs = false;
>>>>> TemplateArgumentListInfo TemplateArgs;
>>>>> if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
>>>>> - TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
>>>>> - TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
>>>>> - TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
>>>>> - ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
>>>>> - TemplateId->NumArgs);
>>>>> - translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
>>>>> + TemplateArgs = makeTemplateArgumentListInfo(*this,
>>>>> *D.getName().TemplateId);
>>>>> HasExplicitTemplateArgs = true;
>>>>> }
>>>>>
>>>>>
>>>>> Modified: cfe/trunk/test/FixIt/fixit.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=206442&r1=206441&r2=206442&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/test/FixIt/fixit.cpp (original)
>>>>> +++ cfe/trunk/test/FixIt/fixit.cpp Wed Apr 16 22:29:33 2014
>>>>> @@ -19,7 +19,7 @@ virtual void C1::f() { } // expected-err
>>>>>
>>>>> static void C1::g() { } // expected-error{{'static' can only be
>>>>> specified inside the class definition}}
>>>>>
>>>>> -template<int Value> struct CT { }; // expected-note{{previous use is
>>>>> here}}
>>>>> +template<int Value> struct CT { template<typename> struct Inner; };
>>>>> // expected-note{{previous use is here}}
>>>>>
>>>>> CT<10 >> 2> ct; // expected-warning{{require parentheses}}
>>>>>
>>>>> @@ -32,6 +32,8 @@ struct CT<0> { }; // expected-error{{'te
>>>>>
>>>>> template<> union CT<1> { }; // expected-error{{tag type}}
>>>>>
>>>>> +struct CT<2>::Inner<int> { }; // expected-error 2{{'template<>'}}
>>>>> +
>>>>> // Access declarations
>>>>> class A {
>>>>> protected:
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> cfe-commits mailing list
>>>>> cfe-commits at cs.uiuc.edu
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>>>>
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150129/0b0d6707/attachment.html>
More information about the cfe-commits
mailing list