diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-10-12 20:18:28 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-10-12 20:18:28 +0000 |
commit | b3ae4fcd4314a9c1c46d41b200883599c32025b4 (patch) | |
tree | a25ed84a04f126c2beae7a3b09dc855d7c37d196 /include/clang | |
parent | 2ebe7ebb1d6149a1845dd3169009f99b78e91bc9 (diff) |
Diagnose the declaration of explicit specializations after an implicit
instantiation has already been required. To do so, keep track of the
point of instantiation for anything that can be instantiated.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83890 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/Decl.h | 18 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 5 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 36 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 4 |
4 files changed, 62 insertions, 1 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 0e91511dbd..7c326dee33 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -593,6 +593,11 @@ public: /// template specialization or instantiation this is. TemplateSpecializationKind getTemplateSpecializationKind(); + /// \brief If this variable is an instantiation of a static data member of a + /// class template specialization, retrieves the member specialization + /// information. + MemberSpecializationInfo *getMemberSpecializationInfo(); + /// \brief For a static data member that was instantiated from a static /// data member of a class template, set the template specialiation kind. void setTemplateSpecializationKind(TemplateSpecializationKind TSK); @@ -1075,6 +1080,11 @@ public: /// declaration returned by getInstantiatedFromMemberFunction(). FunctionDecl *getInstantiatedFromMemberFunction() const; + /// \brief If this function is an instantiation of a member function of a + /// class template specialization, retrieves the member specialization + /// information. + MemberSpecializationInfo *getMemberSpecializationInfo() const; + /// \brief Specify that this record is an instantiation of the /// member function FD. void setInstantiationOfMemberFunction(FunctionDecl *FD, @@ -1105,6 +1115,14 @@ public: bool isFunctionTemplateSpecialization() const { return getPrimaryTemplate() != 0; } + + /// \brief If this function is actually a function template specialization, + /// retrieve information about this function template specialization. + /// Otherwise, returns NULL. + FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const { + return TemplateOrSpecialization. + dyn_cast<FunctionTemplateSpecializationInfo*>(); + } /// \brief Retrieve the primary template that this function template /// specialization either specializes or was instantiated from. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 7c651b2cc0..c858c5c0df 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -706,6 +706,11 @@ public: /// declaration returned by getInstantiatedFromMemberClass(). CXXRecordDecl *getInstantiatedFromMemberClass() const; + /// \brief If this class is an instantiation of a member class of a + /// class template specialization, retrieves the member specialization + /// information. + MemberSpecializationInfo *getMemberSpecializationInfo() const; + /// \brief Specify that this record is an instantiation of the /// member class RD. void setInstantiationOfMemberClass(CXXRecordDecl *RD, diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index f49aeccb46..e21849c453 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -518,6 +518,10 @@ public: /// specialization from the function template. const TemplateArgumentList *TemplateArguments; + /// \brief The point at which this function template specialization was + /// first instantiated. + SourceLocation PointOfInstantiation; + /// \brief Retrieve the template from which this function was specialized. FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); } @@ -533,6 +537,21 @@ public: Template.setInt(TSK - 1); } + /// \brief Retrieve the first point of instantiation of this function + /// template specialization. + /// + /// The point of instantiation may be an invalid source location if this + /// function has yet to be instantiated. + SourceLocation getPointOfInstantiation() const { + return PointOfInstantiation; + } + + /// \brief Set the (first) point of instantiation of this function template + /// specialization. + void setPointOfInstantiation(SourceLocation POI) { + PointOfInstantiation = POI; + } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, TemplateArguments->getFlatArgumentList(), TemplateArguments->flat_size(), @@ -556,10 +575,13 @@ class MemberSpecializationInfo { // manner in which the instantiation occurred (in the lower two bits). llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK; + // The point at which this member was first instantiated. + SourceLocation PointOfInstantiation; + public: explicit MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK) - : MemberAndTSK(IF, TSK - 1) { + : MemberAndTSK(IF, TSK - 1), PointOfInstantiation() { assert(TSK != TSK_Undeclared && "Cannot encode undeclared template specializations for members"); } @@ -579,6 +601,18 @@ public: "Cannot encode undeclared template specializations for members"); MemberAndTSK.setInt(TSK - 1); } + + /// \brief Retrieve the first point of instantiation of this member. + /// If the point of instantiation is an invalid location, then this member + /// has not yet been instantiated. + SourceLocation getPointOfInstantiation() const { + return PointOfInstantiation; + } + + /// \brief Set the first point of instantiation. + void setPointOfInstantiation(SourceLocation POI) { + PointOfInstantiation = POI; + } }; /// Declaration of a template function. diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 252cfd2718..cdc121f342 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -967,6 +967,10 @@ def err_template_spec_redecl_global_scope : Error< def err_spec_member_not_instantiated : Error< "specialization of member %q0 does not specialize an instantiated member">; def note_specialized_decl : Note<"attempt to specialize declaration here">; +def err_specialization_after_instantiation : Error< + "explicit specialization of %0 after instantiation">; +def note_instantiation_required_here : Note< + "%select{implicit|explicit}0 instantiation first required here">; // C++ class template specializations and out-of-line definitions def err_template_spec_needs_header : Error< |