Skip to content

Commit 78e636b

Browse files
committed
[clang][NFC] Generate the {Type,ArrayType,UnaryExprOrType,Expression}Traits...
...enumerations from TokenKinds.def and use the new macros from TokenKinds.def to remove the hard-coded lists of traits. All the information needed to generate these enumerations is already present in TokenKinds.def. The motivation here is to be able to dump the trait spelling without hard-coding the list in yet another place. Note that this change the order of the enumerators in the enumerations (except that in the TypeTrait enumeration all unary type traits are before all binary type traits, and all binary type traits are before all n-ary type traits). Apart from the aforementioned ordering which is relied upon, after this patch no code in clang or in the various clang tools depend on the specific ordering of the enumerators. No functional changes intended. Differential Revision: https://reviews.llvm.org/D81455 Reviewed By: aaron.ballman
1 parent f45c65a commit 78e636b

File tree

13 files changed

+258
-210
lines changed

13 files changed

+258
-210
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6009,24 +6009,16 @@ def err_atomic_specifier_bad_type
60096009
"1 byte of precision|with a non power of 2 precision}0">;
60106010

60116011
// Expressions.
6012-
def select_unary_expr_or_type_trait_kind : TextSubstitution<
6013-
"%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align|"
6014-
"__alignof}0">;
60156012
def ext_sizeof_alignof_function_type : Extension<
6016-
"invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
6017-
"to a function type">, InGroup<PointerArith>;
6013+
"invalid application of '%0' to a function type">, InGroup<PointerArith>;
60186014
def ext_sizeof_alignof_void_type : Extension<
6019-
"invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
6020-
"to a void type">, InGroup<PointerArith>;
6015+
"invalid application of '%0' to a void type">, InGroup<PointerArith>;
60216016
def err_opencl_sizeof_alignof_type : Error<
6022-
"invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
6023-
"to a void type">;
6017+
"invalid application of '%0' to a void type">;
60246018
def err_sizeof_alignof_incomplete_or_sizeless_type : Error<
6025-
"invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
6026-
"to %select{an incomplete|sizeless}1 type %2">;
6019+
"invalid application of '%0' to %select{an incomplete|sizeless}1 type %2">;
60276020
def err_sizeof_alignof_function_type : Error<
6028-
"invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
6029-
"to a function type">;
6021+
"invalid application of '%0' to a function type">;
60306022
def err_openmp_default_simd_align_expr : Error<
60316023
"invalid application of '__builtin_omp_required_simd_align' to an expression, only type is allowed">;
60326024
def err_sizeof_alignof_typeof_bitfield : Error<

clang/include/clang/Basic/ExpressionTraits.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,24 @@
1414
#ifndef LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H
1515
#define LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H
1616

17+
#include "llvm/Support/Compiler.h"
18+
1719
namespace clang {
1820

19-
enum ExpressionTrait {
20-
ET_IsLValueExpr,
21-
ET_IsRValueExpr
22-
};
23-
}
21+
enum ExpressionTrait {
22+
#define EXPRESSION_TRAIT(Spelling, Name, Key) ET_##Name,
23+
#include "clang/Basic/TokenKinds.def"
24+
ET_Last = -1 // ET_Last == last ET_XX in the enum.
25+
#define EXPRESSION_TRAIT(Spelling, Name, Key) +1
26+
#include "clang/Basic/TokenKinds.def"
27+
};
28+
29+
/// Return the internal name of type trait \p T. Never null.
30+
const char *getTraitName(ExpressionTrait T) LLVM_READONLY;
31+
32+
/// Return the spelling of the type trait \p TT. Never null.
33+
const char *getTraitSpelling(ExpressionTrait T) LLVM_READONLY;
34+
35+
} // namespace clang
2436

2537
#endif

