aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-08-24 13:43:27 +0000
committerDouglas Gregor <dgregor@apple.com>2009-08-24 13:43:27 +0000
commit19b7b158699983e70693c73f3b982fd16c056585 (patch)
treee203747acc933ca038426cb9f1bcea51085760d1
parentf42e4a6e089e8413247400fe58ad299193371f9c (diff)
Refactor the template-instantiation logic for expressions into a
generic tree transformation (also used for recanonicalization) and a small amount of template-instantiation-specific logic. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79917 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaOverload.cpp83
1 files changed, 59 insertions, 24 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 850b5e7d8a..0a65a36b47 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -2883,6 +2883,31 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
}
}
+/// \brief Helper function for AddBuiltinOperatorCandidates() that adds
+/// the volatile- and non-volatile-qualified assignment operators for the
+/// given type to the candidate set.
+static void AddBuiltinAssignmentOperatorCandidates(Sema &S,
+ QualType T,
+ Expr **Args,
+ unsigned NumArgs,
+ OverloadCandidateSet &CandidateSet) {
+ QualType ParamTypes[2];
+
+ // T& operator=(T&, T)
+ ParamTypes[0] = S.Context.getLValueReferenceType(T);
+ ParamTypes[1] = T;
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ /*IsAssignmentOperator=*/true);
+
+ if (!S.Context.getCanonicalType(T).isVolatileQualified()) {
+ // volatile T& operator=(volatile T&, T)
+ ParamTypes[0] = S.Context.getLValueReferenceType(T.withVolatile());
+ ParamTypes[1] = T;
+ S.AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+ /*IsAssignmentOperator=*/true);
+ }
+}
+
/// AddBuiltinOperatorCandidates - Add the appropriate built-in
/// operator overloads to the candidate set (C++ [over.built]), based
/// on the operator @p Op and the arguments given. For example, if the
@@ -2906,7 +2931,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
const unsigned NumArithmeticTypes = 16;
QualType ArithmeticTypes[NumArithmeticTypes] = {
Context.BoolTy, Context.CharTy, Context.WCharTy,
-// Context.Char16Ty, Context.Char32Ty,
+// FIXME: Context.Char16Ty, Context.Char32Ty,
Context.SignedCharTy, Context.ShortTy,
Context.UnsignedCharTy, Context.UnsignedShortTy,
Context.IntTy, Context.LongTy, Context.LongLongTy,
@@ -3119,12 +3144,29 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// operator '->', the built-in candidates set is empty.
break;
+ case OO_EqualEqual:
+ case OO_ExclaimEqual:
+ // C++ [over.match.oper]p16:
+ // For every pointer to member type T, there exist candidate operator
+ // functions of the form
+ //
+ // bool operator==(T,T);
+ // bool operator!=(T,T);
+ for (BuiltinCandidateTypeSet::iterator
+ MemPtr = CandidateTypes.member_pointer_begin(),
+ MemPtrEnd = CandidateTypes.member_pointer_end();
+ MemPtr != MemPtrEnd;
+ ++MemPtr) {
+ QualType ParamTypes[2] = { *MemPtr, *MemPtr };
+ AddBuiltinCandidate(Context.BoolTy, ParamTypes, Args, 2, CandidateSet);
+ }
+
+ // Fall through
+
case OO_Less:
case OO_Greater:
case OO_LessEqual:
case OO_GreaterEqual:
- case OO_EqualEqual:
- case OO_ExclaimEqual:
// C++ [over.built]p15:
//
// For every pointer or enumeration type T, there exist
@@ -3279,30 +3321,23 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
// C++ [over.built]p20:
//
// For every pair (T, VQ), where T is an enumeration or
- // (FIXME:) pointer to member type and VQ is either volatile or
+ // pointer to member type and VQ is either volatile or
// empty, there exist candidate operator functions of the form
//
// VQ T& operator=(VQ T&, T);
- for (BuiltinCandidateTypeSet::iterator Enum
- = CandidateTypes.enumeration_begin();
- Enum != CandidateTypes.enumeration_end(); ++Enum) {
- QualType ParamTypes[2];
-
- // T& operator=(T&, T)
- ParamTypes[0] = Context.getLValueReferenceType(*Enum);
- ParamTypes[1] = *Enum;
- AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
- /*IsAssignmentOperator=*/false);
-
- if (!Context.getCanonicalType(*Enum).isVolatileQualified()) {
- // volatile T& operator=(volatile T&, T)
- ParamTypes[0] = Context.getLValueReferenceType((*Enum).withVolatile());
- ParamTypes[1] = *Enum;
- AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
- /*IsAssignmentOperator=*/false);
- }
- }
- // Fall through.
+ for (BuiltinCandidateTypeSet::iterator
+ Enum = CandidateTypes.enumeration_begin(),
+ EnumEnd = CandidateTypes.enumeration_end();
+ Enum != EnumEnd; ++Enum)
+ AddBuiltinAssignmentOperatorCandidates(*this, *Enum, Args, 2,
+ CandidateSet);
+ for (BuiltinCandidateTypeSet::iterator
+ MemPtr = CandidateTypes.member_pointer_begin(),
+ MemPtrEnd = CandidateTypes.member_pointer_end();
+ MemPtr != MemPtrEnd; ++MemPtr)
+ AddBuiltinAssignmentOperatorCandidates(*this, *MemPtr, Args, 2,
+ CandidateSet);
+ // Fall through.
case OO_PlusEqual:
case OO_MinusEqual: