r206442 - Refactor all the checking for missing 'template<>'s when a declaration has a

Richard Smith richard at metafoo.co.uk
Thu Jan 29 16:24:17 PST 2015


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/fcb3c6a9/attachment.html>


More information about the cfe-commits mailing list