[cfe-commits] r91252 - in /cfe/trunk: lib/Sema/TreeTransform.h test/SemaTemplate/instantiate-expr-1.cpp
Douglas Gregor
dgregor at apple.com
Sun Dec 13 12:44:56 PST 2009
Author: dgregor
Date: Sun Dec 13 14:44:55 2009
New Revision: 91252
URL: http://llvm.org/viewvc/llvm-project?rev=91252&view=rev
Log:
Fix template instantiation for non-dependent calls to overloaded call
operators. Fixes PR5266.
Modified:
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=91252&r1=91251&r2=91252&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sun Dec 13 14:44:55 2009
@@ -4131,6 +4131,68 @@
template<typename Derived>
Sema::OwningExprResult
TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
+ switch (E->getOperator()) {
+ case OO_New:
+ case OO_Delete:
+ case OO_Array_New:
+ case OO_Array_Delete:
+ llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
+ return SemaRef.ExprError();
+
+ case OO_Call: {
+ // This is a call to an object's operator().
+ assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
+
+ // Transform the object itself.
+ OwningExprResult Object = getDerived().TransformExpr(E->getArg(0));
+ if (Object.isInvalid())
+ return SemaRef.ExprError();
+
+ // FIXME: Poor location information
+ SourceLocation FakeLParenLoc
+ = SemaRef.PP.getLocForEndOfToken(
+ static_cast<Expr *>(Object.get())->getLocEnd());
+
+ // Transform the call arguments.
+ ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
+ llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
+ for (unsigned I = 1, N = E->getNumArgs(); I != N; ++I) {
+ OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
+ if (Arg.isInvalid())
+ return SemaRef.ExprError();
+
+ // FIXME: Poor source location information.
+ SourceLocation FakeCommaLoc
+ = SemaRef.PP.getLocForEndOfToken(
+ static_cast<Expr *>(Arg.get())->getLocEnd());
+ FakeCommaLocs.push_back(FakeCommaLoc);
+ Args.push_back(Arg.release());
+ }
+
+ return getDerived().RebuildCallExpr(move(Object), FakeLParenLoc,
+ move_arg(Args),
+ FakeCommaLocs.data(),
+ E->getLocEnd());
+ }
+
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+ case OO_##Name:
+#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
+#include "clang/Basic/OperatorKinds.def"
+ case OO_Subscript:
+ // Handled below.
+ break;
+
+ case OO_Conditional:
+ llvm_unreachable("conditional operator is not actually overloadable");
+ return SemaRef.ExprError();
+
+ case OO_None:
+ case NUM_OVERLOADED_OPERATORS:
+ llvm_unreachable("not an overloaded operator?");
+ return SemaRef.ExprError();
+ }
+
OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
if (Callee.isInvalid())
return SemaRef.ExprError();
Modified: cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp?rev=91252&r1=91251&r2=91252&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-expr-1.cpp Sun Dec 13 14:44:55 2009
@@ -94,3 +94,21 @@
void test_add(Addable &a) {
add(a);
}
+
+struct CallOperator {
+ int &operator()(int);
+ double &operator()(double);
+};
+
+template<typename Result, typename F, typename Arg1>
+Result test_call_operator(F f, Arg1 arg1) {
+ // PR5266: non-dependent invocations of a function call operator.
+ CallOperator call_op;
+ int &ir = call_op(17);
+ return f(arg1);
+}
+
+void test_call_operator(CallOperator call_op, int i, double d) {
+ int &ir = test_call_operator<int&>(call_op, i);
+ double &dr = test_call_operator<double&>(call_op, d);
+}
More information about the cfe-commits
mailing list