r206442 - Refactor all the checking for missing 'template<>'s when a declaration has a
Nico Weber
thakis at chromium.org
Thu Jan 29 18:35:49 PST 2015
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. The one place that doesn't is the `if (ParamIdx >=
ParamLists.size())` branch, and that branch is taken for valid code (e.g.
`class C {} C;`), so setting Invalid there is incorrect.
>
> 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/86c17dd4/attachment.html>
More information about the cfe-commits
mailing list