diff options
| author | John McCall <rjmccall@apple.com> | 2013-03-04 01:30:55 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2013-03-04 01:30:55 +0000 |
| commit | f22d0acfac3fb58cfaab1c4283bff37d6fd7a2c9 (patch) | |
| tree | a423bde969ebe63b1dc0068015fbe9bc82307d64 /clang/lib/Sema | |
| parent | 4588e349b0e23348001d629f0bc0d87a6ceeb741 (diff) | |
| download | bcm5719-llvm-f22d0acfac3fb58cfaab1c4283bff37d6fd7a2c9.tar.gz bcm5719-llvm-f22d0acfac3fb58cfaab1c4283bff37d6fd7a2c9.zip | |
Perform non-overload placeholder conversions on the operands
to a subscript operator.
rdar://13332183
llvm-svn: 176428
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 55 |
1 files changed, 39 insertions, 16 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 65bdd2a47fb..7dd17a028f6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3341,33 +3341,56 @@ static bool checkArithmeticOnObjCPointer(Sema &S, } ExprResult -Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, - Expr *Idx, SourceLocation RLoc) { +Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base, SourceLocation lbLoc, + Expr *idx, SourceLocation rbLoc) { // Since this might be a postfix expression, get rid of ParenListExprs. - ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base); - if (Result.isInvalid()) return ExprError(); - Base = Result.take(); + if (isa<ParenListExpr>(base)) { + ExprResult result = MaybeConvertParenListExprToParenExpr(S, base); + if (result.isInvalid()) return ExprError(); + base = result.take(); + } - Expr *LHSExp = Base, *RHSExp = Idx; + // Handle any non-overload placeholder types in the base and index + // expressions. We can't handle overloads here because the other + // operand might be an overloadable type, in which case the overload + // resolution for the operator overload should get the first crack + // at the overload. + if (base->getType()->isNonOverloadPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(base); + if (result.isInvalid()) return ExprError(); + base = result.take(); + } + if (idx->getType()->isNonOverloadPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(idx); + if (result.isInvalid()) return ExprError(); + idx = result.take(); + } + // Build an unanalyzed expression if either operand is type-dependent. if (getLangOpts().CPlusPlus && - (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) { - return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, + (base->isTypeDependent() || idx->isTypeDependent())) { + return Owned(new (Context) ArraySubscriptExpr(base, idx, Context.DependentTy, VK_LValue, OK_Ordinary, - RLoc)); + rbLoc)); } + // Use C++ overloaded-operator rules if either operand has record + // type. The spec says to do this if either type is *overloadable*, + // but enum types can't declare subscript operators or conversion + // operators, so there's nothing interesting for overload resolution + // to do if there aren't any record types involved. + // + // ObjC pointers have their own subscripting logic that is not tied + // to overload resolution and so should not take this path. if (getLangOpts().CPlusPlus && - (LHSExp->getType()->isRecordType() || - LHSExp->getType()->isEnumeralType() || - RHSExp->getType()->isRecordType() || - RHSExp->getType()->isEnumeralType()) && - !LHSExp->getType()->isObjCObjectPointerType()) { - return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx); + (base->getType()->isRecordType() || + (!base->getType()->isObjCObjectPointerType() && + idx->getType()->isRecordType()))) { + return CreateOverloadedArraySubscriptExpr(lbLoc, rbLoc, base, idx); } - return CreateBuiltinArraySubscriptExpr(Base, LLoc, Idx, RLoc); + return CreateBuiltinArraySubscriptExpr(base, lbLoc, idx, rbLoc); } ExprResult |

