[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">&#x2713;</td>
   <td class="complete" align="center">&#x2713;</td>
-  <td class="medium" align="center"></td>
+  <td class="complete" align="center">&#x2713;</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