From 584a96f1045df22f805ba0a7cac20a93eff9c7b6 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Fri, 9 Aug 2019 08:52:54 +0000 Subject: [PATCH] Add SVE opaque built-in types This patch adds the SVE built-in types defined by the Procedure Call Standard for the Arm Architecture: https://developer.arm.com/docs/100986/0000 It handles the types in all relevant places that deal with built-in types. At the moment, some of these places bail out with an error, including: (1) trying to generate LLVM IR for the types (2) trying to generate debug info for the types (3) trying to mangle the types using the Microsoft C++ ABI (4) trying to @encode the types in Objective C (1) and (2) are fixed by follow-on patches but (unlike this patch) they deal mostly with target-specific LLVM details, so seemed like a logically separate change. There is currently no spec for (3) and (4), so reporting an error seems like the correct behaviour for now. The intention is that the types will become sizeless types: http://lists.llvm.org/pipermail/cfe-dev/2019-June/062523.html The main purpose of the sizeless type extension is to diagnose impossible or dangerous uses of the types, such as any that would require sizeof to have a meaningful defined value. Until then, the patch sets the alignments of the types to the values specified in the link above. It also sets the sizes of the types to zero, which is chosen to be consistently wrong and shouldn't affect correctly-written code (i.e. code that would compile even with the sizeless type extension). The patch adds the common subset of functionality needed to test the sizeless type extension on the one hand and to provide SVE intrinsic functions on the other. After this patch, the two pieces of work are essentially independent. The patch is based on one by Graham Hunter: https://reviews.llvm.org/D59245 Differential Revision: https://reviews.llvm.org/D62960 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368413 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 3 + include/clang/AST/Type.h | 3 + include/clang/Basic/AArch64SVEACLETypes.def | 70 +++++++++++++++++++ include/clang/Basic/TargetInfo.h | 6 ++ include/clang/Serialization/ASTBitCodes.h | 3 + lib/AST/ASTContext.cpp | 47 +++++++++++-- lib/AST/ASTImporter.cpp | 4 ++ lib/AST/ExprConstant.cpp | 3 + lib/AST/ItaniumMangle.cpp | 9 +++ lib/AST/MicrosoftMangle.cpp | 3 + lib/AST/NSAPI.cpp | 3 + lib/AST/PrintfFormatString.cpp | 3 + lib/AST/Type.cpp | 7 ++ lib/AST/TypeLoc.cpp | 3 + lib/Basic/TargetInfo.cpp | 1 + lib/Basic/Targets/AArch64.cpp | 10 +++ lib/CodeGen/CGDebugInfo.cpp | 16 +++++ lib/CodeGen/CodeGenTypes.cpp | 16 +++++ lib/CodeGen/ItaniumCXXABI.cpp | 3 + lib/Index/USRGeneration.cpp | 3 + lib/Sema/Sema.cpp | 8 ++- lib/Sema/SemaExpr.cpp | 8 +++ lib/Serialization/ASTCommon.cpp | 5 ++ lib/Serialization/ASTReader.cpp | 5 ++ test/AST/ast-dump-aarch64-sve-types.c | 38 ++++++++++ test/CodeGen/aarch64-sve.c | 9 +++ .../aarch64-mangle-sve-vectors-msvc.cpp | 7 ++ .../CodeGenCXX/aarch64-mangle-sve-vectors.cpp | 31 ++++++++ test/CodeGenCXX/aarch64-sve-typeinfo.cpp | 58 +++++++++++++++ test/CodeGenObjC/aarch64-sve-types.m | 32 +++++++++ test/PCH/aarch64-sve-types.c | 21 ++++++ test/Sema/aarch64-sve-types.c | 52 ++++++++++++++ test/SemaObjC/aarch64-sve-types.m | 22 ++++++ tools/libclang/CIndex.cpp | 3 + unittests/AST/ASTImporterTest.cpp | 38 ++++++++++ 35 files changed, 547 insertions(+), 6 deletions(-) create mode 100644 include/clang/Basic/AArch64SVEACLETypes.def create mode 100644 test/AST/ast-dump-aarch64-sve-types.c create mode 100644 test/CodeGen/aarch64-sve.c create mode 100644 test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp create mode 100644 test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp create mode 100644 test/CodeGenCXX/aarch64-sve-typeinfo.cpp create mode 100644 test/CodeGenObjC/aarch64-sve-types.m create mode 100644 test/PCH/aarch64-sve-types.c create mode 100644 test/Sema/aarch64-sve-types.c create mode 100644 test/SemaObjC/aarch64-sve-types.m diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 1d1aaf4fb1..3b5fc9e57e 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -1054,6 +1054,9 @@ public: #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" +#define SVE_TYPE(Name, Id, SingletonId) \ + CanQualType SingletonId; +#include "clang/Basic/AArch64SVEACLETypes.def" // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. mutable QualType AutoDeductTy; // Deduction against 'auto'. diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 00a2b76433..e80dd1a4ec 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -2414,6 +2414,9 @@ public: // OpenCL extension types #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) Id, #include "clang/Basic/OpenCLExtensionTypes.def" +// SVE Types +#define SVE_TYPE(Name, Id, SingletonId) Id, +#include "clang/Basic/AArch64SVEACLETypes.def" // All other builtin types #define BUILTIN_TYPE(Id, SingletonId) Id, #define LAST_BUILTIN_TYPE(Id) LastKind = Id diff --git a/include/clang/Basic/AArch64SVEACLETypes.def b/include/clang/Basic/AArch64SVEACLETypes.def new file mode 100644 index 0000000000..7d387587dc --- /dev/null +++ b/include/clang/Basic/AArch64SVEACLETypes.def @@ -0,0 +1,70 @@ +//===-- AArch64SVEACLETypes.def - Metadata about SVE types ------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines various SVE builtin types. The macros are: +// +// SVE_TYPE(Name, Id, SingletonId) - A builtin type that has not been +// covered by any other #define. Defining this macro covers all +// the builtins. +// +// SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP) - +// An SVE scalable vector. +// +// SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind) - An SVE scalable +// predicate. +// +// where: +// +// - Name is the name of the builtin type. +// +// - BuiltinType::Id is the enumerator defining the type. +// +// - Context.SingletonId is the global singleton of this type. +// +// - ElKind enumerates the type of the elements. +// +// - ElBits is the size of one element in bits. +// +// - IsSigned is true for vectors of signed integer elements and +// for vectors of floating-point elements. +// +// - IsFP is true for vectors of floating-point elements. +// +//===----------------------------------------------------------------------===// + +#ifndef SVE_VECTOR_TYPE +#define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\ + SVE_TYPE(Name, Id, SingletonId) +#endif + +#ifndef SVE_PREDICATE_TYPE +#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind)\ + SVE_TYPE(Name, Id, SingletonId) +#endif + +//===- Vector point types -----------------------------------------------===// + +SVE_VECTOR_TYPE("__SVInt8_t", SveInt8, SveInt8Ty, SveElSInt8, 8, true, false) +SVE_VECTOR_TYPE("__SVInt16_t", SveInt16, SveInt16Ty, SveElSInt16, 16, true, false) +SVE_VECTOR_TYPE("__SVInt32_t", SveInt32, SveInt32Ty, SveElSInt32, 32, true, false) +SVE_VECTOR_TYPE("__SVInt64_t", SveInt64, SveInt64Ty, SveElSInt64, 64, true, false) + +SVE_VECTOR_TYPE("__SVUint8_t", SveUint8, SveUint8Ty, SveElUInt8, 8, false, false) +SVE_VECTOR_TYPE("__SVUint16_t", SveUint16, SveUint16Ty, SveElUInt16, 16, false, false) +SVE_VECTOR_TYPE("__SVUint32_t", SveUint32, SveUint32Ty, SveElUInt32, 32, false, false) +SVE_VECTOR_TYPE("__SVUint64_t", SveUint64, SveUint64Ty, SveElUInt64, 64, false, false) + +SVE_VECTOR_TYPE("__SVFloat16_t", SveFloat16, SveFloat16Ty, SveElHalf, 16, true, true) +SVE_VECTOR_TYPE("__SVFloat32_t", SveFloat32, SveFloat32Ty, SveElFloat, 32, true, true) +SVE_VECTOR_TYPE("__SVFloat64_t", SveFloat64, SveFloat64Ty, SveElDouble, 64, true, true) + +SVE_PREDICATE_TYPE("__SVBool_t", SveBool, SveBoolTy, SveElBool) + +#undef SVE_VECTOR_TYPE +#undef SVE_PREDICATE_TYPE +#undef SVE_TYPE diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index f9cf075072..36109f1ccc 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -193,6 +193,8 @@ protected: unsigned IsRenderScriptTarget : 1; + unsigned HasAArch64SVETypes : 1; + // TargetInfo Constructor. Default initializes all fields. TargetInfo(const llvm::Triple &T); @@ -789,6 +791,10 @@ public: /// Returns true for RenderScript. bool isRenderScriptTarget() const { return IsRenderScriptTarget; } + /// Returns whether or not the AArch64 SVE built-in types are + /// available on this target. + bool hasAArch64SVETypes() const { return HasAArch64SVETypes; } + /// Returns whether the passed in string is a valid clobber in an /// inline asm statement. /// diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 0e1b9e0af9..7b9ff7e550 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -1018,6 +1018,9 @@ namespace serialization { #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ PREDEF_TYPE_##Id##_ID, #include "clang/Basic/OpenCLExtensionTypes.def" + // \brief SVE types with auto numeration +#define SVE_TYPE(Name, Id, SingletonId) PREDEF_TYPE_##Id##_ID, +#include "clang/Basic/AArch64SVEACLETypes.def" }; /// The number of predefined type IDs that are reserved for diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index be7830640e..452194aa86 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1298,6 +1298,12 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target, #include "clang/Basic/OpenCLExtensionTypes.def" } + if (Target.hasAArch64SVETypes()) { +#define SVE_TYPE(Name, Id, SingletonId) \ + InitBuiltinType(SingletonId, BuiltinType::Id); +#include "clang/Basic/AArch64SVEACLETypes.def" + } + // Builtin type for __objc_yes and __objc_no ObjCBuiltinBoolTy = (Target.useSignedCharForObjCBool() ? SignedCharTy : BoolTy); @@ -1968,6 +1974,25 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const { Width = Target->getPointerWidth(AS); Align = Target->getPointerAlign(AS); break; + // The SVE types are effectively target-specific. The length of an + // SVE_VECTOR_TYPE is only known at runtime, but it is always a multiple + // of 128 bits. There is one predicate bit for each vector byte, so the + // length of an SVE_PREDICATE_TYPE is always a multiple of 16 bits. + // + // Because the length is only known at runtime, we use a dummy value + // of 0 for the static length. The alignment values are those defined + // by the Procedure Call Standard for the Arm Architecture. +#define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\ + case BuiltinType::Id: \ + Width = 0; \ + Align = 128; \ + break; +#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind) \ + case BuiltinType::Id: \ + Width = 0; \ + Align = 16; \ + break; +#include "clang/Basic/AArch64SVEACLETypes.def" } break; case Type::ObjCObjectPointer: @@ -6556,8 +6581,9 @@ void ASTContext::getObjCEncodingForPropertyType(QualType T, /*Field=*/nullptr); } -static char getObjCEncodingForPrimitiveKind(const ASTContext *C, - BuiltinType::Kind kind) { +static char getObjCEncodingForPrimitiveType(const ASTContext *C, + const BuiltinType *BT) { + BuiltinType::Kind kind = BT->getKind(); switch (kind) { case BuiltinType::Void: return 'v'; case BuiltinType::Bool: return 'B'; @@ -6617,6 +6643,17 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C, // FIXME: potentially need @encodes for these! return ' '; +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" + { + DiagnosticsEngine &Diags = C->getDiagnostics(); + unsigned DiagID = Diags.getCustomDiagID( + DiagnosticsEngine::Error, "cannot yet @encode type %0"); + Diags.Report(DiagID) << BT->getName(C->getPrintingPolicy()); + return ' '; + } + case BuiltinType::ObjCId: case BuiltinType::ObjCClass: case BuiltinType::ObjCSel: @@ -6653,7 +6690,7 @@ static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) { // The encoding of a fixed enum type matches its fixed underlying type. const auto *BT = Enum->getIntegerType()->castAs(); - return getObjCEncodingForPrimitiveKind(C, BT->getKind()); + return getObjCEncodingForPrimitiveType(C, BT); } static void EncodeBitField(const ASTContext *Ctx, std::string& S, @@ -6693,7 +6730,7 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S, S += ObjCEncodingForEnumType(Ctx, ET); else { const auto *BT = T->castAs(); - S += getObjCEncodingForPrimitiveKind(Ctx, BT->getKind()); + S += getObjCEncodingForPrimitiveType(Ctx, BT); } } S += llvm::utostr(FD->getBitWidthValue(*Ctx)); @@ -6711,7 +6748,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S, if (FD && FD->isBitField()) return EncodeBitField(this, S, T, FD); if (const auto *BT = dyn_cast(CT)) - S += getObjCEncodingForPrimitiveKind(this, BT->getKind()); + S += getObjCEncodingForPrimitiveType(this, BT); else S += ObjCEncodingForEnumType(this, cast(CT)); return; diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index 8ecbad3c68..69a9f9ddb6 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -959,6 +959,10 @@ ExpectedType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) { case BuiltinType::Id: \ return Importer.getToContext().Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: \ + return Importer.getToContext().SingletonId; +#include "clang/Basic/AArch64SVEACLETypes.def" #define SHARED_SINGLETON_TYPE(Expansion) #define BUILTIN_TYPE(Id, SingletonId) \ case BuiltinType::Id: return Importer.getToContext().SingletonId; diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index f01b42e7ff..b4d0245974 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -9008,6 +9008,9 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) { case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: case BuiltinType::OCLReserveID: +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" return GCCTypeClass::None; case BuiltinType::Dependent: diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index 6c813f09a4..08fd0adf13 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -2671,6 +2671,15 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { Out << type_name.size() << type_name; \ break; #include "clang/Basic/OpenCLExtensionTypes.def" + // The SVE types are effectively target-specific. The mangling scheme + // is defined in the appendices to the Procedure Call Standard for the + // Arm Architecture. +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: \ + type_name = Name; \ + Out << 'u' << type_name.size() << type_name; \ + break; +#include "clang/Basic/AArch64SVEACLETypes.def" } } diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 5e9358e24f..f7a456e06a 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -2109,6 +2109,9 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers, mangleArtificialTagType(TTK_Struct, "_Half", {"__clang"}); break; +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::ShortAccum: case BuiltinType::Accum: case BuiltinType::LongAccum: diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp index 5104dc59d6..f8ff91e2bc 100644 --- a/lib/AST/NSAPI.cpp +++ b/lib/AST/NSAPI.cpp @@ -482,6 +482,9 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: case BuiltinType::OCLReserveID: +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::BoundMember: case BuiltinType::Dependent: case BuiltinType::Overload: diff --git a/lib/AST/PrintfFormatString.cpp b/lib/AST/PrintfFormatString.cpp index a1207aae5a..68f78299a0 100644 --- a/lib/AST/PrintfFormatString.cpp +++ b/lib/AST/PrintfFormatString.cpp @@ -769,6 +769,9 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ case BuiltinType::Id: #include "clang/Basic/OpenCLExtensionTypes.def" +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" #define SIGNED_TYPE(Id, SingletonId) #define UNSIGNED_TYPE(Id, SingletonId) #define FLOATING_TYPE(Id, SingletonId) diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 8d474a8ec2..7e08e72f4e 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -2885,6 +2885,10 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { case Id: \ return #ExtType; #include "clang/Basic/OpenCLExtensionTypes.def" +#define SVE_TYPE(Name, Id, SingletonId) \ + case Id: \ + return Name; +#include "clang/Basic/AArch64SVEACLETypes.def" } llvm_unreachable("Invalid builtin type."); @@ -3886,6 +3890,9 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: case BuiltinType::OCLReserveID: +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::BuiltinFn: case BuiltinType::NullPtr: case BuiltinType::OMPArraySection: diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp index abe4c4eb25..e4788f32b2 100644 --- a/lib/AST/TypeLoc.cpp +++ b/lib/AST/TypeLoc.cpp @@ -391,6 +391,9 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: case BuiltinType::OCLReserveID: +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::BuiltinFn: case BuiltinType::OMPArraySection: return TST_unspecified; diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index a9dfe69b90..9a8783446e 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -111,6 +111,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) { HasAlignMac68kSupport = false; HasBuiltinMSVaList = false; IsRenderScriptTarget = false; + HasAArch64SVETypes = false; // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; diff --git a/lib/Basic/Targets/AArch64.cpp b/lib/Basic/Targets/AArch64.cpp index 93a525b09d..c86cc63e3d 100644 --- a/lib/Basic/Targets/AArch64.cpp +++ b/lib/Basic/Targets/AArch64.cpp @@ -62,6 +62,16 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple, // Make __builtin_ms_va_list available. HasBuiltinMSVaList = true; + // Make the SVE types available. Note that this deliberately doesn't + // depend on SveMode, since in principle it should be possible to turn + // SVE on and off within a translation unit. It should also be possible + // to compile the global declaration: + // + // __SVInt8_t *ptr; + // + // even without SVE. + HasAArch64SVETypes = true; + // {} in inline assembly are neon specifiers, not assembly variant // specifiers. NoAsmVariants = true; diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index f6ee7ee26d..422fbc1e29 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -697,6 +697,22 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { case BuiltinType::Id: \ return getOrCreateStructPtrType("opencl_" #ExtType, Id##Ty); #include "clang/Basic/OpenCLExtensionTypes.def" + // TODO: real support for SVE types requires more infrastructure + // to be added first. The types have a variable length and are + // represented in debug info as types whose length depends on a + // target-specific pseudo register. +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" + { + unsigned DiagID = CGM.getDiags().getCustomDiagID( + DiagnosticsEngine::Error, + "cannot yet generate debug info for SVE type '%0'"); + auto Name = BT->getName(CGM.getContext().getPrintingPolicy()); + CGM.getDiags().Report(DiagID) << Name; + // Return something safe. + return CreateType(cast(CGM.getContext().IntTy)); + } case BuiltinType::UChar: case BuiltinType::Char_U: diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index 79b29b3d91..1e42c92d53 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -512,6 +512,22 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty); break; + // TODO: real CodeGen support for SVE types requires more infrastructure + // to be added first. Report an error until then. +#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" + { + unsigned DiagID = CGM.getDiags().getCustomDiagID( + DiagnosticsEngine::Error, + "cannot yet generate code for SVE type '%0'"); + auto *BT = cast(Ty); + auto Name = BT->getName(CGM.getContext().getPrintingPolicy()); + CGM.getDiags().Report(DiagID) << Name; + // Return something safe. + ResultType = llvm::IntegerType::get(getLLVMContext(), 32); + break; + } + case BuiltinType::Dependent: #define BUILTIN_TYPE(Id, SingletonId) #define PLACEHOLDER_TYPE(Id, SingletonId) \ diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 826d98151d..29ec2d4b81 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -2860,6 +2860,9 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: case BuiltinType::OCLReserveID: +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::ShortAccum: case BuiltinType::Accum: case BuiltinType::LongAccum: diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp index 228651de92..f4316fe7d0 100644 --- a/lib/Index/USRGeneration.cpp +++ b/lib/Index/USRGeneration.cpp @@ -724,6 +724,9 @@ void USRGenerator::VisitType(QualType T) { case BuiltinType::OCLQueue: case BuiltinType::OCLReserveID: case BuiltinType::OCLSampler: +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::ShortAccum: case BuiltinType::Accum: case BuiltinType::LongAccum: diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 30b8d49b5b..101a135e94 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -335,7 +335,13 @@ void Sema::Initialize() { addImplicitTypedef(#ExtType, Context.Id##Ty); \ setOpenCLExtensionForType(Context.Id##Ty, #Ext); #include "clang/Basic/OpenCLExtensionTypes.def" - }; + } + + if (Context.getTargetInfo().hasAArch64SVETypes()) { +#define SVE_TYPE(Name, Id, SingletonId) \ + addImplicitTypedef(Name, Context.SingletonId); +#include "clang/Basic/AArch64SVEACLETypes.def" + } if (Context.getTargetInfo().hasBuiltinMSVaList()) { DeclarationName MSVaList = &Context.Idents.get("__builtin_ms_va_list"); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index a4f8660ac5..585f95c418 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -5305,6 +5305,11 @@ static bool isPlaceholderToRemoveAsArg(QualType type) { #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ case BuiltinType::Id: #include "clang/Basic/OpenCLExtensionTypes.def" + // In practice we'll never use this, since all SVE types are sugared + // via TypedefTypes rather than exposed directly as BuiltinTypes. +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) #define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: #include "clang/AST/BuiltinTypes.def" @@ -17565,6 +17570,9 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) { #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ case BuiltinType::Id: #include "clang/Basic/OpenCLExtensionTypes.def" +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" #define BUILTIN_TYPE(Id, SingletonId) case BuiltinType::Id: #define PLACEHOLDER_TYPE(Id, SingletonId) #include "clang/AST/BuiltinTypes.def" diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index aa3477a7d3..dd06e0582a 100644 --- a/lib/Serialization/ASTCommon.cpp +++ b/lib/Serialization/ASTCommon.cpp @@ -232,6 +232,11 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { case BuiltinType::OCLReserveID: ID = PREDEF_TYPE_RESERVE_ID_ID; break; +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: \ + ID = PREDEF_TYPE_##Id##_ID; \ + break; +#include "clang/Basic/AArch64SVEACLETypes.def" case BuiltinType::BuiltinFn: ID = PREDEF_TYPE_BUILTIN_FN; break; diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 52ea1bf4a0..dc54025fb4 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -7421,6 +7421,11 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_OMP_ARRAY_SECTION: T = Context.OMPArraySectionTy; break; +#define SVE_TYPE(Name, Id, SingletonId) \ + case PREDEF_TYPE_##Id##_ID: \ + T = Context.SingletonId; \ + break; +#include "clang/Basic/AArch64SVEACLETypes.def" } assert(!T.isNull() && "Unknown predefined type"); diff --git a/test/AST/ast-dump-aarch64-sve-types.c b/test/AST/ast-dump-aarch64-sve-types.c new file mode 100644 index 0000000000..fdad9b4efc --- /dev/null +++ b/test/AST/ast-dump-aarch64-sve-types.c @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -ast-dump \ +// RUN: -ast-dump-filter __SV %s | FileCheck %s + +// CHECK: TypedefDecl {{.*}} implicit __SVInt8_t '__SVInt8_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVInt8_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVInt16_t '__SVInt16_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVInt16_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVInt32_t '__SVInt32_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVInt32_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVInt64_t '__SVInt64_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVInt64_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVUint8_t '__SVUint8_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVUint8_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVUint16_t '__SVUint16_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVUint16_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVUint32_t '__SVUint32_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVUint32_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVUint64_t '__SVUint64_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVUint64_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVFloat16_t '__SVFloat16_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVFloat16_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVFloat32_t '__SVFloat32_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVFloat32_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVFloat64_t '__SVFloat64_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVFloat64_t' + +// CHECK: TypedefDecl {{.*}} implicit __SVBool_t '__SVBool_t' +// CHECK-NEXT: -BuiltinType {{.*}} '__SVBool_t' diff --git a/test/CodeGen/aarch64-sve.c b/test/CodeGen/aarch64-sve.c new file mode 100644 index 0000000000..b596fbbfcc --- /dev/null +++ b/test/CodeGen/aarch64-sve.c @@ -0,0 +1,9 @@ +// RUN: not %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve \ +// RUN: -emit-llvm -o - %s -debug-info-kind=limited 2>&1 | FileCheck %s + +// Placeholder test for SVE types + +// CHECK: cannot yet generate code for SVE type '__SVInt8_t' +// CHECK: cannot yet generate debug info for SVE type '__SVInt8_t' + +__SVInt8_t *ptr; diff --git a/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp b/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp new file mode 100644 index 0000000000..55b87da122 --- /dev/null +++ b/test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp @@ -0,0 +1,7 @@ +// RUN: not %clang_cc1 -triple aarch64-unknown-windows-msvc %s -emit-llvm \ +// RUN: -o - 2>&1 | FileCheck %s + +template struct S {}; + +// CHECK: cannot mangle this built-in __SVInt8_t type yet +void f1(S<__SVInt8_t>) {} diff --git a/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp b/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp new file mode 100644 index 0000000000..87e38ab3b0 --- /dev/null +++ b/test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ +// RUN: -target-feature +sve | FileCheck %s + +template struct S {}; + +// CHECK: _Z2f11SIu10__SVInt8_tE +void f1(S<__SVInt8_t>) {} +// CHECK: _Z2f21SIu11__SVInt16_tE +void f2(S<__SVInt16_t>) {} +// CHECK: _Z2f31SIu11__SVInt32_tE +void f3(S<__SVInt32_t>) {} +// CHECK: _Z2f41SIu11__SVInt64_tE +void f4(S<__SVInt64_t>) {} +// CHECK: _Z2f51SIu11__SVUint8_tE +void f5(S<__SVUint8_t>) {} +// CHECK: _Z2f61SIu12__SVUint16_tE +void f6(S<__SVUint16_t>) {} +// CHECK: _Z2f71SIu12__SVUint32_tE +void f7(S<__SVUint32_t>) {} +// CHECK: _Z2f81SIu12__SVUint64_tE +void f8(S<__SVUint64_t>) {} +// CHECK: _Z2f91SIu13__SVFloat16_tE +void f9(S<__SVFloat16_t>) {} +// CHECK: _Z3f101SIu13__SVFloat32_tE +void f10(S<__SVFloat32_t>) {} +// CHECK: _Z3f111SIu13__SVFloat64_tE +void f11(S<__SVFloat64_t>) {} +// CHECK: _Z3f121SIu10__SVBool_tE +void f12(S<__SVBool_t>) {} diff --git a/test/CodeGenCXX/aarch64-sve-typeinfo.cpp b/test/CodeGenCXX/aarch64-sve-typeinfo.cpp new file mode 100644 index 0000000000..5627efaf6a --- /dev/null +++ b/test/CodeGenCXX/aarch64-sve-typeinfo.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ +// RUN: | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ +// RUN: -target-feature +sve | FileCheck %s + +namespace std { class type_info; }; + +auto &s8 = typeid(__SVInt8_t); +auto &s16 = typeid(__SVInt16_t); +auto &s32 = typeid(__SVInt32_t); +auto &s64 = typeid(__SVInt64_t); + +auto &u8 = typeid(__SVUint8_t); +auto &u16 = typeid(__SVUint16_t); +auto &u32 = typeid(__SVUint32_t); +auto &u64 = typeid(__SVUint64_t); + +auto &f16 = typeid(__SVFloat16_t); +auto &f32 = typeid(__SVFloat32_t); +auto &f64 = typeid(__SVFloat64_t); + +auto &b8 = typeid(__SVBool_t); + +// CHECK-DAG: @_ZTSu10__SVInt8_t = {{.*}} c"u10__SVInt8_t\00" +// CHECK-DAG: @_ZTIu10__SVInt8_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu10__SVInt8_t + +// CHECK-DAG: @_ZTSu11__SVInt16_t = {{.*}} c"u11__SVInt16_t\00" +// CHECK-DAG: @_ZTIu11__SVInt16_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu11__SVInt16_t + +// CHECK-DAG: @_ZTSu11__SVInt32_t = {{.*}} c"u11__SVInt32_t\00" +// CHECK-DAG: @_ZTIu11__SVInt32_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu11__SVInt32_t + +// CHECK-DAG: @_ZTSu11__SVInt64_t = {{.*}} c"u11__SVInt64_t\00" +// CHECK-DAG: @_ZTIu11__SVInt64_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu11__SVInt64_t + +// CHECK-DAG: @_ZTSu11__SVUint8_t = {{.*}} c"u11__SVUint8_t\00" +// CHECK-DAG: @_ZTIu11__SVUint8_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu11__SVUint8_t + +// CHECK-DAG: @_ZTSu12__SVUint16_t = {{.*}} c"u12__SVUint16_t\00" +// CHECK-DAG: @_ZTIu12__SVUint16_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu12__SVUint16_t + +// CHECK-DAG: @_ZTSu12__SVUint32_t = {{.*}} c"u12__SVUint32_t\00" +// CHECK-DAG: @_ZTIu12__SVUint32_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu12__SVUint32_t + +// CHECK-DAG: @_ZTSu12__SVUint64_t = {{.*}} c"u12__SVUint64_t\00" +// CHECK-DAG: @_ZTIu12__SVUint64_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu12__SVUint64_t + +// CHECK-DAG: @_ZTSu13__SVFloat16_t = {{.*}} c"u13__SVFloat16_t\00" +// CHECK-DAG: @_ZTIu13__SVFloat16_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu13__SVFloat16_t + +// CHECK-DAG: @_ZTSu13__SVFloat32_t = {{.*}} c"u13__SVFloat32_t\00" +// CHECK-DAG: @_ZTIu13__SVFloat32_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu13__SVFloat32_t + +// CHECK-DAG: @_ZTSu13__SVFloat64_t = {{.*}} c"u13__SVFloat64_t\00" +// CHECK-DAG: @_ZTIu13__SVFloat64_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu13__SVFloat64_t + +// CHECK-DAG: @_ZTSu10__SVBool_t = {{.*}} c"u10__SVBool_t\00" +// CHECK-DAG: @_ZTIu10__SVBool_t = {{.*}} @_ZTVN10__cxxabiv123__fundamental_type_infoE, {{.*}} @_ZTSu10__SVBool_t diff --git a/test/CodeGenObjC/aarch64-sve-types.m b/test/CodeGenObjC/aarch64-sve-types.m new file mode 100644 index 0000000000..625c752965 --- /dev/null +++ b/test/CodeGenObjC/aarch64-sve-types.m @@ -0,0 +1,32 @@ +// RUN: not %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ +// RUN: 2>&1 | FileCheck %s +// RUN: not %clang_cc1 -triple aarch64-none-linux-gnu %s -emit-llvm -o - \ +// RUN: -target-feature +sve 2>&1 | FileCheck %s + +// CHECK: error: cannot yet @encode type __SVInt8_t +const char s8[] = @encode(__SVInt8_t); +// CHECK: error: cannot yet @encode type __SVInt16_t +const char s16[] = @encode(__SVInt16_t); +// CHECK: error: cannot yet @encode type __SVInt32_t +const char s32[] = @encode(__SVInt32_t); +// CHECK: error: cannot yet @encode type __SVInt64_t +const char s64[] = @encode(__SVInt64_t); + +// CHECK: error: cannot yet @encode type __SVUint8_t +const char u8[] = @encode(__SVUint8_t); +// CHECK: error: cannot yet @encode type __SVUint16_t +const char u16[] = @encode(__SVUint16_t); +// CHECK: error: cannot yet @encode type __SVUint32_t +const char u32[] = @encode(__SVUint32_t); +// CHECK: error: cannot yet @encode type __SVUint64_t +const char u64[] = @encode(__SVUint64_t); + +// CHECK: error: cannot yet @encode type __SVFloat16_t +const char f16[] = @encode(__SVFloat16_t); +// CHECK: error: cannot yet @encode type __SVFloat32_t +const char f32[] = @encode(__SVFloat32_t); +// CHECK: error: cannot yet @encode type __SVFloat64_t +const char f64[] = @encode(__SVFloat64_t); + +// CHECK: error: cannot yet @encode type __SVBool_t +const char b8[] = @encode(__SVBool_t); diff --git a/test/PCH/aarch64-sve-types.c b/test/PCH/aarch64-sve-types.c new file mode 100644 index 0000000000..27f1630692 --- /dev/null +++ b/test/PCH/aarch64-sve-types.c @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-pch -o %t %s +// RUN: %clang_cc1 -triple aarch64-linux-gnu -include-pch %t \ +// RUN: -fsyntax-only -verify %s + +// expected-no-diagnostics + +__SVInt8_t *s8; +__SVInt16_t *s16; +__SVInt32_t *s32; +__SVInt64_t *s64; + +__SVUint8_t *u8; +__SVUint16_t *u16; +__SVUint32_t *u32; +__SVUint64_t *u64; + +__SVFloat16_t *f16; +__SVFloat32_t *f32; +__SVFloat64_t *f64; + +__SVBool_t *b8; diff --git a/test/Sema/aarch64-sve-types.c b/test/Sema/aarch64-sve-types.c new file mode 100644 index 0000000000..f85e0f8b61 --- /dev/null +++ b/test/Sema/aarch64-sve-types.c @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 %s -triple aarch64-none-linux-gnu -target-feature +sve -fsyntax-only -verify + +// This test is invalid under the sizeless type extension and is a stop-gap +// until that extension is added. The test makes sure that sizeof and +// alignof queries are handled without assertion failures, since at +// present there is nothing to prevent such queries being made. +// +// Under this scheme, sizeof returns 0 for all built-in sizeless types. +// This is compatible with correct usage but it relies on the user being +// careful to avoid constructs that depend directly or indirectly on the +// value of sizeof. (The sizeless type extension avoids this by treating +// such constructs as an error.) + +// expected-no-diagnostics + +void f() { + int size_s8[sizeof(__SVInt8_t) == 0 ? 1 : -1]; + int align_s8[__alignof__(__SVInt8_t) == 16 ? 1 : -1]; + + int size_s16[sizeof(__SVInt16_t) == 0 ? 1 : -1]; + int align_s16[__alignof__(__SVInt16_t) == 16 ? 1 : -1]; + + int size_s32[sizeof(__SVInt32_t) == 0 ? 1 : -1]; + int align_s32[__alignof__(__SVInt32_t) == 16 ? 1 : -1]; + + int size_s64[sizeof(__SVInt64_t) == 0 ? 1 : -1]; + int align_s64[__alignof__(__SVInt64_t) == 16 ? 1 : -1]; + + int size_u8[sizeof(__SVUint8_t) == 0 ? 1 : -1]; + int align_u8[__alignof__(__SVUint8_t) == 16 ? 1 : -1]; + + int size_u16[sizeof(__SVUint16_t) == 0 ? 1 : -1]; + int align_u16[__alignof__(__SVUint16_t) == 16 ? 1 : -1]; + + int size_u32[sizeof(__SVUint32_t) == 0 ? 1 : -1]; + int align_u32[__alignof__(__SVUint32_t) == 16 ? 1 : -1]; + + int size_u64[sizeof(__SVUint64_t) == 0 ? 1 : -1]; + int align_u64[__alignof__(__SVUint64_t) == 16 ? 1 : -1]; + + int size_f16[sizeof(__SVFloat16_t) == 0 ? 1 : -1]; + int align_f16[__alignof__(__SVFloat16_t) == 16 ? 1 : -1]; + + int size_f32[sizeof(__SVFloat32_t) == 0 ? 1 : -1]; + int align_f32[__alignof__(__SVFloat32_t) == 16 ? 1 : -1]; + + int size_f64[sizeof(__SVFloat64_t) == 0 ? 1 : -1]; + int align_f64[__alignof__(__SVFloat64_t) == 16 ? 1 : -1]; + + int size_b8[sizeof(__SVBool_t) == 0 ? 1 : -1]; + int align_b8[__alignof__(__SVBool_t) == 2 ? 1 : -1]; +} diff --git a/test/SemaObjC/aarch64-sve-types.m b/test/SemaObjC/aarch64-sve-types.m new file mode 100644 index 0000000000..9e1af311de --- /dev/null +++ b/test/SemaObjC/aarch64-sve-types.m @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -fsyntax-only -verify %s + +// Check that we don't abort when SVE types are made nullable. This +// interface is invalid anyway, but we won't diagnose that until the +// sizeless type extension is added. +@interface foo +@property(nullable) __SVInt8_t s8; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVInt16_t s16; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVInt32_t s32; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVInt64_t s64; // expected-error {{cannot be applied to non-pointer type}} + +@property(nullable) __SVUint8_t u8; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVUint16_t u16; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVUint32_t u32; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVUint64_t u64; // expected-error {{cannot be applied to non-pointer type}} + +@property(nullable) __SVFloat16_t f16; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVFloat32_t f32; // expected-error {{cannot be applied to non-pointer type}} +@property(nullable) __SVFloat64_t f64; // expected-error {{cannot be applied to non-pointer type}} + +@property(nullable) __SVBool_t b8; // expected-error {{cannot be applied to non-pointer type}} +@end diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 7c6ae91632..30b71458c2 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -1527,6 +1527,9 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { case BuiltinType::OCLClkEvent: case BuiltinType::OCLQueue: case BuiltinType::OCLReserveID: +#define SVE_TYPE(Name, Id, SingletonId) \ + case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" #define BUILTIN_TYPE(Id, SingletonId) #define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id: #define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id: diff --git a/unittests/AST/ASTImporterTest.cpp b/unittests/AST/ASTImporterTest.cpp index 151b279b9b..97c88b95be 100644 --- a/unittests/AST/ASTImporterTest.cpp +++ b/unittests/AST/ASTImporterTest.cpp @@ -5236,6 +5236,44 @@ TEST_P(LLDBLookupTest, ImporterShouldFindInTransparentContext) { EXPECT_EQ(ImportedX->getCanonicalDecl(), ToX->getCanonicalDecl()); } +struct SVEBuiltins : ASTImporterOptionSpecificTestBase {}; + +TEST_P(SVEBuiltins, ImportTypes) { + static const char *const TypeNames[] = { + "__SVInt8_t", + "__SVInt16_t", + "__SVInt32_t", + "__SVInt64_t", + "__SVUint8_t", + "__SVUint16_t", + "__SVUint32_t", + "__SVUint64_t", + "__SVFloat16_t", + "__SVFloat32_t", + "__SVFloat64_t", + "__SVBool_t" + }; + + TranslationUnitDecl *ToTU = getToTuDecl("", Lang_CXX); + TranslationUnitDecl *FromTU = getTuDecl("", Lang_CXX, "input.cc"); + for (auto *TypeName : TypeNames) { + auto *ToTypedef = FirstDeclMatcher().match( + ToTU, typedefDecl(hasName(TypeName))); + QualType ToType = ToTypedef->getUnderlyingType(); + + auto *FromTypedef = FirstDeclMatcher().match( + FromTU, typedefDecl(hasName(TypeName))); + QualType FromType = FromTypedef->getUnderlyingType(); + + QualType ImportedType = ImportType(FromType, FromTypedef, Lang_CXX); + EXPECT_EQ(ImportedType, ToType); + } +} + +INSTANTIATE_TEST_CASE_P(ParameterizedTests, SVEBuiltins, + ::testing::Values(ArgVector{"-target", + "aarch64-linux-gnu"}), ); + INSTANTIATE_TEST_CASE_P(ParameterizedTests, ASTImporterLookupTableTest, DefaultTestValuesForRunOptions, ); -- 2.40.0