aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaExpr.cpp8
-rw-r--r--lib/Sema/SemaOverload.cpp3
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp31
3 files changed, 41 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 418b3b8ce0..ed62b254d5 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1665,6 +1665,14 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
*RHSExp = static_cast<Expr*>(Idx.get());
if (getLangOptions().CPlusPlus &&
+ (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) {
+ Base.release();
+ Idx.release();
+ return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
+ Context.DependentTy, RLoc));
+ }
+
+ if (getLangOptions().CPlusPlus &&
(LHSExp->getType()->isRecordType() ||
LHSExp->getType()->isEnumeralType() ||
RHSExp->getType()->isRecordType() ||
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 90da96b5fb..ef175315e6 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2402,7 +2402,8 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
T2 = Args[1]->getType();
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
- LookupOverloadedOperatorName(Op, S, T1, T2, Functions);
+ if (S)
+ LookupOverloadedOperatorName(Op, S, T1, T2, Functions);
ArgumentDependentLookup(OpName, Args, NumArgs, Functions);
AddFunctionCandidates(Functions, Args, NumArgs, CandidateSet);
AddMemberOperatorCandidates(Op, OpLoc, Args, NumArgs, CandidateSet, OpRange);
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index c6ce6f4693..41df7aba29 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -45,6 +45,7 @@ namespace {
OwningExprResult VisitDeclRefExpr(DeclRefExpr *E);
OwningExprResult VisitParenExpr(ParenExpr *E);
OwningExprResult VisitUnaryOperator(UnaryOperator *E);
+ OwningExprResult VisitArraySubscriptExpr(ArraySubscriptExpr *E);
OwningExprResult VisitBinaryOperator(BinaryOperator *E);
OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
OwningExprResult VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E);
@@ -173,6 +174,36 @@ TemplateExprInstantiator::VisitUnaryOperator(UnaryOperator *E) {
}
Sema::OwningExprResult
+TemplateExprInstantiator::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
+ Sema::OwningExprResult LHS = Visit(E->getLHS());
+ if (LHS.isInvalid())
+ return SemaRef.ExprError();
+
+ Sema::OwningExprResult RHS = Visit(E->getRHS());
+ if (RHS.isInvalid())
+ return SemaRef.ExprError();
+
+ // Since the overloaded array-subscript operator (operator[]) can
+ // only be a member function, we can make several simplifying
+ // assumptions here:
+ // 1) Normal name lookup (from the current scope) will not ever
+ // find any declarations of operator[] that won't also be found be
+ // member operator lookup, so it is safe to pass a NULL Scope
+ // during the instantiation to avoid the lookup entirely.
+ //
+ // 2) Neither normal name lookup nor argument-dependent lookup at
+ // template definition time will find any operators that won't be
+ // found at template instantiation time, so we do not need to
+ // cache the results of name lookup as we do for the binary
+ // operators.
+ SourceLocation LLocFake = ((Expr*)LHS.get())->getSourceRange().getBegin();
+ return SemaRef.ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
+ /*FIXME:*/LLocFake,
+ move(RHS),
+ E->getRBracketLoc());
+}
+
+Sema::OwningExprResult
TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
Sema::OwningExprResult LHS = Visit(E->getLHS());
if (LHS.isInvalid())