diff options
author | John McCall <rjmccall@apple.com> | 2011-04-27 00:36:17 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-04-27 00:36:17 +0000 |
commit | f5307514ee48978b5e17e42542e111afee4ce62b (patch) | |
tree | a97f371ac0b609fa07c77951a2d87831866a0137 | |
parent | 0f7b3dcece1475130e2946d66dbe3075059b31f7 (diff) |
FixOverloadedFunctionReference needs to rebuild member accesses of
instance methods to have bound-member type.
Fixing that broke __unknown_anytype, which I've in turn fixed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130266 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 15 |
2 files changed, 23 insertions, 12 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 212f584f5f..73fe0003f0 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10478,16 +10478,17 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *call) { Expr *callee = call->getCallee(); enum FnKind { - FK_Function, + FK_MemberFunction, FK_FunctionPointer, FK_BlockPointer }; FnKind kind; QualType type = callee->getType(); - if (type->isFunctionType()) { - assert(isa<CXXMemberCallExpr>(call) || isa<CXXOperatorCallExpr>(call)); - kind = FK_Function; + if (type == S.Context.BoundMemberTy) { + assert(isa<CXXMemberCallExpr>(call) || isa<CXXOperatorCallExpr>(call)); + kind = FK_MemberFunction; + type = Expr::findBoundMemberType(callee); } else if (const PointerType *ptr = type->getAs<PointerType>()) { type = ptr->getPointeeType(); kind = FK_FunctionPointer; @@ -10525,7 +10526,7 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *call) { // Rebuild the appropriate pointer-to-function type. switch (kind) { - case FK_Function: + case FK_MemberFunction: // Nothing to do. break; @@ -10594,13 +10595,16 @@ ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *expr, ValueDecl *decl) { // - functions if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) { - if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(fn)) - if (method->isInstance()) valueKind = VK_RValue; - // This is true because FunctionDecls must always have function // type, so we can't be resolving the entire thing at once. assert(type->isFunctionType()); + if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(fn)) + if (method->isInstance()) { + valueKind = VK_RValue; + type = S.Context.BoundMemberTy; + } + // Function references aren't l-values in C. if (!S.getLangOptions().CPlusPlus) valueKind = VK_RValue; diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 2e85263ce3..5776820ab0 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -9274,6 +9274,16 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, } else Base = MemExpr->getBase(); + ExprValueKind valueKind; + QualType type; + if (cast<CXXMethodDecl>(Fn)->isStatic()) { + valueKind = VK_LValue; + type = Fn->getType(); + } else { + valueKind = VK_RValue; + type = Context.BoundMemberTy; + } + return MemberExpr::Create(Context, Base, MemExpr->isArrow(), MemExpr->getQualifierLoc(), @@ -9281,10 +9291,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Found, MemExpr->getMemberNameInfo(), TemplateArgs, - Fn->getType(), - cast<CXXMethodDecl>(Fn)->isStatic() - ? VK_LValue : VK_RValue, - OK_Ordinary); + type, valueKind, OK_Ordinary); } llvm_unreachable("Invalid reference to overloaded function"); |