]> granicus.if.org Git - clang/commitdiff
Add support for "neon_vector_type" and "neon_polyvector_type" attributes
authorBob Wilson <bob.wilson@apple.com>
Tue, 16 Nov 2010 00:32:24 +0000 (00:32 +0000)
committerBob Wilson <bob.wilson@apple.com>
Tue, 16 Nov 2010 00:32:24 +0000 (00:32 +0000)
to create the special Neon vector types.  These are intended to be used in
Clang's version of <arm_neon.h> to define special Neon vector types that will
be mangled according to ARM's ABI.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119301 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
include/clang/Sema/AttributeList.h
lib/Sema/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaType.cpp

index 61e5f07cbb77c4b80571a624a78c46aa0c43461f..560120b51e79c60a326296dbc507642990a8e82f 100644 (file)
@@ -895,6 +895,8 @@ def err_iboutletcollection_object_type : Error<
 def err_attribute_missing_parameter_name : Error<
   "attribute requires unquoted parameter">;
 def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">;
+def err_attribute_bad_neon_vector_size : Error<
+  "Neon vector size must be 64 or 128 bits">;
 def err_attribute_argument_not_int : Error<
   "'%0' attribute requires integer constant">;
 def err_attribute_argument_outof_range : Error<
index 1a4f38204bf62bc84a1b1344c98d7074a83838a4..577b7edc89ed6e6e185bc7c0c6246e621a29ad5f 100644 (file)
@@ -106,6 +106,8 @@ public:
     AT_hiding,
     AT_malloc,
     AT_mode,
+    AT_neon_polyvector_type,    // Clang-specific.
+    AT_neon_vector_type,        // Clang-specific.
     AT_naked,
     AT_nodebug,
     AT_noinline,
index 06bde633d963c0bf9177815e9a77b64a689764f2..87639e017eedc7ec069c98c5b287067d9c9dad7f 100644 (file)
@@ -102,6 +102,8 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
     .Case("vec_type_hint", IgnoredAttribute)
     .Case("objc_exception", AT_objc_exception)
     .Case("ext_vector_type", AT_ext_vector_type)
+    .Case("neon_vector_type", AT_neon_vector_type)
+    .Case("neon_polyvector_type", AT_neon_polyvector_type)
     .Case("transparent_union", AT_transparent_union)
     .Case("analyzer_noreturn", AT_analyzer_noreturn)
     .Case("warn_unused_result", AT_warn_unused_result)
index e07b1ac47165abd790a5974b53772b46340915db..a1c07434ecce95cbea80e6e88be42c45ab65e399 100644 (file)
@@ -2297,6 +2297,8 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
   case AttributeList::AT_address_space:
   case AttributeList::AT_objc_gc:
   case AttributeList::AT_vector_size:
+  case AttributeList::AT_neon_vector_type:
+  case AttributeList::AT_neon_polyvector_type:
     // Ignore these, these are type attributes, handled by
     // ProcessTypeAttributes.
     break;
index b244ae1481e07918b3c9c70b17dc91ea102ccead..6e857a7f3b04e748da6560211e611ab69a7a6324 100644 (file)
@@ -2047,6 +2047,65 @@ static void HandleVectorSizeAttr(QualType& CurType, const AttributeList &Attr,
                                     VectorType::GenericVector);
 }
 
+/// HandleNeonVectorTypeAttr - The "neon_vector_type" and
+/// "neon_polyvector_type" attributes are used to create vector types that
+/// are mangled according to ARM's ABI.  Otherwise, these types are identical
+/// to those created with the "vector_size" attribute.  Unlike "vector_size"
+/// the argument to these Neon attributes is the number of vector elements,
+/// not the vector size in bytes.  The vector width and element type must
+/// match one of the standard Neon vector types.
+static void HandleNeonVectorTypeAttr(QualType& CurType,
+                                     const AttributeList &Attr, Sema &S,
+                                     VectorType::VectorKind VecKind,
+                                     const char *AttrName) {
+  // Check the attribute arguments.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
+    Attr.setInvalid();
+    return;
+  }
+  // The number of elements must be an ICE.
+  Expr *numEltsExpr = static_cast<Expr *>(Attr.getArg(0));
+  llvm::APSInt numEltsInt(32);
+  if (numEltsExpr->isTypeDependent() || numEltsExpr->isValueDependent() ||
+      !numEltsExpr->isIntegerConstantExpr(numEltsInt, S.Context)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_not_int)
+      << AttrName << numEltsExpr->getSourceRange();
+    Attr.setInvalid();
+    return;
+  }
+  // Only certain element types are supported for Neon vectors.
+  const BuiltinType* BTy = CurType->getAs<BuiltinType>();
+  if (!BTy ||
+      (VecKind == VectorType::NeonPolyVector &&
+       BTy->getKind() != BuiltinType::SChar &&
+       BTy->getKind() != BuiltinType::Short) ||
+      (BTy->getKind() != BuiltinType::SChar &&
+       BTy->getKind() != BuiltinType::UChar &&
+       BTy->getKind() != BuiltinType::Short &&
+       BTy->getKind() != BuiltinType::UShort &&
+       BTy->getKind() != BuiltinType::Int &&
+       BTy->getKind() != BuiltinType::UInt &&
+       BTy->getKind() != BuiltinType::LongLong &&
+       BTy->getKind() != BuiltinType::ULongLong &&
+       BTy->getKind() != BuiltinType::Float)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_invalid_vector_type) <<CurType;
+    Attr.setInvalid();
+    return;
+  }
+  // The total size of the vector must be 64 or 128 bits.
+  unsigned typeSize = static_cast<unsigned>(S.Context.getTypeSize(CurType));
+  unsigned numElts = static_cast<unsigned>(numEltsInt.getZExtValue());
+  unsigned vecSize = typeSize * numElts;
+  if (vecSize != 64 && vecSize != 128) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_bad_neon_vector_size) << CurType;
+    Attr.setInvalid();
+    return;
+  }
+
+  CurType = S.Context.getVectorType(CurType, numElts, VecKind);
+}
+
 void ProcessTypeAttributeList(Sema &S, QualType &Result,
                               bool IsDeclSpec, const AttributeList *AL,
                               DelayedAttributeSet &FnAttrs) {
@@ -2073,6 +2132,14 @@ void ProcessTypeAttributeList(Sema &S, QualType &Result,
     case AttributeList::AT_vector_size:
       HandleVectorSizeAttr(Result, *AL, S);
       break;
+    case AttributeList::AT_neon_vector_type:
+      HandleNeonVectorTypeAttr(Result, *AL, S, VectorType::NeonVector,
+                               "neon_vector_type");
+      break;
+    case AttributeList::AT_neon_polyvector_type:
+      HandleNeonVectorTypeAttr(Result, *AL, S, VectorType::NeonPolyVector,
+                               "neon_polyvector_type");
+      break;
 
     case AttributeList::AT_noreturn:
     case AttributeList::AT_cdecl: