Skip to content

Commit fa80803

Browse files
committed
[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
1 parent 7420f96 commit fa80803

File tree

5 files changed

+110
-0
lines changed

5 files changed

+110
-0
lines changed

clang/include/clang/AST/CanonicalType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ class CanProxyBase {
264264
// Type predicates
265265
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType)
266266
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType)
267+
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessType)
268+
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessBuiltinType)
267269
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType)
268270
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType)
269271
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType)

clang/include/clang/AST/Type.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,6 +1926,15 @@ class alignas(8) Type : public ExtQualsTypeCommonBase {
19261926
/// or QualType::getSingleStepDesugaredType(const ASTContext&).
19271927
QualType getLocallyUnqualifiedSingleStepDesugaredType() const;
19281928

1929+
/// As an extension, we classify types as one of "sized" or "sizeless";
1930+
/// every type is one or the other. Standard types are all sized;
1931+
/// sizeless types are purely an extension.
1932+
///
1933+
/// Sizeless types contain data with no specified size, alignment,
1934+
/// or layout.
1935+
bool isSizelessType() const;
1936+
bool isSizelessBuiltinType() const;
1937+
19291938
/// Types are partitioned into 3 broad categories (C99 6.2.5p1):
19301939
/// object types, function types, and incomplete types.
19311940

clang/lib/AST/Type.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2182,6 +2182,22 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
21822182
}
21832183
}
21842184

2185+
bool Type::isSizelessBuiltinType() const {
2186+
if (const BuiltinType *BT = getAs<BuiltinType>()) {
2187+
switch (BT->getKind()) {
2188+
// SVE Types
2189+
#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
2190+
#include "clang/Basic/AArch64SVEACLETypes.def"
2191+
return true;
2192+
default:
2193+
return false;
2194+
}
2195+
}
2196+
return false;
2197+
}
2198+
2199+
bool Type::isSizelessType() const { return isSizelessBuiltinType(); }
2200+
21852201
bool QualType::isPODType(const ASTContext &Context) const {
21862202
// C++11 has a more relaxed definition of POD.
21872203
if (Context.getLangOpts().CPlusPlus11)

clang/unittests/AST/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ add_clang_unittest(ASTTests
2828
Language.cpp
2929
NamedDeclPrinterTest.cpp
3030
RecursiveASTVisitorTest.cpp
31+
SizelessTypesTest.cpp
3132
SourceLocationTest.cpp
3233
StmtPrinterTest.cpp
3334
StructuralEquivalenceTest.cpp
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//===- unittests/AST/SizelessTypesTest.cpp --- Sizeless type tests --------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains tests for clang::Type queries related to sizeless types.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "clang/AST/ASTContext.h"
14+
#include "clang/AST/Type.h"
15+
#include "clang/Tooling/Tooling.h"
16+
#include "gtest/gtest.h"
17+
18+
using namespace clang;
19+
20+
struct SizelessTypeTester : public ::testing::Test {
21+
// Declare an incomplete structure type.
22+
std::unique_ptr<ASTUnit> AST = tooling::buildASTFromCodeWithArgs(
23+
"struct foo;", {"-target", "aarch64-linux-gnu"});
24+
ASTContext &Ctx = AST->getASTContext();
25+
TranslationUnitDecl &TU = *Ctx.getTranslationUnitDecl();
26+
TypeDecl *Foo = cast<TypeDecl>(TU.lookup(&Ctx.Idents.get("foo")).front());
27+
const Type *FooTy = Foo->getTypeForDecl();
28+
};
29+
30+
TEST_F(SizelessTypeTester, TestSizelessBuiltin) {
31+
ASSERT_TRUE(Ctx.SveInt8Ty->isSizelessBuiltinType());
32+
ASSERT_TRUE(Ctx.SveInt16Ty->isSizelessBuiltinType());
33+
ASSERT_TRUE(Ctx.SveInt32Ty->isSizelessBuiltinType());
34+
ASSERT_TRUE(Ctx.SveInt64Ty->isSizelessBuiltinType());
35+
36+
ASSERT_TRUE(Ctx.SveUint8Ty->isSizelessBuiltinType());
37+
ASSERT_TRUE(Ctx.SveUint16Ty->isSizelessBuiltinType());
38+
ASSERT_TRUE(Ctx.SveUint32Ty->isSizelessBuiltinType());
39+
ASSERT_TRUE(Ctx.SveUint64Ty->isSizelessBuiltinType());
40+
41+
ASSERT_TRUE(Ctx.SveFloat16Ty->isSizelessBuiltinType());
42+
ASSERT_TRUE(Ctx.SveFloat32Ty->isSizelessBuiltinType());
43+
ASSERT_TRUE(Ctx.SveFloat64Ty->isSizelessBuiltinType());
44+
45+
ASSERT_TRUE(Ctx.SveBoolTy->isSizelessBuiltinType());
46+
47+
ASSERT_FALSE(Ctx.VoidTy->isSizelessBuiltinType());
48+
ASSERT_FALSE(Ctx.PseudoObjectTy->isSizelessBuiltinType());
49+
ASSERT_FALSE(FooTy->isSizelessBuiltinType());
50+
51+
ASSERT_FALSE(Ctx.getPointerType(Ctx.SveBoolTy)->isSizelessBuiltinType());
52+
ASSERT_FALSE(
53+
Ctx.getLValueReferenceType(Ctx.SveBoolTy)->isSizelessBuiltinType());
54+
ASSERT_FALSE(
55+
Ctx.getRValueReferenceType(Ctx.SveBoolTy)->isSizelessBuiltinType());
56+
}
57+
58+
TEST_F(SizelessTypeTester, TestSizeless) {
59+
ASSERT_TRUE(Ctx.SveInt8Ty->isSizelessType());
60+
ASSERT_TRUE(Ctx.SveInt16Ty->isSizelessType());
61+
ASSERT_TRUE(Ctx.SveInt32Ty->isSizelessType());
62+
ASSERT_TRUE(Ctx.SveInt64Ty->isSizelessType());
63+
64+
ASSERT_TRUE(Ctx.SveUint8Ty->isSizelessType());
65+
ASSERT_TRUE(Ctx.SveUint16Ty->isSizelessType());
66+
ASSERT_TRUE(Ctx.SveUint32Ty->isSizelessType());
67+
ASSERT_TRUE(Ctx.SveUint64Ty->isSizelessType());
68+
69+
ASSERT_TRUE(Ctx.SveFloat16Ty->isSizelessType());
70+
ASSERT_TRUE(Ctx.SveFloat32Ty->isSizelessType());
71+
ASSERT_TRUE(Ctx.SveFloat64Ty->isSizelessType());
72+
73+
ASSERT_TRUE(Ctx.SveBoolTy->isSizelessType());
74+
75+
ASSERT_FALSE(Ctx.VoidTy->isSizelessType());
76+
ASSERT_FALSE(Ctx.PseudoObjectTy->isSizelessType());
77+
ASSERT_FALSE(FooTy->isSizelessType());
78+
79+
ASSERT_FALSE(Ctx.getPointerType(Ctx.SveBoolTy)->isSizelessType());
80+
ASSERT_FALSE(Ctx.getLValueReferenceType(Ctx.SveBoolTy)->isSizelessType());
81+
ASSERT_FALSE(Ctx.getRValueReferenceType(Ctx.SveBoolTy)->isSizelessType());
82+
}

0 commit comments

Comments
 (0)