[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