[cfe-commits] r69555 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/conditional-expr.cpp www/cxx_status.html
Sebastian Redl
sebastian.redl at getdesigned.at
Sun Apr 19 14:53:20 PDT 2009
Author: cornedbee
Date: Sun Apr 19 16:53:20 2009
New Revision: 69555
URL: http://llvm.org/viewvc/llvm-project?rev=69555&view=rev
Log:
Conditional operator C++ checking complete. What issues remain are in more general code.
Modified:
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/conditional-expr.cpp
cfe/trunk/www/cxx_status.html
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=69555&r1=69554&r2=69555&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun Apr 19 16:53:20 2009
@@ -1151,6 +1151,8 @@
ICS.Standard.ReferenceBinding) {
assert(ICS.Standard.DirectBinding &&
"TryClassUnification should never generate indirect ref bindings");
+ // FIXME: Should use CheckReferenceInit here, but we no longer have a
+ // reference type.
Self.ImpCastExprToType(E, TargetType(ICS), true);
return false;
}
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=69555&r1=69554&r2=69555&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Sun Apr 19 16:53:20 2009
@@ -2497,6 +2497,10 @@
/// built-in candidates.
TypeSet PointerTypes;
+ /// MemberPointerTypes - The set of member pointer types that will be
+ /// used in the built-in candidates.
+ TypeSet MemberPointerTypes;
+
/// EnumerationTypes - The set of enumeration types that will be
/// used in the built-in candidates.
TypeSet EnumerationTypes;
@@ -2504,7 +2508,8 @@
/// Context - The AST context in which we will build the type sets.
ASTContext &Context;
- bool AddWithMoreQualifiedTypeVariants(QualType Ty);
+ bool AddPointerWithMoreQualifiedTypeVariants(QualType Ty);
+ bool AddMemberPointerWithMoreQualifiedTypeVariants(QualType Ty);
public:
/// iterator - Iterates through the types that are part of the set.
@@ -2518,24 +2523,31 @@
/// pointer_begin - First pointer type found;
iterator pointer_begin() { return PointerTypes.begin(); }
- /// pointer_end - Last pointer type found;
+ /// pointer_end - Past the last pointer type found;
iterator pointer_end() { return PointerTypes.end(); }
+ /// member_pointer_begin - First member pointer type found;
+ iterator member_pointer_begin() { return MemberPointerTypes.begin(); }
+
+ /// member_pointer_end - Past the last member pointer type found;
+ iterator member_pointer_end() { return MemberPointerTypes.end(); }
+
/// enumeration_begin - First enumeration type found;
iterator enumeration_begin() { return EnumerationTypes.begin(); }
- /// enumeration_end - Last enumeration type found;
+ /// enumeration_end - Past the last enumeration type found;
iterator enumeration_end() { return EnumerationTypes.end(); }
};
-/// AddWithMoreQualifiedTypeVariants - Add the pointer type @p Ty to
+/// AddPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty to
/// the set of pointer types along with any more-qualified variants of
/// that type. For example, if @p Ty is "int const *", this routine
/// will add "int const *", "int const volatile *", "int const
/// restrict *", and "int const volatile restrict *" to the set of
/// pointer types. Returns true if the add of @p Ty itself succeeded,
/// false otherwise.
-bool BuiltinCandidateTypeSet::AddWithMoreQualifiedTypeVariants(QualType Ty) {
+bool
+BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty) {
// Insert this type.
if (!PointerTypes.insert(Ty))
return false;
@@ -2547,22 +2559,56 @@
// FIXME: Do we have to add CVR qualifiers at *all* levels to deal
// with all pointer conversions that don't cast away constness?
if (!PointeeTy.isConstQualified())
- AddWithMoreQualifiedTypeVariants
+ AddPointerWithMoreQualifiedTypeVariants
(Context.getPointerType(PointeeTy.withConst()));
if (!PointeeTy.isVolatileQualified())
- AddWithMoreQualifiedTypeVariants
+ AddPointerWithMoreQualifiedTypeVariants
(Context.getPointerType(PointeeTy.withVolatile()));
if (!PointeeTy.isRestrictQualified())
- AddWithMoreQualifiedTypeVariants
+ AddPointerWithMoreQualifiedTypeVariants
(Context.getPointerType(PointeeTy.withRestrict()));
}
return true;
}
+/// AddMemberPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty
+/// to the set of pointer types along with any more-qualified variants of
+/// that type. For example, if @p Ty is "int const *", this routine
+/// will add "int const *", "int const volatile *", "int const
+/// restrict *", and "int const volatile restrict *" to the set of
+/// pointer types. Returns true if the add of @p Ty itself succeeded,
+/// false otherwise.
+bool
+BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
+ QualType Ty) {
+ // Insert this type.
+ if (!MemberPointerTypes.insert(Ty))
+ return false;
+
+ if (const MemberPointerType *PointerTy = Ty->getAsMemberPointerType()) {
+ QualType PointeeTy = PointerTy->getPointeeType();
+ const Type *ClassTy = PointerTy->getClass();
+ // FIXME: Optimize this so that we don't keep trying to add the same types.
+
+ if (!PointeeTy.isConstQualified())
+ AddMemberPointerWithMoreQualifiedTypeVariants
+ (Context.getMemberPointerType(PointeeTy.withConst(), ClassTy));
+ if (!PointeeTy.isVolatileQualified())
+ AddMemberPointerWithMoreQualifiedTypeVariants
+ (Context.getMemberPointerType(PointeeTy.withVolatile(), ClassTy));
+ if (!PointeeTy.isRestrictQualified())
+ AddMemberPointerWithMoreQualifiedTypeVariants
+ (Context.getMemberPointerType(PointeeTy.withRestrict(), ClassTy));
+ }
+
+ return true;
+}
+
/// AddTypesConvertedFrom - Add each of the types to which the type @p
/// Ty can be implicit converted to the given set of @p Types. We're
-/// primarily interested in pointer types and enumeration types.
+/// primarily interested in pointer types and enumeration types. We also
+/// take member pointer types, for the conditional operator.
/// AllowUserConversions is true if we should look at the conversion
/// functions of a class type, and AllowExplicitConversions if we
/// should also include the explicit conversion functions of a class
@@ -2587,14 +2633,14 @@
// Insert our type, and its more-qualified variants, into the set
// of types.
- if (!AddWithMoreQualifiedTypeVariants(Ty))
+ if (!AddPointerWithMoreQualifiedTypeVariants(Ty))
return;
// Add 'cv void*' to our set of types.
if (!Ty->isVoidType()) {
QualType QualVoid
= Context.VoidTy.getQualifiedType(PointeeTy.getCVRQualifiers());
- AddWithMoreQualifiedTypeVariants(Context.getPointerType(QualVoid));
+ AddPointerWithMoreQualifiedTypeVariants(Context.getPointerType(QualVoid));
}
// If this is a pointer to a class type, add pointers to its bases
@@ -2612,6 +2658,10 @@
AddTypesConvertedFrom(Context.getPointerType(BaseTy), false, false);
}
}
+ } else if (Ty->isMemberPointerType()) {
+ // Member pointers are far easier, since the pointee can't be converted.
+ if (!AddMemberPointerWithMoreQualifiedTypeVariants(Ty))
+ return;
} else if (Ty->isEnumeralType()) {
EnumerationTypes.insert(Ty);
} else if (AllowUserConversions) {
@@ -3231,12 +3281,17 @@
//
// T operator?(bool, T, T);
//
- // FIXME: pointer-to-member
for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin(),
E = CandidateTypes.pointer_end(); Ptr != E; ++Ptr) {
QualType ParamTypes[2] = { *Ptr, *Ptr };
AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
}
+ for (BuiltinCandidateTypeSet::iterator Ptr =
+ CandidateTypes.member_pointer_begin(),
+ E = CandidateTypes.member_pointer_end(); Ptr != E; ++Ptr) {
+ QualType ParamTypes[2] = { *Ptr, *Ptr };
+ AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+ }
goto Conditional;
}
}
Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conditional-expr.cpp?rev=69555&r1=69554&r2=69555&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conditional-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conditional-expr.cpp Sun Apr 19 16:53:20 2009
@@ -108,11 +108,18 @@
// should fail: const lost
(void)(i1 ? Base() : constder()); // expected-error {{incompatible operand types ('struct Base' and 'struct Derived const')}}
(void)(i1 ? constder() : Base()); // expected-error {{incompatible operand types ('struct Derived const' and 'struct Base')}}
- // FIXME: should fail: private or ambiguous base
+
+ // FIXME: these are invalid hierarchy conversions
+ Priv priv;
+ Fin fin;
(void)(i1 ? Base() : Priv()); // xpected-error private base
(void)(i1 ? Priv() : Base()); // xpected-error private base
(void)(i1 ? Base() : Fin()); // xpected-error ambiguous base
(void)(i1 ? Fin() : Base()); // xpected-error ambiguous base
+ (void)(i1 ? base : priv); // xpected-error private base
+ (void)(i1 ? priv : base); // xpected-error private base
+ (void)(i1 ? base : fin); // xpected-error ambiguous base
+ (void)(i1 ? fin : base); // xpected-error ambiguous base
// b2.2 (non-hierarchy)
i1 = i1 ? I() : i1;
@@ -142,9 +149,8 @@
double d1 = i1 ? I() : K();
pfn = i1 ? F() : G();
DFnPtr pfm;
- // FIXME: Overload resolution won't choose the member pointer yet.
- //pfm = i1 ? DFnPtr() : &Base::fn1;
- //pfm = i1 ? &Base::fn1 : DFnPtr();
+ pfm = i1 ? DFnPtr() : &Base::fn1;
+ pfm = i1 ? &Base::fn1 : DFnPtr();
// p6 (final conversions)
i1 = i1 ? i1 : ir1;
Modified: cfe/trunk/www/cxx_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=69555&r1=69554&r2=69555&view=diff
==============================================================================
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Sun Apr 19 16:53:20 2009
@@ -788,9 +788,9 @@
<td> 5.16 [expr.cond]</td>
<td class="complete" align="center">✓</td>
<td class="complete" align="center">✓</td>
- <td class="medium" align="center"></td>
+ <td class="complete" align="center">✓</td>
<td></td>
- <td>throw expressions not supported, type unification rules are based on C only</td>
+ <td>some invalid hierarchy casts still accepted, but that's a general problem</td>
</tr>
<tr>
<td> 5.17 [expr.ass]</td>
More information about the cfe-commits
mailing list