aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-05-19 20:02:01 +0000
committerDouglas Gregor <dgregor@apple.com>2009-05-19 20:02:01 +0000
commit6731c31150524b365138e5b8f46e6a4751a7c391 (patch)
treeac9b088e9e0f470b3dd1d35fbe7f4565217f6ccd
parent3bb423bb7f809c9182be3ba79adfbb38854afa64 (diff)
Template instantiation for compound assignment operators.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72126 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp7
-rw-r--r--test/SemaTemplate/instantiate-expr-3.cpp29
2 files changed, 36 insertions, 0 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index e5ad0cd304..9dda383342 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -50,6 +50,7 @@ namespace {
// FIXME: VisitMemberExpr
// FIXME: CompoundLiteralExpr
OwningExprResult VisitBinaryOperator(BinaryOperator *E);
+ OwningExprResult VisitCompoundAssignOperator(CompoundAssignOperator *E);
OwningExprResult VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E);
OwningExprResult VisitCXXConditionDeclExpr(CXXConditionDeclExpr *E);
OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
@@ -284,6 +285,12 @@ TemplateExprInstantiator::VisitBinaryOperator(BinaryOperator *E) {
}
Sema::OwningExprResult
+TemplateExprInstantiator::VisitCompoundAssignOperator(
+ CompoundAssignOperator *E) {
+ return VisitBinaryOperator(E);
+}
+
+Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
Sema::OwningExprResult First = Visit(E->getArg(0));
if (First.isInvalid())
diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp
index cf6139d0ce..892f649ef7 100644
--- a/test/SemaTemplate/instantiate-expr-3.cpp
+++ b/test/SemaTemplate/instantiate-expr-3.cpp
@@ -9,3 +9,32 @@ struct ImaginaryLiteral0 {
template struct ImaginaryLiteral0<_Complex float>;
template struct ImaginaryLiteral0<int*>; // expected-note{{instantiation}}
+
+namespace N1 {
+ struct X { };
+
+ int& operator+=(X&, int); // expected-note{{candidate}}
+}
+
+namespace N2 {
+ long& operator+=(N1::X&, long); // expected-note{{candidate}}
+
+ template<typename T, typename U, typename Result>
+ struct PlusEquals0 {
+ void f(T t, U u) {
+ Result r = t += u; // expected-error{{ambiguous}}
+ }
+ };
+}
+
+namespace N3 {
+ struct Y : public N1::X {
+ short& operator+=(long); // expected-note{{candidate}}
+ };
+}
+
+template struct N2::PlusEquals0<N1::X, int, int&>;
+template struct N2::PlusEquals0<N1::X, long, long&>;
+template struct N2::PlusEquals0<N3::Y, long, short&>;
+template struct N2::PlusEquals0<int, int, int&>;
+template struct N2::PlusEquals0<N3::Y, int, short&>; // expected-note{{instantiation}}