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.h109
1 files changed, 105 insertions, 4 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 8d1a4ca..1ec38ba 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -376,6 +376,81 @@ public:
PointOfInstantiation = POI;
}
};
+
+/// \brief Provides information about a dependent function-template
+/// specialization declaration. Since explicit function template
+/// specialization and instantiation declarations can only appear in
+/// namespace scope, and you can only specialize a member of a
+/// fully-specialized class, the only way to get one of these is in
+/// a friend declaration like the following:
+///
+/// template <class T> void foo(T);
+/// template <class T> class A {
+/// friend void foo<>(T);
+/// };
+class DependentFunctionTemplateSpecializationInfo {
+ union {
+ // Force sizeof to be a multiple of sizeof(void*) so that the
+ // trailing data is aligned.
+ void *Aligner;
+
+ struct {
+ /// The number of potential template candidates.
+ unsigned NumTemplates;
+
+ /// The number of template arguments.
+ unsigned NumArgs;
+ } d;
+ };
+
+ /// The locations of the left and right angle brackets.
+ SourceRange AngleLocs;
+
+ FunctionTemplateDecl * const *getTemplates() const {
+ return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
+ }
+
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc*>(
+ &getTemplates()[getNumTemplates()]);
+ }
+
+public:
+ DependentFunctionTemplateSpecializationInfo(
+ const UnresolvedSetImpl &Templates,
+ const TemplateArgumentListInfo &TemplateArgs);
+
+ /// \brief Returns the number of function templates that this might
+ /// be a specialization of.
+ unsigned getNumTemplates() const {
+ return d.NumTemplates;
+ }
+
+ /// \brief Returns the i'th template candidate.
+ FunctionTemplateDecl *getTemplate(unsigned I) const {
+ assert(I < getNumTemplates() && "template index out of range");
+ return getTemplates()[I];
+ }
+
+ /// \brief Returns the number of explicit template arguments that were given.
+ unsigned getNumTemplateArgs() const {
+ return d.NumArgs;
+ }
+
+ /// \brief Returns the nth template argument.
+ const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
+ assert(I < getNumTemplateArgs() && "template arg index out of range");
+ return getTemplateArgs()[I];
+ }
+
+ SourceLocation getLAngleLoc() const {
+ return AngleLocs.getBegin();
+ }
+
+ SourceLocation getRAngleLoc() const {
+ return AngleLocs.getEnd();
+ }
+};
/// Declaration of a template function.
class FunctionTemplateDecl : public TemplateDecl {
@@ -652,7 +727,8 @@ class NonTypeTemplateParmDecl
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
TypeSourceInfo *TInfo)
- : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None),
+ : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, VarDecl::None,
+ VarDecl::None),
TemplateParmPosition(D, P), DefaultArgument(0)
{ }
@@ -935,6 +1011,11 @@ class ClassTemplatePartialSpecializationDecl
TemplateArgumentLoc *ArgsAsWritten;
unsigned NumArgsAsWritten;
+ /// \brief Sequence number indicating when this class template partial
+ /// 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
/// class template partial specialization was instantiated.
///
@@ -950,13 +1031,15 @@ class ClassTemplatePartialSpecializationDecl
TemplateArgumentListBuilder &Builder,
TemplateArgumentLoc *ArgInfos,
unsigned NumArgInfos,
- ClassTemplatePartialSpecializationDecl *PrevDecl)
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
DC, L, SpecializedTemplate, Builder,
PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
- NumArgsAsWritten(NumArgInfos), InstantiatedFromMember(0, false) { }
+ NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
+ InstantiatedFromMember(0, false) { }
public:
static ClassTemplatePartialSpecializationDecl *
@@ -966,7 +1049,8 @@ public:
TemplateArgumentListBuilder &Builder,
const TemplateArgumentListInfo &ArgInfos,
QualType CanonInjectedType,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
+ ClassTemplatePartialSpecializationDecl *PrevDecl,
+ unsigned SequenceNumber);
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
@@ -983,6 +1067,10 @@ public:
return NumArgsAsWritten;
}
+ /// \brief Get the sequence number for this class template partial
+ /// specialization.
+ unsigned getSequenceNumber() const { return SequenceNumber; }
+
/// \brief Retrieve the member class template partial specialization from
/// which this particular class template partial specialization was
/// instantiated.
@@ -1046,6 +1134,15 @@ public:
"Only member templates can be member template specializations");
return First->InstantiatedFromMember.setInt(true);
}
+
+ /// Retrieves the injected specialization type for this partial
+ /// specialization. This is not the same as the type-decl-type for
+ /// this partial specialization, which is an InjectedClassNameType.
+ QualType getInjectedSpecializationType() const {
+ assert(getTypeForDecl() && "partial specialization has no type set!");
+ return cast<InjectedClassNameType>(getTypeForDecl())
+ ->getInjectedSpecializationType();
+ }
// FIXME: Add Profile support!
@@ -1141,6 +1238,10 @@ public:
return CommonPtr->PartialSpecializations;
}
+ /// \brief Retrieve the partial specializations as an ordered list.
+ void getPartialSpecializations(
+ llvm::SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
+
/// \brief Find a class template partial specialization with the given
/// type T.
///
OpenPOWER on IntegriCloud