diff options
Diffstat (limited to 'clang/include/clang')
-rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 3 | ||||
-rw-r--r-- | clang/include/clang/AST/DeclNodes.def | 6 | ||||
-rw-r--r-- | clang/include/clang/AST/DeclTemplate.h | 75 | ||||
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 |
4 files changed, 77 insertions, 12 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 36c461bf52e..4a74a2c2cbc 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -449,7 +449,8 @@ public: static bool classof(const Decl *D) { return D->getKind() == CXXRecord || - D->getKind() == ClassTemplateSpecialization; + D->getKind() == ClassTemplateSpecialization || + D->getKind() == ClassTemplatePartialSpecialization; } static bool classof(const CXXRecordDecl *D) { return true; } static bool classof(const ClassTemplateSpecializationDecl *D) { diff --git a/clang/include/clang/AST/DeclNodes.def b/clang/include/clang/AST/DeclNodes.def index a82d26a20c0..d1b921a4cb6 100644 --- a/clang/include/clang/AST/DeclNodes.def +++ b/clang/include/clang/AST/DeclNodes.def @@ -86,6 +86,8 @@ ABSTRACT_DECL(Named, Decl) DECL(Record, TagDecl) DECL(CXXRecord, RecordDecl) DECL(ClassTemplateSpecialization, CXXRecordDecl) + DECL(ClassTemplatePartialSpecialization, + ClassTemplateSpecializationDecl) DECL(TemplateTypeParm, TypeDecl) ABSTRACT_DECL(Value, NamedDecl) DECL(EnumConstant, ValueDecl) @@ -141,8 +143,8 @@ DECL_RANGE(Named, OverloadedFunction, ObjCImplementation) DECL_RANGE(ObjCContainer, ObjCContainer, ObjCInterface) DECL_RANGE(Field, Field, ObjCAtDefsField) DECL_RANGE(Type, Typedef, TemplateTypeParm) -DECL_RANGE(Tag, Enum, ClassTemplateSpecialization) -DECL_RANGE(Record, Record, ClassTemplateSpecialization) +DECL_RANGE(Tag, Enum, ClassTemplatePartialSpecialization) +DECL_RANGE(Record, Record, ClassTemplatePartialSpecialization) DECL_RANGE(Value, EnumConstant, NonTypeTemplateParm) DECL_RANGE(Function, Function, CXXConversion) DECL_RANGE(Template, Template, TemplateTemplateParm) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index b68b46f56d0..226af3411d5 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -24,6 +24,7 @@ class TemplateParameterList; class TemplateDecl; class FunctionTemplateDecl; class ClassTemplateDecl; +class ClassTemplatePartialSpecializationDecl; class TemplateTypeParmDecl; class NonTypeTemplateParmDecl; class TemplateTemplateParmDecl; @@ -619,7 +620,8 @@ enum TemplateSpecializationKind { /// has not yet been declared, defined, or instantiated. TSK_Undeclared = 0, /// This template specialization was declared or defined by an - /// explicit specialization (C++ [temp.expl.spec]). + /// explicit specialization (C++ [temp.expl.spec]) or partial + /// specialization (C++ [temp.class.spec]). TSK_ExplicitSpecialization, /// This template specialization was implicitly instantiated from a /// template. (C++ [temp.inst]). @@ -654,7 +656,8 @@ class ClassTemplateSpecializationDecl /// Really a value of type TemplateSpecializationKind. unsigned SpecializationKind : 2; - ClassTemplateSpecializationDecl(ASTContext &Context, +protected: + ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, DeclContext *DC, SourceLocation L, ClassTemplateDecl *SpecializedTemplate, TemplateArgument *TemplateArgs, @@ -686,16 +689,16 @@ public: SpecializationKind = TSK; } - void Profile(llvm::FoldingSetNodeID &ID) const { - Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size()); - } - /// \brief Sets the type of this specialization as it was written by /// the user. This will be a class template specialization type. void setTypeAsWritten(QualType T) { TypeForDecl = T.getTypePtr(); } + void Profile(llvm::FoldingSetNodeID &ID) const { + Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size()); + } + static void Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs, unsigned NumTemplateArgs) { @@ -704,12 +707,58 @@ public: } static bool classof(const Decl *D) { - return D->getKind() == ClassTemplateSpecialization; + return D->getKind() == ClassTemplateSpecialization || + D->getKind() == ClassTemplatePartialSpecialization; } static bool classof(const ClassTemplateSpecializationDecl *) { return true; } + + static bool classof(const ClassTemplatePartialSpecializationDecl *) { + return true; + } +}; + +class ClassTemplatePartialSpecializationDecl + : public ClassTemplateSpecializationDecl +{ + /// \brief The list of template parameters + TemplateParameterList* TemplateParams; + + ClassTemplatePartialSpecializationDecl(ASTContext &Context, + DeclContext *DC, SourceLocation L, + TemplateParameterList *Params, + ClassTemplateDecl *SpecializedTemplate, + TemplateArgument *TemplateArgs, + unsigned NumTemplateArgs) + : ClassTemplateSpecializationDecl(Context, ClassTemplatePartialSpecialization, + DC, L, SpecializedTemplate, TemplateArgs, + NumTemplateArgs), + TemplateParams(Params) { } + +public: + static ClassTemplatePartialSpecializationDecl * + Create(ASTContext &Context, DeclContext *DC, SourceLocation L, + TemplateParameterList *Params, + ClassTemplateDecl *SpecializedTemplate, + TemplateArgument *TemplateArgs, unsigned NumTemplateArgs, + ClassTemplatePartialSpecializationDecl *PrevDecl); + + /// Get the list of template parameters + TemplateParameterList *getTemplateParameters() const { + return TemplateParams; + } + + // FIXME: Add Profile support! + + static bool classof(const Decl *D) { + return D->getKind() == ClassTemplatePartialSpecialization; + } + + static bool classof(const ClassTemplatePartialSpecializationDecl *) { + return true; + } }; /// Declaration of a class template. @@ -722,6 +771,11 @@ protected: /// template, including explicit specializations and instantiations. llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations; + /// \brief The class template partial specializations for this class + /// template. + llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> + PartialSpecializations; + /// \brief The injected-class-name type for this class template. QualType InjectedClassNameType; }; @@ -768,6 +822,13 @@ public: return CommonPtr->Specializations; } + /// \brief Retrieve the set of partial specializations of this class + /// template. + llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> & + getPartialSpecializations() { + return CommonPtr->PartialSpecializations; + } + /// \brief Retrieve the type of the injected-class-name for this /// class template. /// diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 946b8003bea..1f72c249635 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -733,8 +733,9 @@ def err_template_spec_needs_header : Error< "template specialization requires 'template<>'">; def err_template_spec_extra_headers : Error< "template specialization must have a single 'template<>' header">; -def unsup_template_partial_spec : Error< - "class template partial specialization is not yet supported">; +def unsup_template_partial_spec_ordering : Error< + "partial ordering of class template partial specializations is not yet " + "supported">; def err_template_spec_decl_out_of_scope_global : Error< "class template specialization of %0 must occur in the global scope">; def err_template_spec_decl_out_of_scope : Error< |