Author: dgregor Date: Mon May 18 19:01:19 2009 New Revision: 72076 URL: http://llvm.org/viewvc/llvm-project?rev=72076&view=rev Log: Template instantiation for array subscript expressions. This was far easier than expected because of the limitation that subscript operators must be member functions.
Added: cfe/trunk/test/SemaTemplate/instantiate-subscript.cpp Modified: cfe/trunk/lib/Sema/SemaExpr.cpp cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Modified: cfe/trunk/lib/Sema/SemaExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=72076&r1=72075&r2=72076&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon May 18 19:01:19 2009 @@ -1665,6 +1665,14 @@ *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() || Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=72076&r1=72075&r2=72076&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon May 18 19:01:19 2009 @@ -2402,7 +2402,8 @@ 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); Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp?rev=72076&r1=72075&r2=72076&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Mon May 18 19:01:19 2009 @@ -45,6 +45,7 @@ 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 @@ } 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()) Added: cfe/trunk/test/SemaTemplate/instantiate-subscript.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-subscript.cpp?rev=72076&view=auto ============================================================================== --- cfe/trunk/test/SemaTemplate/instantiate-subscript.cpp (added) +++ cfe/trunk/test/SemaTemplate/instantiate-subscript.cpp Mon May 18 19:01:19 2009 @@ -0,0 +1,26 @@ +// RUN: clang-cc -fsyntax-only -verify %s + + +struct Sub0 { + int &operator[](int); +}; + +struct Sub1 { + long &operator[](long); +}; + +struct ConvertibleToInt { + operator int(); +}; + +template<typename T, typename U, typename Result> +struct Subscript0 { + void test(T t, U u) { + Result &result = t[u]; // expected-error{{subscripted value is not}} + } +}; + +template struct Subscript0<int*, int, int&>; +template struct Subscript0<Sub0, int, int&>; +template struct Subscript0<Sub1, ConvertibleToInt, long&>; +template struct Subscript0<Sub1, Sub0, long&>; // expected-note{{instantiation}} _______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits