Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -1054,6 +1054,9 @@ #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'. Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -2414,6 +2414,9 @@ // 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 Index: include/clang/Basic/AArch64SVEACLETypes.def =================================================================== --- /dev/null +++ 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 Index: include/clang/Basic/TargetInfo.h =================================================================== --- include/clang/Basic/TargetInfo.h +++ include/clang/Basic/TargetInfo.h @@ -193,6 +193,8 @@ unsigned IsRenderScriptTarget : 1; + unsigned HasAArch64SVETypes : 1; + // TargetInfo Constructor. Default initializes all fields. TargetInfo(const llvm::Triple &T); @@ -789,6 +791,10 @@ /// 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. /// Index: include/clang/Serialization/ASTBitCodes.h =================================================================== --- include/clang/Serialization/ASTBitCodes.h +++ include/clang/Serialization/ASTBitCodes.h @@ -1018,6 +1018,9 @@ #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 Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -1298,6 +1298,12 @@ #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 @@ 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 @@ /*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 @@ // 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 @@ // 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 @@ 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 @@ 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; Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -959,6 +959,10 @@ 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; Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -9008,6 +9008,9 @@ 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: Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -2671,6 +2671,15 @@ 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" } } Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -2109,6 +2109,9 @@ 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: Index: lib/AST/NSAPI.cpp =================================================================== --- lib/AST/NSAPI.cpp +++ lib/AST/NSAPI.cpp @@ -482,6 +482,9 @@ 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: Index: lib/AST/PrintfFormatString.cpp =================================================================== --- lib/AST/PrintfFormatString.cpp +++ lib/AST/PrintfFormatString.cpp @@ -769,6 +769,9 @@ #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) Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -2885,6 +2885,10 @@ 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 @@ 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: Index: lib/AST/TypeLoc.cpp =================================================================== --- lib/AST/TypeLoc.cpp +++ lib/AST/TypeLoc.cpp @@ -391,6 +391,9 @@ 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; Index: lib/Basic/TargetInfo.cpp =================================================================== --- lib/Basic/TargetInfo.cpp +++ lib/Basic/TargetInfo.cpp @@ -111,6 +111,7 @@ HasAlignMac68kSupport = false; HasBuiltinMSVaList = false; IsRenderScriptTarget = false; + HasAArch64SVETypes = false; // Default to no types using fpret. RealTypeUsesObjCFPRet = 0; Index: lib/Basic/Targets/AArch64.cpp =================================================================== --- lib/Basic/Targets/AArch64.cpp +++ lib/Basic/Targets/AArch64.cpp @@ -62,6 +62,16 @@ // 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; Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -697,6 +697,22 @@ 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: Index: lib/CodeGen/CodeGenTypes.cpp =================================================================== --- lib/CodeGen/CodeGenTypes.cpp +++ lib/CodeGen/CodeGenTypes.cpp @@ -512,6 +512,22 @@ 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) \ Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -2860,6 +2860,9 @@ 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: Index: lib/Index/USRGeneration.cpp =================================================================== --- lib/Index/USRGeneration.cpp +++ lib/Index/USRGeneration.cpp @@ -724,6 +724,9 @@ 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: Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -335,7 +335,13 @@ 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"); Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -5305,6 +5305,11 @@ #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 @@ #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" Index: lib/Serialization/ASTCommon.cpp =================================================================== --- lib/Serialization/ASTCommon.cpp +++ lib/Serialization/ASTCommon.cpp @@ -232,6 +232,11 @@ 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; Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -7421,6 +7421,11 @@ 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"); Index: test/AST/ast-dump-aarch64-sve-types.c =================================================================== --- /dev/null +++ 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' Index: test/CodeGen/aarch64-sve.c =================================================================== --- /dev/null +++ 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; Index: test/CodeGenCXX/aarch64-mangle-sve-vectors-msvc.cpp =================================================================== --- /dev/null +++ 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>) {} Index: test/CodeGenCXX/aarch64-mangle-sve-vectors.cpp =================================================================== --- /dev/null +++ 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>) {} Index: test/CodeGenCXX/aarch64-sve-typeinfo.cpp =================================================================== --- /dev/null +++ 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 Index: test/CodeGenObjC/aarch64-sve-types.m =================================================================== --- /dev/null +++ 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); Index: test/PCH/aarch64-sve-types.c =================================================================== --- /dev/null +++ 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; Index: test/Sema/aarch64-sve-types.c =================================================================== --- /dev/null +++ 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 rely 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]; +} Index: test/SemaObjC/aarch64-sve-types.m =================================================================== --- /dev/null +++ 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 Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -1527,6 +1527,9 @@ 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: Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -5236,6 +5236,44 @@ 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, );