aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-11-12 18:38:13 +0000
committerDouglas Gregor <dgregor@apple.com>2009-11-12 18:38:13 +0000
commitcaddba07f82096ee0d0a0312727d4418ee7a8d36 (patch)
tree90ae2bddbd3ec5b9daa3e1ece12740cdda79113c /lib/Sema/SemaTemplate.cpp
parent23908b8a43adefd42b3635364cfab44de1064942 (diff)
Recognize (and check) pointer-to-member template arguments that are
non-type template parameters or constants of pointer-to-member type. Once checked, be sure to retain those pointer-to-member constants as expressions if they are dependent, or as declarations if they are not dependent. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@87010 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r--lib/Sema/SemaTemplate.cpp61
1 files changed, 34 insertions, 27 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index af7634ae86..07d7839455 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1187,11 +1187,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
QualType CanonType;
- if (TemplateSpecializationType::anyDependentTemplateArguments(
+ if (Name.isDependent() ||
+ TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs,
- NumTemplateArgs) ||
- isa<TemplateTemplateParmDecl>(Template) ||
- Template->getDeclContext()->isDependentContext()) {
+ NumTemplateArgs)) {
// This class template specialization is a dependent
// type. Therefore, its canonical type is another class template
// specialization type that contains all of the converted
@@ -2088,8 +2087,8 @@ bool Sema::CheckTemplateArgumentAddressOfObjectOrFunction(Expr *Arg,
/// \brief Checks whether the given template argument is a pointer to
/// member constant according to C++ [temp.arg.nontype]p1.
-bool
-Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member) {
+bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg,
+ TemplateArgument &Converted) {
bool Invalid = false;
// See through any implicit casts we added to fix the type.
@@ -2120,13 +2119,33 @@ Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member) {
Arg = Parens->getSubExpr();
}
- if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg))
+ // A pointer-to-member constant written &Class::member.
+ if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
if (UnOp->getOpcode() == UnaryOperator::AddrOf) {
DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
if (DRE && !DRE->getQualifier())
DRE = 0;
}
-
+ }
+ // A constant of pointer-to-member type.
+ else if ((DRE = dyn_cast<DeclRefExpr>(Arg))) {
+ if (ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) {
+ if (VD->getType()->isMemberPointerType()) {
+ if (isa<NonTypeTemplateParmDecl>(VD) ||
+ (isa<VarDecl>(VD) &&
+ Context.getCanonicalType(VD->getType()).isConstQualified())) {
+ if (Arg->isTypeDependent() || Arg->isValueDependent())
+ Converted = TemplateArgument(Arg->Retain());
+ else
+ Converted = TemplateArgument(VD->getCanonicalDecl());
+ return Invalid;
+ }
+ }
+ }
+
+ DRE = 0;
+ }
+
if (!DRE)
return Diag(Arg->getSourceRange().getBegin(),
diag::err_template_arg_not_pointer_to_member_form)
@@ -2139,7 +2158,10 @@ Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, NamedDecl *&Member) {
// Okay: this is the address of a non-static member, and therefore
// a member pointer constant.
- Member = DRE->getDecl();
+ if (Arg->isTypeDependent() || Arg->isValueDependent())
+ Converted = TemplateArgument(Arg->Retain());
+ else
+ Converted = TemplateArgument(DRE->getDecl()->getCanonicalDecl());
return Invalid;
}
@@ -2343,16 +2365,8 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
return true;
}
- if (ParamType->isMemberPointerType()) {
- NamedDecl *Member = 0;
- if (CheckTemplateArgumentPointerToMember(Arg, Member))
- return true;
-
- if (Member)
- Member = cast<NamedDecl>(Member->getCanonicalDecl());
- Converted = TemplateArgument(Member);
- return false;
- }
+ if (ParamType->isMemberPointerType())
+ return CheckTemplateArgumentPointerToMember(Arg, Converted);
NamedDecl *Entity = 0;
if (CheckTemplateArgumentAddressOfObjectOrFunction(Arg, Entity))
@@ -2465,14 +2479,7 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
return true;
}
- NamedDecl *Member = 0;
- if (CheckTemplateArgumentPointerToMember(Arg, Member))
- return true;
-
- if (Member)
- Member = cast<NamedDecl>(Member->getCanonicalDecl());
- Converted = TemplateArgument(Member);
- return false;
+ return CheckTemplateArgumentPointerToMember(Arg, Converted);
}
/// \brief Check a template argument against its corresponding