From: Bob Wilson Date: Tue, 16 Nov 2010 00:32:24 +0000 (+0000) Subject: Add support for "neon_vector_type" and "neon_polyvector_type" attributes X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4211bb68cff1f310be280f66a59520548ef99d8f;p=clang Add support for "neon_vector_type" and "neon_polyvector_type" attributes to create the special Neon vector types. These are intended to be used in Clang's version of 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 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 61e5f07cbb..560120b51e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 1a4f38204b..577b7edc89 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -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, diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp index 06bde633d9..87639e017e 100644 --- a/lib/Sema/AttributeList.cpp +++ b/lib/Sema/AttributeList.cpp @@ -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) diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index e07b1ac471..a1c07434ec 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -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; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index b244ae1481..6e857a7f3b 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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(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(); + 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) <(S.Context.getTypeSize(CurType)); + unsigned numElts = static_cast(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: