]> granicus.if.org Git - clang/commitdiff
Implement C++ builtin operator candidates for vector types.
authorDouglas Gregor <dgregor@apple.com>
Wed, 19 May 2010 03:21:00 +0000 (03:21 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 19 May 2010 03:21:00 +0000 (03:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104105 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
lib/Sema/SemaOverload.cpp
test/SemaCXX/vector.cpp

index 8bc3d063b1d95bc9eddf161de6f8dd9505fccaa5..5e1f21b4c3b67d51778f3c1bb49931e100c64cab 100644 (file)
@@ -4929,7 +4929,13 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
       if (const VectorType *RV = rhsType->getAs<VectorType>())
         if (LV->getElementType() == RV->getElementType() &&
             LV->getNumElements() == RV->getNumElements()) {
-          return lhsType->isExtVectorType() ? lhsType : rhsType;
+          if (lhsType->isExtVectorType()) {
+            ImpCastExprToType(rex, lhsType, CastExpr::CK_BitCast);
+            return lhsType;
+          } 
+
+          ImpCastExprToType(lex, rhsType, CastExpr::CK_BitCast);
+          return rhsType;
         }
     }
   }
index 897ee6626524aa86de43cc85e1b032a87c9dd884..14042ea6abebe41c05f217f22e67463948a2b6c5 100644 (file)
@@ -3774,6 +3774,10 @@ class BuiltinCandidateTypeSet  {
   /// used in the built-in candidates.
   TypeSet EnumerationTypes;
 
+  /// \brief The set of vector types that will be used in the built-in 
+  /// candidates.
+  TypeSet VectorTypes;
+  
   /// Sema - The semantic analysis instance where we are building the
   /// candidate type set.
   Sema &SemaRef;
@@ -3815,6 +3819,9 @@ public:
 
   /// enumeration_end - Past the last enumeration type found;
   iterator enumeration_end() { return EnumerationTypes.end(); }
+  
+  iterator vector_begin() { return VectorTypes.begin(); }
+  iterator vector_end() { return VectorTypes.end(); }
 };
 
 /// AddPointerWithMoreQualifiedTypeVariants - Add the pointer type @p Ty to
@@ -3947,6 +3954,8 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
       return;
   } else if (Ty->isEnumeralType()) {
     EnumerationTypes.insert(Ty);
+  } else if (Ty->isVectorType()) {
+    VectorTypes.insert(Ty);
   } else if (AllowUserConversions) {
     if (const RecordType *TyRec = Ty->getAs<RecordType>()) {
       if (SemaRef.RequireCompleteType(Loc, Ty, 0)) {
@@ -4111,21 +4120,14 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
     VisibleTypeConversionsQuals += CollectVRQualifiers(Context, Args[ArgIdx]);
   
   BuiltinCandidateTypeSet CandidateTypes(*this);
-  if (Op == OO_Less || Op == OO_Greater || Op == OO_LessEqual ||
-      Op == OO_GreaterEqual || Op == OO_EqualEqual || Op == OO_ExclaimEqual ||
-      Op == OO_Plus || (Op == OO_Minus && NumArgs == 2) || Op == OO_Equal ||
-      Op == OO_PlusEqual || Op == OO_MinusEqual || Op == OO_Subscript ||
-      Op == OO_ArrowStar || Op == OO_PlusPlus || Op == OO_MinusMinus ||
-      (Op == OO_Star && NumArgs == 1) || Op == OO_Conditional) {
-    for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
-      CandidateTypes.AddTypesConvertedFrom(Args[ArgIdx]->getType(),
-                                           OpLoc,
-                                           true,
-                                           (Op == OO_Exclaim ||
-                                            Op == OO_AmpAmp ||
-                                            Op == OO_PipePipe),
-                                           VisibleTypeConversionsQuals);
-  }
+  for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
+    CandidateTypes.AddTypesConvertedFrom(Args[ArgIdx]->getType(),
+                                         OpLoc,
+                                         true,
+                                         (Op == OO_Exclaim ||
+                                          Op == OO_AmpAmp ||
+                                          Op == OO_PipePipe),
+                                         VisibleTypeConversionsQuals);
 
   bool isComparison = false;
   switch (Op) {
@@ -4289,6 +4291,14 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
       QualType ArithTy = ArithmeticTypes[Arith];
       AddBuiltinCandidate(ArithTy, &ArithTy, Args, 1, CandidateSet);
     }
+      
+    // Extension: We also add these operators for vector types.
+    for (BuiltinCandidateTypeSet::iterator Vec = CandidateTypes.vector_begin(),
+                                        VecEnd = CandidateTypes.vector_end(); 
+         Vec != VecEnd; ++Vec) {
+      QualType VecTy = *Vec;
+      AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet);
+    }
     break;
 
   case OO_Tilde:
@@ -4302,6 +4312,14 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
       QualType IntTy = ArithmeticTypes[Int];
       AddBuiltinCandidate(IntTy, &IntTy, Args, 1, CandidateSet);
     }
+      
+    // Extension: We also add this operator for vector types.
+    for (BuiltinCandidateTypeSet::iterator Vec = CandidateTypes.vector_begin(),
+                                        VecEnd = CandidateTypes.vector_end(); 
+         Vec != VecEnd; ++Vec) {
+      QualType VecTy = *Vec;
+      AddBuiltinCandidate(VecTy, &VecTy, Args, 1, CandidateSet);
+    }      
     break;
 
   case OO_New:
@@ -4458,6 +4476,30 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
         AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
       }
     }
+
+    // Extension: Add the binary operators ==, !=, <, <=, >=, >, *, /, and the
+    // conditional operator for vector types.
+    for (BuiltinCandidateTypeSet::iterator Vec1 = CandidateTypes.vector_begin(),
+         Vec1End = CandidateTypes.vector_end(); 
+         Vec1 != Vec1End; ++Vec1)
+      for (BuiltinCandidateTypeSet::iterator 
+           Vec2 = CandidateTypes.vector_begin(),
+           Vec2End = CandidateTypes.vector_end(); 
+           Vec2 != Vec2End; ++Vec2) {
+        QualType LandR[2] = { *Vec1, *Vec2 };
+        QualType Result;
+        if (isComparison)
+          Result = Context.BoolTy;
+        else {
+          if ((*Vec1)->isExtVectorType() || !(*Vec2)->isExtVectorType())
+            Result = *Vec1;
+          else
+            Result = *Vec2;
+        }
+        
+        AddBuiltinCandidate(Result, LandR, Args, 2, CandidateSet);
+      }
+      
     break;
 
   case OO_Percent:
@@ -4513,7 +4555,8 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
          MemPtr != MemPtrEnd; ++MemPtr)
       AddBuiltinAssignmentOperatorCandidates(*this, *MemPtr, Args, 2,
                                              CandidateSet);
-      // Fall through.
+      
+    // Fall through.
 
   case OO_PlusEqual:
   case OO_MinusEqual:
@@ -4588,6 +4631,30 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
         }
       }
     }
+      
+    // Extension: Add the binary operators =, +=, -=, *=, /= for vector types.
+    for (BuiltinCandidateTypeSet::iterator Vec1 = CandidateTypes.vector_begin(),
+                                        Vec1End = CandidateTypes.vector_end(); 
+         Vec1 != Vec1End; ++Vec1)
+      for (BuiltinCandidateTypeSet::iterator 
+                Vec2 = CandidateTypes.vector_begin(),
+             Vec2End = CandidateTypes.vector_end(); 
+           Vec2 != Vec2End; ++Vec2) {
+        QualType ParamTypes[2];
+        ParamTypes[1] = *Vec2;
+        // Add this built-in operator as a candidate (VQ is empty).
+        ParamTypes[0] = Context.getLValueReferenceType(*Vec1);
+        AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                            /*IsAssigmentOperator=*/Op == OO_Equal);
+        
+        // Add this built-in operator as a candidate (VQ is 'volatile').
+        if (VisibleTypeConversionsQuals.hasVolatile()) {
+          ParamTypes[0] = Context.getVolatileType(*Vec1);
+          ParamTypes[0] = Context.getLValueReferenceType(ParamTypes[0]);
+          AddBuiltinCandidate(ParamTypes[0], ParamTypes, Args, 2, CandidateSet,
+                              /*IsAssigmentOperator=*/Op == OO_Equal);
+        }
+      }
     break;
 
   case OO_PercentEqual:
@@ -4683,7 +4750,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
       ParamTypes[0] = ParamTypes[1];
       ParamTypes[1] = *Ptr;
       AddBuiltinCandidate(ResultTy, ParamTypes, Args, 2, CandidateSet);
-    }
+    }      
     break;
 
   case OO_ArrowStar:
index e0fd1e770e4c1eaafeb7bada5bc9a708719d3236..b548865553c2a8be7c1ca8a02c3aca188b5c8977 100644 (file)
@@ -101,16 +101,18 @@ void casts(longlong16 ll16, longlong16_e ll16e) {
 }
 
 template<typename T>
