From 13c8577201e4fc0ddac5f09d05fd1778832137d1 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 6 May 2010 00:28:52 +0000 Subject: [PATCH] Partial and full specializations of a class template may have a different tag kind ("struct" vs. "class") than the primary template, which has an affect on access control. Should fix the last remaining Boost.Accumulors failure. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103144 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/DeclTemplate.h | 10 +++++----- include/clang/Basic/DiagnosticSemaKinds.td | 4 +++- lib/AST/DeclTemplate.cpp | 16 ++++++--------- lib/Sema/SemaDeclCXX.cpp | 1 - lib/Sema/SemaTemplate.cpp | 15 +++++++------- lib/Sema/SemaTemplateInstantiate.cpp | 2 ++ lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 +++- .../SemaTemplate/partial-spec-instantiate.cpp | 20 +++++++++++++++++++ 8 files changed, 47 insertions(+), 25 deletions(-) diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 1ec38bacb5..3af89f9377 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -862,7 +862,7 @@ class ClassTemplateSpecializationDecl unsigned SpecializationKind : 3; protected: - ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, + ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, @@ -870,7 +870,7 @@ protected: public: static ClassTemplateSpecializationDecl * - Create(ASTContext &Context, DeclContext *DC, SourceLocation L, + Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, ClassTemplateSpecializationDecl *PrevDecl); @@ -1024,7 +1024,7 @@ class ClassTemplatePartialSpecializationDecl llvm::PointerIntPair InstantiatedFromMember; - ClassTemplatePartialSpecializationDecl(ASTContext &Context, + ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, @@ -1035,7 +1035,7 @@ class ClassTemplatePartialSpecializationDecl unsigned SequenceNumber) : ClassTemplateSpecializationDecl(Context, ClassTemplatePartialSpecialization, - DC, L, SpecializedTemplate, Builder, + TK, DC, L, SpecializedTemplate, Builder, PrevDecl), TemplateParams(Params), ArgsAsWritten(ArgInfos), NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber), @@ -1043,7 +1043,7 @@ class ClassTemplatePartialSpecializationDecl public: static ClassTemplatePartialSpecializationDecl * - Create(ASTContext &Context, DeclContext *DC, SourceLocation L, + Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6b40820da8..a62408129c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2293,7 +2293,9 @@ def err_cannot_form_pointer_to_member_of_reference_type : Error< "cannot form a pointer-to-member to member %0 of reference type %1">; def err_incomplete_object_call : Error< "incomplete type in call to object of type %0">; - +def err_incomplete_pointer_to_member_return : Error< + "incomplete return type %0 of pointer-to-member constant">; + def warn_condition_is_assignment : Warning<"using the result of an " "assignment as a condition without parentheses">, InGroup; diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index c498dea177..cf4a242df7 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -395,16 +395,12 @@ TemplateArgumentList::~TemplateArgumentList() { // ClassTemplateSpecializationDecl Implementation //===----------------------------------------------------------------------===// ClassTemplateSpecializationDecl:: -ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, +ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, ClassTemplateSpecializationDecl *PrevDecl) - : CXXRecordDecl(DK, - SpecializedTemplate->getTemplatedDecl()->getTagKind(), - DC, L, - // FIXME: Should we use DeclarationName for the name of - // class template specializations? + : CXXRecordDecl(DK, TK, DC, L, SpecializedTemplate->getIdentifier(), PrevDecl), SpecializedTemplate(SpecializedTemplate), @@ -414,7 +410,7 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, } ClassTemplateSpecializationDecl * -ClassTemplateSpecializationDecl::Create(ASTContext &Context, +ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, @@ -422,7 +418,7 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, ClassTemplateSpecializationDecl *Result = new (Context)ClassTemplateSpecializationDecl(Context, ClassTemplateSpecialization, - DC, L, + TK, DC, L, SpecializedTemplate, Builder, PrevDecl); @@ -464,7 +460,7 @@ ClassTemplateSpecializationDecl::getSpecializedTemplate() const { //===----------------------------------------------------------------------===// ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl:: -Create(ASTContext &Context, DeclContext *DC, SourceLocation L, +Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, TemplateArgumentListBuilder &Builder, @@ -478,7 +474,7 @@ Create(ASTContext &Context, DeclContext *DC, SourceLocation L, ClonedArgs[I] = ArgInfos[I]; ClassTemplatePartialSpecializationDecl *Result - = new (Context)ClassTemplatePartialSpecializationDecl(Context, + = new (Context)ClassTemplatePartialSpecializationDecl(Context, TK, DC, L, Params, SpecializedTemplate, Builder, diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 6b87463a6f..23b3601f09 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -504,7 +504,6 @@ Sema::CheckBaseSpecifier(CXXRecordDecl *Class, SetClassDeclAttributesFromBase(Class, CXXBaseDecl, Virtual); // Create the base specifier. - // FIXME: Allocate via ASTContext? return new (Context) CXXBaseSpecifier(SpecifierRange, Virtual, Class->getTagKind() == RecordDecl::TK_class, Access, BaseType); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 050bbbd683..4689a53bdf 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1506,10 +1506,11 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, // specialization. Create the canonical declaration and add it to // the set of specializations. Decl = ClassTemplateSpecializationDecl::Create(Context, - ClassTemplate->getDeclContext(), - ClassTemplate->getLocation(), - ClassTemplate, - Converted, 0); + ClassTemplate->getTemplatedDecl()->getTagKind(), + ClassTemplate->getDeclContext(), + ClassTemplate->getLocation(), + ClassTemplate, + Converted, 0); ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos); Decl->setLexicalDeclContext(CurContext); } @@ -3798,7 +3799,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, unsigned SequenceNumber = PrevPartial? PrevPartial->getSequenceNumber() : ClassTemplate->getPartialSpecializations().size(); ClassTemplatePartialSpecializationDecl *Partial - = ClassTemplatePartialSpecializationDecl::Create(Context, + = ClassTemplatePartialSpecializationDecl::Create(Context, Kind, ClassTemplate->getDeclContext(), TemplateNameLoc, TemplateParams, @@ -3859,7 +3860,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, // Create a new class template specialization declaration node for // this explicit specialization or friend declaration. Specialization - = ClassTemplateSpecializationDecl::Create(Context, + = ClassTemplateSpecializationDecl::Create(Context, Kind, ClassTemplate->getDeclContext(), TemplateNameLoc, ClassTemplate, @@ -4705,7 +4706,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, // Create a new class template specialization declaration node for // this explicit specialization. Specialization - = ClassTemplateSpecializationDecl::Create(Context, + = ClassTemplateSpecializationDecl::Create(Context, Kind, ClassTemplate->getDeclContext(), TemplateNameLoc, ClassTemplate, diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 14bd243201..c7489ad821 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -1169,6 +1169,8 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, // Start the definition of this instantiation. Instantiation->startDefinition(); + + Instantiation->setTagKind(Pattern->getTagKind()); // Do substitution on the base class specifiers. if (SubstBaseSpecifiers(Instantiation, Pattern, TemplateArgs)) diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index da8480633d..44bce7976c 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1761,7 +1761,9 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( // Create the class template partial specialization declaration. ClassTemplatePartialSpecializationDecl *InstPartialSpec - = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context, Owner, + = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context, + PartialSpec->getTagKind(), + Owner, PartialSpec->getLocation(), InstParams, ClassTemplate, diff --git a/test/SemaTemplate/partial-spec-instantiate.cpp b/test/SemaTemplate/partial-spec-instantiate.cpp index 3156892a72..68b4964816 100644 --- a/test/SemaTemplate/partial-spec-instantiate.cpp +++ b/test/SemaTemplate/partial-spec-instantiate.cpp @@ -18,3 +18,23 @@ struct X2 { }; void a(char *a, char *b) {X2::f();} + +namespace WonkyAccess { + template + struct X { + int m; + }; + + template + class Y; + + template + struct Y : X { }; + + template<> + struct Y : X { }; + + int f(Y y, Y y2) { + return y.m + y2.m; + } +} -- 2.40.0