clang/include/clang/Basic/TokenKinds.def

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,18 @@
5050
#ifndef TYPE_TRAIT_N
5151
#define TYPE_TRAIT_N(I,E,K) TYPE_TRAIT(0,I,K)
5252
#endif
53+
#ifndef ARRAY_TYPE_TRAIT
54+
#define ARRAY_TYPE_TRAIT(I,E,K) KEYWORD(I,K)
55+
#endif
56+
#ifndef UNARY_EXPR_OR_TYPE_TRAIT
57+
#define UNARY_EXPR_OR_TYPE_TRAIT(I,E,K) KEYWORD(I,K)
58+
#endif
59+
#ifndef CXX11_UNARY_EXPR_OR_TYPE_TRAIT
60+
#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(I,E,K) CXX11_KEYWORD(I,K)
61+
#endif
62+
#ifndef EXPRESSION_TRAIT
63+
#define EXPRESSION_TRAIT(I,E,K) KEYWORD(I,K)
64+
#endif
5365
#ifndef ALIAS
5466
#define ALIAS(X,Y,Z)
5567
#endif
@@ -292,7 +304,7 @@ KEYWORD(restrict , KEYC99)
292304
KEYWORD(return , KEYALL)
293305
KEYWORD(short , KEYALL)
294306
KEYWORD(signed , KEYALL)
295-
KEYWORD(sizeof , KEYALL)
307+
UNARY_EXPR_OR_TYPE_TRAIT(sizeof, SizeOf, KEYALL)
296308
KEYWORD(static , KEYALL)
297309
KEYWORD(struct , KEYALL)
298310
KEYWORD(switch , KEYALL)
@@ -364,7 +376,8 @@ CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
364376

365377
// C++11 keywords
366378
CXX11_KEYWORD(alignas , 0)
367-
CXX11_KEYWORD(alignof , 0)
379+
// alignof and _Alignof return the required ABI alignment
380+
CXX11_UNARY_EXPR_OR_TYPE_TRAIT(alignof, AlignOf, 0)
368381
CXX11_KEYWORD(char16_t , KEYNOMS18)
369382
CXX11_KEYWORD(char32_t , KEYNOMS18)
370383
CXX11_KEYWORD(constexpr , 0)
@@ -406,7 +419,9 @@ KEYWORD(_Decimal32 , KEYALL)
406419
KEYWORD(_Decimal64 , KEYALL)
407420
KEYWORD(_Decimal128 , KEYALL)
408421
KEYWORD(__null , KEYCXX)
409-
KEYWORD(__alignof , KEYALL)
422+
// __alignof returns the preferred alignment of a type, the alignment
423+
// clang will attempt to give an object of the type if allowed by ABI.
424+
UNARY_EXPR_OR_TYPE_TRAIT(__alignof, PreferredAlignOf, KEYALL)
410425
KEYWORD(__attribute , KEYALL)
411426
KEYWORD(__builtin_choose_expr , KEYALL)
412427
KEYWORD(__builtin_offsetof , KEYALL)
@@ -494,8 +509,8 @@ KEYWORD(__underlying_type , KEYCXX)
494509
TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
495510

496511
// Embarcadero Expression Traits
497-
KEYWORD(__is_lvalue_expr , KEYCXX)
498-
KEYWORD(__is_rvalue_expr , KEYCXX)
512+
EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX)
513+
EXPRESSION_TRAIT(__is_rvalue_expr, IsRValueExpr, KEYCXX)
499514

500515
// Embarcadero Unary Type Traits
501516
TYPE_TRAIT_1(__is_arithmetic, IsArithmetic, KEYCXX)
@@ -524,8 +539,8 @@ TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX)
524539
// Embarcadero Binary Type Traits
525540
TYPE_TRAIT_2(__is_same, IsSame, KEYCXX)
526541
TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX)
527-
KEYWORD(__array_rank , KEYCXX)
528-
KEYWORD(__array_extent , KEYCXX)
542+
ARRAY_TYPE_TRAIT(__array_rank, ArrayRank, KEYCXX)
543+
ARRAY_TYPE_TRAIT(__array_extent, ArrayExtent, KEYCXX)
529544
// Name for GCC 6 compatibility.
530545
ALIAS("__is_same_as", __is_same, KEYCXX)
531546

@@ -571,15 +586,15 @@ ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX)
571586
ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX)
572587
// OpenCL builtins
573588
KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX)
574-
KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR)
589+
UNARY_EXPR_OR_TYPE_TRAIT(vec_step, VecStep, KEYOPENCLC | KEYALTIVEC | KEYZVECTOR)
575590
#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX)
576591
#include "clang/Basic/OpenCLImageTypes.def"
577592
KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX)
578593
// C++ for OpenCL s2.3.1: addrspace_cast operator
579594
KEYWORD(addrspace_cast , KEYOPENCLCXX)
580595

581596
// OpenMP Type Traits
582-
KEYWORD(__builtin_omp_required_simd_align, KEYALL)
597+
UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
583598