-struct convertible_to {
+struct convertible_to { // expected-note 3 {{candidate function (the implicit copy assignment operator)}}
   operator T() const;
 };
 
-void test_implicit_conversions(char16 c16, longlong16 ll16, char16_e c16e
-                               longlong16_e ll16e,
+void test_implicit_conversions(bool Cond, char16 c16, longlong16 ll16
+                               char16_e c16e, longlong16_e ll16e,
                                convertible_to<char16> to_c16, 
                                convertible_to<longlong16> to_ll16, 
                                convertible_to<char16_e> to_c16e, 
-                               convertible_to<longlong16_e> to_ll16e) {
+                               convertible_to<longlong16_e> to_ll16e,
+                               convertible_to<char16&> rto_c16,
+                               convertible_to<char16_e&> rto_c16e) {
   f0(to_c16);
   f0(to_ll16);
   f0(to_c16e);
@@ -119,4 +121,68 @@ void test_implicit_conversions(char16 c16, longlong16 ll16, char16_e c16e,
   f2(to_ll16);
   f2(to_c16e);
   f2(to_ll16e); // expected-error{{no matching function}}
+
+  (void)(c16 == c16e);
+  (void)(c16 == to_c16);
+  (void)+to_c16;
+  (void)-to_c16;
+  (void)~to_c16;
+  (void)(to_c16 == to_c16e);
+  (void)(to_c16 != to_c16e);
+  (void)(to_c16 <  to_c16e);
+  (void)(to_c16 <= to_c16e);
+  (void)(to_c16 >  to_c16e);
+  (void)(to_c16 >= to_c16e);
+  (void)(to_c16 + to_c16);
+  (void)(to_c16 - to_c16);
+  (void)(to_c16 * to_c16);
+  (void)(to_c16 / to_c16);
+  (void)(rto_c16 = to_c16); // expected-error{{no viable overloaded '='}}
+  (void)(rto_c16 += to_c16);
+  (void)(rto_c16 -= to_c16);
+  (void)(rto_c16 *= to_c16);
+  (void)(rto_c16 /= to_c16);
+
+  (void)+to_c16e;
+  (void)-to_c16e;
+  (void)~to_c16e;
+  (void)(to_c16e == to_c16e);
+  (void)(to_c16e != to_c16e);
+  (void)(to_c16e <  to_c16e);
+  (void)(to_c16e <= to_c16e);
+  (void)(to_c16e >  to_c16e);
+  (void)(to_c16e >= to_c16e);
+  (void)(to_c16e + to_c16);
+  (void)(to_c16e - to_c16);
+  (void)(to_c16e * to_c16);
+  (void)(to_c16e / to_c16);
+  (void)(rto_c16e = to_c16); // expected-error{{no viable overloaded '='}}
+  (void)(rto_c16e += to_c16);
+  (void)(rto_c16e -= to_c16);
+  (void)(rto_c16e *= to_c16);
+  (void)(rto_c16e /= to_c16);
+
+  (void)+to_c16;
+  (void)-to_c16;
+  (void)~to_c16;
+  (void)(to_c16 == to_c16e);
+  (void)(to_c16 != to_c16e);
+  (void)(to_c16 <  to_c16e);
+  (void)(to_c16 <= to_c16e);
+  (void)(to_c16 >  to_c16e);
+  (void)(to_c16 >= to_c16e);
+  (void)(to_c16 + to_c16e);
+  (void)(to_c16 - to_c16e);
+  (void)(to_c16 * to_c16e);
+  (void)(to_c16 / to_c16e);
+  (void)(rto_c16 = c16e); // expected-error{{no viable overloaded '='}}
+  (void)(rto_c16 += to_c16e); // expected-error{{expression is not assignable}}
+  (void)(rto_c16 -= to_c16e); // expected-error{{expression is not assignable}}
+  (void)(rto_c16 *= to_c16e); // expected-error{{expression is not assignable}}
+  (void)(rto_c16 /= to_c16e); // expected-error{{expression is not assignable}}
+
+  (void)(Cond? to_c16 : to_c16e);
+  (void)(Cond? to_ll16e : to_ll16);
+  (void)(Cond? to_c16 : to_ll16); // expected-error{{can't convert between vector values of different size}}
+  (void)(Cond? to_c16e : to_ll16e); // expected-error{{can't convert between vector values of different size}}
 }