diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-11-12 18:38:13 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-11-12 18:38:13 +0000 |
commit | caddba07f82096ee0d0a0312727d4418ee7a8d36 (patch) | |
tree | 90ae2bddbd3ec5b9daa3e1ece12740cdda79113c /lib/Sema/SemaTemplate.cpp | |
parent | 23908b8a43adefd42b3635364cfab44de1064942 (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.cpp | 61 |
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 |