584599
// Borland Extensions.
585600
KEYWORD(__pascal , KEYALL)
@@ -871,6 +886,10 @@ ANNOTATION(header_unit)
871886
#undef CXX_KEYWORD_OPERATOR
872887
#undef PPKEYWORD
873888
#undef ALIAS
889+
#undef EXPRESSION_TRAIT
890+
#undef CXX11_UNARY_EXPR_OR_TYPE_TRAIT
891+
#undef UNARY_EXPR_OR_TYPE_TRAIT
892+
#undef ARRAY_TYPE_TRAIT
874893
#undef TYPE_TRAIT_N
875894
#undef TYPE_TRAIT_2
876895
#undef TYPE_TRAIT_1

clang/include/clang/Basic/TypeTraits.h

Lines changed: 50 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -14,97 +14,59 @@
1414
#ifndef LLVM_CLANG_BASIC_TYPETRAITS_H
1515
#define LLVM_CLANG_BASIC_TYPETRAITS_H
1616

17+
#include "llvm/Support/Compiler.h"
18+
1719
namespace clang {
20+
/// Names for traits that operate specifically on types.
21+
enum TypeTrait {
22+
#define TYPE_TRAIT_1(Spelling, Name, Key) UTT_##Name,
23+
#include "clang/Basic/TokenKinds.def"
24+
UTT_Last = -1 // UTT_Last == last UTT_XX in the enum.
25+
#define TYPE_TRAIT_1(Spelling, Name, Key) +1
26+
#include "clang/Basic/TokenKinds.def"
27+
,
28+
#define TYPE_TRAIT_2(Spelling, Name, Key) BTT_##Name,
29+
#include "clang/Basic/TokenKinds.def"
30+
BTT_Last = UTT_Last // BTT_Last == last BTT_XX in the enum.
31+
#define TYPE_TRAIT_2(Spelling, Name, Key) +1
32+
#include "clang/Basic/TokenKinds.def"
33+
,
34+
#define TYPE_TRAIT_N(Spelling, Name, Key) TT_##Name,
35+
#include "clang/Basic/TokenKinds.def"
36+
TT_Last = BTT_Last // TT_Last == last TT_XX in the enum.
37+
#define TYPE_TRAIT_N(Spelling, Name, Key) +1
38+
#include "clang/Basic/TokenKinds.def"
39+
};
40+
41+
/// Names for the array type traits.
42+
enum ArrayTypeTrait {
43+
#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) ATT_##Name,
44+
#include "clang/Basic/TokenKinds.def"
45+
ATT_Last = -1 // ATT_Last == last ATT_XX in the enum.
46+
#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) +1
47+
#include "clang/Basic/TokenKinds.def"
48+
};
1849

19-
/// Names for traits that operate specifically on types.
20-
enum TypeTrait {
21-
UTT_HasNothrowAssign,
22-
UTT_HasNothrowMoveAssign,
23-
UTT_HasNothrowCopy,
24-
UTT_HasNothrowConstructor,
25-
UTT_HasTrivialAssign,
26-
UTT_HasTrivialMoveAssign,
27-
UTT_HasTrivialCopy,
28-
UTT_HasTrivialDefaultConstructor,
29-
UTT_HasTrivialMoveConstructor,
30-
UTT_HasTrivialDestructor,
31-
UTT_HasVirtualDestructor,
32-
UTT_IsAbstract,
33-
UTT_IsAggregate,
34-
UTT_IsArithmetic,
35-
UTT_IsArray,
36-
UTT_IsClass,
37-
UTT_IsCompleteType,
38-
UTT_IsCompound,
39-
UTT_IsConst,
40-
UTT_IsDestructible,
41-
UTT_IsEmpty,
42-
UTT_IsEnum,
43-
UTT_IsFinal,
44-
UTT_IsFloatingPoint,
45-
UTT_IsFunction,
46-
UTT_IsFundamental,
47-
UTT_IsIntegral,
48-
UTT_IsInterfaceClass,
49-
UTT_IsLiteral,
50-
UTT_IsLvalueReference,
51-
UTT_IsMemberFunctionPointer,
52-
UTT_IsMemberObjectPointer,
53-
UTT_IsMemberPointer,
54-
UTT_IsNothrowDestructible,
55-
UTT_IsObject,
56-
UTT_IsPOD,
57-
UTT_IsPointer,
58-
UTT_IsPolymorphic,
59-
UTT_IsReference,
60-
UTT_IsRvalueReference,
61-
UTT_IsScalar,
62-
UTT_IsSealed,
63-
UTT_IsSigned,
64-
UTT_IsStandardLayout,
65-
UTT_IsTrivial,
66-
UTT_IsTriviallyCopyable,
67-
UTT_IsTriviallyDestructible,
68-
UTT_IsUnion,
69-
UTT_IsUnsigned,
70-
UTT_IsVoid,
71-
UTT_IsVolatile,
72-
UTT_HasUniqueObjectRepresentations,
73-
UTT_Last = UTT_HasUniqueObjectRepresentations,
74-
BTT_IsBaseOf,
75-
BTT_IsConvertible,
76-
BTT_IsConvertibleTo,
77-
BTT_IsSame,
78-
BTT_TypeCompatible,
79-
BTT_IsAssignable,
80-
BTT_IsNothrowAssignable,
81-
BTT_IsTriviallyAssignable,
82-
BTT_ReferenceBindsToTemporary,
83-
BTT_Last = BTT_ReferenceBindsToTemporary,
84-
TT_IsConstructible,
85-
TT_IsNothrowConstructible,
86-
TT_IsTriviallyConstructible
87-
};
50+
/// Names for the "expression or type" traits.
51+
enum UnaryExprOrTypeTrait {
52+
#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) UETT_##Name,
53+
#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) UETT_##Name,
54+
#include "clang/Basic/TokenKinds.def"
55+
UETT_Last = -1 // UETT_Last == last UETT_XX in the enum.
56+
#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) +1
57+
#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) +1
58+
#include "clang/Basic/TokenKinds.def"
59+
};
8860

89-
/// Names for the array type traits.
90-
enum ArrayTypeTrait {
91-
ATT_ArrayRank,
92-
ATT_ArrayExtent
93-
};
61+
/// Return the internal name of type trait \p T. Never null.
62+
const char *getTraitName(TypeTrait T) LLVM_READONLY;
63+
const char *getTraitName(ArrayTypeTrait T) LLVM_READONLY;
64+
const char *getTraitName(UnaryExprOrTypeTrait T) LLVM_READONLY;
9465

95-
/// Names for the "expression or type" traits.
96-
enum UnaryExprOrTypeTrait {
97-
UETT_SizeOf,
98-
/// Used for C's _Alignof and C++'s alignof.
99-
/// _Alignof and alignof return the required ABI alignment.
100-
UETT_AlignOf,
101-
UETT_VecStep,
102-
UETT_OpenMPRequiredSimdAlign,
103-
/// Used for GCC's __alignof.
104-
/// __alignof returns the preferred alignment of a type, the alignment
105-
/// clang will attempt to give an object of the type if allowed by ABI.
106-
UETT_PreferredAlignOf,
107-
};
108-
}
66+
/// Return the spelling of the type trait \p TT. Never null.
67+
const char *getTraitSpelling(TypeTrait T) LLVM_READONLY;
68+
const char *getTraitSpelling(ArrayTypeTrait T) LLVM_READONLY;
69+
const char *getTraitSpelling(UnaryExprOrTypeTrait T) LLVM_READONLY;
70+
} // namespace clang
10971

11072
#endif

clang/lib/AST/JSONNodeDumper.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1235,14 +1235,7 @@ void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {
12351235

12361236
void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(
12371237
const UnaryExprOrTypeTraitExpr *TTE) {
1238-
switch (TTE->getKind()) {
1239-
case UETT_SizeOf: JOS.attribute("name", "sizeof"); break;
1240-
case UETT_AlignOf: JOS.attribute("name", "alignof"); break;
1241-
case UETT_VecStep: JOS.attribute("name", "vec_step"); break;
1242-
case UETT_PreferredAlignOf: JOS.attribute("name", "__alignof"); break;
1243-
case UETT_OpenMPRequiredSimdAlign:
1244-
JOS.attribute("name", "__builtin_omp_required_simd_align"); break;
1245-
}
1238+
JOS.attribute("name", getTraitSpelling(TTE->getKind()));
12461239
if (TTE->isArgumentType())
12471240
JOS.attribute("argType", createQualType(TTE->getArgumentType()));
12481241
}

0 commit comments

Comments
 (0)