diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 34 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 62 | 
3 files changed, 46 insertions, 51 deletions
| diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 308f6b4dc02..82526119e2a 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1345,6 +1345,7 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {    case PredefinedExprClass:      return LV_Valid;    case UnresolvedLookupExprClass: +  case UnresolvedMemberExprClass:      return LV_Valid;    case CXXDefaultArgExprClass:      return cast<CXXDefaultArgExpr>(this)->getExpr()->isLvalue(Ctx); diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 7c324235ca8..60ced725e90 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -1660,6 +1660,21 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,      return false;    } +  // Resolve overloaded function references. +  if (Context.hasSameType(FromType, Context.OverloadTy)) { +    DeclAccessPair Found; +    FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType, +                                                          true, Found); +    if (!Fn) +      return true; + +    if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin())) +      return true; + +    From = FixOverloadedFunctionReference(From, Found, Fn); +    FromType = From->getType(); +  } +    // Perform the first implicit conversion.    switch (SCS.First) {    case ICK_Identity: @@ -1673,25 +1688,6 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,      break;    case ICK_Function_To_Pointer: -    if (Context.getCanonicalType(FromType) == Context.OverloadTy) { -      DeclAccessPair Found; -      FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(From, ToType, -                                                            true, Found); -      if (!Fn) -        return true; - -      if (DiagnoseUseOfDecl(Fn, From->getSourceRange().getBegin())) -        return true; - -      From = FixOverloadedFunctionReference(From, Found, Fn); -      FromType = From->getType(); -         -      // If there's already an address-of operator in the expression, we have -      // the right type already, and the code below would just introduce an -      // invalid additional pointer level. -      if (FromType->isPointerType() || FromType->isMemberFunctionPointerType()) -        break; -    }      FromType = Context.getPointerType(FromType);      ImpCastExprToType(From, FromType, CastExpr::CK_FunctionToPointerDecay);      break; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 06b5fcb318c..2a2521a32c2 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -622,8 +622,36 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,    // array-to-pointer conversion, or function-to-pointer conversion    // (C++ 4p1). -  DeclAccessPair AccessPair; - +  if (FromType == Context.OverloadTy) { +    DeclAccessPair AccessPair; +    if (FunctionDecl *Fn +          = ResolveAddressOfOverloadedFunction(From, ToType, false,  +                                               AccessPair)) { +      // We were able to resolve the address of the overloaded function, +      // so we can convert to the type of that function. +      FromType = Fn->getType(); +      if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Fn)) { +        if (!Method->isStatic()) { +          Type *ClassType  +            = Context.getTypeDeclType(Method->getParent()).getTypePtr(); +          FromType = Context.getMemberPointerType(FromType, ClassType); +        } +      } +       +      // If the "from" expression takes the address of the overloaded +      // function, update the type of the resulting expression accordingly. +      if (FromType->getAs<FunctionType>()) +        if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(From->IgnoreParens())) +          if (UnOp->getOpcode() == UnaryOperator::AddrOf) +            FromType = Context.getPointerType(FromType); +  +      // Check that we've computed the proper type after overload resolution. +      assert(Context.hasSameType(FromType, +              FixOverloadedFunctionReference(From, AccessPair, Fn)->getType())); +    } else { +      return false; +    } +  }     // Lvalue-to-rvalue conversion (C++ 4.1):    //   An lvalue (3.10) of a non-function, non-array type T can be    //   converted to an rvalue. @@ -668,36 +696,6 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,      // type "pointer to T." The result is a pointer to the      // function. (C++ 4.3p1).      FromType = Context.getPointerType(FromType); -  } else if (From->getType() == Context.OverloadTy) { -    if (FunctionDecl *Fn -          = ResolveAddressOfOverloadedFunction(From, ToType, false,  -                                               AccessPair)) { -      // Address of overloaded function (C++ [over.over]). -      SCS.First = ICK_Function_To_Pointer; - -      // We were able to resolve the address of the overloaded function, -      // so we can convert to the type of that function. -      FromType = Fn->getType(); -      if (ToType->isLValueReferenceType()) -        FromType = Context.getLValueReferenceType(FromType); -      else if (ToType->isRValueReferenceType()) -        FromType = Context.getRValueReferenceType(FromType); -      else if (ToType->isMemberPointerType()) { -        // Resolve address only succeeds if both sides are member pointers, -        // but it doesn't have to be the same class. See DR 247. -        // Note that this means that the type of &Derived::fn can be -        // Ret (Base::*)(Args) if the fn overload actually found is from the -        // base class, even if it was brought into the derived class via a -        // using declaration. The standard isn't clear on this issue at all. -        CXXMethodDecl *M = cast<CXXMethodDecl>(Fn); -        FromType = Context.getMemberPointerType(FromType, -                      Context.getTypeDeclType(M->getParent()).getTypePtr()); -      } else { -        FromType = Context.getPointerType(FromType); -      } -    } else { -      return false; -    }    } else {      // We don't require any conversions for the first step.      SCS.First = ICK_Identity; | 

