[cfe-commits] r85524 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaOverload.cpp lib/Sema/TreeTransform.h test/SemaTemplate/instantiate-subscript.cpp

Douglas Gregor dgregor at apple.com
Thu Oct 29 13:45:52 PDT 2009


On Oct 29, 2009, at 1:17 PM, Sebastian Redl wrote:

> Author: cornedbee
> Date: Thu Oct 29 15:17:01 2009
> New Revision: 85524
>
> URL: http://llvm.org/viewvc/llvm-project?rev=85524&view=rev
> Log:
> Properly instantiate usage of overloaded operator []. Fixes PR5345.

Cool. One comment below.

> Modified:
>    cfe/trunk/lib/Sema/Sema.h
>    cfe/trunk/lib/Sema/SemaExpr.cpp
>    cfe/trunk/lib/Sema/SemaOverload.cpp
>    cfe/trunk/lib/Sema/TreeTransform.h
>    cfe/trunk/test/SemaTemplate/instantiate-subscript.cpp
>
> Modified: cfe/trunk/lib/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=85524&r1=85523&r2=85524&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- cfe/trunk/lib/Sema/Sema.h (original)
> +++ cfe/trunk/lib/Sema/Sema.h Thu Oct 29 15:17:01 2009
> @@ -962,6 +962,10 @@
>                                          FunctionSet &Functions,
>                                          Expr *LHS, Expr *RHS);
>
> +  OwningExprResult CreateOverloadedArraySubscriptExpr 
> (SourceLocation LLoc,
> +                                                       
> SourceLocation RLoc,
> +                                                      ExprArg  
> Base,ExprArg Idx);
> +
>   ExprResult
>   BuildCallToMemberFunction(Scope *S, Expr *MemExpr,
>                             SourceLocation LParenLoc, Expr **Args,
> @@ -1684,6 +1688,10 @@
>                                                    SourceLocation  
> LLoc,
>                                                    ExprArg Idx,
>                                                    SourceLocation  
> RLoc);
> +  OwningExprResult CreateBuiltinArraySubscriptExpr(ExprArg Base,
> +                                                   SourceLocation  
> LLoc,
> +                                                   ExprArg Idx,
> +                                                   SourceLocation  
> RLoc);
>
>   OwningExprResult BuildMemberReferenceExpr(Scope *S, ExprArg Base,
>                                             SourceLocation OpLoc,
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=85524&r1=85523&r2=85524&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Oct 29 15:17:01 2009
> @@ -1600,103 +1600,18 @@
>        LHSExp->getType()->isEnumeralType() ||
>        RHSExp->getType()->isRecordType() ||
>        RHSExp->getType()->isEnumeralType())) {
> -    // Add the appropriate overloaded operators (C++  
> [over.match.oper])
> -    // to the candidate set.
> -    OverloadCandidateSet CandidateSet;
> -    Expr *Args[2] = { LHSExp, RHSExp };
> -    AddOperatorCandidates(OO_Subscript, S, LLoc, Args, 2,  
> CandidateSet,
> -                          SourceRange(LLoc, RLoc));
> -
> -    // Perform overload resolution.
> -    OverloadCandidateSet::iterator Best;
> -    switch (BestViableFunction(CandidateSet, LLoc, Best)) {
> -    case OR_Success: {
> -      // We found a built-in operator or an overloaded operator.
> -      FunctionDecl *FnDecl = Best->Function;
> -
> -      if (FnDecl) {
> -        // We matched an overloaded operator. Build a call to that
> -        // operator.
> -
> -        // Convert the arguments.
> -        if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl> 
> (FnDecl)) {
> -          if (PerformObjectArgumentInitialization(LHSExp, Method) ||
> -              PerformCopyInitialization(RHSExp,
> -                                        FnDecl->getParamDecl(0)- 
> >getType(),
> -                                        "passing"))
> -            return ExprError();
> -        } else {
> -          // Convert the arguments.
> -          if (PerformCopyInitialization(LHSExp,
> -                                        FnDecl->getParamDecl(0)- 
> >getType(),
> -                                        "passing") ||
> -              PerformCopyInitialization(RHSExp,
> -                                        FnDecl->getParamDecl(1)- 
> >getType(),
> -                                        "passing"))
> -            return ExprError();
> -        }
> -
> -        // Determine the result type
> -        QualType ResultTy = FnDecl->getResultType 
> ().getNonReferenceType();
> -
> -        // Build the actual expression node.
> -        Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl- 
> >getType(),
> -                                                 SourceLocation());
> -        UsualUnaryConversions(FnExpr);
> -
> -        Base.release();
> -        Idx.release();
> -        Args[0] = LHSExp;
> -        Args[1] = RHSExp;
> -
> -        ExprOwningPtr<CXXOperatorCallExpr>
> -          TheCall(this, new (Context) CXXOperatorCallExpr(Context,  
> OO_Subscript,
> -                                                          FnExpr,  
> Args, 2,
> -                                                          ResultTy,  
> RLoc));
> -        if (CheckCallReturnType(FnDecl->getResultType(), LLoc,  
> TheCall.get(),
> -                                FnDecl))
> -          return ExprError();
> -
> -        return Owned(TheCall.release());
> -      } else {
> -        // We matched a built-in operator. Convert the arguments,  
> then
> -        // break out so that we will build the appropriate built-in
> -        // operator node.
> -        if (PerformCopyInitialization(LHSExp, Best- 
> >BuiltinTypes.ParamTypes[0],
> -                                      "passing") ||
> -            PerformCopyInitialization(RHSExp, Best- 
> >BuiltinTypes.ParamTypes[1],
> -                                      "passing"))
> -          return ExprError();
> -
> -        break;
> -      }
> -    }
> -
> -    case OR_No_Viable_Function:
> -      // No viable function; fall through to handling this as a
> -      // built-in operator, which will produce an error message for  
> us.
> -      break;
> +    return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, move 
> (Base),move(Idx));
> +  }
>
> -    case OR_Ambiguous:
> -      Diag(LLoc,  diag::err_ovl_ambiguous_oper)
> -          << "[]"
> -          << LHSExp->getSourceRange() << RHSExp->getSourceRange();
> -      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
> -      return ExprError();
> +  return CreateBuiltinArraySubscriptExpr(move(Base), LLoc, move 
> (Idx), RLoc);
> +}
>
> -    case OR_Deleted:
> -      Diag(LLoc, diag::err_ovl_deleted_oper)
> -        << Best->Function->isDeleted()
> -        << "[]"
> -        << LHSExp->getSourceRange() << RHSExp->getSourceRange();
> -      PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true);
> -      return ExprError();
> -    }
>
> -    // Either we found no viable overloaded operator or we matched a
> -    // built-in operator. In either case, fall through to trying to
> -    // build a built-in operation.
> -  }
> +Action::OwningExprResult
> +Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation  
> LLoc,
> +                                     ExprArg Idx, SourceLocation  
> RLoc) {
> +  Expr *LHSExp = static_cast<Expr*>(Base.get());
> +  Expr *RHSExp = static_cast<Expr*>(Idx.get());
>
>   // Perform default conversions.
>   DefaultFunctionArrayConversion(LHSExp);
>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=85524&r1=85523&r2=85524&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Oct 29 15:17:01 2009
> @@ -4942,6 +4942,134 @@
>   return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]);
> }
>
> +Action::OwningExprResult
> +Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
> +                                         SourceLocation RLoc,
> +                                         ExprArg Base, ExprArg Idx) {
> +  Expr *Args[2] = { static_cast<Expr*>(Base.get()),
> +                    static_cast<Expr*>(Idx.get()) };
> +  DeclarationName OpName =
> +      Context.DeclarationNames.getCXXOperatorName(OO_Subscript);
> +
> +  // If either side is type-dependent, create an appropriate  
> dependent
> +  // expression.
> +  if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
> +
> +    OverloadedFunctionDecl *Overloads
> +      = OverloadedFunctionDecl::Create(Context, CurContext, OpName);
> +
> +    DeclRefExpr *Fn = new (Context) DeclRefExpr(Overloads,  
> Context.OverloadTy,
> +                                                LLoc, false, false);
> +
> +    Base.release();
> +    Idx.release();
> +    return Owned(new (Context) CXXOperatorCallExpr(Context,  
> OO_Subscript, Fn,
> +                                                   Args, 2,
> +                                                    
> Context.DependentTy,
> +                                                   RLoc));
> +  }

I think I've managed to get myself confused over this... if we don't  
have any overloads in the overload set (since we don't need to retain  
the member operator candidates or built-in operator candidates), why  
not just build an ArraySubscriptExpr here?

	- Doug



More information about the cfe-commits mailing list