On Thu, Jan 29, 2015 at 6:35 PM, Nico Weber <[email protected]> wrote:
> On Thu, Jan 29, 2015 at 5:51 PM, Nico Weber <[email protected]> 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 <[email protected]> >> 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 <[email protected]> wrote: >>> >>>> On Wed, Apr 16, 2014 at 8:29 PM, Richard Smith < >>>> [email protected]> 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 >>>>> [email protected] >>>>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >>>>> >>>> >>>> >>> >> >> _______________________________________________ >> cfe-commits mailing list >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> >> >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
