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.h790
1 files changed, 441 insertions, 349 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index aad19a6..5d0fe15 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -100,6 +100,352 @@ public:
}
};
+/// \brief Represents a template argument within a class template
+/// specialization.
+class TemplateArgument {
+ union {
+ uintptr_t TypeOrValue;
+ struct {
+ char Value[sizeof(llvm::APSInt)];
+ void *Type;
+ } Integer;
+ struct {
+ TemplateArgument *Args;
+ unsigned NumArgs;
+ bool CopyArgs;
+ } Args;
+ };
+
+ /// \brief Location of the beginning of this template argument.
+ SourceLocation StartLoc;
+
+public:
+ /// \brief The type of template argument we're storing.
+ enum ArgKind {
+ Null = 0,
+ /// The template argument is a type. Its value is stored in the
+ /// TypeOrValue field.
+ Type = 1,
+ /// The template argument is a declaration
+ Declaration = 2,
+ /// The template argument is an integral value stored in an llvm::APSInt.
+ Integral = 3,
+ /// The template argument is a value- or type-dependent expression
+ /// stored in an Expr*.
+ Expression = 4,
+
+ /// The template argument is actually a parameter pack. Arguments are stored
+ /// in the Args struct.
+ Pack = 5
+ } Kind;
+
+ /// \brief Construct an empty, invalid template argument.
+ TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
+
+ /// \brief Construct a template type argument.
+ TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct a template argument that refers to a
+ /// declaration, which is either an external declaration or a
+ /// template declaration.
+ TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
+ // FIXME: Need to be sure we have the "canonical" declaration!
+ TypeOrValue = reinterpret_cast<uintptr_t>(D);
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct an integral constant template argument.
+ TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
+ QualType Type)
+ : Kind(Integral) {
+ new (Integer.Value) llvm::APSInt(Value);
+ Integer.Type = Type.getAsOpaquePtr();
+ StartLoc = Loc;
+ }
+
+ /// \brief Construct a template argument that is an expression.
+ ///
+ /// This form of template argument only occurs in template argument
+ /// lists used for dependent types and for expression; it will not
+ /// occur in a non-dependent, canonical template argument list.
+ TemplateArgument(Expr *E);
+
+ /// \brief Copy constructor for a template argument.
+ TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
+ if (Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else if (Kind == Pack) {
+ Args.NumArgs = Other.Args.NumArgs;
+ Args.Args = new TemplateArgument[Args.NumArgs];
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I] = Other.Args.Args[I];
+ }
+ else
+ TypeOrValue = Other.TypeOrValue;
+ StartLoc = Other.StartLoc;
+ }
+
+ TemplateArgument& operator=(const TemplateArgument& Other) {
+ // FIXME: Does not provide the strong guarantee for exception
+ // safety.
+ using llvm::APSInt;
+
+ // FIXME: Handle Packs
+ assert(Kind != Pack && "FIXME: Handle packs");
+ assert(Other.Kind != Pack && "FIXME: Handle packs");
+
+ if (Kind == Other.Kind && Kind == Integral) {
+ // Copy integral values.
+ *this->getAsIntegral() = *Other.getAsIntegral();
+ Integer.Type = Other.Integer.Type;
+ } else {
+ // Destroy the current integral value, if that's what we're holding.
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+
+ Kind = Other.Kind;
+
+ if (Other.Kind == Integral) {
+ new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
+ Integer.Type = Other.Integer.Type;
+ } else
+ TypeOrValue = Other.TypeOrValue;
+ }
+ StartLoc = Other.StartLoc;
+
+ return *this;
+ }
+
+ ~TemplateArgument() {
+ using llvm::APSInt;
+
+ if (Kind == Integral)
+ getAsIntegral()->~APSInt();
+ else if (Kind == Pack && Args.CopyArgs)
+ delete[] Args.Args;
+ }
+
+ /// \brief Return the kind of stored template argument.
+ ArgKind getKind() const { return Kind; }
+
+ /// \brief Determine whether this template argument has no value.
+ bool isNull() const { return Kind == Null; }
+
+ /// \brief Retrieve the template argument as a type.
+ QualType getAsType() const {
+ if (Kind != Type)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(
+ reinterpret_cast<void*>(TypeOrValue));
+ }
+
+ /// \brief Retrieve the template argument as a declaration.
+ Decl *getAsDecl() const {
+ if (Kind != Declaration)
+ return 0;
+ return reinterpret_cast<Decl *>(TypeOrValue);
+ }
+
+ /// \brief Retrieve the template argument as an integral value.
+ llvm::APSInt *getAsIntegral() {
+ if (Kind != Integral)
+ return 0;
+ return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
+ }
+
+ const llvm::APSInt *getAsIntegral() const {
+ return const_cast<TemplateArgument*>(this)->getAsIntegral();
+ }
+
+ /// \brief Retrieve the type of the integral value.
+ QualType getIntegralType() const {
+ if (Kind != Integral)
+ return QualType();
+
+ return QualType::getFromOpaquePtr(Integer.Type);
+ }
+
+ void setIntegralType(QualType T) {
+ assert(Kind == Integral &&
+ "Cannot set the integral type of a non-integral template argument");
+ Integer.Type = T.getAsOpaquePtr();
+ };
+
+ /// \brief Retrieve the template argument as an expression.
+ Expr *getAsExpr() const {
+ if (Kind != Expression)
+ return 0;
+
+ return reinterpret_cast<Expr *>(TypeOrValue);
+ }
+
+ /// \brief Iterator that traverses the elements of a template argument pack.
+ typedef const TemplateArgument * pack_iterator;
+
+ /// \brief Iterator referencing the first argument of a template argument
+ /// pack.
+ pack_iterator pack_begin() const {
+ assert(Kind == Pack);
+ return Args.Args;
+ }
+
+ /// \brief Iterator referencing one past the last argument of a template
+ /// argument pack.
+ pack_iterator pack_end() const {
+ assert(Kind == Pack);
+ return Args.Args + Args.NumArgs;
+ }
+
+ /// \brief The number of template arguments in the given template argument
+ /// pack.
+ unsigned pack_size() const {
+ assert(Kind == Pack);
+ return Args.NumArgs;
+ }
+
+ /// \brief Retrieve the location where the template argument starts.
+ SourceLocation getLocation() const { return StartLoc; }
+
+ /// \brief Construct a template argument pack.
+ void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
+
+ /// \brief Used to insert TemplateArguments into FoldingSets.
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger(Kind);
+ switch (Kind) {
+ case Null:
+ break;
+
+ case Type:
+ getAsType().Profile(ID);
+ break;
+
+ case Declaration:
+ ID.AddPointer(getAsDecl()); // FIXME: Must be canonical!
+ break;
+
+ case Integral:
+ getAsIntegral()->Profile(ID);
+ getIntegralType().Profile(ID);
+ break;
+
+ case Expression:
+ // FIXME: We need a canonical representation of expressions.
+ ID.AddPointer(getAsExpr());
+ break;
+
+ case Pack:
+ ID.AddInteger(Args.NumArgs);
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I].Profile(ID);
+ }
+ }
+};
+
+/// \brief A helper class for making template argument lists.
+class TemplateArgumentListBuilder {
+ TemplateArgument *StructuredArgs;
+ unsigned MaxStructuredArgs;
+ unsigned NumStructuredArgs;
+
+ TemplateArgument *FlatArgs;
+ unsigned MaxFlatArgs;
+ unsigned NumFlatArgs;
+
+ bool AddingToPack;
+ unsigned PackBeginIndex;
+
+public:
+ TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
+ unsigned NumTemplateArgs)
+ : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
+ NumStructuredArgs(0), FlatArgs(0),
+ MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
+ AddingToPack(false), PackBeginIndex(0) { }
+
+ void Append(const TemplateArgument& Arg);
+ void BeginPack();
+ void EndPack();
+
+ void ReleaseArgs();
+
+ unsigned flatSize() const {
+ return NumFlatArgs;
+ }
+ const TemplateArgument *getFlatArguments() const {
+ return FlatArgs;
+ }
+
+ unsigned structuredSize() const {
+ // If we don't have any structured args, just reuse the flat size.
+ if (!StructuredArgs)
+ return flatSize();
+
+ return NumStructuredArgs;
+ }
+ const TemplateArgument *getStructuredArguments() const {
+ // If we don't have any structured args, just reuse the flat args.
+ if (!StructuredArgs)
+ return getFlatArguments();
+
+ return StructuredArgs;
+ }
+};
+
+/// \brief A template argument list.
+///
+/// FIXME: In the future, this class will be extended to support
+/// variadic templates and member templates, which will make some of
+/// the function names below make more sense.
+class TemplateArgumentList {
+ /// \brief The template argument list.
+ ///
+ /// The integer value will be non-zero to indicate that this
+ /// template argument list does not own the pointer.
+ llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
+
+ /// \brief The number of template arguments in this template
+ /// argument list.
+ unsigned NumFlatArguments;
+
+ llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
+ unsigned NumStructuredArguments;
+
+public:
+ TemplateArgumentList(ASTContext &Context,
+ TemplateArgumentListBuilder &Builder,
+ bool TakeArgs);
+
+ ~TemplateArgumentList();
+
+ /// \brief Retrieve the template argument at a given index.
+ const TemplateArgument &get(unsigned Idx) const {
+ assert(Idx < NumFlatArguments && "Invalid template argument index");
+ return getFlatArgumentList()[Idx];
+ }
+
+ /// \brief Retrieve the template argument at a given index.
+ const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
+
+ /// \brief Retrieve the number of template arguments in this
+ /// template argument list.
+ unsigned size() const { return NumFlatArguments; }
+
+ /// \brief Retrieve the number of template arguments in the
+ /// flattened template argument list.
+ unsigned flat_size() const { return NumFlatArguments; }
+
+ /// \brief Retrieve the flattened template argument list.
+ const TemplateArgument *getFlatArgumentList() const {
+ return FlatArguments.getPointer();
+ }
+};
+
//===----------------------------------------------------------------------===//
// Kinds of Templates
//===----------------------------------------------------------------------===//
@@ -154,18 +500,110 @@ protected:
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.
+ ///
+ /// The bit will be 0 for an implicit instantiation, 1 for an explicit
+ /// specialization.
+ llvm::PointerIntPair<FunctionTemplateDecl *, 1> Template;
+
+ /// \brief The template arguments used to produce the function template
+ /// specialization from the function template.
+ const TemplateArgumentList *TemplateArguments;
+
+ /// \brief Retrieve the template from which this function was specialized.
+ FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
+
+ /// \brief Determine whether this is an explicit specialization.
+ bool isExplicitSpecialization() const { return Template.getInt(); }
+
+ /// \brief Set whether this is an explicit specialization or an implicit
+ /// instantiation.
+ void setExplicitSpecialization(bool ES) {
+ Template.setInt(ES);
+ }
+
+ 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 {
+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) { }
+ : TemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl),
+ CommonOrPrev((Common*)0) { }
+
public:
- /// Get the underling function declaration of the template.
+ 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,
@@ -396,352 +834,6 @@ public:
static bool classof(const TemplateTemplateParmDecl *D) { return true; }
};
-/// \brief Represents a template argument within a class template
-/// specialization.
-class TemplateArgument {
- union {
- uintptr_t TypeOrValue;
- struct {
- char Value[sizeof(llvm::APSInt)];
- void *Type;
- } Integer;
- struct {
- TemplateArgument *Args;
- unsigned NumArgs;
- bool CopyArgs;
- } Args;
- };
-
- /// \brief Location of the beginning of this template argument.
- SourceLocation StartLoc;
-
-public:
- /// \brief The type of template argument we're storing.
- enum ArgKind {
- Null = 0,
- /// The template argument is a type. Its value is stored in the
- /// TypeOrValue field.
- Type = 1,
- /// The template argument is a declaration
- Declaration = 2,
- /// The template argument is an integral value stored in an llvm::APSInt.
- Integral = 3,
- /// The template argument is a value- or type-dependent expression
- /// stored in an Expr*.
- Expression = 4,
-
- /// The template argument is actually a parameter pack. Arguments are stored
- /// in the Args struct.
- Pack = 5
- } Kind;
-
- /// \brief Construct an empty, invalid template argument.
- TemplateArgument() : TypeOrValue(0), StartLoc(), Kind(Null) { }
-
- /// \brief Construct a template type argument.
- TemplateArgument(SourceLocation Loc, QualType T) : Kind(Type) {
- TypeOrValue = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
- StartLoc = Loc;
- }
-
- /// \brief Construct a template argument that refers to a
- /// declaration, which is either an external declaration or a
- /// template declaration.
- TemplateArgument(SourceLocation Loc, Decl *D) : Kind(Declaration) {
- // FIXME: Need to be sure we have the "canonical" declaration!
- TypeOrValue = reinterpret_cast<uintptr_t>(D);
- StartLoc = Loc;
- }
-
- /// \brief Construct an integral constant template argument.
- TemplateArgument(SourceLocation Loc, const llvm::APSInt &Value,
- QualType Type)
- : Kind(Integral) {
- new (Integer.Value) llvm::APSInt(Value);
- Integer.Type = Type.getAsOpaquePtr();
- StartLoc = Loc;
- }
-
- /// \brief Construct a template argument that is an expression.
- ///
- /// This form of template argument only occurs in template argument
- /// lists used for dependent types and for expression; it will not
- /// occur in a non-dependent, canonical template argument list.
- TemplateArgument(Expr *E);
-
- /// \brief Copy constructor for a template argument.
- TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
- if (Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else if (Kind == Pack) {
- Args.NumArgs = Other.Args.NumArgs;
- Args.Args = new TemplateArgument[Args.NumArgs];
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I] = Other.Args.Args[I];
- }
- else
- TypeOrValue = Other.TypeOrValue;
- StartLoc = Other.StartLoc;
- }
-
- TemplateArgument& operator=(const TemplateArgument& Other) {
- // FIXME: Does not provide the strong guarantee for exception
- // safety.
- using llvm::APSInt;
-
- // FIXME: Handle Packs
- assert(Kind != Pack && "FIXME: Handle packs");
- assert(Other.Kind != Pack && "FIXME: Handle packs");
-
- if (Kind == Other.Kind && Kind == Integral) {
- // Copy integral values.
- *this->getAsIntegral() = *Other.getAsIntegral();
- Integer.Type = Other.Integer.Type;
- } else {
- // Destroy the current integral value, if that's what we're holding.
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
-
- Kind = Other.Kind;
-
- if (Other.Kind == Integral) {
- new (Integer.Value) llvm::APSInt(*Other.getAsIntegral());
- Integer.Type = Other.Integer.Type;
- } else
- TypeOrValue = Other.TypeOrValue;
- }
- StartLoc = Other.StartLoc;
-
- return *this;
- }
-
- ~TemplateArgument() {
- using llvm::APSInt;
-
- if (Kind == Integral)
- getAsIntegral()->~APSInt();
- else if (Kind == Pack && Args.CopyArgs)
- delete[] Args.Args;
- }
-
- /// \brief Return the kind of stored template argument.
- ArgKind getKind() const { return Kind; }
-
- /// \brief Determine whether this template argument has no value.
- bool isNull() const { return Kind == Null; }
-
- /// \brief Retrieve the template argument as a type.
- QualType getAsType() const {
- if (Kind != Type)
- return QualType();
-
- return QualType::getFromOpaquePtr(
- reinterpret_cast<void*>(TypeOrValue));
- }
-
- /// \brief Retrieve the template argument as a declaration.
- Decl *getAsDecl() const {
- if (Kind != Declaration)
- return 0;
- return reinterpret_cast<Decl *>(TypeOrValue);
- }
-
- /// \brief Retrieve the template argument as an integral value.
- llvm::APSInt *getAsIntegral() {
- if (Kind != Integral)
- return 0;
- return reinterpret_cast<llvm::APSInt*>(&Integer.Value[0]);
- }
-
- const llvm::APSInt *getAsIntegral() const {
- return const_cast<TemplateArgument*>(this)->getAsIntegral();
- }
-
- /// \brief Retrieve the type of the integral value.
- QualType getIntegralType() const {
- if (Kind != Integral)
- return QualType();
-
- return QualType::getFromOpaquePtr(Integer.Type);
- }
-
- void setIntegralType(QualType T) {
- assert(Kind == Integral &&
- "Cannot set the integral type of a non-integral template argument");
- Integer.Type = T.getAsOpaquePtr();
- };
-
- /// \brief Retrieve the template argument as an expression.
- Expr *getAsExpr() const {
- if (Kind != Expression)
- return 0;
-
- return reinterpret_cast<Expr *>(TypeOrValue);
- }
-
- /// \brief Iterator that traverses the elements of a template argument pack.
- typedef const TemplateArgument * pack_iterator;
-
- /// \brief Iterator referencing the first argument of a template argument
- /// pack.
- pack_iterator pack_begin() const {
- assert(Kind == Pack);
- return Args.Args;
- }
-
- /// \brief Iterator referencing one past the last argument of a template
- /// argument pack.
- pack_iterator pack_end() const {
- assert(Kind == Pack);
- return Args.Args + Args.NumArgs;
- }
-
- /// \brief The number of template arguments in the given template argument
- /// pack.
- unsigned pack_size() const {
- assert(Kind == Pack);
- return Args.NumArgs;
- }
-
- /// \brief Retrieve the location where the template argument starts.
- SourceLocation getLocation() const { return StartLoc; }
-
- /// \brief Construct a template argument pack.
- void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
-
- /// \brief Used to insert TemplateArguments into FoldingSets.
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddInteger(Kind);
- switch (Kind) {
- case Null:
- break;
-
- case Type:
- getAsType().Profile(ID);
- break;
-
- case Declaration:
- ID.AddPointer(getAsDecl()); // FIXME: Must be canonical!
- break;
-
- case Integral:
- getAsIntegral()->Profile(ID);
- getIntegralType().Profile(ID);
- break;
-
- case Expression:
- // FIXME: We need a canonical representation of expressions.
- ID.AddPointer(getAsExpr());
- break;
-
- case Pack:
- ID.AddInteger(Args.NumArgs);
- for (unsigned I = 0; I != Args.NumArgs; ++I)
- Args.Args[I].Profile(ID);
- }
- }
-};
-
-/// \brief A helper class for making template argument lists.
-class TemplateArgumentListBuilder {
- TemplateArgument *StructuredArgs;
- unsigned MaxStructuredArgs;
- unsigned NumStructuredArgs;
-
- TemplateArgument *FlatArgs;
- unsigned MaxFlatArgs;
- unsigned NumFlatArgs;
-
- bool AddingToPack;
- unsigned PackBeginIndex;
-
-public:
- TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
- unsigned NumTemplateArgs)
- : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
- NumStructuredArgs(0), FlatArgs(0),
- MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
- AddingToPack(false), PackBeginIndex(0) { }
-
- void Append(const TemplateArgument& Arg);
- void BeginPack();
- void EndPack();
-
- void ReleaseArgs();
-
- unsigned flatSize() const {
- return NumFlatArgs;
- }
- const TemplateArgument *getFlatArguments() const {
- return FlatArgs;
- }
-
- unsigned structuredSize() const {
- // If we don't have any structured args, just reuse the flat size.
- if (!StructuredArgs)
- return flatSize();
-
- return NumStructuredArgs;
- }
- const TemplateArgument *getStructuredArguments() const {
- // If we don't have any structured args, just reuse the flat args.
- if (!StructuredArgs)
- return getFlatArguments();
-
- return StructuredArgs;
- }
-};
-
-/// \brief A template argument list.
-///
-/// FIXME: In the future, this class will be extended to support
-/// variadic templates and member templates, which will make some of
-/// the function names below make more sense.
-class TemplateArgumentList {
- /// \brief The template argument list.
- ///
- /// The integer value will be non-zero to indicate that this
- /// template argument list does not own the pointer.
- llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
-
- /// \brief The number of template arguments in this template
- /// argument list.
- unsigned NumFlatArguments;
-
- llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
- unsigned NumStructuredArguments;
-
-public:
- TemplateArgumentList(ASTContext &Context,
- TemplateArgumentListBuilder &Builder,
- bool TakeArgs);
-
- ~TemplateArgumentList();
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &get(unsigned Idx) const {
- assert(Idx < NumFlatArguments && "Invalid template argument index");
- return getFlatArgumentList()[Idx];
- }
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
-
- /// \brief Retrieve the number of template arguments in this
- /// template argument list.
- unsigned size() const { return NumFlatArguments; }
-
- /// \brief Retrieve the number of template arguments in the
- /// flattened template argument list.
- unsigned flat_size() const { return NumFlatArguments; }
-
- /// \brief Retrieve the flattened template argument list.
- const TemplateArgument *getFlatArgumentList() const {
- return FlatArguments.getPointer();
- }
-};
-
// \brief Describes the kind of template specialization that a
// particular template specialization declaration represents.
enum TemplateSpecializationKind {
OpenPOWER on IntegriCloud