[clang] fa80803 - [AST][SVE] Add new Type queries for sizeless types
Richard Sandiford via cfe-commits
cfe-commits at lists.llvm.org
Thu Mar 12 09:33:29 PDT 2020
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());
+}
More information about the cfe-commits
mailing list