|
|
|
@ -100,327 +100,6 @@ public:
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// Kinds of Templates
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
|
|
|
|
|
/// class, function, etc.). The TemplateDecl class stores the list of template
|
|
|
|
|
/// parameters and a reference to the templated scoped declaration: the
|
|
|
|
|
/// underlying AST node.
|
|
|
|
|
class TemplateDecl : public NamedDecl {
|
|
|
|
|
protected:
|
|
|
|
|
// This is probably never used.
|
|
|
|
|
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
|
|
|
|
DeclarationName Name)
|
|
|
|
|
: NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
// Construct a template decl with the given name and parameters.
|
|
|
|
|
// Used when there is not templated element (tt-params, alias?).
|
|
|
|
|
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
|
|
|
|
DeclarationName Name, TemplateParameterList *Params)
|
|
|
|
|
: NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
// Construct a template decl with name, parameters, and templated element.
|
|
|
|
|
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
|
|
|
|
DeclarationName Name, TemplateParameterList *Params,
|
|
|
|
|
NamedDecl *Decl)
|
|
|
|
|
: NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
|
|
|
|
|
TemplateParams(Params) { }
|
|
|
|
|
public:
|
|
|
|
|
~TemplateDecl();
|
|
|
|
|
|
|
|
|
|
/// Get the list of template parameters
|
|
|
|
|
TemplateParameterList *getTemplateParameters() const {
|
|
|
|
|
return TemplateParams;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Get the underlying, templated declaration.
|
|
|
|
|
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
|
static bool classof(const Decl *D) {
|
|
|
|
|
return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
|
|
|
|
|
}
|
|
|
|
|
static bool classof(const TemplateDecl *D) { return true; }
|
|
|
|
|
static bool classof(const FunctionTemplateDecl *D) { return true; }
|
|
|
|
|
static bool classof(const ClassTemplateDecl *D) { return true; }
|
|
|
|
|
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
NamedDecl *TemplatedDecl;
|
|
|
|
|
TemplateParameterList* TemplateParams;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// \brief Provides information about a function template specialization,
|
|
|
|
|
/// which is a FunctionDecl that has been explicitly specialization or
|
|
|
|
|
/// instantiated from a function template.
|
|
|
|
|
class FunctionTemplateSpecializationInfo {
|
|
|
|
|
public:
|
|
|
|
|
FunctionTemplateDecl *Template;
|
|
|
|
|
const TemplateArgumentList *TemplateArguments;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// Declaration of a template function.
|
|
|
|
|
class FunctionTemplateDecl : public TemplateDecl {
|
|
|
|
|
protected:
|
|
|
|
|
/// \brief Data that is common to all of the declarations of a given
|
|
|
|
|
/// class template.
|
|
|
|
|
struct Common {
|
|
|
|
|
/// \brief The class template specializations for this class
|
|
|
|
|
/// 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;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
|
|
|
|
|
TemplateParameterList *Params, NamedDecl *Decl)
|
|
|
|
|
: TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
|
|
|
|
|
public:
|
|
|
|
|
/// Get the underling function declaration of the template.
|
|
|
|
|
FunctionDecl *getTemplatedDecl() const {
|
|
|
|
|
return static_cast<FunctionDecl*>(TemplatedDecl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Create a template function node.
|
|
|
|
|
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
|
|
|
|
|
SourceLocation L,
|
|
|
|
|
DeclarationName Name,
|
|
|
|
|
TemplateParameterList *Params,
|
|
|
|
|
NamedDecl *Decl);
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast support
|
|
|
|
|
static bool classof(const Decl *D)
|
|
|
|
|
{ return D->getKind() == FunctionTemplate; }
|
|
|
|
|
static bool classof(const FunctionTemplateDecl *D)
|
|
|
|
|
{ return true; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// Kinds of Template Parameters
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
/// The TemplateParmPosition class defines the position of a template parameter
|
|
|
|
|
/// within a template parameter list. Because template parameter can be listed
|
|
|
|
|
/// sequentially for out-of-line template members, each template parameter is
|
|
|
|
|
/// given a Depth - the nesting of template parameter scopes - and a Position -
|
|
|
|
|
/// the occurrence within the parameter list.
|
|
|
|
|
/// This class is inheritedly privately by different kinds of template
|
|
|
|
|
/// parameters and is not part of the Decl hierarchy. Just a facility.
|
|
|
|
|
class TemplateParmPosition
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
// FIXME: This should probably never be called, but it's here as
|
|
|
|
|
TemplateParmPosition()
|
|
|
|
|
: Depth(0), Position(0)
|
|
|
|
|
{ /* assert(0 && "Cannot create positionless template parameter"); */ }
|
|
|
|
|
|
|
|
|
|
TemplateParmPosition(unsigned D, unsigned P)
|
|
|
|
|
: Depth(D), Position(P)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
// FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
|
|
|
|
|
// position? Maybe?
|
|
|
|
|
unsigned Depth;
|
|
|
|
|
unsigned Position;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
/// Get the nesting depth of the template parameter.
|
|
|
|
|
unsigned getDepth() const { return Depth; }
|
|
|
|
|
|
|
|
|
|
/// Get the position of the template parameter within its parameter list.
|
|
|
|
|
unsigned getPosition() const { return Position; }
|
|
|
|
|
|
|
|
|
|
/// Get the index of the template parameter within its parameter list.
|
|
|
|
|
unsigned getIndex() const { return Position; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// TemplateTypeParmDecl - Declaration of a template type parameter,
|
|
|
|
|
/// e.g., "T" in
|
|
|
|
|
/// @code
|
|
|
|
|
/// template<typename T> class vector;
|
|
|
|
|
/// @endcode
|
|
|
|
|
class TemplateTypeParmDecl : public TypeDecl {
|
|
|
|
|
/// \brief Whether this template type parameter was declaration with
|
|
|
|
|
/// the 'typename' keyword. If false, it was declared with the
|
|
|
|
|
/// 'class' keyword.
|
|
|
|
|
bool Typename : 1;
|
|
|
|
|
|
|
|
|
|
/// \brief Whether this template type parameter inherited its
|
|
|
|
|
/// default argument.
|
|
|
|
|
bool InheritedDefault : 1;
|
|
|
|
|
|
|
|
|
|
/// \brief Whether this is a parameter pack.
|
|
|
|
|
bool ParameterPack : 1;
|
|
|
|
|
|
|
|
|
|
/// \brief The location of the default argument, if any.
|
|
|
|
|
SourceLocation DefaultArgumentLoc;
|
|
|
|
|
|
|
|
|
|
/// \brief The default template argument, if any.
|
|
|
|
|
QualType DefaultArgument;
|
|
|
|
|
|
|
|
|
|
TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
|
|
|
|
|
bool Typename, QualType Type, bool ParameterPack)
|
|
|
|
|
: TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
|
|
|
|
|
InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
|
|
|
|
|
TypeForDecl = Type.getTypePtr();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
|
|
|
|
|
SourceLocation L, unsigned D, unsigned P,
|
|
|
|
|
IdentifierInfo *Id, bool Typename,
|
|
|
|
|
bool ParameterPack);
|
|
|
|
|
|
|
|
|
|
/// \brief Whether this template type parameter was declared with
|
|
|
|
|
/// the 'typename' keyword. If not, it was declared with the 'class'
|
|
|
|
|
/// keyword.
|
|
|
|
|
bool wasDeclaredWithTypename() const { return Typename; }
|
|
|
|
|
|
|
|
|
|
/// \brief Determine whether this template parameter has a default
|
|
|
|
|
/// argument.
|
|
|
|
|
bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the default argument, if any.
|
|
|
|
|
QualType getDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the location of the default argument, if any.
|
|
|
|
|
SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the default argument was inherited
|
|
|
|
|
/// from a previous declaration of this template.
|
|
|
|
|
bool defaultArgumentWasInherited() const { return InheritedDefault; }
|
|
|
|
|
|
|
|
|
|
/// \brief Set the default argument for this template parameter, and
|
|
|
|
|
/// whether that default argument was inherited from another
|
|
|
|
|
/// declaration.
|
|
|
|
|
void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
|
|
|
|
|
bool Inherited) {
|
|
|
|
|
DefaultArgument = DefArg;
|
|
|
|
|
DefaultArgumentLoc = DefArgLoc;
|
|
|
|
|
InheritedDefault = Inherited;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Returns whether this is a parameter pack.
|
|
|
|
|
bool isParameterPack() const { return ParameterPack; }
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
|
static bool classof(const Decl *D) {
|
|
|
|
|
return D->getKind() == TemplateTypeParm;
|
|
|
|
|
}
|
|
|
|
|
static bool classof(const TemplateTypeParmDecl *D) { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
|
|
|
|
|
/// e.g., "Size" in
|
|
|
|
|
/// @code
|
|
|
|
|
/// template<int Size> class array { };
|
|
|
|
|
/// @endcode
|
|
|
|
|
class NonTypeTemplateParmDecl
|
|
|
|
|
: public VarDecl, protected TemplateParmPosition {
|
|
|
|
|
/// \brief The default template argument, if any.
|
|
|
|
|
Expr *DefaultArgument;
|
|
|
|
|
|
|
|
|
|
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
|
|
|
|
|
unsigned P, IdentifierInfo *Id, QualType T,
|
|
|
|
|
SourceLocation TSSL = SourceLocation())
|
|
|
|
|
: VarDecl(NonTypeTemplateParm, DC, L, Id, T, VarDecl::None, TSSL),
|
|
|
|
|
TemplateParmPosition(D, P), DefaultArgument(0)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static NonTypeTemplateParmDecl *
|
|
|
|
|
Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
|
|
|
|
|
unsigned P, IdentifierInfo *Id, QualType T,
|
|
|
|
|
SourceLocation TypeSpecStartLoc = SourceLocation());
|
|
|
|
|
|
|
|
|
|
using TemplateParmPosition::getDepth;
|
|
|
|
|
using TemplateParmPosition::getPosition;
|
|
|
|
|
using TemplateParmPosition::getIndex;
|
|
|
|
|
|
|
|
|
|
/// \brief Determine whether this template parameter has a default
|
|
|
|
|
/// argument.
|
|
|
|
|
bool hasDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the default argument, if any.
|
|
|
|
|
Expr *getDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the location of the default argument, if any.
|
|
|
|
|
SourceLocation getDefaultArgumentLoc() const;
|
|
|
|
|
|
|
|
|
|
/// \brief Set the default argument for this template parameter.
|
|
|
|
|
void setDefaultArgument(Expr *DefArg) {
|
|
|
|
|
DefaultArgument = DefArg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
|
static bool classof(const Decl *D) {
|
|
|
|
|
return D->getKind() == NonTypeTemplateParm;
|
|
|
|
|
}
|
|
|
|
|
static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// TemplateTemplateParmDecl - Declares a template template parameter,
|
|
|
|
|
/// e.g., "T" in
|
|
|
|
|
/// @code
|
|
|
|
|
/// template <template <typename> class T> class container { };
|
|
|
|
|
/// @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 {
|
|
|
|
|
|
|
|
|
|
/// \brief The default template argument, if any.
|
|
|
|
|
Expr *DefaultArgument;
|
|
|
|
|
|
|
|
|
|
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
|
|
|
|
|
unsigned D, unsigned P,
|
|
|
|
|
IdentifierInfo *Id, TemplateParameterList *Params)
|
|
|
|
|
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
|
|
|
|
|
TemplateParmPosition(D, P), DefaultArgument(0)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
|
|
|
|
|
SourceLocation L, unsigned D,
|
|
|
|
|
unsigned P, IdentifierInfo *Id,
|
|
|
|
|
TemplateParameterList *Params);
|
|
|
|
|
|
|
|
|
|
using TemplateParmPosition::getDepth;
|
|
|
|
|
using TemplateParmPosition::getPosition;
|
|
|
|
|
using TemplateParmPosition::getIndex;
|
|
|
|
|
|
|
|
|
|
/// \brief Determine whether this template parameter has a default
|
|
|
|
|
/// argument.
|
|
|
|
|
bool hasDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the default argument, if any.
|
|
|
|
|
Expr *getDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the location of the default argument, if any.
|
|
|
|
|
SourceLocation getDefaultArgumentLoc() const;
|
|
|
|
|
|
|
|
|
|
/// \brief Set the default argument for this template parameter.
|
|
|
|
|
void setDefaultArgument(Expr *DefArg) {
|
|
|
|
|
DefaultArgument = DefArg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
|
static bool classof(const Decl *D) {
|
|
|
|
|
return D->getKind() == TemplateTemplateParm;
|
|
|
|
|
}
|
|
|
|
|
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// \brief Represents a template argument within a class template
|
|
|
|
|
/// specialization.
|
|
|
|
|
class TemplateArgument {
|
|
|
|
@ -767,6 +446,379 @@ public:
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// Kinds of Templates
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
/// TemplateDecl - The base class of all kinds of template declarations (e.g.,
|
|
|
|
|
/// class, function, etc.). The TemplateDecl class stores the list of template
|
|
|
|
|
/// parameters and a reference to the templated scoped declaration: the
|
|
|
|
|
/// underlying AST node.
|
|
|
|
|
class TemplateDecl : public NamedDecl {
|
|
|
|
|
protected:
|
|
|
|
|
// This is probably never used.
|
|
|
|
|
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
|
|
|
|
DeclarationName Name)
|
|
|
|
|
: NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(0)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
// Construct a template decl with the given name and parameters.
|
|
|
|
|
// Used when there is not templated element (tt-params, alias?).
|
|
|
|
|
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
|
|
|
|
DeclarationName Name, TemplateParameterList *Params)
|
|
|
|
|
: NamedDecl(DK, DC, L, Name), TemplatedDecl(0), TemplateParams(Params)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
// Construct a template decl with name, parameters, and templated element.
|
|
|
|
|
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
|
|
|
|
|
DeclarationName Name, TemplateParameterList *Params,
|
|
|
|
|
NamedDecl *Decl)
|
|
|
|
|
: NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
|
|
|
|
|
TemplateParams(Params) { }
|
|
|
|
|
public:
|
|
|
|
|
~TemplateDecl();
|
|
|
|
|
|
|
|
|
|
/// Get the list of template parameters
|
|
|
|
|
TemplateParameterList *getTemplateParameters() const {
|
|
|
|
|
return TemplateParams;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Get the underlying, templated declaration.
|
|
|
|
|
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
|
static bool classof(const Decl *D) {
|
|
|
|
|
return D->getKind() >= TemplateFirst && D->getKind() <= TemplateLast;
|
|
|
|
|
}
|
|
|
|
|
static bool classof(const TemplateDecl *D) { return true; }
|
|
|
|
|
static bool classof(const FunctionTemplateDecl *D) { return true; }
|
|
|
|
|
static bool classof(const ClassTemplateDecl *D) { return true; }
|
|
|
|
|
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
NamedDecl *TemplatedDecl;
|
|
|
|
|
TemplateParameterList* TemplateParams;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// \brief Provides information about a function template specialization,
|
|
|
|
|
/// which is a FunctionDecl that has been explicitly specialization or
|
|
|
|
|
/// instantiated from a function template.
|
|
|
|
|
class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
|
|
|
|
|
public:
|
|
|
|
|
/// \brief The function template specialization that this structure
|
|
|
|
|
/// describes.
|
|
|
|
|
FunctionDecl *Function;
|
|
|
|
|
|
|
|
|
|
/// \brief The function template from which this function template
|
|
|
|
|
/// specialization was generated.
|
|
|
|
|
FunctionTemplateDecl *Template;
|
|
|
|
|
|
|
|
|
|
/// \brief The template arguments used to produce the function template
|
|
|
|
|
/// specialization from the function template.
|
|
|
|
|
const TemplateArgumentList *TemplateArguments;
|
|
|
|
|
|
|
|
|
|
void Profile(llvm::FoldingSetNodeID &ID) {
|
|
|
|
|
Profile(ID, TemplateArguments->getFlatArgumentList(),
|
|
|
|
|
TemplateArguments->flat_size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
Profile(llvm::FoldingSetNodeID &ID, const TemplateArgument *TemplateArgs,
|
|
|
|
|
unsigned NumTemplateArgs) {
|
|
|
|
|
ID.AddInteger(NumTemplateArgs);
|
|
|
|
|
for (unsigned Arg = 0; Arg != NumTemplateArgs; ++Arg)
|
|
|
|
|
TemplateArgs[Arg].Profile(ID);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// Declaration of a template function.
|
|
|
|
|
class FunctionTemplateDecl : public TemplateDecl {
|
|
|
|
|
protected:
|
|
|
|
|
/// \brief Data that is common to all of the declarations of a given
|
|
|
|
|
/// function template.
|
|
|
|
|
struct Common {
|
|
|
|
|
/// \brief The function template specializations for this function
|
|
|
|
|
/// template, including explicit specializations and instantiations.
|
|
|
|
|
llvm::FoldingSet<FunctionTemplateSpecializationInfo> Specializations;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// \brief A pointer to the previous declaration (if this is a redeclaration)
|
|
|
|
|
/// or to the data that is common to all declarations of this function
|
|
|
|
|
/// template.
|
|
|
|
|
llvm::PointerUnion<Common*, FunctionTemplateDecl*> CommonOrPrev;
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieves the "common" pointer shared by all
|
|
|
|
|
/// (re-)declarations of the same function template. Calling this routine
|
|
|
|
|
/// may implicitly allocate memory for the common pointer.
|
|
|
|
|
Common *getCommonPtr();
|
|
|
|
|
|
|
|
|
|
FunctionTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
|
|
|
|
|
TemplateParameterList *Params, NamedDecl *Decl)
|
|
|
|
|
: TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
|
|
|
|
|
CommonOrPrev((Common*)0) { }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void Destroy(ASTContext &C);
|
|
|
|
|
|
|
|
|
|
/// Get the underlying function declaration of the template.
|
|
|
|
|
FunctionDecl *getTemplatedDecl() const {
|
|
|
|
|
return static_cast<FunctionDecl*>(TemplatedDecl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the set of function template specializations of this
|
|
|
|
|
/// function template.
|
|
|
|
|
llvm::FoldingSet<FunctionTemplateSpecializationInfo> &getSpecializations() {
|
|
|
|
|
return getCommonPtr()->Specializations;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the previous declaration of this function template, or
|
|
|
|
|
/// NULL if no such declaration exists.
|
|
|
|
|
const FunctionTemplateDecl *getPreviousDeclaration() const {
|
|
|
|
|
return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the previous declaration of this function template, or
|
|
|
|
|
/// NULL if no such declaration exists.
|
|
|
|
|
FunctionTemplateDecl *getPreviousDeclaration() {
|
|
|
|
|
return CommonOrPrev.dyn_cast<FunctionTemplateDecl*>();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Set the previous declaration of this function template.
|
|
|
|
|
void setPreviousDeclaration(FunctionTemplateDecl *Prev) {
|
|
|
|
|
if (Prev)
|
|
|
|
|
CommonOrPrev = Prev;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Create a template function node.
|
|
|
|
|
static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
|
|
|
|
|
SourceLocation L,
|
|
|
|
|
DeclarationName Name,
|
|
|
|
|
TemplateParameterList *Params,
|
|
|
|
|
NamedDecl *Decl);
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast support
|
|
|
|
|
static bool classof(const Decl *D)
|
|
|
|
|
{ return D->getKind() == FunctionTemplate; }
|
|
|
|
|
static bool classof(const FunctionTemplateDecl *D)
|
|
|
|
|
{ return true; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
// Kinds of Template Parameters
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
|
|
/// The TemplateParmPosition class defines the position of a template parameter
|
|
|
|
|
/// within a template parameter list. Because template parameter can be listed
|
|
|
|
|
/// sequentially for out-of-line template members, each template parameter is
|
|
|
|
|
/// given a Depth - the nesting of template parameter scopes - and a Position -
|
|
|
|
|
/// the occurrence within the parameter list.
|
|
|
|
|
/// This class is inheritedly privately by different kinds of template
|
|
|
|
|
/// parameters and is not part of the Decl hierarchy. Just a facility.
|
|
|
|
|
class TemplateParmPosition
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
// FIXME: This should probably never be called, but it's here as
|
|
|
|
|
TemplateParmPosition()
|
|
|
|
|
: Depth(0), Position(0)
|
|
|
|
|
{ /* assert(0 && "Cannot create positionless template parameter"); */ }
|
|
|
|
|
|
|
|
|
|
TemplateParmPosition(unsigned D, unsigned P)
|
|
|
|
|
: Depth(D), Position(P)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
// FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
|
|
|
|
|
// position? Maybe?
|
|
|
|
|
unsigned Depth;
|
|
|
|
|
unsigned Position;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
/// Get the nesting depth of the template parameter.
|
|
|
|
|
unsigned getDepth() const { return Depth; }
|
|
|
|
|
|
|
|
|
|
/// Get the position of the template parameter within its parameter list.
|
|
|
|
|
unsigned getPosition() const { return Position; }
|
|
|
|
|
|
|
|
|
|
/// Get the index of the template parameter within its parameter list.
|
|
|
|
|
unsigned getIndex() const { return Position; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// TemplateTypeParmDecl - Declaration of a template type parameter,
|
|
|
|
|
/// e.g., "T" in
|
|
|
|
|
/// @code
|
|
|
|
|
/// template<typename T> class vector;
|
|
|
|
|
/// @endcode
|
|
|
|
|
class TemplateTypeParmDecl : public TypeDecl {
|
|
|
|
|
/// \brief Whether this template type parameter was declaration with
|
|
|
|
|
/// the 'typename' keyword. If false, it was declared with the
|
|
|
|
|
/// 'class' keyword.
|
|
|
|
|
bool Typename : 1;
|
|
|
|
|
|
|
|
|
|
/// \brief Whether this template type parameter inherited its
|
|
|
|
|
/// default argument.
|
|
|
|
|
bool InheritedDefault : 1;
|
|
|
|
|
|
|
|
|
|
/// \brief Whether this is a parameter pack.
|
|
|
|
|
bool ParameterPack : 1;
|
|
|
|
|
|
|
|
|
|
/// \brief The location of the default argument, if any.
|
|
|
|
|
SourceLocation DefaultArgumentLoc;
|
|
|
|
|
|
|
|
|
|
/// \brief The default template argument, if any.
|
|
|
|
|
QualType DefaultArgument;
|
|
|
|
|
|
|
|
|
|
TemplateTypeParmDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
|
|
|
|
|
bool Typename, QualType Type, bool ParameterPack)
|
|
|
|
|
: TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
|
|
|
|
|
InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
|
|
|
|
|
TypeForDecl = Type.getTypePtr();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
|
|
|
|
|
SourceLocation L, unsigned D, unsigned P,
|
|
|
|
|
IdentifierInfo *Id, bool Typename,
|
|
|
|
|
bool ParameterPack);
|
|
|
|
|
|
|
|
|
|
/// \brief Whether this template type parameter was declared with
|
|
|
|
|
/// the 'typename' keyword. If not, it was declared with the 'class'
|
|
|
|
|
/// keyword.
|
|
|
|
|
bool wasDeclaredWithTypename() const { return Typename; }
|
|
|
|
|
|
|
|
|
|
/// \brief Determine whether this template parameter has a default
|
|
|
|
|
/// argument.
|
|
|
|
|
bool hasDefaultArgument() const { return !DefaultArgument.isNull(); }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the default argument, if any.
|
|
|
|
|
QualType getDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the location of the default argument, if any.
|
|
|
|
|
SourceLocation getDefaultArgumentLoc() const { return DefaultArgumentLoc; }
|
|
|
|
|
|
|
|
|
|
/// \brief Determines whether the default argument was inherited
|
|
|
|
|
/// from a previous declaration of this template.
|
|
|
|
|
bool defaultArgumentWasInherited() const { return InheritedDefault; }
|
|
|
|
|
|
|
|
|
|
/// \brief Set the default argument for this template parameter, and
|
|
|
|
|
/// whether that default argument was inherited from another
|
|
|
|
|
/// declaration.
|
|
|
|
|
void setDefaultArgument(QualType DefArg, SourceLocation DefArgLoc,
|
|
|
|
|
bool Inherited) {
|
|
|
|
|
DefaultArgument = DefArg;
|
|
|
|
|
DefaultArgumentLoc = DefArgLoc;
|
|
|
|
|
InheritedDefault = Inherited;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// \brief Returns whether this is a parameter pack.
|
|
|
|
|
bool isParameterPack() const { return ParameterPack; }
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
|
static bool classof(const Decl *D) {
|
|
|
|
|
return D->getKind() == TemplateTypeParm;
|
|
|
|
|
}
|
|
|
|
|
static bool classof(const TemplateTypeParmDecl *D) { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// NonTypeTemplateParmDecl - Declares a non-type template parameter,
|
|
|
|
|
/// e.g., "Size" in
|
|
|
|
|
/// @code
|
|
|
|
|
/// template<int Size> class array { };
|
|
|
|
|
/// @endcode
|
|
|
|
|
class NonTypeTemplateParmDecl
|
|
|
|
|
: public VarDecl, protected TemplateParmPosition {
|
|
|
|
|
/// \brief The default template argument, if any.
|
|
|
|
|
Expr *DefaultArgument;
|
|
|
|
|
|
|
|
|
|
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
|
|
|
|
|
unsigned P, IdentifierInfo *Id, QualType T,
|
|
|
|
|
SourceLocation TSSL = SourceLocation())
|
|
|
|
|
: VarDecl(NonTypeTemplateParm, DC, L, Id, T, VarDecl::None, TSSL),
|
|
|
|
|
TemplateParmPosition(D, P), DefaultArgument(0)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static NonTypeTemplateParmDecl *
|
|
|
|
|
Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
|
|
|
|
|
unsigned P, IdentifierInfo *Id, QualType T,
|
|
|
|
|
SourceLocation TypeSpecStartLoc = SourceLocation());
|
|
|
|
|
|
|
|
|
|
using TemplateParmPosition::getDepth;
|
|
|
|
|
using TemplateParmPosition::getPosition;
|
|
|
|
|
using TemplateParmPosition::getIndex;
|
|
|
|
|
|
|
|
|
|
/// \brief Determine whether this template parameter has a default
|
|
|
|
|
/// argument.
|
|
|
|
|
bool hasDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the default argument, if any.
|
|
|
|
|
Expr *getDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the location of the default argument, if any.
|
|
|
|
|
SourceLocation getDefaultArgumentLoc() const;
|
|
|
|
|
|
|
|
|
|
/// \brief Set the default argument for this template parameter.
|
|
|
|
|
void setDefaultArgument(Expr *DefArg) {
|
|
|
|
|
DefaultArgument = DefArg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
|
static bool classof(const Decl *D) {
|
|
|
|
|
return D->getKind() == NonTypeTemplateParm;
|
|
|
|
|
}
|
|
|
|
|
static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/// TemplateTemplateParmDecl - Declares a template template parameter,
|
|
|
|
|
/// e.g., "T" in
|
|
|
|
|
/// @code
|
|
|
|
|
/// template <template <typename> class T> class container { };
|
|
|
|
|
/// @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 {
|
|
|
|
|
|
|
|
|
|
/// \brief The default template argument, if any.
|
|
|
|
|
Expr *DefaultArgument;
|
|
|
|
|
|
|
|
|
|
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
|
|
|
|
|
unsigned D, unsigned P,
|
|
|
|
|
IdentifierInfo *Id, TemplateParameterList *Params)
|
|
|
|
|
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
|
|
|
|
|
TemplateParmPosition(D, P), DefaultArgument(0)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
|
|
|
|
|
SourceLocation L, unsigned D,
|
|
|
|
|
unsigned P, IdentifierInfo *Id,
|
|
|
|
|
TemplateParameterList *Params);
|
|
|
|
|
|
|
|
|
|
using TemplateParmPosition::getDepth;
|
|
|
|
|
using TemplateParmPosition::getPosition;
|
|
|
|
|
using TemplateParmPosition::getIndex;
|
|
|
|
|
|
|
|
|
|
/// \brief Determine whether this template parameter has a default
|
|
|
|
|
/// argument.
|
|
|
|
|
bool hasDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the default argument, if any.
|
|
|
|
|
Expr *getDefaultArgument() const { return DefaultArgument; }
|
|
|
|
|
|
|
|
|
|
/// \brief Retrieve the location of the default argument, if any.
|
|
|
|
|
SourceLocation getDefaultArgumentLoc() const;
|
|
|
|
|
|
|
|
|
|
/// \brief Set the default argument for this template parameter.
|
|
|
|
|
void setDefaultArgument(Expr *DefArg) {
|
|
|
|
|
DefaultArgument = DefArg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Implement isa/cast/dyncast/etc.
|
|
|
|
|
static bool classof(const Decl *D) {
|
|
|
|
|
return D->getKind() == TemplateTemplateParm;
|
|
|
|
|
}
|
|
|
|
|
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// \brief Describes the kind of template specialization that a
|
|
|
|
|
// particular template specialization declaration represents.
|
|
|
|
|
enum TemplateSpecializationKind {
|
|
|
|
|