Author: Richard Sandiford Date: 2020-03-12T16:30:50Z New Revision: fa8080376e739e2148aa53715dc93e5406f53fd2
URL: https://github.com/llvm/llvm-project/commit/fa8080376e739e2148aa53715dc93e5406f53fd2 DIFF: https://github.com/llvm/llvm-project/commit/fa8080376e739e2148aa53715dc93e5406f53fd2.diff LOG: [AST][SVE] Add new Type queries for sizeless types One of the defining features of the SVE ACLE types is that they are "sizeless"; see the SVE ACLE spec: https://developer.arm.com/docs/100987/0000/arm-c-language-extensions-for-sve or the email message: http://lists.llvm.org/pipermail/cfe-dev/2019-June/062523.html for a fuller definition of what that means. This patch adds two associated type queries: - isSizelessBuiltinType asks specifically about types that are built into clang. It is effectively an enum range check. - isSizelessType instead tests for any type that has the "sizeless" type property. At the moment it only returns true for the built-in types, but it seems better not to hard-code that assumption throughout the codebase. (E.g. we could in principle support some form of user-defined sizeless types in future. Even if that seems unlikely and never actually happens, the possibility at least exists.) Differential Revision: https://reviews.llvm.org/D75570 Added: clang/unittests/AST/SizelessTypesTest.cpp Modified: clang/include/clang/AST/CanonicalType.h clang/include/clang/AST/Type.h clang/lib/AST/Type.cpp clang/unittests/AST/CMakeLists.txt Removed: ################################################################################ diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h index 31b14c0d39c3..488284713bce 100644 --- a/clang/include/clang/AST/CanonicalType.h +++ b/clang/include/clang/AST/CanonicalType.h @@ -264,6 +264,8 @@ class CanProxyBase { // Type predicates LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessBuiltinType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index e589d3fa4e64..f9a269e12d2d 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1926,6 +1926,15 @@ class alignas(8) Type : public ExtQualsTypeCommonBase { /// or QualType::getSingleStepDesugaredType(const ASTContext&). QualType getLocallyUnqualifiedSingleStepDesugaredType() const; + /// As an extension, we classify types as one of "sized" or "sizeless"; + /// every type is one or the other. Standard types are all sized; + /// sizeless types are purely an extension. + /// + /// Sizeless types contain data with no specified size, alignment, + /// or layout. + bool isSizelessType() const; + bool isSizelessBuiltinType() const; + /// Types are partitioned into 3 broad categories (C99 6.2.5p1): /// object types, function types, and incomplete types. diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 5099494da5fd..6e1c70f95262 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2182,6 +2182,22 @@ bool Type::isIncompleteType(NamedDecl **Def) const { } } +bool Type::isSizelessBuiltinType() const { + if (const BuiltinType *BT = getAs<BuiltinType>()) { + switch (BT->getKind()) { + // SVE Types +#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" + return true; + default: + return false; + } + } + return false; +} + +bool Type::isSizelessType() const { return isSizelessBuiltinType(); } + bool QualType::isPODType(const ASTContext &Context) const { // C++11 has a more relaxed definition of POD. if (Context.getLangOpts().CPlusPlus11) diff --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt index d1876dff5012..a7012b812596 100644 --- a/clang/unittests/AST/CMakeLists.txt +++ b/clang/unittests/AST/CMakeLists.txt @@ -28,6 +28,7 @@ add_clang_unittest(ASTTests Language.cpp NamedDeclPrinterTest.cpp RecursiveASTVisitorTest.cpp + SizelessTypesTest.cpp SourceLocationTest.cpp StmtPrinterTest.cpp StructuralEquivalenceTest.cpp diff --git a/clang/unittests/AST/SizelessTypesTest.cpp b/clang/unittests/AST/SizelessTypesTest.cpp new file mode 100644 index 000000000000..8daf30e6bbe3 --- /dev/null +++ b/clang/unittests/AST/SizelessTypesTest.cpp @@ -0,0 +1,82 @@ +//===- unittests/AST/SizelessTypesTest.cpp --- Sizeless type tests --------===// +// +// 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 contains tests for clang::Type queries related to sizeless types. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" +#include "clang/Tooling/Tooling.h" +#include "gtest/gtest.h" + +using namespace clang; + +struct SizelessTypeTester : public ::testing::Test { + // Declare an incomplete structure type. + std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs( + "struct foo;", {"-target", "aarch64-linux-gnu"}); + ASTContext &Ctx = AST->getASTContext(); + TranslationUnitDecl &TU = *Ctx.getTranslationUnitDecl(); + TypeDecl *Foo = cast<TypeDecl>(TU.lookup(&Ctx.Idents.get("foo")).front()); + const Type *FooTy = Foo->getTypeForDecl(); +}; + +TEST_F(SizelessTypeTester, TestSizelessBuiltin) { + ASSERT_TRUE(Ctx.SveInt8Ty->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveInt16Ty->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveInt32Ty->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveInt64Ty->isSizelessBuiltinType()); + + ASSERT_TRUE(Ctx.SveUint8Ty->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveUint16Ty->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveUint32Ty->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveUint64Ty->isSizelessBuiltinType()); + + ASSERT_TRUE(Ctx.SveFloat16Ty->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveFloat32Ty->isSizelessBuiltinType()); + ASSERT_TRUE(Ctx.SveFloat64Ty->isSizelessBuiltinType()); + + ASSERT_TRUE(Ctx.SveBoolTy->isSizelessBuiltinType()); + + ASSERT_FALSE(Ctx.VoidTy->isSizelessBuiltinType()); + ASSERT_FALSE(Ctx.PseudoObjectTy->isSizelessBuiltinType()); + ASSERT_FALSE(FooTy->isSizelessBuiltinType()); + + ASSERT_FALSE(Ctx.getPointerType(Ctx.SveBoolTy)->isSizelessBuiltinType()); + ASSERT_FALSE( + Ctx.getLValueReferenceType(Ctx.SveBoolTy)->isSizelessBuiltinType()); + ASSERT_FALSE( + Ctx.getRValueReferenceType(Ctx.SveBoolTy)->isSizelessBuiltinType()); +} + +TEST_F(SizelessTypeTester, TestSizeless) { + ASSERT_TRUE(Ctx.SveInt8Ty->isSizelessType()); + ASSERT_TRUE(Ctx.SveInt16Ty->isSizelessType()); + ASSERT_TRUE(Ctx.SveInt32Ty->isSizelessType()); + ASSERT_TRUE(Ctx.SveInt64Ty->isSizelessType()); + + ASSERT_TRUE(Ctx.SveUint8Ty->isSizelessType()); + ASSERT_TRUE(Ctx.SveUint16Ty->isSizelessType()); + ASSERT_TRUE(Ctx.SveUint32Ty->isSizelessType()); + ASSERT_TRUE(Ctx.SveUint64Ty->isSizelessType()); + + ASSERT_TRUE(Ctx.SveFloat16Ty->isSizelessType()); + ASSERT_TRUE(Ctx.SveFloat32Ty->isSizelessType()); + ASSERT_TRUE(Ctx.SveFloat64Ty->isSizelessType()); + + ASSERT_TRUE(Ctx.SveBoolTy->isSizelessType()); + + ASSERT_FALSE(Ctx.VoidTy->isSizelessType()); + ASSERT_FALSE(Ctx.PseudoObjectTy->isSizelessType()); + ASSERT_FALSE(FooTy->isSizelessType()); + + ASSERT_FALSE(Ctx.getPointerType(Ctx.SveBoolTy)->isSizelessType()); + ASSERT_FALSE(Ctx.getLValueReferenceType(Ctx.SveBoolTy)->isSizelessType()); + ASSERT_FALSE(Ctx.getRValueReferenceType(Ctx.SveBoolTy)->isSizelessType()); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits