aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/Decl.h19
-rw-r--r--include/clang/AST/DeclFriend.h10
-rw-r--r--include/clang/AST/DeclTemplate.h75
3 files changed, 93 insertions, 11 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 569a94e8a1..a6a8b4cc84 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -31,7 +31,9 @@ class StringLiteral;
class TemplateArgumentList;
class MemberSpecializationInfo;
class FunctionTemplateSpecializationInfo;
+class DependentFunctionTemplateSpecializationInfo;
class TypeLoc;
+class UnresolvedSetImpl;
/// \brief A container of type source information.
///
@@ -1037,9 +1039,10 @@ private:
/// FunctionTemplateSpecializationInfo, which contains information about
/// the template being specialized and the template arguments involved in
/// that specialization.
- llvm::PointerUnion3<FunctionTemplateDecl *,
+ llvm::PointerUnion4<FunctionTemplateDecl *,
MemberSpecializationInfo *,
- FunctionTemplateSpecializationInfo *>
+ FunctionTemplateSpecializationInfo *,
+ DependentFunctionTemplateSpecializationInfo *>
TemplateOrSpecialization;
protected:
@@ -1365,6 +1368,18 @@ public:
void *InsertPos,
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation);
+ /// \brief Specifies that this function declaration is actually a
+ /// dependent function template specialization.
+ void setDependentTemplateSpecialization(ASTContext &Context,
+ const UnresolvedSetImpl &Templates,
+ const TemplateArgumentListInfo &TemplateArgs);
+
+ DependentFunctionTemplateSpecializationInfo *
+ getDependentSpecializationInfo() const {
+ return TemplateOrSpecialization.
+ dyn_cast<DependentFunctionTemplateSpecializationInfo*>();
+ }
+
/// \brief Determine what kind of template instantiation this function
/// represents.
TemplateSpecializationKind getTemplateSpecializationKind() const;
diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h
index 99ef738980..a20625da56 100644
--- a/include/clang/AST/DeclFriend.h
+++ b/include/clang/AST/DeclFriend.h
@@ -48,10 +48,6 @@ private:
// Location of the 'friend' specifier.
SourceLocation FriendLoc;
- // FIXME: Hack to keep track of whether this was a friend function
- // template specialization.
- bool WasSpecialization;
-
friend class CXXRecordDecl::friend_iterator;
friend class CXXRecordDecl;
@@ -60,8 +56,7 @@ private:
: Decl(Decl::Friend, DC, L),
Friend(Friend),
NextFriend(0),
- FriendLoc(FriendL),
- WasSpecialization(false) {
+ FriendLoc(FriendL) {
}
public:
@@ -88,9 +83,6 @@ public:
return FriendLoc;
}
- bool wasSpecialization() const { return WasSpecialization; }
- void setSpecialization(bool WS) { WasSpecialization = WS; }
-
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const FriendDecl *D) { return true; }
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 8d1a4caccb..bb24c3f5f0 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 {