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

Richard Smith richard at metafoo.co.uk
Thu Jan 29 18:43:31 PST 2015


On Thu, Jan 29, 2015 at 6:35 PM, Nico Weber <thakis at chromium.org> wrote:

> 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.
>

So it does, thanks!

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


More information about the cfe-commits mailing list