summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/DeclTemplate.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/DeclTemplate.h')
-rw-r--r--include/clang/AST/DeclTemplate.h529
1 files changed, 241 insertions, 288 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 138e47d..36549ea 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -15,8 +15,10 @@
#define LLVM_CLANG_AST_DECLTEMPLATE_H
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Redeclarable.h"
#include "clang/AST/TemplateBase.h"
#include "llvm/ADT/PointerUnion.h"
+#include "llvm/Support/Compiler.h"
#include <limits>
namespace clang {
@@ -99,12 +101,12 @@ public:
/// The first template parameter list in a declaration will have depth 0,
/// the second template parameter list will have depth 1, etc.
unsigned getDepth() const;
-
+
SourceLocation getTemplateLoc() const { return TemplateLoc; }
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(TemplateLoc, RAngleLoc);
}
};
@@ -116,7 +118,8 @@ class FixedSizeTemplateParameterList : public TemplateParameterList {
NamedDecl *Params[N];
public:
- FixedSizeTemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
+ FixedSizeTemplateParameterList(SourceLocation TemplateLoc,
+ SourceLocation LAngleLoc,
NamedDecl **Params, SourceLocation RAngleLoc) :
TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) {
}
@@ -142,7 +145,7 @@ class TemplateArgumentList {
: Arguments(Args, Owned), NumArguments(NumArgs) { }
public:
- /// \brief Type used to indicate that the template argument list itself is a
+ /// \brief Type used to indicate that the template argument list itself is a
/// stack object. It does not own its template arguments.
enum OnStackType { OnStack };
@@ -156,12 +159,12 @@ public:
///
/// The template argument list does not own the template arguments
/// provided.
- explicit TemplateArgumentList(OnStackType,
+ explicit TemplateArgumentList(OnStackType,
const TemplateArgument *Args, unsigned NumArgs)
: Arguments(Args, false), NumArguments(NumArgs) { }
-
- /// \brief Produces a shallow copy of the given template argument list.
- ///
+
+ /// \brief Produces a shallow copy of the given template argument list.
+ ///
/// This operation assumes that the input argument list outlives it.
/// This takes the list as a pointer to avoid looking like a copy
/// constructor, since this really really isn't safe to use that
@@ -197,6 +200,7 @@ public:
/// parameters and a reference to the templated scoped declaration: the
/// underlying AST node.
class TemplateDecl : public NamedDecl {
+ virtual void anchor();
protected:
// This is probably never used.
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -236,7 +240,7 @@ public:
return K >= firstTemplate && K <= lastTemplate;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
return SourceRange(TemplateParams->getTemplateLoc(),
TemplatedDecl->getSourceRange().getEnd());
}
@@ -244,7 +248,7 @@ public:
protected:
NamedDecl *TemplatedDecl;
TemplateParameterList* TemplateParams;
-
+
public:
/// \brief Initialize the underlying templated declaration and
/// template parameters.
@@ -298,9 +302,9 @@ public:
const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
/// \brief The point at which this function template specialization was
- /// first instantiated.
+ /// first instantiated.
SourceLocation PointOfInstantiation;
-
+
/// \brief Retrieve the template from which this function was specialized.
FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
@@ -325,16 +329,16 @@ public:
///
/// The point of instantiation may be an invalid source location if this
/// function has yet to be instantiated.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
+ 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->data(),
TemplateArguments->size(),
@@ -350,49 +354,49 @@ public:
}
};
-/// \brief Provides information a specialization of a member of a class
-/// template, which may be a member function, static data member, or
-/// member class.
+/// \brief Provides information a specialization of a member of a class
+/// template, which may be a member function, static data member,
+/// member class or member enumeration.
class MemberSpecializationInfo {
// The member declaration from which this member was instantiated, and the
// 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
+ explicit
MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
SourceLocation POI = SourceLocation())
: MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
- assert(TSK != TSK_Undeclared &&
+ assert(TSK != TSK_Undeclared &&
"Cannot encode undeclared template specializations for members");
}
-
+
/// \brief Retrieve the member declaration from which this member was
/// instantiated.
NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
-
+
/// \brief Determine what kind of template specialization this is.
TemplateSpecializationKind getTemplateSpecializationKind() const {
return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
}
-
+
/// \brief Set the template specialization kind.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
- assert(TSK != TSK_Undeclared &&
+ assert(TSK != TSK_Undeclared &&
"Cannot encode undeclared template specializations for members");
MemberAndTSK.setInt(TSK - 1);
}
-
- /// \brief Retrieve the first point of instantiation of this member.
+
+ /// \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;
+ SourceLocation getPointOfInstantiation() const {
+ return PointOfInstantiation;
}
-
+
/// \brief Set the first point of instantiation.
void setPointOfInstantiation(SourceLocation POI) {
PointOfInstantiation = POI;
@@ -414,14 +418,14 @@ class DependentFunctionTemplateSpecializationInfo {
union {
// Force sizeof to be a multiple of sizeof(void*) so that the
// trailing data is aligned.
- void *Aligner;
+ void *Aligner;
struct {
/// The number of potential template candidates.
unsigned NumTemplates;
/// The number of template arguments.
- unsigned NumArgs;
+ unsigned NumArgs;
} d;
};
@@ -452,7 +456,7 @@ public:
/// \brief Returns the explicit template arguments that were given.
const TemplateArgumentLoc *getTemplateArgs() const {
return reinterpret_cast<const TemplateArgumentLoc*>(
- &getTemplates()[getNumTemplates()]);
+ &getTemplates()[getNumTemplates()]);
}
/// \brief Returns the number of explicit template arguments that were given.
@@ -474,33 +478,28 @@ public:
return AngleLocs.getEnd();
}
};
-
-/// Declaration of a redeclarable template.
-class RedeclarableTemplateDecl : public TemplateDecl {
- RedeclarableTemplateDecl *getPreviousDeclarationImpl() {
- return CommonOrPrev.dyn_cast<RedeclarableTemplateDecl*>();
+/// Declaration of a redeclarable template.
+class RedeclarableTemplateDecl : public TemplateDecl,
+ public Redeclarable<RedeclarableTemplateDecl>
+{
+ typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
+ virtual RedeclarableTemplateDecl *getNextRedeclaration() {
+ return RedeclLink.getNext();
}
-
- RedeclarableTemplateDecl *getCanonicalDeclImpl();
-
- void setPreviousDeclarationImpl(RedeclarableTemplateDecl *Prev);
-
- RedeclarableTemplateDecl *getInstantiatedFromMemberTemplateImpl() {
- return getCommonPtr()->InstantiatedFromMember.getPointer();
+ virtual RedeclarableTemplateDecl *getPreviousDeclImpl() {
+ return getPreviousDecl();
}
-
- void setInstantiatedFromMemberTemplateImpl(RedeclarableTemplateDecl *TD) {
- assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
- getCommonPtr()->InstantiatedFromMember.setPointer(TD);
+ virtual RedeclarableTemplateDecl *getMostRecentDeclImpl() {
+ return getMostRecentDecl();
}
protected:
template <typename EntryType> struct SpecEntryTraits {
typedef EntryType DeclType;
- static DeclType *getMostRecentDeclaration(EntryType *D) {
- return D->getMostRecentDeclaration();
+ static DeclType *getMostRecentDecl(EntryType *D) {
+ return D->getMostRecentDecl();
}
};
@@ -522,7 +521,7 @@ protected:
SpecIterator(SetIteratorType SetIter) : SetIter(SetIter) {}
DeclType *operator*() const {
- return SETraits::getMostRecentDeclaration(&*SetIter);
+ return SETraits::getMostRecentDecl(&*SetIter);
}
DeclType *operator->() const { return **this; }
@@ -562,15 +561,12 @@ protected:
/// was explicitly specialized.
llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
InstantiatedFromMember;
-
- /// \brief The latest declaration of this template.
- RedeclarableTemplateDecl *Latest;
};
- /// \brief A pointer to the previous declaration (if this is a redeclaration)
- /// or to the data that is common to all declarations of this template.
- llvm::PointerUnion<CommonBase*, RedeclarableTemplateDecl*> CommonOrPrev;
-
+ /// \brief Pointer to the common data shared by all declarations of this
+ /// template.
+ CommonBase *Common;
+
/// \brief Retrieves the "common" pointer shared by all (re-)declarations of
/// the same template. Calling this routine may implicitly allocate memory
/// for the common pointer.
@@ -582,56 +578,18 @@ protected:
RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
NamedDecl *Decl)
- : TemplateDecl(DK, DC, L, Name, Params, Decl),
- CommonOrPrev((CommonBase*)0) { }
+ : TemplateDecl(DK, DC, L, Name, Params, Decl), Common() { }
public:
template <class decl_type> friend class RedeclarableTemplate;
- RedeclarableTemplateDecl *getCanonicalDecl() {
- return getCanonicalDeclImpl();
- }
-
- /// \brief Retrieve the previous declaration of this template, or
- /// NULL if no such declaration exists.
- RedeclarableTemplateDecl *getPreviousDeclaration() {
- return getPreviousDeclarationImpl();
- }
-
- /// \brief Retrieve the previous declaration of this template, or
- /// NULL if no such declaration exists.
- const RedeclarableTemplateDecl *getPreviousDeclaration() const {
- return
- const_cast<RedeclarableTemplateDecl*>(this)->getPreviousDeclaration();
- }
-
- /// \brief Retrieve the first declaration of this template, or itself
- /// if this the first one.
- RedeclarableTemplateDecl *getFirstDeclaration() {
- return getCanonicalDecl();
- }
-
- /// \brief Retrieve the first declaration of this template, or itself
- /// if this the first one.
- const RedeclarableTemplateDecl *getFirstDeclaration() const {
- return
- const_cast<RedeclarableTemplateDecl*>(this)->getFirstDeclaration();
- }
-
- /// \brief Retrieve the most recent declaration of this template, or itself
- /// if this the most recent one.
- RedeclarableTemplateDecl *getMostRecentDeclaration() {
- return getCommonPtr()->Latest;
- }
-
- /// \brief Retrieve the most recent declaration of this template, or itself
- /// if this the most recent one.
- const RedeclarableTemplateDecl *getMostRecentDeclaration() const {
- return
- const_cast<RedeclarableTemplateDecl*>(this)->getMostRecentDeclaration();
+ /// Retrieves the canonical declaration of this template.
+ RedeclarableTemplateDecl *getCanonicalDecl() { return getFirstDeclaration(); }
+ const RedeclarableTemplateDecl *getCanonicalDecl() const {
+ return getFirstDeclaration();
}
- /// \brief Determines whether this template was a specialization of a
+ /// \brief Determines whether this template was a specialization of a
/// member template.
///
/// In the following example, the function template \c X<int>::f and the
@@ -652,21 +610,64 @@ public:
bool isMemberSpecialization() {
return getCommonPtr()->InstantiatedFromMember.getInt();
}
-
+
/// \brief Note that this member template is a specialization.
void setMemberSpecialization() {
assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
"Only member templates can be member template specializations");
getCommonPtr()->InstantiatedFromMember.setInt(true);
}
-
- /// \brief Retrieve the previous declaration of this template, or
- /// NULL if no such declaration exists.
+
+ /// \brief Retrieve the member template from which this template was
+ /// instantiated, or NULL if this template was not instantiated from a
+ /// member template.
+ ///
+ /// A template is instantiated from a member template when the member
+ /// template itself is part of a class template (or member thereof). For
+ /// example, given
+ ///
+ /// \code
+ /// template<typename T>
+ /// struct X {
+ /// template<typename U> void f(T, U);
+ /// };
+ ///
+ /// void test(X<int> x) {
+ /// x.f(1, 'a');
+ /// };
+ /// \endcode
+ ///
+ /// \c X<int>::f is a FunctionTemplateDecl that describes the function
+ /// template
+ ///
+ /// \code
+ /// template<typename U> void X<int>::f(int, U);
+ /// \endcode
+ ///
+ /// which was itself created during the instantiation of \c X<int>. Calling
+ /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
+ /// retrieve the FunctionTemplateDecl for the original template "f" within
+ /// the class template \c X<T>, i.e.,
+ ///
+ /// \code
+ /// template<typename T>
+ /// template<typename U>
+ /// void X<T>::f(T, U);
+ /// \endcode
RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() {
- return getInstantiatedFromMemberTemplateImpl();
+ return getCommonPtr()->InstantiatedFromMember.getPointer();
+ }
+
+ void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
+ assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
+ getCommonPtr()->InstantiatedFromMember.setPointer(TD);
}
- virtual RedeclarableTemplateDecl *getNextRedeclaration();
+ typedef redeclarable_base::redecl_iterator redecl_iterator;
+ using redeclarable_base::redecls_begin;
+ using redeclarable_base::redecls_end;
+ using redeclarable_base::getPreviousDecl;
+ using redeclarable_base::getMostRecentDecl;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -678,107 +679,35 @@ public:
return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
}
+ friend class ASTReader;
friend class ASTDeclReader;
friend class ASTDeclWriter;
};
-template <class decl_type>
-class RedeclarableTemplate {
- RedeclarableTemplateDecl *thisDecl() {
- return static_cast<decl_type*>(this);
- }
-
-public:
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- decl_type *getPreviousDeclaration() {
- return static_cast<decl_type*>(thisDecl()->getPreviousDeclarationImpl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- const decl_type *getPreviousDeclaration() const {
- return const_cast<RedeclarableTemplate*>(this)->getPreviousDeclaration();
- }
-
- /// \brief Set the previous declaration of this function template.
- void setPreviousDeclaration(decl_type *Prev) {
- thisDecl()->setPreviousDeclarationImpl(Prev);
- }
-
- decl_type *getCanonicalDecl() {
- return static_cast<decl_type*>(thisDecl()->getCanonicalDeclImpl());
- }
-
- const decl_type *getCanonicalDecl() const {
- return const_cast<RedeclarableTemplate*>(this)->getCanonicalDecl();
- }
-
- /// \brief Retrieve the member template that this template was instantiated
- /// from.
- ///
- /// This routine will return non-NULL for member templates of
- /// class templates. For example, given:
- ///
- /// \code
- /// template <typename T>
- /// struct X {
- /// template <typename U> void f();
- /// template <typename U> struct A {};
- /// };
- /// \endcode
- ///
- /// X<int>::f<float> is a CXXMethodDecl (whose parent is X<int>, a
- /// ClassTemplateSpecializationDecl) for which getPrimaryTemplate() will
- /// return X<int>::f, a FunctionTemplateDecl (whose parent is again
- /// X<int>) for which getInstantiatedFromMemberTemplate() will return
- /// X<T>::f, a FunctionTemplateDecl (whose parent is X<T>, a
- /// ClassTemplateDecl).
- ///
- /// X<int>::A<float> is a ClassTemplateSpecializationDecl (whose parent
- /// is X<int>, also a CTSD) for which getSpecializedTemplate() will
- /// return X<int>::A<U>, a ClassTemplateDecl (whose parent is again
- /// X<int>) for which getInstantiatedFromMemberTemplate() will return
- /// X<T>::A<U>, a ClassTemplateDecl (whose parent is X<T>, also a CTD).
- ///
- /// \returns NULL if this is not an instantiation of a member template.
- decl_type *getInstantiatedFromMemberTemplate() {
- return static_cast<decl_type*>(
- thisDecl()->getInstantiatedFromMemberTemplateImpl());
- }
-
- void setInstantiatedFromMemberTemplate(decl_type *TD) {
- thisDecl()->setInstantiatedFromMemberTemplateImpl(TD);
- }
-};
-
template <> struct RedeclarableTemplateDecl::
SpecEntryTraits<FunctionTemplateSpecializationInfo> {
typedef FunctionDecl DeclType;
static DeclType *
- getMostRecentDeclaration(FunctionTemplateSpecializationInfo *I) {
- return I->Function->getMostRecentDeclaration();
+ getMostRecentDecl(FunctionTemplateSpecializationInfo *I) {
+ return I->Function->getMostRecentDecl();
}
};
/// Declaration of a template function.
-class FunctionTemplateDecl : public RedeclarableTemplateDecl,
- public RedeclarableTemplate<FunctionTemplateDecl> {
+class FunctionTemplateDecl : public RedeclarableTemplateDecl {
static void DeallocateCommon(void *Ptr);
protected:
- typedef RedeclarableTemplate<FunctionTemplateDecl> redeclarable_base;
-
/// \brief Data that is common to all of the declarations of a given
/// function template.
struct Common : CommonBase {
Common() : InjectedArgs(0) { }
-
+
/// \brief The function template specializations for this function
/// template, including explicit specializations and instantiations.
llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
-
+
/// \brief The set of "injected" template arguments used within this
/// function template.
///
@@ -813,7 +742,7 @@ protected:
/// retrieved by an earlier call to findSpecialization().
void addSpecialization(FunctionTemplateSpecializationInfo* Info,
void *InsertPos);
-
+
public:
/// Get the underlying function declaration of the template.
FunctionDecl *getTemplatedDecl() const {
@@ -832,26 +761,31 @@ public:
unsigned NumArgs, void *&InsertPos);
FunctionTemplateDecl *getCanonicalDecl() {
- return redeclarable_base::getCanonicalDecl();
+ return cast<FunctionTemplateDecl>(
+ RedeclarableTemplateDecl::getCanonicalDecl());
}
const FunctionTemplateDecl *getCanonicalDecl() const {
- return redeclarable_base::getCanonicalDecl();
+ return cast<FunctionTemplateDecl>(
+ RedeclarableTemplateDecl::getCanonicalDecl());
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
- FunctionTemplateDecl *getPreviousDeclaration() {
- return redeclarable_base::getPreviousDeclaration();
+ FunctionTemplateDecl *getPreviousDecl() {
+ return cast_or_null<FunctionTemplateDecl>(
+ RedeclarableTemplateDecl::getPreviousDecl());
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
- const FunctionTemplateDecl *getPreviousDeclaration() const {
- return redeclarable_base::getPreviousDeclaration();
+ const FunctionTemplateDecl *getPreviousDecl() const {
+ return cast_or_null<FunctionTemplateDecl>(
+ RedeclarableTemplateDecl::getPreviousDecl());
}
FunctionTemplateDecl *getInstantiatedFromMemberTemplate() {
- return redeclarable_base::getInstantiatedFromMemberTemplate();
+ return cast_or_null<FunctionTemplateDecl>(
+ RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
}
typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
@@ -866,13 +800,13 @@ public:
/// \brief Retrieve the "injected" template arguments that correspond to the
/// template parameters of this function template.
- ///
+ ///
/// Although the C++ standard has no notion of the "injected" template
/// arguments for a function template, the notion is convenient when
/// we need to perform substitutions inside the definition of a function
- /// template.
+ /// template.
std::pair<const TemplateArgument *, unsigned> getInjectedTemplateArgs();
-
+
/// \brief Create a function template node.
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -881,7 +815,7 @@ public:
NamedDecl *Decl);
/// \brief Create an empty function template node.
- static FunctionTemplateDecl *Create(ASTContext &C, EmptyShell);
+ static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -966,7 +900,8 @@ public:
unsigned D, unsigned P,
IdentifierInfo *Id, bool Typename,
bool ParameterPack);
- static TemplateTypeParmDecl *Create(const ASTContext &C, EmptyShell Empty);
+ static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
+ unsigned ID);
/// \brief Whether this template type parameter was declared with
/// the 'typename' keyword. If not, it was declared with the 'class'
@@ -1003,21 +938,21 @@ public:
DefaultArgument = 0;
InheritedDefault = false;
}
-
+
/// \brief Set whether this template type parameter was declared with
/// the 'typename' or 'class' keyword.
void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
/// \brief Retrieve the depth of the template parameter.
unsigned getDepth() const;
-
+
/// \brief Retrieve the index of the template parameter.
unsigned getIndex() const;
/// \brief Returns whether this is a parameter pack.
bool isParameterPack() const;
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1038,18 +973,18 @@ class NonTypeTemplateParmDecl
// FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
// down here to save memory.
-
+
/// \brief Whether this non-type template parameter is a parameter pack.
bool ParameterPack;
-
- /// \brief Whether this non-type template parameter is an "expanded"
+
+ /// \brief Whether this non-type template parameter is an "expanded"
/// parameter pack, meaning that its type is a pack expansion and we
/// already know the set of types that expansion expands to.
bool ExpandedParameterPack;
-
+
/// \brief The number of types in an expanded parameter pack.
unsigned NumExpandedTypes;
-
+
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, unsigned D, unsigned P,
IdentifierInfo *Id, QualType T,
@@ -1069,7 +1004,7 @@ class NonTypeTemplateParmDecl
TypeSourceInfo **ExpandedTInfos);
friend class ASTDeclReader;
-
+
public:
static NonTypeTemplateParmDecl *
Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
@@ -1083,13 +1018,19 @@ public:
const QualType *ExpandedTypes, unsigned NumExpandedTypes,
TypeSourceInfo **ExpandedTInfos);
+ static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID);
+ static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID,
+ unsigned NumExpandedTypes);
+
using TemplateParmPosition::getDepth;
using TemplateParmPosition::setDepth;
using TemplateParmPosition::getPosition;
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
/// \brief Determine whether this template parameter has a default
/// argument.
@@ -1135,7 +1076,7 @@ public:
/// template<typename T, unsigned ...Dims> struct multi_array;
/// \endcode
bool isParameterPack() const { return ParameterPack; }
-
+
/// \brief Whether this parameter is a non-type template parameter pack
/// that has different types at different positions.
///
@@ -1150,25 +1091,26 @@ public:
/// struct Y { /* ... */ };
/// };
/// \endcode
- ///
+ ///
/// The parameter pack \c Values has a \c PackExpansionType as its type,
/// which expands \c Types. When \c Types is supplied with template arguments
- /// by instantiating \c X, the instantiation of \c Values becomes an
- /// expanded parameter pack. For example, instantiating
+ /// by instantiating \c X, the instantiation of \c Values becomes an
+ /// expanded parameter pack. For example, instantiating
/// \c X<int, unsigned int> results in \c Values being an expanded parameter
/// pack with expansion types \c int and \c unsigned int.
///
- /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
+ /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
/// return the expansion types.
bool isExpandedParameterPack() const { return ExpandedParameterPack; }
-
- /// \brief Retrieves the number of expansion types in an expanded parameter pack.
+
+ /// \brief Retrieves the number of expansion types in an expanded parameter
+ /// pack.
unsigned getNumExpansionTypes() const {
assert(ExpandedParameterPack && "Not an expansion parameter pack");
return NumExpandedTypes;
}
- /// \brief Retrieve a particular expansion type within an expanded parameter
+ /// \brief Retrieve a particular expansion type within an expanded parameter
/// pack.
QualType getExpansionType(unsigned I) const {
assert(I < NumExpandedTypes && "Out-of-range expansion type index");
@@ -1176,7 +1118,7 @@ public:
return QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
}
- /// \brief Retrieve a particular expansion type source info within an
+ /// \brief Retrieve a particular expansion type source info within an
/// expanded parameter pack.
TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
assert(I < NumExpandedTypes && "Out-of-range expansion type index");
@@ -1197,8 +1139,10 @@ public:
/// @endcode
/// A template template parameter is a TemplateDecl because it defines the
/// name of a template and the template parameters allowable for substitution.
-class TemplateTemplateParmDecl
- : public TemplateDecl, protected TemplateParmPosition {
+class TemplateTemplateParmDecl : public TemplateDecl,
+ protected TemplateParmPosition
+{
+ virtual void anchor();
/// DefaultArgument - The default template argument, if any.
TemplateArgumentLoc DefaultArgument;
@@ -1207,7 +1151,7 @@ class TemplateTemplateParmDecl
/// \brief Whether this parameter is a parameter pack.
bool ParameterPack;
-
+
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
unsigned D, unsigned P, bool ParameterPack,
IdentifierInfo *Id, TemplateParameterList *Params)
@@ -1223,6 +1167,9 @@ public:
IdentifierInfo *Id,
TemplateParameterList *Params);
+ static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
+ unsigned ID);
+
using TemplateParmPosition::getDepth;
using TemplateParmPosition::getPosition;
using TemplateParmPosition::getIndex;
@@ -1269,7 +1216,7 @@ public:
DefaultArgumentWasInherited = false;
}
- SourceRange getSourceRange() const {
+ SourceRange getSourceRange() const LLVM_READONLY {
SourceLocation End = getLocation();
if (hasDefaultArgument() && !defaultArgumentWasInherited())
End = getDefaultArgument().getSourceRange().getEnd();
@@ -1365,19 +1312,19 @@ public:
unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl);
static ClassTemplateSpecializationDecl *
- Create(ASTContext &Context, EmptyShell Empty);
+ CreateDeserialized(ASTContext &C, unsigned ID);
virtual void getNameForDiagnostic(std::string &S,
const PrintingPolicy &Policy,
bool Qualified) const;
- ClassTemplateSpecializationDecl *getMostRecentDeclaration() {
+ ClassTemplateSpecializationDecl *getMostRecentDecl() {
CXXRecordDecl *Recent
- = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDeclaration());
+ = cast<CXXRecordDecl>(CXXRecordDecl::getMostRecentDecl());
if (!isa<ClassTemplateSpecializationDecl>(Recent)) {
// FIXME: Does injected class name need to be in the redeclarations chain?
- assert(Recent->isInjectedClassName() && Recent->getPreviousDeclaration());
- Recent = Recent->getPreviousDeclaration();
+ assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
+ Recent = Recent->getPreviousDecl();
}
return cast<ClassTemplateSpecializationDecl>(Recent);
}
@@ -1525,7 +1472,7 @@ public:
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
}
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange() const LLVM_READONLY;
void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
@@ -1552,13 +1499,15 @@ public:
static bool classof(const ClassTemplatePartialSpecializationDecl *) {
return true;
}
-
+
friend class ASTDeclReader;
friend class ASTDeclWriter;
};
class ClassTemplatePartialSpecializationDecl
: public ClassTemplateSpecializationDecl {
+ virtual void anchor();
+
/// \brief The list of template parameters
TemplateParameterList* TemplateParams;
@@ -1571,15 +1520,15 @@ class ClassTemplatePartialSpecializationDecl
/// specialization was added to the set of partial specializations for
/// its owning class template.
unsigned SequenceNumber;
-
- /// \brief The class template partial specialization from which this
+
+ /// \brief The class template partial specialization from which this
/// class template partial specialization was instantiated.
///
/// The boolean value will be true to indicate that this class template
/// partial specialization was specialized at this level.
llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
InstantiatedFromMember;
-
+
ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
DeclContext *DC,
SourceLocation StartLoc,
@@ -1592,7 +1541,7 @@ class ClassTemplatePartialSpecializationDecl
unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl,
unsigned SequenceNumber);
-
+
ClassTemplatePartialSpecializationDecl()
: ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
TemplateParams(0), ArgsAsWritten(0),
@@ -1601,7 +1550,7 @@ class ClassTemplatePartialSpecializationDecl
public:
static ClassTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, TagKind TK,DeclContext *DC,
+ Create(ASTContext &Context, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
@@ -1613,11 +1562,11 @@ public:
unsigned SequenceNumber);
static ClassTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, EmptyShell Empty);
+ CreateDeserialized(ASTContext &C, unsigned ID);
- ClassTemplatePartialSpecializationDecl *getMostRecentDeclaration() {
+ ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
return cast<ClassTemplatePartialSpecializationDecl>(
- ClassTemplateSpecializationDecl::getMostRecentDeclaration());
+ ClassTemplateSpecializationDecl::getMostRecentDecl());
}
/// Get the list of template parameters
@@ -1654,9 +1603,9 @@ public:
/// \endcode
///
/// In this example, the instantiation of \c Outer<float>::Inner<int*> will
- /// end up instantiating the partial specialization
- /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
- /// template partial specialization \c Outer<T>::Inner<U*>. Given
+ /// end up instantiating the partial specialization
+ /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
+ /// template partial specialization \c Outer<T>::Inner<U*>. Given
/// \c Outer<float>::Inner<U*>, this function would return
/// \c Outer<T>::Inner<U*>.
ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() {
@@ -1664,15 +1613,15 @@ public:
= cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
return First->InstantiatedFromMember.getPointer();
}
-
+
void setInstantiatedFromMember(
ClassTemplatePartialSpecializationDecl *PartialSpec) {
ClassTemplatePartialSpecializationDecl *First
= cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
First->InstantiatedFromMember.setPointer(PartialSpec);
}
-
- /// \brief Determines whether this class template partial specialization
+
+ /// \brief Determines whether this class template partial specialization
/// template was a specialization of a member partial specialization.
///
/// In the following example, the member template partial specialization
@@ -1693,7 +1642,7 @@ public:
= cast<ClassTemplatePartialSpecializationDecl>(getFirstDeclaration());
return First->InstantiatedFromMember.getInt();
}
-
+
/// \brief Note that this member template is a specialization.
void setMemberSpecialization() {
ClassTemplatePartialSpecializationDecl *First
@@ -1711,7 +1660,7 @@ public:
return cast<InjectedClassNameType>(getTypeForDecl())
->getInjectedSpecializationType();
}
-
+
// FIXME: Add Profile support!
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1728,18 +1677,15 @@ public:
};
/// Declaration of a class template.
-class ClassTemplateDecl : public RedeclarableTemplateDecl,
- public RedeclarableTemplate<ClassTemplateDecl> {
+class ClassTemplateDecl : public RedeclarableTemplateDecl {
static void DeallocateCommon(void *Ptr);
-
-protected:
- typedef RedeclarableTemplate<ClassTemplateDecl> redeclarable_base;
+protected:
/// \brief Data that is common to all of the declarations of a given
/// class template.
struct Common : CommonBase {
Common() : LazySpecializations() { }
-
+
/// \brief The class template specializations for this class
/// template, including explicit specializations and instantiations.
llvm::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
@@ -1751,7 +1697,7 @@ protected:
/// \brief The injected-class-name type for this class template.
QualType InjectedClassNameType;
-
+
/// \brief If non-null, points to an array of specializations (including
/// partial specializations) known ownly by their external declaration IDs.
///
@@ -1762,7 +1708,7 @@ protected:
/// \brief Load any lazily-loaded specializations from the external source.
void LoadLazySpecializations();
-
+
/// \brief Retrieve the set of specializations of this class template.
llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations();
@@ -1806,7 +1752,7 @@ public:
ClassTemplateDecl *PrevDecl);
/// Create an empty class template node.
- static ClassTemplateDecl *Create(ASTContext &C, EmptyShell);
+ static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// \brief Return the specialization with the provided arguments if it exists,
/// otherwise return the insertion point.
@@ -1819,26 +1765,31 @@ public:
void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
ClassTemplateDecl *getCanonicalDecl() {
- return redeclarable_base::getCanonicalDecl();
+ return cast<ClassTemplateDecl>(
+ RedeclarableTemplateDecl::getCanonicalDecl());
}
const ClassTemplateDecl *getCanonicalDecl() const {
- return redeclarable_base::getCanonicalDecl();
+ return cast<ClassTemplateDecl>(
+ RedeclarableTemplateDecl::getCanonicalDecl());
}
/// \brief Retrieve the previous declaration of this class template, or
/// NULL if no such declaration exists.
- ClassTemplateDecl *getPreviousDeclaration() {
- return redeclarable_base::getPreviousDeclaration();
+ ClassTemplateDecl *getPreviousDecl() {
+ return cast_or_null<ClassTemplateDecl>(
+ RedeclarableTemplateDecl::getPreviousDecl());
}
/// \brief Retrieve the previous declaration of this class template, or
/// NULL if no such declaration exists.
- const ClassTemplateDecl *getPreviousDeclaration() const {
- return redeclarable_base::getPreviousDeclaration();
+ const ClassTemplateDecl *getPreviousDecl() const {
+ return cast_or_null<ClassTemplateDecl>(
+ RedeclarableTemplateDecl::getPreviousDecl());
}
ClassTemplateDecl *getInstantiatedFromMemberTemplate() {
- return redeclarable_base::getInstantiatedFromMemberTemplate();
+ return cast_or_null<ClassTemplateDecl>(
+ RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
}
/// \brief Return the partial specialization with the provided arguments if it
@@ -1860,7 +1811,7 @@ public:
/// \brief Retrieve the partial specializations as an ordered list.
void getPartialSpecializations(
SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
-
+
/// \brief Find a class template partial specialization with the given
/// type T.
///
@@ -1870,7 +1821,7 @@ public:
/// \returns the class template partial specialization that exactly matches
/// the type \p T, or NULL if no such partial specialization exists.
ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
-
+
/// \brief Find a class template partial specialization which was instantiated
/// from the given member partial specialization.
///
@@ -1939,6 +1890,7 @@ public:
/// NOTE: This class is not currently in use. All of the above
/// will yield a FriendDecl, not a FriendTemplateDecl.
class FriendTemplateDecl : public Decl {
+ virtual void anchor();
public:
typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
@@ -1957,7 +1909,7 @@ private:
FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
- unsigned NParams,
+ unsigned NParams,
TemplateParameterList **Params,
FriendUnion Friend,
SourceLocation FriendLoc)
@@ -1977,12 +1929,12 @@ private:
public:
static FriendTemplateDecl *Create(ASTContext &Context,
DeclContext *DC, SourceLocation Loc,
- unsigned NParams,
+ unsigned NParams,
TemplateParameterList **Params,
FriendUnion Friend,
SourceLocation FriendLoc);
- static FriendTemplateDecl *Create(ASTContext &Context, EmptyShell Empty);
+ static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
/// If this friend declaration names a templated type (or
/// a dependent member type of a templated type), return that
@@ -2023,13 +1975,10 @@ public:
/// Declaration of an alias template. For example:
///
/// template <typename T> using V = std::map<T*, int, MyCompare<T>>;
-class TypeAliasTemplateDecl : public RedeclarableTemplateDecl,
- public RedeclarableTemplate<TypeAliasTemplateDecl> {
+class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
static void DeallocateCommon(void *Ptr);
protected:
- typedef RedeclarableTemplate<TypeAliasTemplateDecl> redeclarable_base;
-
typedef CommonBase Common;
TypeAliasTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
@@ -2050,29 +1999,34 @@ public:
TypeAliasTemplateDecl *getCanonicalDecl() {
- return redeclarable_base::getCanonicalDecl();
+ return cast<TypeAliasTemplateDecl>(
+ RedeclarableTemplateDecl::getCanonicalDecl());
}
const TypeAliasTemplateDecl *getCanonicalDecl() const {
- return redeclarable_base::getCanonicalDecl();
+ return cast<TypeAliasTemplateDecl>(
+ RedeclarableTemplateDecl::getCanonicalDecl());
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
- TypeAliasTemplateDecl *getPreviousDeclaration() {
- return redeclarable_base::getPreviousDeclaration();
+ TypeAliasTemplateDecl *getPreviousDecl() {
+ return cast_or_null<TypeAliasTemplateDecl>(
+ RedeclarableTemplateDecl::getPreviousDecl());
}
/// \brief Retrieve the previous declaration of this function template, or
/// NULL if no such declaration exists.
- const TypeAliasTemplateDecl *getPreviousDeclaration() const {
- return redeclarable_base::getPreviousDeclaration();
+ const TypeAliasTemplateDecl *getPreviousDecl() const {
+ return cast_or_null<TypeAliasTemplateDecl>(
+ RedeclarableTemplateDecl::getPreviousDecl());
}
TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() {
- return redeclarable_base::getInstantiatedFromMemberTemplate();
+ return cast_or_null<TypeAliasTemplateDecl>(
+ RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
}
-
+
/// \brief Create a function template node.
static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
@@ -2081,7 +2035,7 @@ public:
NamedDecl *Decl);
/// \brief Create an empty alias template node.
- static TypeAliasTemplateDecl *Create(ASTContext &C, EmptyShell);
+ static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
// Implement isa/cast/dyncast support
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2105,7 +2059,8 @@ public:
/// CXXMethodDecl. Then during an instantiation of class A, it will be
/// transformed into an actual function specialization.
class ClassScopeFunctionSpecializationDecl : public Decl {
-private:
+ virtual void anchor();
+
ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
CXXMethodDecl *FD)
: Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
@@ -2126,11 +2081,9 @@ public:
return new (C) ClassScopeFunctionSpecializationDecl(DC , Loc, FD);
}
- static ClassScopeFunctionSpecializationDecl *Create(ASTContext &Context,
- EmptyShell Empty) {
- return new (Context)ClassScopeFunctionSpecializationDecl(0,
- SourceLocation(), 0);
- }
+ static ClassScopeFunctionSpecializationDecl *
+ CreateDeserialized(ASTContext &Context, unsigned ID);
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
OpenPOWER on IntegriCloud