r206442 - Refactor all the checking for missing 'template<>'s when a declaration has a
Nico Weber
thakis at chromium.org
Thu Jan 29 17:51:14 PST 2015
r227540, thanks. I'll look
through MatchTemplateParametersToScopeSpecifier() for places that need to
set Invalid.
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
>>>
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150129/1e33f8a8/attachment.html>
More information about the cfe-commits
mailing list