forked from OSchip/llvm-project
Fixed inconsistency when adding TemplateParameterListsInfo.
llvm-svn: 127876
This commit is contained in:
parent
3fbfcc0e1e
commit
60804e1604
|
@ -507,16 +507,24 @@ public:
|
|||
/// name qualifier, to be used for the case of out-of-line declarations.
|
||||
struct QualifierInfo {
|
||||
NestedNameSpecifierLoc QualifierLoc;
|
||||
/// NumTemplParamLists - The number of template parameter lists
|
||||
/// that were matched against the template-ids occurring into the NNS.
|
||||
|
||||
/// NumTemplParamLists - The number of "outer" template parameter lists.
|
||||
/// The count includes all of the template parameter lists that were matched
|
||||
/// against the template-ids occurring into the NNS and possibly (in the
|
||||
/// case of an explicit specialization) a final "template <>".
|
||||
unsigned NumTemplParamLists;
|
||||
|
||||
/// TemplParamLists - A new-allocated array of size NumTemplParamLists,
|
||||
/// containing pointers to the matched template parameter lists.
|
||||
/// containing pointers to the "outer" template parameter lists.
|
||||
/// It includes all of the template parameter lists that were matched
|
||||
/// against the template-ids occurring into the NNS and possibly (in the
|
||||
/// case of an explicit specialization) a final "template <>".
|
||||
TemplateParameterList** TemplParamLists;
|
||||
|
||||
/// Default constructor.
|
||||
QualifierInfo() : QualifierLoc(), NumTemplParamLists(0), TemplParamLists(0) {}
|
||||
/// setTemplateParameterListsInfo - Sets info about matched template
|
||||
|
||||
/// setTemplateParameterListsInfo - Sets info about "outer" template
|
||||
/// parameter lists.
|
||||
void setTemplateParameterListsInfo(ASTContext &Context,
|
||||
unsigned NumTPLists,
|
||||
|
@ -603,9 +611,7 @@ public:
|
|||
return getExtInfo()->TemplParamLists[index];
|
||||
}
|
||||
void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
|
||||
TemplateParameterList **TPLists) {
|
||||
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
|
||||
}
|
||||
TemplateParameterList **TPLists);
|
||||
|
||||
SourceLocation getTypeSpecStartLoc() const;
|
||||
|
||||
|
@ -2238,9 +2244,7 @@ public:
|
|||
return getExtInfo()->TemplParamLists[i];
|
||||
}
|
||||
void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists,
|
||||
TemplateParameterList **TPLists) {
|
||||
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
|
||||
}
|
||||
TemplateParameterList **TPLists);
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
|
||||
|
|
|
@ -961,16 +961,38 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
|
|||
else {
|
||||
// Here Qualifier == 0, i.e., we are removing the qualifier (if any).
|
||||
if (hasExtInfo()) {
|
||||
// Save type source info pointer.
|
||||
TypeSourceInfo *savedTInfo = getExtInfo()->TInfo;
|
||||
// Deallocate the extended decl info.
|
||||
getASTContext().Deallocate(getExtInfo());
|
||||
// Restore savedTInfo into (non-extended) decl info.
|
||||
DeclInfo = savedTInfo;
|
||||
if (getExtInfo()->NumTemplParamLists == 0) {
|
||||
// Save type source info pointer.
|
||||
TypeSourceInfo *savedTInfo = getExtInfo()->TInfo;
|
||||
// Deallocate the extended decl info.
|
||||
getASTContext().Deallocate(getExtInfo());
|
||||
// Restore savedTInfo into (non-extended) decl info.
|
||||
DeclInfo = savedTInfo;
|
||||
}
|
||||
else
|
||||
getExtInfo()->QualifierLoc = QualifierLoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DeclaratorDecl::setTemplateParameterListsInfo(ASTContext &Context,
|
||||
unsigned NumTPLists,
|
||||
TemplateParameterList **TPLists) {
|
||||
assert(NumTPLists > 0);
|
||||
// Make sure the extended decl info is allocated.
|
||||
if (!hasExtInfo()) {
|
||||
// Save (non-extended) type source info pointer.
|
||||
TypeSourceInfo *savedTInfo = DeclInfo.get<TypeSourceInfo*>();
|
||||
// Allocate external info struct.
|
||||
DeclInfo = new (getASTContext()) ExtInfo;
|
||||
// Restore savedTInfo into (extended) decl info.
|
||||
getExtInfo()->TInfo = savedTInfo;
|
||||
}
|
||||
// Set the template parameter lists info.
|
||||
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
|
||||
}
|
||||
|
||||
SourceLocation DeclaratorDecl::getOuterLocStart() const {
|
||||
return getTemplateOrInnerLocStart(this);
|
||||
}
|
||||
|
@ -1030,8 +1052,6 @@ QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
|
|||
TemplateParameterList **TPLists) {
|
||||
assert((NumTPLists == 0 || TPLists != 0) &&
|
||||
"Empty array of template parameters with positive size!");
|
||||
assert((NumTPLists == 0 || QualifierLoc) &&
|
||||
"Nonempty array of template parameters with no qualifier!");
|
||||
|
||||
// Free previous template parameters (if any).
|
||||
if (NumTemplParamLists > 0) {
|
||||
|
@ -2100,12 +2120,28 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
|
|||
else {
|
||||
// Here Qualifier == 0, i.e., we are removing the qualifier (if any).
|
||||
if (hasExtInfo()) {
|
||||
getASTContext().Deallocate(getExtInfo());
|
||||
TypedefDeclOrQualifier = (TypedefDecl*) 0;
|
||||
if (getExtInfo()->NumTemplParamLists == 0) {
|
||||
getASTContext().Deallocate(getExtInfo());
|
||||
TypedefDeclOrQualifier = (TypedefDecl*) 0;
|
||||
}
|
||||
else
|
||||
getExtInfo()->QualifierLoc = QualifierLoc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TagDecl::setTemplateParameterListsInfo(ASTContext &Context,
|
||||
unsigned NumTPLists,
|
||||
TemplateParameterList **TPLists) {
|
||||
assert(NumTPLists > 0);
|
||||
// Make sure the extended decl info is allocated.
|
||||
if (!hasExtInfo())
|
||||
// Allocate external info struct.
|
||||
TypedefDeclOrQualifier = new (getASTContext()) ExtInfo;
|
||||
// Set the template parameter lists info.
|
||||
getExtInfo()->setTemplateParameterListsInfo(Context, NumTPLists, TPLists);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// EnumDecl Implementation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -3094,7 +3094,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
// Match up the template parameter lists with the scope specifier, then
|
||||
// determine whether we have a template or a template specialization.
|
||||
isExplicitSpecialization = false;
|
||||
unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
|
||||
bool Invalid = false;
|
||||
if (TemplateParameterList *TemplateParams
|
||||
= MatchTemplateParametersToScopeSpecifier(
|
||||
|
@ -3105,9 +3104,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
/*never a friend*/ false,
|
||||
isExplicitSpecialization,
|
||||
Invalid)) {
|
||||
// All but one template parameter lists have been matching.
|
||||
--NumMatchedTemplateParamLists;
|
||||
|
||||
if (TemplateParams->size() > 0) {
|
||||
// There is no such thing as a variable template.
|
||||
Diag(D.getIdentifierLoc(), diag::err_template_variable)
|
||||
|
@ -3123,7 +3119,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
<< II
|
||||
<< SourceRange(TemplateParams->getTemplateLoc(),
|
||||
TemplateParams->getRAngleLoc());
|
||||
|
||||
isExplicitSpecialization = true;
|
||||
}
|
||||
}
|
||||
|
@ -3143,9 +3138,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
|||
|
||||
SetNestedNameSpecifier(NewVD, D);
|
||||
|
||||
if (NumMatchedTemplateParamLists > 0 && D.getCXXScopeSpec().isSet()) {
|
||||
if (TemplateParamLists.size() > 0 && D.getCXXScopeSpec().isSet()) {
|
||||
NewVD->setTemplateParameterListsInfo(Context,
|
||||
NumMatchedTemplateParamLists,
|
||||
TemplateParamLists.size(),
|
||||
TemplateParamLists.release());
|
||||
}
|
||||
}
|
||||
|
@ -3636,7 +3631,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
FunctionTemplateDecl *FunctionTemplate = 0;
|
||||
bool isExplicitSpecialization = false;
|
||||
bool isFunctionTemplateSpecialization = false;
|
||||
unsigned NumMatchedTemplateParamLists = 0;
|
||||
|
||||
if (!getLangOptions().CPlusPlus) {
|
||||
// Determine whether the function was written with a
|
||||
|
@ -3783,7 +3777,6 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
SetNestedNameSpecifier(NewFD, D);
|
||||
isExplicitSpecialization = false;
|
||||
isFunctionTemplateSpecialization = false;
|
||||
NumMatchedTemplateParamLists = TemplateParamLists.size();
|
||||
if (D.isInvalidType())
|
||||
NewFD->setInvalidDecl();
|
||||
|
||||
|
@ -3804,61 +3797,71 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
isFriend,
|
||||
isExplicitSpecialization,
|
||||
Invalid)) {
|
||||
// All but one template parameter lists have been matching.
|
||||
--NumMatchedTemplateParamLists;
|
||||
if (TemplateParams->size() > 0) {
|
||||
// This is a function template
|
||||
|
||||
if (TemplateParams->size() > 0) {
|
||||
// This is a function template
|
||||
// Check that we can declare a template here.
|
||||
if (CheckTemplateDeclScope(S, TemplateParams))
|
||||
return 0;
|
||||
|
||||
// Check that we can declare a template here.
|
||||
if (CheckTemplateDeclScope(S, TemplateParams))
|
||||
return 0;
|
||||
|
||||
// A destructor cannot be a template.
|
||||
if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
|
||||
Diag(NewFD->getLocation(), diag::err_destructor_template);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
FunctionTemplate = FunctionTemplateDecl::Create(Context, DC,
|
||||
NewFD->getLocation(),
|
||||
Name, TemplateParams,
|
||||
NewFD);
|
||||
FunctionTemplate->setLexicalDeclContext(CurContext);
|
||||
NewFD->setDescribedFunctionTemplate(FunctionTemplate);
|
||||
} else {
|
||||
// This is a function template specialization.
|
||||
isFunctionTemplateSpecialization = true;
|
||||
|
||||
// C++0x [temp.expl.spec]p20 forbids "template<> friend void foo(int);".
|
||||
if (isFriend && isFunctionTemplateSpecialization) {
|
||||
// We want to remove the "template<>", found here.
|
||||
SourceRange RemoveRange = TemplateParams->getSourceRange();
|
||||
|
||||
// If we remove the template<> and the name is not a
|
||||
// template-id, we're actually silently creating a problem:
|
||||
// the friend declaration will refer to an untemplated decl,
|
||||
// and clearly the user wants a template specialization. So
|
||||
// we need to insert '<>' after the name.
|
||||
SourceLocation InsertLoc;
|
||||
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
|
||||
InsertLoc = D.getName().getSourceRange().getEnd();
|
||||
InsertLoc = PP.getLocForEndOfToken(InsertLoc);
|
||||
}
|
||||
|
||||
Diag(D.getIdentifierLoc(), diag::err_template_spec_decl_friend)
|
||||
<< Name << RemoveRange
|
||||
<< FixItHint::CreateRemoval(RemoveRange)
|
||||
<< FixItHint::CreateInsertion(InsertLoc, "<>");
|
||||
}
|
||||
}
|
||||
// A destructor cannot be a template.
|
||||
if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
|
||||
Diag(NewFD->getLocation(), diag::err_destructor_template);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NumMatchedTemplateParamLists > 0 && D.getCXXScopeSpec().isSet()) {
|
||||
NewFD->setTemplateParameterListsInfo(Context,
|
||||
NumMatchedTemplateParamLists,
|
||||
TemplateParamLists.release());
|
||||
FunctionTemplate = FunctionTemplateDecl::Create(Context, DC,
|
||||
NewFD->getLocation(),
|
||||
Name, TemplateParams,
|
||||
NewFD);
|
||||
FunctionTemplate->setLexicalDeclContext(CurContext);
|
||||
NewFD->setDescribedFunctionTemplate(FunctionTemplate);
|
||||
|
||||
// For source fidelity, store the other template param lists.
|
||||
if (TemplateParamLists.size() > 1) {
|
||||
NewFD->setTemplateParameterListsInfo(Context,
|
||||
TemplateParamLists.size() - 1,
|
||||
TemplateParamLists.release());
|
||||
}
|
||||
} else {
|
||||
// This is a function template specialization.
|
||||
isFunctionTemplateSpecialization = true;
|
||||
// For source fidelity, store all the template param lists.
|
||||
NewFD->setTemplateParameterListsInfo(Context,
|
||||
TemplateParamLists.size(),
|
||||
TemplateParamLists.release());
|
||||
|
||||
// C++0x [temp.expl.spec]p20 forbids "template<> friend void foo(int);".
|
||||
if (isFriend) {
|
||||
// We want to remove the "template<>", found here.
|
||||
SourceRange RemoveRange = TemplateParams->getSourceRange();
|
||||
|
||||
// If we remove the template<> and the name is not a
|
||||
// template-id, we're actually silently creating a problem:
|
||||
// the friend declaration will refer to an untemplated decl,
|
||||
// and clearly the user wants a template specialization. So
|
||||
// we need to insert '<>' after the name.
|
||||
SourceLocation InsertLoc;
|
||||
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
|
||||
InsertLoc = D.getName().getSourceRange().getEnd();
|
||||
InsertLoc = PP.getLocForEndOfToken(InsertLoc);
|
||||
}
|
||||
|
||||
Diag(D.getIdentifierLoc(), diag::err_template_spec_decl_friend)
|
||||
<< Name << RemoveRange
|
||||
<< FixItHint::CreateRemoval(RemoveRange)
|
||||
<< FixItHint::CreateInsertion(InsertLoc, "<>");
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// All template param lists were matched against the scope specifier:
|
||||
// this is NOT (an explicit specialization of) a template.
|
||||
if (TemplateParamLists.size() > 0)
|
||||
// For source fidelity, store all the template param lists.
|
||||
NewFD->setTemplateParameterListsInfo(Context,
|
||||
TemplateParamLists.size(),
|
||||
TemplateParamLists.release());
|
||||
}
|
||||
|
||||
if (Invalid) {
|
||||
|
@ -4180,7 +4183,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
// are situations where these conditions don't apply and we
|
||||
// can actually do this check immediately.
|
||||
if (isFriend &&
|
||||
(NumMatchedTemplateParamLists ||
|
||||
(TemplateParamLists.size() ||
|
||||
D.getCXXScopeSpec().getScopeRep()->isDependent() ||
|
||||
CurContext->isDependentContext())) {
|
||||
// ignore these
|
||||
|
@ -6035,27 +6038,24 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
|||
|
||||
// FIXME: Check explicit specializations more carefully.
|
||||
bool isExplicitSpecialization = false;
|
||||
unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
|
||||
bool Invalid = false;
|
||||
|
||||
// We only need to do this matching if we have template parameters
|
||||
// or a scope specifier, which also conveniently avoids this work
|
||||
// for non-C++ cases.
|
||||
if (NumMatchedTemplateParamLists ||
|
||||
if (TemplateParameterLists.size() > 0 ||
|
||||
(SS.isNotEmpty() && TUK != TUK_Reference)) {
|
||||
if (TemplateParameterList *TemplateParams
|
||||
= MatchTemplateParametersToScopeSpecifier(KWLoc, SS,
|
||||
TemplateParameterLists.get(),
|
||||
TemplateParameterLists.size(),
|
||||
TemplateParameterLists.size(),
|
||||
TUK == TUK_Friend,
|
||||
isExplicitSpecialization,
|
||||
Invalid)) {
|
||||
// All but one template parameter lists have been matching.
|
||||
--NumMatchedTemplateParamLists;
|
||||
|
||||
if (TemplateParams->size() > 0) {
|
||||
// This is a declaration or definition of a class template (which may
|
||||
// be a member of another template).
|
||||
|
||||
if (Invalid)
|
||||
return 0;
|
||||
|
||||
|
@ -6063,7 +6063,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
|||
DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc,
|
||||
SS, Name, NameLoc, Attr,
|
||||
TemplateParams, AS,
|
||||
NumMatchedTemplateParamLists,
|
||||
TemplateParameterLists.size() - 1,
|
||||
(TemplateParameterList**) TemplateParameterLists.release());
|
||||
return Result.get();
|
||||
} else {
|
||||
|
@ -6584,9 +6584,9 @@ CreateNewDecl:
|
|||
if (SS.isNotEmpty()) {
|
||||
if (SS.isSet()) {
|
||||
New->setQualifierInfo(SS.getWithLocInContext(Context));
|
||||
if (NumMatchedTemplateParamLists > 0) {
|
||||
if (TemplateParameterLists.size() > 0) {
|
||||
New->setTemplateParameterListsInfo(Context,
|
||||
NumMatchedTemplateParamLists,
|
||||
TemplateParameterLists.size(),
|
||||
(TemplateParameterList**) TemplateParameterLists.release());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6977,7 +6977,6 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
|
|||
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
|
||||
|
||||
bool isExplicitSpecialization = false;
|
||||
unsigned NumMatchedTemplateParamLists = TempParamLists.size();
|
||||
bool Invalid = false;
|
||||
|
||||
if (TemplateParameterList *TemplateParams
|
||||
|
@ -6987,8 +6986,6 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
|
|||
/*friend*/ true,
|
||||
isExplicitSpecialization,
|
||||
Invalid)) {
|
||||
--NumMatchedTemplateParamLists;
|
||||
|
||||
if (TemplateParams->size() > 0) {
|
||||
// This is a declaration of a class template.
|
||||
if (Invalid)
|
||||
|
@ -6997,7 +6994,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
|
|||
return CheckClassTemplate(S, TagSpec, TUK_Friend, TagLoc,
|
||||
SS, Name, NameLoc, Attr,
|
||||
TemplateParams, AS_public,
|
||||
NumMatchedTemplateParamLists,
|
||||
TempParamLists.size() - 1,
|
||||
(TemplateParameterList**) TempParamLists.release()).take();
|
||||
} else {
|
||||
// The "template<>" header is extraneous.
|
||||
|
@ -7012,7 +7009,7 @@ Decl *Sema::ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
|
|||
assert(SS.isNotEmpty() && "valid templated tag with no SS and no direct?");
|
||||
|
||||
bool isAllExplicitSpecializations = true;
|
||||
for (unsigned I = 0; I != NumMatchedTemplateParamLists; ++I) {
|
||||
for (unsigned I = TempParamLists.size(); I-- > 0; ) {
|
||||
if (TempParamLists.get()[I]->size()) {
|
||||
isAllExplicitSpecializations = false;
|
||||
break;
|
||||
|
|
|
@ -1456,9 +1456,9 @@ DependsOnTemplateParameters(const TemplateSpecializationType *TemplateId,
|
|||
///
|
||||
/// \returns the template parameter list, if any, that corresponds to the
|
||||
/// name that is preceded by the scope specifier @p SS. This template
|
||||
/// parameter list may be have template parameters (if we're declaring a
|
||||
/// parameter list may have template parameters (if we're declaring a
|
||||
/// template) or may have no template parameters (if we're declaring a
|
||||
/// template specialization), or may be NULL (if we were's declaring isn't
|
||||
/// template specialization), or may be NULL (if what we're declaring isn't
|
||||
/// itself a template).
|
||||
TemplateParameterList *
|
||||
Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
|
||||
|
@ -4390,6 +4390,11 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
MultiTemplateParamsArg TemplateParameterLists) {
|
||||
assert(TUK != TUK_Reference && "References are not specializations");
|
||||
|
||||
// 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.get()[0]->getTemplateLoc() : SourceLocation();
|
||||
|
||||
// Find the class template we're specializing
|
||||
TemplateName Name = TemplateD.getAsVal<TemplateName>();
|
||||
ClassTemplateDecl *ClassTemplate
|
||||
|
@ -4420,10 +4425,6 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
if (Invalid)
|
||||
return true;
|
||||
|
||||
unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
|
||||
if (TemplateParams)
|
||||
--NumMatchedTemplateParamLists;
|
||||
|
||||
if (TemplateParams && TemplateParams->size() > 0) {
|
||||
isPartialSpecialization = true;
|
||||
|
||||
|
@ -4565,10 +4566,15 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
// Since the only prior class template specialization with these
|
||||
// arguments was referenced but not declared, or we're only
|
||||
// referencing this specialization as a friend, reuse that
|
||||
// declaration node as our own, updating its source location to
|
||||
// reflect our new declaration.
|
||||
// declaration node as our own, updating its source location and
|
||||
// the list of outer template parameters to reflect our new declaration.
|
||||
Specialization = PrevDecl;
|
||||
Specialization->setLocation(TemplateNameLoc);
|
||||
if (TemplateParameterLists.size() > 0) {
|
||||
Specialization->setTemplateParameterListsInfo(Context,
|
||||
TemplateParameterLists.size(),
|
||||
(TemplateParameterList**) TemplateParameterLists.release());
|
||||
}
|
||||
PrevDecl = 0;
|
||||
CanonType = Context.getTypeDeclType(Specialization);
|
||||
} else if (isPartialSpecialization) {
|
||||
|
@ -4594,7 +4600,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
Attr,
|
||||
TemplateParams,
|
||||
AS_none,
|
||||
NumMatchedTemplateParamLists,
|
||||
TemplateParameterLists.size() - 1,
|
||||
(TemplateParameterList**) TemplateParameterLists.release());
|
||||
}
|
||||
|
||||
|
@ -4616,9 +4622,9 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
PrevPartial,
|
||||
SequenceNumber);
|
||||
SetNestedNameSpecifier(Partial, SS);
|
||||
if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
|
||||
if (TemplateParameterLists.size() > 1 && SS.isSet()) {
|
||||
Partial->setTemplateParameterListsInfo(Context,
|
||||
NumMatchedTemplateParamLists,
|
||||
TemplateParameterLists.size() - 1,
|
||||
(TemplateParameterList**) TemplateParameterLists.release());
|
||||
}
|
||||
|
||||
|
@ -4675,9 +4681,9 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
Converted.size(),
|
||||
PrevDecl);
|
||||
SetNestedNameSpecifier(Specialization, SS);
|
||||
if (NumMatchedTemplateParamLists > 0 && SS.isSet()) {
|
||||
if (TemplateParameterLists.size() > 0) {
|
||||
Specialization->setTemplateParameterListsInfo(Context,
|
||||
NumMatchedTemplateParamLists,
|
||||
TemplateParameterLists.size(),
|
||||
(TemplateParameterList**) TemplateParameterLists.release());
|
||||
}
|
||||
|
||||
|
@ -4747,8 +4753,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|||
TemplateArgs, CanonType);
|
||||
if (TUK != TUK_Friend) {
|
||||
Specialization->setTypeAsWritten(WrittenTy);
|
||||
if (TemplateParams)
|
||||
Specialization->setTemplateKeywordLoc(TemplateParams->getTemplateLoc());
|
||||
Specialization->setTemplateKeywordLoc(TemplateKWLoc);
|
||||
}
|
||||
TemplateArgsIn.release();
|
||||
|
||||
|
|
Loading…
Reference in New Issue