aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST/TemplateBase.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/TemplateBase.h')
-rw-r--r--include/clang/AST/TemplateBase.h55
1 files changed, 44 insertions, 11 deletions
diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h
index 93ec35bebe..a4e074e083 100644
--- a/include/clang/AST/TemplateBase.h
+++ b/include/clang/AST/TemplateBase.h
@@ -80,8 +80,14 @@ private:
const TemplateArgument *Args;
unsigned NumArgs;
} Args;
+ struct {
+ void *Name;
+ unsigned NumExpansions;
+ } TemplateArg;
};
+ TemplateArgument(TemplateName, bool); // DO NOT USE
+
public:
/// \brief Construct an empty, invalid template argument.
TemplateArgument() : Kind(Null), TypeOrValue(0) { }
@@ -107,8 +113,7 @@ public:
Integer.Type = Type.getAsOpaquePtr();
}
- /// \brief Construct a template argument that is a template or a pack
- /// expansion of templates.
+ /// \brief Construct a template argument that is a template.
///
/// This form of template argument is generally used for template template
/// parameters. However, the template name could be a dependent template
@@ -116,13 +121,33 @@ public:
/// is taken.
///
/// \param Name The template name.
- /// \param PackExpansion Whether this template argument is a pack expansion.
- TemplateArgument(TemplateName Name, bool PackExpansion = false)
- : Kind(PackExpansion? TemplateExpansion : Template)
+ TemplateArgument(TemplateName Name) : Kind(Template)
{
- TypeOrValue = reinterpret_cast<uintptr_t>(Name.getAsVoidPointer());
+ TemplateArg.Name = Name.getAsVoidPointer();
+ TemplateArg.NumExpansions = 0;
}
-
+
+ /// \brief Construct a template argument that is a template pack expansion.
+ ///
+ /// This form of template argument is generally used for template template
+ /// parameters. However, the template name could be a dependent template
+ /// name that ends up being instantiated to a function template whose address
+ /// is taken.
+ ///
+ /// \param Name The template name.
+ ///
+ /// \param NumExpansions The number of expansions that will be generated by
+ /// instantiating
+ TemplateArgument(TemplateName Name, llvm::Optional<unsigned> NumExpansions)
+ : Kind(TemplateExpansion)
+ {
+ TemplateArg.Name = Name.getAsVoidPointer();
+ if (NumExpansions)
+ TemplateArg.NumExpansions = *NumExpansions + 1;
+ else
+ TemplateArg.NumExpansions = 0;
+ }
+
/// \brief Construct a template argument that is an expression.
///
/// This form of template argument only occurs in template argument
@@ -151,6 +176,9 @@ public:
} else if (Kind == Pack) {
Args.NumArgs = Other.Args.NumArgs;
Args.Args = Other.Args.Args;
+ } else if (Kind == Template || Kind == TemplateExpansion) {
+ TemplateArg.Name = Other.TemplateArg.Name;
+ TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions;
} else
TypeOrValue = Other.TypeOrValue;
}
@@ -177,6 +205,9 @@ public:
} else if (Other.Kind == Pack) {
Args.NumArgs = Other.Args.NumArgs;
Args.Args = Other.Args.Args;
+ } else if (Kind == Template || Kind == TemplateExpansion) {
+ TemplateArg.Name = Other.TemplateArg.Name;
+ TemplateArg.NumExpansions = Other.TemplateArg.NumExpansions;
} else {
TypeOrValue = Other.TypeOrValue;
}
@@ -234,8 +265,7 @@ public:
if (Kind != Template)
return TemplateName();
- return TemplateName::getFromVoidPointer(
- reinterpret_cast<void*>(TypeOrValue));
+ return TemplateName::getFromVoidPointer(TemplateArg.Name);
}
/// \brief Retrieve the template argument as a template name; if the argument
@@ -244,10 +274,13 @@ public:
if (Kind != Template && Kind != TemplateExpansion)
return TemplateName();
- return TemplateName::getFromVoidPointer(
- reinterpret_cast<void*>(TypeOrValue));
+ return TemplateName::getFromVoidPointer(TemplateArg.Name);
}
+ /// \brief Retrieve the number of expansions that a template template argument
+ /// expansion will produce, if known.
+ llvm::Optional<unsigned> getNumTemplateExpansions() const;
+
/// \brief Retrieve the template argument as an integral value.
llvm::APSInt *getAsIntegral() {
if (Kind != Integral)