aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-04-27 00:36:17 +0000
committerJohn McCall <rjmccall@apple.com>2011-04-27 00:36:17 +0000
commitf5307514ee48978b5e17e42542e111afee4ce62b (patch)
treea97f371ac0b609fa07c77951a2d87831866a0137
parent0f7b3dcece1475130e2946d66dbe3075059b31f7 (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.cpp20
-rw-r--r--lib/Sema/SemaOverload.cpp15
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");