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