https://github.com/Tsche updated https://github.com/llvm/llvm-project/pull/201491
>From 906fec10a276bfdfa4de6e123d0d834710f53d6a Mon Sep 17 00:00:00 2001 From: Matthias Wippich <[email protected]> Date: Sun, 19 Jul 2026 01:33:45 +0200 Subject: [PATCH] [clang][NFC] move traits to tablegen --- clang/include/clang/AST/TypeBase.h | 2 +- clang/include/clang/Basic/CMakeLists.txt | 4 + clang/include/clang/Basic/ExpressionTraits.h | 4 +- clang/include/clang/Basic/Specifiers.h | 2 +- clang/include/clang/Basic/TokenKinds.def | 149 +--- clang/include/clang/Basic/Traits.td | 639 ++++++++++++++++++ .../clang/Basic/TransformTypeTraits.def | 29 - clang/include/clang/Basic/TypeTraits.h | 53 +- clang/include/clang/Sema/DeclSpec.h | 4 +- clang/lib/AST/ItaniumMangle.cpp | 2 +- clang/lib/AST/JSONNodeDumper.cpp | 2 +- clang/lib/AST/TextNodeDumper.cpp | 2 +- clang/lib/AST/TypePrinter.cpp | 2 +- clang/lib/ASTMatchers/Dynamic/Marshallers.cpp | 2 +- clang/lib/ASTMatchers/Dynamic/Marshallers.h | 2 +- clang/lib/Basic/ExpressionTraits.cpp | 4 +- clang/lib/Basic/TypeTraits.cpp | 57 +- clang/lib/Format/FormatToken.h | 2 +- clang/lib/Format/TokenAnnotator.cpp | 2 +- clang/lib/Lex/Lexer.cpp | 2 +- clang/lib/Lex/PPMacroExpansion.cpp | 2 +- clang/lib/Parse/ParseDecl.cpp | 2 +- clang/lib/Parse/ParseDeclCXX.cpp | 4 +- clang/lib/Parse/ParseExpr.cpp | 4 +- clang/lib/Parse/ParseExprCXX.cpp | 10 +- clang/lib/Parse/ParseStmt.cpp | 2 +- clang/lib/Parse/ParseTentative.cpp | 6 +- clang/lib/Sema/DeclSpec.cpp | 4 +- clang/lib/Sema/SemaDecl.cpp | 2 +- clang/lib/Sema/SemaTemplateVariadic.cpp | 2 +- clang/lib/Sema/SemaType.cpp | 4 +- clang/lib/Sema/SemaTypeTraits.cpp | 12 +- clang/utils/TableGen/CMakeLists.txt | 1 + clang/utils/TableGen/ClangTraitsEmitter.cpp | 232 +++++++ clang/utils/TableGen/TableGen.cpp | 10 +- clang/utils/TableGen/TableGenBackends.h | 2 + 36 files changed, 955 insertions(+), 309 deletions(-) create mode 100644 clang/include/clang/Basic/Traits.td delete mode 100644 clang/include/clang/Basic/TransformTypeTraits.def create mode 100644 clang/utils/TableGen/ClangTraitsEmitter.cpp diff --git a/clang/include/clang/AST/TypeBase.h b/clang/include/clang/AST/TypeBase.h index c9658775f0470..bd7e415936a74 100644 --- a/clang/include/clang/AST/TypeBase.h +++ b/clang/include/clang/AST/TypeBase.h @@ -6465,7 +6465,7 @@ class UnaryTransformType : public Type, public llvm::FoldingSetNode { public: enum UTTKind { #define TRANSFORM_TYPE_TRAIT_DEF(Enum, _) Enum, -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" }; private: diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index d334c1d41e475..baae7bc0245f5 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -154,6 +154,10 @@ clang_tablegen(BuiltinTemplates.inc -gen-clang-builtin-templates SOURCE BuiltinTemplates.td TARGET ClangBuiltinTemplates) +clang_tablegen(Traits.inc -gen-clang-traits + SOURCE Traits.td + TARGET ClangTraits) + # ARM NEON and MVE clang_tablegen(arm_neon.inc -gen-arm-neon-sema SOURCE arm_neon.td diff --git a/clang/include/clang/Basic/ExpressionTraits.h b/clang/include/clang/Basic/ExpressionTraits.h index b38ebd9ac60b9..48ae69cf1ae17 100644 --- a/clang/include/clang/Basic/ExpressionTraits.h +++ b/clang/include/clang/Basic/ExpressionTraits.h @@ -20,10 +20,10 @@ namespace clang { enum ExpressionTrait { #define EXPRESSION_TRAIT(Spelling, Name, Key) ET_##Name, -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" ET_Last = -1 // ET_Last == last ET_XX in the enum. #define EXPRESSION_TRAIT(Spelling, Name, Key) +1 -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" }; /// Return the internal name of type trait \p T. Never null. diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index 8da6fd4cf454a..6aeca806730b1 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -89,7 +89,7 @@ namespace clang { TST_typeof_unqualExpr, // C23 typeof_unqual(expression) TST_decltype, // C++11 decltype #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait, -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" TST_auto, // C++11 auto TST_decltype_auto, // C++1y decltype(auto) TST_auto_type, // __auto_type extension diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index f07d8ebb75035..3d8d42caa39cf 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -327,8 +327,6 @@ KEYWORD(register , KEYALL) KEYWORD(return , KEYALL) KEYWORD(short , KEYALL) KEYWORD(signed , KEYALL) -UNARY_EXPR_OR_TYPE_TRAIT(sizeof, SizeOf, KEYALL) -UNARY_EXPR_OR_TYPE_TRAIT(__datasizeof, DataSizeOf, KEYCXX) KEYWORD(static , KEYALL) KEYWORD(struct , KEYALL) KEYWORD(switch , KEYALL) @@ -362,9 +360,6 @@ KEYWORD(__ptrauth , KEYALL) KEYWORD(__ob_wrap , KEYALL) KEYWORD(__ob_trap , KEYALL) -// C2y -UNARY_EXPR_OR_TYPE_TRAIT(_Countof, CountOf, KEYNOCXX) - // C++ 2.11p1: Keywords. KEYWORD(asm , KEYCXX|KEYGNU) KEYWORD(bool , BOOLSUPPORT|KEYC23) @@ -417,8 +412,6 @@ C99_KEYWORD(inline , KEYCXX|KEYGNU) // C++11 keywords CXX11_KEYWORD(alignas , KEYC23) -// alignof and _Alignof return the required ABI alignment -CXX11_UNARY_EXPR_OR_TYPE_TRAIT(alignof, AlignOf, KEYC23) CXX11_KEYWORD(char16_t , KEYNOMS18) CXX11_KEYWORD(char32_t , KEYNOMS18) CXX11_KEYWORD(constexpr , KEYC23) @@ -466,9 +459,6 @@ KEYWORD(_Decimal32 , KEYALL) KEYWORD(_Decimal64 , KEYALL) KEYWORD(_Decimal128 , KEYALL) KEYWORD(__null , KEYCXX) -// __alignof returns the preferred alignment of a type, the alignment -// clang will attempt to give an object of the type if allowed by ABI. -UNARY_EXPR_OR_TYPE_TRAIT(__alignof, PreferredAlignOf, KEYALL) KEYWORD(__attribute , KEYALL) KEYWORD(__builtin_choose_expr , KEYALL) KEYWORD(__builtin_offsetof , KEYALL) @@ -480,9 +470,6 @@ KEYWORD(__builtin_LINE , KEYALL) KEYWORD(__builtin_COLUMN , KEYALL) KEYWORD(__builtin_source_location , KEYCXX) -// __builtin_types_compatible_p is a GNU C extension that we handle like a C++ -// type trait. -TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX) KEYWORD(__builtin_va_arg , KEYALL) KEYWORD(__extension__ , KEYALL) KEYWORD(__float128 , KEYALL) @@ -501,131 +488,11 @@ KEYWORD(__FUNCDNAME__ , KEYMS) KEYWORD(__FUNCSIG__ , KEYMS) KEYWORD(L__FUNCTION__ , KEYMS) KEYWORD(L__FUNCSIG__ , KEYMS) -TYPE_TRAIT_1(__is_interface_class, IsInterfaceClass, KEYMS) -TYPE_TRAIT_1(__is_sealed, IsSealed, KEYMS) - -// MSVC12.0 / VS2013 Type Traits -TYPE_TRAIT_1(__is_destructible, IsDestructible, KEYALL) -TYPE_TRAIT_1(__is_trivially_destructible, IsTriviallyDestructible, KEYCXX) -TYPE_TRAIT_1(__is_nothrow_destructible, IsNothrowDestructible, KEYALL) -TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX) -TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX) -TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX) - -// MSVC14.0 / VS2015 Type Traits -TYPE_TRAIT_2(__is_assignable, IsAssignable, KEYCXX) - -// MSVC Type Traits of unknown vintage -TYPE_TRAIT_1(__has_nothrow_move_assign, HasNothrowMoveAssign, KEYCXX) -TYPE_TRAIT_1(__has_trivial_move_assign, HasTrivialMoveAssign, KEYCXX) -TYPE_TRAIT_1(__has_trivial_move_constructor, HasTrivialMoveConstructor, KEYCXX) - -// GNU and MS Type Traits -TYPE_TRAIT_1(__builtin_is_implicit_lifetime, IsImplicitLifetime, KEYCXX) -TYPE_TRAIT_2(__builtin_is_virtual_base_of, IsVirtualBaseOf, KEYCXX) -TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX) -TYPE_TRAIT_1(__has_nothrow_copy, HasNothrowCopy, KEYCXX) -TYPE_TRAIT_1(__has_nothrow_constructor, HasNothrowConstructor, KEYCXX) -TYPE_TRAIT_1(__has_trivial_assign, HasTrivialAssign, KEYCXX) -TYPE_TRAIT_1(__has_trivial_copy, HasTrivialCopy, KEYCXX) -TYPE_TRAIT_1(__has_trivial_constructor, HasTrivialDefaultConstructor, KEYCXX) -TYPE_TRAIT_1(__has_trivial_destructor, HasTrivialDestructor, KEYCXX) -TYPE_TRAIT_1(__has_virtual_destructor, HasVirtualDestructor, KEYCXX) -TYPE_TRAIT_1(__is_abstract, IsAbstract, KEYCXX) -TYPE_TRAIT_1(__is_aggregate, IsAggregate, KEYCXX) -TYPE_TRAIT_2(__is_base_of, IsBaseOf, KEYCXX) -TYPE_TRAIT_1(__is_class, IsClass, KEYCXX) -TYPE_TRAIT_2(__is_convertible_to, IsConvertibleTo, KEYCXX) -TYPE_TRAIT_1(__is_empty, IsEmpty, KEYCXX) -TYPE_TRAIT_1(__is_enum, IsEnum, KEYCXX) -TYPE_TRAIT_1(__is_final, IsFinal, KEYCXX) -TYPE_TRAIT_1(__is_literal, IsLiteral, KEYCXX) -// Name for GCC 4.6 compatibility - people have already written libraries using -// this name unfortunately. -ALIAS("__is_literal_type", __is_literal, KEYCXX) -TYPE_TRAIT_1(__is_pod, IsPOD, KEYCXX) -TYPE_TRAIT_1(__is_polymorphic, IsPolymorphic, KEYCXX) -TYPE_TRAIT_1(__is_standard_layout, IsStandardLayout, KEYCXX) -TYPE_TRAIT_1(__is_trivial, IsTrivial, KEYCXX) -TYPE_TRAIT_2(__is_trivially_assignable, IsTriviallyAssignable, KEYCXX) -TYPE_TRAIT_N(__is_trivially_constructible, IsTriviallyConstructible, KEYCXX) -TYPE_TRAIT_1(__is_trivially_copyable, IsTriviallyCopyable, KEYCXX) -TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX) -TYPE_TRAIT_1(__has_unique_object_representations, - HasUniqueObjectRepresentations, KEYCXX) -TYPE_TRAIT_2(__is_layout_compatible, IsLayoutCompatible, KEYCXX) -TYPE_TRAIT_2(__is_pointer_interconvertible_base_of, IsPointerInterconvertibleBaseOf, KEYCXX) - -#include "clang/Basic/TransformTypeTraits.def" - -// Clang-only C++ Type Traits -TYPE_TRAIT_1(__is_trivially_equality_comparable, IsTriviallyEqualityComparable, KEYCXX) -TYPE_TRAIT_1(__is_bounded_array, IsBoundedArray, KEYCXX) -TYPE_TRAIT_1(__is_unbounded_array, IsUnboundedArray, KEYCXX) -TYPE_TRAIT_1(__is_scoped_enum, IsScopedEnum, KEYCXX) -TYPE_TRAIT_1(__can_pass_in_regs, CanPassInRegs, KEYCXX) -TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) -TYPE_TRAIT_2(__reference_constructs_from_temporary, ReferenceConstructsFromTemporary, KEYCXX) -TYPE_TRAIT_2(__reference_converts_from_temporary, ReferenceConvertsFromTemporary, KEYCXX) -TYPE_TRAIT_2(__builtin_lt_synthesizes_from_spaceship, LtSynthesizesFromSpaceship, KEYCXX) -TYPE_TRAIT_2(__builtin_le_synthesizes_from_spaceship, LeSynthesizesFromSpaceship, KEYCXX) -TYPE_TRAIT_2(__builtin_gt_synthesizes_from_spaceship, GtSynthesizesFromSpaceship, KEYCXX) -TYPE_TRAIT_2(__builtin_ge_synthesizes_from_spaceship, GeSynthesizesFromSpaceship, KEYCXX) -// IsDeducible is only used internally by clang for CTAD implementation and -// is not exposed to users. -TYPE_TRAIT_2(/*EmptySpellingName*/, IsDeducible, KEYCXX) - -// __is_trivially_relocatable is deprecated -TYPE_TRAIT_1(__builtin_is_cpp_trivially_relocatable, IsCppTriviallyRelocatable, KEYCXX) -TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX) -TYPE_TRAIT_1(__is_bitwise_cloneable, IsBitwiseCloneable, KEYALL) -TYPE_TRAIT_1(__builtin_structured_binding_size, StructuredBindingSize, KEYCXX) - - - -// Embarcadero Expression Traits -EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX) -EXPRESSION_TRAIT(__is_rvalue_expr, IsRValueExpr, KEYCXX) - -// Embarcadero Unary Type Traits -TYPE_TRAIT_1(__is_arithmetic, IsArithmetic, KEYCXX) -TYPE_TRAIT_1(__is_floating_point, IsFloatingPoint, KEYCXX) -TYPE_TRAIT_1(__is_integral, IsIntegral, KEYCXX) -TYPE_TRAIT_1(__is_complete_type, IsCompleteType, KEYCXX) -TYPE_TRAIT_1(__is_void, IsVoid, KEYCXX) -TYPE_TRAIT_1(__is_array, IsArray, KEYCXX) -TYPE_TRAIT_1(__is_function, IsFunction, KEYCXX) -TYPE_TRAIT_1(__is_reference, IsReference, KEYCXX) -TYPE_TRAIT_1(__is_lvalue_reference, IsLvalueReference, KEYCXX) -TYPE_TRAIT_1(__is_rvalue_reference, IsRvalueReference, KEYCXX) -TYPE_TRAIT_1(__is_fundamental, IsFundamental, KEYCXX) -TYPE_TRAIT_1(__is_object, IsObject, KEYCXX) -TYPE_TRAIT_1(__is_scalar, IsScalar, KEYCXX) -TYPE_TRAIT_1(__is_compound, IsCompound, KEYCXX) -TYPE_TRAIT_1(__is_pointer, IsPointer, KEYCXX) -TYPE_TRAIT_1(__is_member_object_pointer, IsMemberObjectPointer, KEYCXX) -TYPE_TRAIT_1(__is_member_function_pointer, IsMemberFunctionPointer, KEYCXX) -TYPE_TRAIT_1(__is_member_pointer, IsMemberPointer, KEYCXX) -TYPE_TRAIT_1(__is_const, IsConst, KEYCXX) -TYPE_TRAIT_1(__is_volatile, IsVolatile, KEYCXX) -TYPE_TRAIT_1(__is_signed, IsSigned, KEYCXX) -TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX) - -// Embarcadero Binary Type Traits -TYPE_TRAIT_2(__is_same, IsSame, KEYCXX) -TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX) -TYPE_TRAIT_2(__is_nothrow_convertible, IsNothrowConvertible, KEYCXX) -ARRAY_TYPE_TRAIT(__array_rank, ArrayRank, KEYCXX) -ARRAY_TYPE_TRAIT(__array_extent, ArrayExtent, KEYCXX) -// Name for GCC 6 compatibility. -ALIAS("__is_same_as", __is_same, KEYCXX) // Apple Extension. KEYWORD(__private_extern__ , KEYALL) KEYWORD(__module_private__ , KEYALL) -UNARY_EXPR_OR_TYPE_TRAIT(__builtin_ptrauth_type_discriminator, PtrAuthTypeDiscriminator, KEYALL) - // Extension that will be enabled for Microsoft, Borland and PS4, but can be // disabled via '-fno-declspec'. KEYWORD(__declspec , 0) @@ -664,7 +531,6 @@ ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX) ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX) // OpenCL builtins KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX) -UNARY_EXPR_OR_TYPE_TRAIT(vec_step, VecStep, KEYOPENCLC | KEYOPENCLCXX | KEYALTIVEC | KEYZVECTOR) #define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX) #include "clang/Basic/OpenCLImageTypes.def" KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX) @@ -687,15 +553,6 @@ KEYWORD(column_major , KEYHLSL) #define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) KEYWORD(Name, KEYHLSL) #include "clang/Basic/HLSLIntangibleTypes.def" -// HLSL Type traits -TYPE_TRAIT_2(__builtin_hlsl_is_scalarized_layout_compatible, IsScalarizedLayoutCompatible, KEYHLSL) -TYPE_TRAIT_1(__builtin_hlsl_is_intangible, IsIntangibleType, KEYHLSL) -TYPE_TRAIT_1(__builtin_hlsl_is_typed_resource_element_compatible, IsTypedResourceElementCompatible, KEYHLSL) -TYPE_TRAIT_1(__builtin_hlsl_is_constant_buffer_element_compatible, IsConstantBufferElementCompatible, KEYHLSL) - -// OpenMP Type Traits -UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL) - // Borland Extensions. KEYWORD(__pascal , KEYALL) @@ -724,7 +581,6 @@ KEYWORD(__kindof , KEYOBJC) // Alternate spelling for various tokens. There are GCC extensions in all // languages, but should not be disabled in strict conformance mode. -ALIAS("__alignof__" , __alignof , KEYALL) ALIAS("__asm" , asm , KEYALL) ALIAS("__asm__" , asm , KEYALL) ALIAS("__attribute__" , __attribute , KEYALL) @@ -779,12 +635,10 @@ ALIAS("__int8" , char , KEYMS) ALIAS("__int16" , short , KEYMS) ALIAS("__int32" , int , KEYMS) ALIAS("__wchar_t" , wchar_t , KEYMS) -ALIAS("__builtin_alignof", __alignof , KEYMS) // Microsoft single-underscore prefixed aliases for double-underscore prefixed // keywords. ALIAS("_asm" , asm , KEYMS) -ALIAS("_alignof" , __alignof , KEYMS) ALIAS("_cdecl" , __cdecl , KEYMS | KEYBORLAND) ALIAS("_declspec" , __declspec , KEYMS) ALIAS("_fastcall" , __fastcall , KEYMS | KEYBORLAND) @@ -815,7 +669,6 @@ ALIAS("_pascal" , __pascal , KEYBORLAND) // Clang Extensions. KEYWORD(__builtin_convertvector , KEYALL) -UNARY_EXPR_OR_TYPE_TRAIT(__builtin_vectorelements, VectorElements, KEYALL) ALIAS("__char16_t" , char16_t , KEYCXX) ALIAS("__char32_t" , char32_t , KEYCXX) KEYWORD(__builtin_bit_cast , KEYALL) @@ -1060,6 +913,8 @@ ANNOTATION(repl_input_end) // Annotation for #embed ANNOTATION(embed) +#include "clang/Basic/Traits.inc" + #undef PRAGMA_ANNOTATION #undef ANNOTATION #undef TESTING_KEYWORD diff --git a/clang/include/clang/Basic/Traits.td b/clang/include/clang/Basic/Traits.td new file mode 100644 index 0000000000000..f5546acdb17c4 --- /dev/null +++ b/clang/include/clang/Basic/Traits.td @@ -0,0 +1,639 @@ +//==--- Traits.td - expression and type traits ----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +class TokenKey<int V> { + int Value = V; +} + +def KEYC99 : TokenKey<0x1>; +def KEYCXX : TokenKey<0x2>; +def KEYCXX11 : TokenKey<0x4>; +def KEYGNU : TokenKey<0x8>; +def KEYMS : TokenKey<0x10>; +def BOOLSUPPORT : TokenKey<0x20>; +def KEYALTIVEC : TokenKey<0x40>; +def KEYNOCXX : TokenKey<0x80>; +def KEYBORLAND : TokenKey<0x100>; +def KEYOPENCLC : TokenKey<0x200>; +def KEYC23 : TokenKey<0x400>; +def KEYNOMS18 : TokenKey<0x800>; +def KEYNOOPENCL : TokenKey<0x1000>; +def WCHARSUPPORT : TokenKey<0x2000>; +def HALFSUPPORT : TokenKey<0x4000>; +def CHAR8SUPPORT : TokenKey<0x8000>; +def KEYOBJC : TokenKey<0x10000>; +def KEYZVECTOR : TokenKey<0x20000>; +def KEYCOROUTINES : TokenKey<0x40000>; +def KEYMODULES : TokenKey<0x80000>; +def KEYCXX20 : TokenKey<0x100000>; +def KEYOPENCLCXX : TokenKey<0x200000>; +def KEYMSCOMPAT : TokenKey<0x400000>; +def KEYSYCL : TokenKey<0x800000>; +def KEYCUDA : TokenKey<0x1000000>; +def KEYZOS : TokenKey<0x2000000>; +def KEYNOZOS : TokenKey<0x4000000>; +def KEYHLSL : TokenKey<0x8000000>; +def KEYFIXEDPOINT : TokenKey<0x10000000>; +def KEYDEFERTS : TokenKey<0x20000000>; +def KEYNOHLSL : TokenKey<0x40000000>; + +def KEYMAX : TokenKey<KEYNOHLSL.Value>; +def KEYALLCXX : TokenKey<!or(KEYCXX.Value, KEYCXX11.Value, KEYCXX20.Value)>; +def KEYALL : TokenKey<!and(!or(KEYMAX.Value, !sub(KEYMAX.Value, 1)), + !xor(KEYNOMS18.Value, -1), + !xor(KEYNOOPENCL.Value, -1), + !xor(KEYNOZOS.Value, -1), + !xor(KEYNOHLSL.Value, -1))>; +class Trait<string P> { + string Prefix = P; + string Spelling = ""; + string StdName = ""; + list<TokenKey> KeyFlags = [KEYCXX]; +} +class TypeTrait<string P> : Trait<P>; + +class UnaryTrait : TypeTrait<"UTT">; +class BinaryTrait : TypeTrait<"BTT">; +class VariadicTrait : TypeTrait<"TT">; +class ArrayTrait : Trait<"ATT">; +class ExpressionTrait : Trait<"ET">; +class UnaryExprOrTypeTrait : Trait<"UETT">; +class CXX11UnaryExprOrTypeTrait : Trait<"UETT">; +class TransformTypeTrait : Trait<"TST">; + +class Alias<Trait P> { + Trait Primary = P; + string Spelling = ""; + list<TokenKey> KeyFlags = [KEYCXX]; +} + +// C99 6.4.1: Keywords. These turn into kw_* tokens. +def SizeOf : UnaryExprOrTypeTrait { + let Spelling = "sizeof"; + let KeyFlags = [KEYALL]; +} + +def DataSizeOf : UnaryExprOrTypeTrait { + let Spelling = "__datasizeof"; +} + +// C2y +def CountOf : UnaryExprOrTypeTrait { + let Spelling = "_Countof"; + let KeyFlags = [KEYNOCXX]; +} + +// C++11 keywords +// alignof and _Alignof return the required ABI alignment +def AlignOf : CXX11UnaryExprOrTypeTrait { + let Spelling = "alignof"; + let KeyFlags = [KEYC23]; +} + +// GNU Extensions (in impl-reserved namespace) + +// __alignof returns the preferred alignment of a type, the alignment +// clang will attempt to give an object of the type if allowed by ABI. +def PreferredAlignOf : UnaryExprOrTypeTrait { + let Spelling = "__alignof"; + let KeyFlags = [KEYALL]; +} + +def PreferredAlignOfAlt : Alias<PreferredAlignOf> { + let Spelling = "__alignof__"; + let KeyFlags = [KEYALL]; +} + +def BuiltinAlignOf : Alias<PreferredAlignOf> { + let Spelling = "__builtin_alignof"; + let KeyFlags = [KEYMS]; +} + +def MSAlignOf : Alias<PreferredAlignOf> { + let Spelling = "_alignof"; + let KeyFlags = [KEYMS]; +} + +// __builtin_types_compatible_p is a GNU C extension that we handle like a C++ +// type trait. +def TypeCompatible : BinaryTrait { + let Spelling = "__builtin_types_compatible_p"; + let KeyFlags = [KEYNOCXX]; +} + +// MS Extensions +def IsInterfaceClass : UnaryTrait { + let Spelling = "__is_interface_class"; + let KeyFlags = [KEYMS]; +} + +def IsSealed : UnaryTrait { + let Spelling = "__is_sealed"; + let KeyFlags = [KEYMS]; +} + +// MSVC12.0 / VS2013 Type Traits +def IsDestructible : UnaryTrait { + let Spelling = "__is_destructible"; + let KeyFlags = [KEYALL]; +} + +def IsTriviallyDestructible : UnaryTrait { + let Spelling = "__is_trivially_destructible"; +} + +def IsNothrowDestructible : UnaryTrait { + let Spelling = "__is_nothrow_destructible"; + let KeyFlags = [KEYALL]; +} + +def IsNothrowAssignable : BinaryTrait { + let Spelling = "__is_nothrow_assignable"; +} + +def IsConstructible : VariadicTrait { + let Spelling = "__is_constructible"; + let StdName = "is_constructible"; +} + +def IsNothrowConstructible : VariadicTrait { + let Spelling = "__is_nothrow_constructible"; +} + +// MSVC14.0 / VS2015 Type Traits +def IsAssignable : BinaryTrait { + let Spelling = "__is_assignable"; + let StdName = "is_assignable"; +} + +// MSVC Type Traits of unknown vintage +def HasNothrowMoveAssign : UnaryTrait { + let Spelling = "__has_nothrow_move_assign"; +} + +def HasTrivialMoveAssign : UnaryTrait { + let Spelling = "__has_trivial_move_assign"; +} + +def HasTrivialMoveConstructor : UnaryTrait { + let Spelling = "__has_trivial_move_constructor"; +} + +// GNU and MS Type Traits +def IsImplicitLifetime : UnaryTrait { + let Spelling = "__builtin_is_implicit_lifetime"; +} + +def IsVirtualBaseOf : BinaryTrait { + let Spelling = "__builtin_is_virtual_base_of"; +} + +def HasNothrowAssign : UnaryTrait { + let Spelling = "__has_nothrow_assign"; +} + +def HasNothrowCopy : UnaryTrait { + let Spelling = "__has_nothrow_copy"; +} + +def HasNothrowConstructor : UnaryTrait { + let Spelling = "__has_nothrow_constructor"; +} + +def HasTrivialAssign : UnaryTrait { + let Spelling = "__has_trivial_assign"; +} + +def HasTrivialCopy : UnaryTrait { + let Spelling = "__has_trivial_copy"; +} + +def HasTrivialDefaultConstructor : UnaryTrait { + let Spelling = "__has_trivial_constructor"; +} + +def HasTrivialDestructor : UnaryTrait { + let Spelling = "__has_trivial_destructor"; +} + +def HasVirtualDestructor : UnaryTrait { + let Spelling = "__has_virtual_destructor"; +} + +def IsAbstract : UnaryTrait { + let Spelling = "__is_abstract"; + let StdName = "is_abstract"; +} + +def IsAggregate : UnaryTrait { + let Spelling = "__is_aggregate"; + let StdName = "is_aggregate"; +} + +def IsBaseOf : BinaryTrait { + let Spelling = "__is_base_of"; +} + +def IsClass : UnaryTrait { + let Spelling = "__is_class"; +} + +def IsConvertibleTo : BinaryTrait { + let Spelling = "__is_convertible_to"; +} + +def IsEmpty : UnaryTrait { + let Spelling = "__is_empty"; + let StdName = "is_empty"; +} + +def IsEnum : UnaryTrait { + let Spelling = "__is_enum"; +} + +def IsFinal : UnaryTrait { + let Spelling = "__is_final"; + let StdName = "is_final"; +} + +def IsLiteral : UnaryTrait { + let Spelling = "__is_literal"; +} + +// Name for GCC 4.6 compatibility - people have already written libraries using +// this name unfortunately. +def IsLiteralType : Alias<IsLiteral> { + let Spelling = "__is_literal_type"; +} + +def IsPOD : UnaryTrait { + let Spelling = "__is_pod"; +} + +def IsPolymorphic : UnaryTrait { + let Spelling = "__is_polymorphic"; +} + +def IsStandardLayout : UnaryTrait { + let Spelling = "__is_standard_layout"; + let StdName = "is_standard_layout"; +} + +def IsTrivial : UnaryTrait { + let Spelling = "__is_trivial"; +} + +def IsTriviallyAssignable : BinaryTrait { + let Spelling = "__is_trivially_assignable"; +} + +def IsTriviallyConstructible : VariadicTrait { + let Spelling = "__is_trivially_constructible"; +} + +def IsTriviallyCopyable : UnaryTrait { + let Spelling = "__is_trivially_copyable"; + let StdName = "is_trivially_copyable"; +} + +def IsUnion : UnaryTrait { + let Spelling = "__is_union"; +} + +def HasUniqueObjectRepresentations : UnaryTrait { + let Spelling = "__has_unique_object_representations"; +} + +def IsLayoutCompatible : BinaryTrait { + let Spelling = "__is_layout_compatible"; +} + +def IsPointerInterconvertibleBaseOf : BinaryTrait { + let Spelling = "__is_pointer_interconvertible_base_of"; +} + +def AddLvalueReference : TransformTypeTrait { + let Spelling = "__add_lvalue_reference"; + let StdName = "add_lvalue_reference"; +} + +def AddPointer : TransformTypeTrait { + let Spelling = "__add_pointer"; + let StdName = "add_pointer"; +} + +def AddRvalueReference : TransformTypeTrait { + let Spelling = "__add_rvalue_reference"; + let StdName = "add_rvalue_reference"; +} + +def Decay : TransformTypeTrait { + let Spelling = "__decay"; + let StdName = "decay"; +} + +def MakeSigned : TransformTypeTrait { + let Spelling = "__make_signed"; + let StdName = "make_signed"; +} + +def MakeUnsigned : TransformTypeTrait { + let Spelling = "__make_unsigned"; + let StdName = "make_unsigned"; +} + +def RemoveAllExtents : TransformTypeTrait { + let Spelling = "__remove_all_extents"; + let StdName = "remove_all_extents"; +} + +def RemoveConst : TransformTypeTrait { + let Spelling = "__remove_const"; + let StdName = "remove_const"; +} + +def RemoveCV : TransformTypeTrait { + let Spelling = "__remove_cv"; + let StdName = "remove_cv"; +} + +def RemoveCVRef : TransformTypeTrait { + let Spelling = "__remove_cvref"; + let StdName = "remove_cvref"; +} + +def RemoveExtent : TransformTypeTrait { + let Spelling = "__remove_extent"; + let StdName = "remove_extent"; +} + +def RemovePointer : TransformTypeTrait { + let Spelling = "__remove_pointer"; + let StdName = "remove_pointer"; +} + +def RemoveReference : TransformTypeTrait { + let Spelling = "__remove_reference_t"; + let StdName = "remove_reference_t"; +} + +def RemoveRestrict : TransformTypeTrait { + let Spelling = "__remove_restrict"; + let StdName = "remove_restrict"; +} + +def RemoveVolatile : TransformTypeTrait { + let Spelling = "__remove_volatile"; + let StdName = "remove_volatile"; +} + +def EnumUnderlyingType : TransformTypeTrait { + let Spelling = "__underlying_type"; + let StdName = "underlying_type"; +} + +// Clang-only C++ Type Traits +def IsTriviallyEqualityComparable : UnaryTrait { + let Spelling = "__is_trivially_equality_comparable"; +} + +def IsBoundedArray : UnaryTrait { + let Spelling = "__is_bounded_array"; +} + +def IsUnboundedArray : UnaryTrait { + let Spelling = "__is_unbounded_array"; +} + +def IsScopedEnum : UnaryTrait { + let Spelling = "__is_scoped_enum"; +} + +def CanPassInRegs : UnaryTrait { + let Spelling = "__can_pass_in_regs"; +} + +def ReferenceBindsToTemporary : BinaryTrait { + let Spelling = "__reference_binds_to_temporary"; +} + +def ReferenceConstructsFromTemporary : BinaryTrait { + let Spelling = "__reference_constructs_from_temporary"; +} + +def ReferenceConvertsFromTemporary : BinaryTrait { + let Spelling = "__reference_converts_from_temporary"; +} + +def LtSynthesizesFromSpaceship : BinaryTrait { + let Spelling = "__builtin_lt_synthesizes_from_spaceship"; +} + +def LeSynthesizesFromSpaceship : BinaryTrait { + let Spelling = "__builtin_le_synthesizes_from_spaceship"; +} + +def GtSynthesizesFromSpaceship : BinaryTrait { + let Spelling = "__builtin_gt_synthesizes_from_spaceship"; +} + +def GeSynthesizesFromSpaceship : BinaryTrait { + let Spelling = "__builtin_ge_synthesizes_from_spaceship"; +} + +// IsDeducible is only used internally by clang for CTAD implementation and +// is not exposed to users. +def IsDeducible : BinaryTrait {} + +// __is_trivially_relocatable is deprecated +def IsCppTriviallyRelocatable : UnaryTrait { + let Spelling = "__builtin_is_cpp_trivially_relocatable"; + let StdName = "is_trivially_relocatable"; +} + +def IsTriviallyRelocatable : UnaryTrait { + let Spelling = "__is_trivially_relocatable"; +} + +def IsBitwiseCloneable : UnaryTrait { + let Spelling = "__is_bitwise_cloneable"; + let KeyFlags = [KEYALL]; +} + +def StructuredBindingSize : UnaryTrait { + let Spelling = "__builtin_structured_binding_size"; +} + +// Embarcadero Expression Traits +def IsLValueExpr : ExpressionTrait { + let Spelling = "__is_lvalue_expr"; +} + +def IsRValueExpr : ExpressionTrait { + let Spelling = "__is_rvalue_expr"; +} + +// Embarcadero Unary Type Traits +def IsArithmetic : UnaryTrait { + let Spelling = "__is_arithmetic"; +} + +def IsFloatingPoint : UnaryTrait { + let Spelling = "__is_floating_point"; +} + +def IsIntegral : UnaryTrait { + let Spelling = "__is_integral"; +} + +def IsCompleteType : UnaryTrait { + let Spelling = "__is_complete_type"; +} + +def IsVoid : UnaryTrait { + let Spelling = "__is_void"; +} + +def IsArray : UnaryTrait { + let Spelling = "__is_array"; +} + +def IsFunction : UnaryTrait { + let Spelling = "__is_function"; +} + +def IsReference : UnaryTrait { + let Spelling = "__is_reference"; +} + +def IsLvalueReference : UnaryTrait { + let Spelling = "__is_lvalue_reference"; +} + +def IsRvalueReference : UnaryTrait { + let Spelling = "__is_rvalue_reference"; +} + +def IsFundamental : UnaryTrait { + let Spelling = "__is_fundamental"; +} + +def IsObject : UnaryTrait { + let Spelling = "__is_object"; +} + +def IsScalar : UnaryTrait { + let Spelling = "__is_scalar"; +} + +def IsCompound : UnaryTrait { + let Spelling = "__is_compound"; +} + +def IsPointer : UnaryTrait { + let Spelling = "__is_pointer"; +} + +def IsMemberObjectPointer : UnaryTrait { + let Spelling = "__is_member_object_pointer"; +} + +def IsMemberFunctionPointer : UnaryTrait { + let Spelling = "__is_member_function_pointer"; +} + +def IsMemberPointer : UnaryTrait { + let Spelling = "__is_member_pointer"; +} + +def IsConst : UnaryTrait { + let Spelling = "__is_const"; +} + +def IsVolatile : UnaryTrait { + let Spelling = "__is_volatile"; +} + +def IsSigned : UnaryTrait { + let Spelling = "__is_signed"; +} + +def IsUnsigned : UnaryTrait { + let Spelling = "__is_unsigned"; +} + +// Embarcadero Binary Type Traits +def IsSame : BinaryTrait { + let Spelling = "__is_same"; +} + +// Name for GCC 6 compatibility +def IsSameAs : Alias<IsSame> { + let Spelling = "__is_same_as"; +} + +def IsConvertible : BinaryTrait { + let Spelling = "__is_convertible"; +} + +def IsNothrowConvertible : BinaryTrait { + let Spelling = "__is_nothrow_convertible"; +} + +def ArrayRank : ArrayTrait { + let Spelling = "__array_rank"; +} + +def ArrayExtent : ArrayTrait { + let Spelling = "__array_extent"; +} + +// Apple Extension. +def PtrAuthTypeDiscriminator : UnaryExprOrTypeTrait { + let Spelling = "__builtin_ptrauth_type_discriminator"; + let KeyFlags = [KEYALL]; +} + +// OpenCL builtins +def VecStep : UnaryExprOrTypeTrait { + let Spelling = "vec_step"; + let KeyFlags = [KEYOPENCLC, KEYOPENCLCXX, KEYALTIVEC, KEYZVECTOR]; +} + +// HLSL Type traits +def IsScalarizedLayoutCompatible : BinaryTrait { + let Spelling = "__builtin_hlsl_is_scalarized_layout_compatible"; + let KeyFlags = [KEYHLSL]; +} + +def IsIntangibleType : UnaryTrait { + let Spelling = "__builtin_hlsl_is_intangible"; + let KeyFlags = [KEYHLSL]; +} + +def IsTypedResourceElementCompatible : UnaryTrait { + let Spelling = "__builtin_hlsl_is_typed_resource_element_compatible"; + let KeyFlags = [KEYHLSL]; +} + +def IsConstantBufferElementCompatible : UnaryTrait { + let Spelling = "__builtin_hlsl_is_constant_buffer_element_compatible"; + let KeyFlags = [KEYHLSL]; +} + +// OpenMP Type Traits +def OpenMPRequiredSimdAlign : UnaryExprOrTypeTrait { + let Spelling = "__builtin_omp_required_simd_align"; + let KeyFlags = [KEYALL]; +} + +// Clang Extensions. +def VectorElements : UnaryExprOrTypeTrait { + let Spelling = "__builtin_vectorelements"; + let KeyFlags = [KEYALL]; +} diff --git a/clang/include/clang/Basic/TransformTypeTraits.def b/clang/include/clang/Basic/TransformTypeTraits.def deleted file mode 100644 index e27a2719a9680..0000000000000 --- a/clang/include/clang/Basic/TransformTypeTraits.def +++ /dev/null @@ -1,29 +0,0 @@ -//==--- TransformTypeTraits.def - type trait transformations --------------===// -// -// 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 defines transform type traits' names. -// -//===----------------------------------------------------------------------===// - -TRANSFORM_TYPE_TRAIT_DEF(AddLvalueReference, add_lvalue_reference) -TRANSFORM_TYPE_TRAIT_DEF(AddPointer, add_pointer) -TRANSFORM_TYPE_TRAIT_DEF(AddRvalueReference, add_rvalue_reference) -TRANSFORM_TYPE_TRAIT_DEF(Decay, decay) -TRANSFORM_TYPE_TRAIT_DEF(MakeSigned, make_signed) -TRANSFORM_TYPE_TRAIT_DEF(MakeUnsigned, make_unsigned) -TRANSFORM_TYPE_TRAIT_DEF(RemoveAllExtents, remove_all_extents) -TRANSFORM_TYPE_TRAIT_DEF(RemoveConst, remove_const) -TRANSFORM_TYPE_TRAIT_DEF(RemoveCV, remove_cv) -TRANSFORM_TYPE_TRAIT_DEF(RemoveCVRef, remove_cvref) -TRANSFORM_TYPE_TRAIT_DEF(RemoveExtent, remove_extent) -TRANSFORM_TYPE_TRAIT_DEF(RemovePointer, remove_pointer) -TRANSFORM_TYPE_TRAIT_DEF(RemoveReference, remove_reference_t) -TRANSFORM_TYPE_TRAIT_DEF(RemoveRestrict, remove_restrict) -TRANSFORM_TYPE_TRAIT_DEF(RemoveVolatile, remove_volatile) -TRANSFORM_TYPE_TRAIT_DEF(EnumUnderlyingType, underlying_type) -#undef TRANSFORM_TYPE_TRAIT_DEF diff --git a/clang/include/clang/Basic/TypeTraits.h b/clang/include/clang/Basic/TypeTraits.h index eb8b1923152db..017b8699de89e 100644 --- a/clang/include/clang/Basic/TypeTraits.h +++ b/clang/include/clang/Basic/TypeTraits.h @@ -18,45 +18,28 @@ namespace clang { /// Names for traits that operate specifically on types. -enum TypeTrait { -#define TYPE_TRAIT_1(Spelling, Name, Key) UTT_##Name, -#include "clang/Basic/TokenKinds.def" - UTT_Last = -1 // UTT_Last == last UTT_XX in the enum. -#define TYPE_TRAIT_1(Spelling, Name, Key) +1 -#include "clang/Basic/TokenKinds.def" - , -#define TYPE_TRAIT_2(Spelling, Name, Key) BTT_##Name, -#include "clang/Basic/TokenKinds.def" - BTT_Last = UTT_Last // BTT_Last == last BTT_XX in the enum. -#define TYPE_TRAIT_2(Spelling, Name, Key) +1 -#include "clang/Basic/TokenKinds.def" - , -#define TYPE_TRAIT_N(Spelling, Name, Key) TT_##Name, -#include "clang/Basic/TokenKinds.def" - TT_Last = BTT_Last // TT_Last == last TT_XX in the enum. -#define TYPE_TRAIT_N(Spelling, Name, Key) +1 -#include "clang/Basic/TokenKinds.def" -}; +// enum TypeTrait { +// UTT_ ... +// UTT_Last == last UTT_XX in the enum. +// BTT_ ... +// BTT_Last == last BTT_XX in the enum. +// TT_ ... +// TT_Last == last TT_XX in the enum. +// }; /// Names for the array type traits. -enum ArrayTypeTrait { -#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) ATT_##Name, -#include "clang/Basic/TokenKinds.def" - ATT_Last = -1 // ATT_Last == last ATT_XX in the enum. -#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) +1 -#include "clang/Basic/TokenKinds.def" -}; +// enum ArrayTypeTrait { +// ATT_ ... +// ATT_Last == last ATT_XX in the enum. +// }; /// Names for the "expression or type" traits. -enum UnaryExprOrTypeTrait { -#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) UETT_##Name, -#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) UETT_##Name, -#include "clang/Basic/TokenKinds.def" - UETT_Last = -1 // UETT_Last == last UETT_XX in the enum. -#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) +1 -#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) +1 -#include "clang/Basic/TokenKinds.def" -}; +// enum UnaryExprOrTypeTrait { +// UETT_ ... +// UETT_Last == last UETT_XX in the enum. +// }; +#define EMIT_ENUMS +#include "clang/Basic/Traits.inc" /// Return the internal name of type trait \p T. Never null. const char *getTraitName(TypeTrait T) LLVM_READONLY; diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index d1abc0e3c21fb..f5f26830c6b96 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -287,7 +287,7 @@ class DeclSpec { clang::TST_typename_pack_indexing; #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ static const TST TST_##Trait = clang::TST_##Trait; -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" static const TST TST_auto = clang::TST_auto; static const TST TST_auto_type = clang::TST_auto_type; static const TST TST_unknown_anytype = clang::TST_unknown_anytype; @@ -502,7 +502,7 @@ class DeclSpec { static bool isTransformTypeTrait(TST T) { constexpr std::array<TST, 16> Traits = { #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait, -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" }; return T >= Traits.front() && T <= Traits.back(); diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 172a19f8f3537..eaaa3ce423798 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -4580,7 +4580,7 @@ void CXXNameMangler::mangleType(const UnaryTransformType *T) { case UnaryTransformType::Enum: \ BuiltinName = "__" #Trait; \ break; -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" } mangleVendorType(BuiltinName); } diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index 8373dd8e373e0..428ec70f2f129 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -771,7 +771,7 @@ void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType *UTT) { case UnaryTransformType::Enum: \ JOS.attribute("transformKind", #Trait); \ break; -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" } } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 5d724e9d1d91e..4bc7607a87d92 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -2244,7 +2244,7 @@ void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) { case UnaryTransformType::Enum: \ OS << " " #Trait; \ break; -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" } } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index e8fbffb9f954d..244781c168839 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1395,7 +1395,7 @@ void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T, static const llvm::DenseMap<int, const char *> Transformation = {{ #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \ {UnaryTransformType::Enum, "__" #Trait}, -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" }}; OS << Transformation.lookup(T->getUTTKind()) << '('; print(T->getBaseType(), OS, StringRef()); diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp b/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp index 37c91abb5c839..155bc08e5d45f 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.cpp @@ -102,7 +102,7 @@ clang::ast_matchers::dynamic::internal::ArgTypeTraits< static constexpr llvm::StringRef Allowed[] = { #define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) "UETT_" #Name, #define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) "UETT_" #Name, -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" }; if (Value.isString()) return ::getBestGuess(Value.getString(), llvm::ArrayRef(Allowed), "UETT_"); diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h index 8c0ee465b3eb3..799df88c95827 100644 --- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h @@ -276,7 +276,7 @@ template <> struct ArgTypeTraits<UnaryExprOrTypeTrait> { #define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) .Case(#Name, UETT_##Name) #define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \ .Case(#Name, UETT_##Name) -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" .Default(std::nullopt); } diff --git a/clang/lib/Basic/ExpressionTraits.cpp b/clang/lib/Basic/ExpressionTraits.cpp index 0d642f7149130..67126ff1d8a05 100644 --- a/clang/lib/Basic/ExpressionTraits.cpp +++ b/clang/lib/Basic/ExpressionTraits.cpp @@ -16,12 +16,12 @@ using namespace clang; static constexpr const char *ExpressionTraitNames[] = { #define EXPRESSION_TRAIT(Spelling, Name, Key) #Name, -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" }; static constexpr const char *ExpressionTraitSpellings[] = { #define EXPRESSION_TRAIT(Spelling, Name, Key) #Spelling, -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" }; const char *clang::getTraitName(ExpressionTrait T) { diff --git a/clang/lib/Basic/TypeTraits.cpp b/clang/lib/Basic/TypeTraits.cpp index bd88186bf911c..8307cf9e5afbd 100644 --- a/clang/lib/Basic/TypeTraits.cpp +++ b/clang/lib/Basic/TypeTraits.cpp @@ -15,54 +15,15 @@ #include <cstring> using namespace clang; -static constexpr const char *TypeTraitNames[] = { -#define TYPE_TRAIT_1(Spelling, Name, Key) #Name, -#include "clang/Basic/TokenKinds.def" -#define TYPE_TRAIT_2(Spelling, Name, Key) #Name, -#include "clang/Basic/TokenKinds.def" -#define TYPE_TRAIT_N(Spelling, Name, Key) #Name, -#include "clang/Basic/TokenKinds.def" -}; - -static constexpr const char *TypeTraitSpellings[] = { -#define TYPE_TRAIT_1(Spelling, Name, Key) #Spelling, -#include "clang/Basic/TokenKinds.def" -#define TYPE_TRAIT_2(Spelling, Name, Key) #Spelling, -#include "clang/Basic/TokenKinds.def" -#define TYPE_TRAIT_N(Spelling, Name, Key) #Spelling, -#include "clang/Basic/TokenKinds.def" -}; - -static constexpr const char *ArrayTypeTraitNames[] = { -#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) #Name, -#include "clang/Basic/TokenKinds.def" -}; - -static constexpr const char *ArrayTypeTraitSpellings[] = { -#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) #Spelling, -#include "clang/Basic/TokenKinds.def" -}; - -static constexpr const char *UnaryExprOrTypeTraitNames[] = { -#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Name, -#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Name, -#include "clang/Basic/TokenKinds.def" -}; - -static constexpr const char *UnaryExprOrTypeTraitSpellings[] = { -#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Spelling, -#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Spelling, -#include "clang/Basic/TokenKinds.def" -}; - -static constexpr const unsigned TypeTraitArities[] = { -#define TYPE_TRAIT_1(Spelling, Name, Key) 1, -#include "clang/Basic/TokenKinds.def" -#define TYPE_TRAIT_2(Spelling, Name, Key) 2, -#include "clang/Basic/TokenKinds.def" -#define TYPE_TRAIT_N(Spelling, Name, Key) 0, -#include "clang/Basic/TokenKinds.def" -}; +// static constexpr const char *TypeTraitNames[] = {...}; +// static constexpr const char *TypeTraitSpellings[] = {...}; +// static constexpr const char *ArrayTypeTraitNames[] = {...}; +// static constexpr const char *ArrayTypeTraitSpellings[] = {...}; +// static constexpr const char *UnaryExprOrTypeTraitNames[] = {...}; +// static constexpr const char *UnaryExprOrTypeTraitSpellings[] = {...}; +// static constexpr const unsigned TypeTraitArities[] = {...}; +#define EMIT_ARRAYS +#include "clang/Basic/Traits.inc" const char *clang::getTraitName(TypeTrait T) { assert(T <= TT_Last && "invalid enum value!"); diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 0eeb95950ea2b..5c90a73c45cfc 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -831,7 +831,7 @@ struct FormatToken { tok::kw_decltype, tok::kw_noexcept, tok::kw_static_assert, tok::kw__Atomic, #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait, -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" tok::kw_requires); } diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index b2a858859174b..f82141c687c2b 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -450,7 +450,7 @@ class AnnotatingParser { } else if (PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype, tok::kw_typeof, #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait, -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" tok::kw__Atomic)) { OpeningParen.setType(TT_TypeDeclarationParen); // decltype() and typeof() usually contain expressions. diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index d5085ca6d4c8a..03a3c2b5bf8a1 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -115,7 +115,7 @@ bool Token::isSimpleTypeSpecifier(const LangOptions &LangOpts) const { case tok::kw__Fract: case tok::kw__Sat: #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" case tok::kw___auto_type: case tok::kw_char16_t: case tok::kw_char32_t: diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index e09e80a063c4e..eb8f04c248b79 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1609,7 +1609,7 @@ static bool IsBuiltinTrait(Token &Tok) { switch (Tok.getKind()) { default: return false; -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" } } diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 0825678acaf60..f03b839548208 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -4631,7 +4631,7 @@ void Parser::ParseDeclarationSpecifiers( continue; #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" // HACK: libstdc++ already uses '__remove_cv' as an alias template so we // work around this by expecting all transform type traits to be suffixed // with '('. They're an identifier otherwise. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index d7a9c72eb2da8..150987dae332d 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1241,7 +1241,7 @@ DeclSpec::TST Parser::TypeTransformTokToDeclSpec() { #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ case tok::kw___##Trait: \ return DeclSpec::TST_##Trait; -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" default: llvm_unreachable("passed in an unhandled type transformation built-in"); } @@ -1604,7 +1604,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, !Tok.isAnnotation() && Tok.getIdentifierInfo() && Tok.isOneOf( #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait, -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" tok::kw___is_abstract, tok::kw___is_aggregate, tok::kw___is_arithmetic, diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 74209f579776d..6ca036664094e 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -710,7 +710,7 @@ bool Parser::isRevertibleTypeTrait(const IdentifierInfo *II, REVERTIBLE_TYPE_TRAIT(__reference_binds_to_temporary); #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait)); -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" #undef REVERTIBLE_TYPE_TRAIT #undef RTT_JOIN } @@ -1563,7 +1563,7 @@ Parser::ParseCastExpression(CastParseKind ParseKind, bool isAddressOfOperand, return ExprError(); } #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" // HACK: libstdc++ uses some of the transform-type-traits as alias // templates, so we need to work around this. if (!NextToken().is(tok::l_paren)) { diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index b2b1e74b07133..06ff45da413ca 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -375,7 +375,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier( switch (Tok.getKind()) { #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" if (!NextToken().is(tok::l_paren)) { Tok.setKind(tok::identifier); Diag(Tok, diag::ext_keyword_as_ident) @@ -2881,7 +2881,7 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, switch (Tok.getKind()) { #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" if (!NextToken().is(tok::l_paren)) { Tok.setKind(tok::identifier); Diag(Tok, diag::ext_keyword_as_ident) @@ -3464,7 +3464,7 @@ case tok::kw_ ## Spelling: return BTT_ ## Name; #include "clang/Basic/TokenKinds.def" #define TYPE_TRAIT_N(Spelling, Name, Key) \ case tok::kw_ ## Spelling: return TT_ ## Name; -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" } } @@ -3475,7 +3475,7 @@ static ArrayTypeTrait ArrayTypeTraitFromTokKind(tok::TokenKind kind) { #define ARRAY_TYPE_TRAIT(Spelling, Name, Key) \ case tok::kw_##Spelling: \ return ATT_##Name; -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" } } @@ -3486,7 +3486,7 @@ static ExpressionTrait ExpressionTraitFromTokKind(tok::TokenKind kind) { #define EXPRESSION_TRAIT(Spelling, Name, Key) \ case tok::kw_##Spelling: \ return ET_##Name; -#include "clang/Basic/TokenKinds.def" +#include "clang/Basic/Traits.inc" } } diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 65f63bb5756e1..973dbb803a42e 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -241,7 +241,7 @@ StmtResult Parser::ParseStatementOrDeclarationAfterAttributes( switch (Tok.getKind()) { #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" if (NextToken().is(tok::less)) { Tok.setKind(tok::identifier); Diag(Tok, diag::ext_keyword_as_ident) diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 1477fc38bcc6d..61bcd17c3a0f3 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -174,7 +174,7 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() { case tok::kw_typeof_unqual: case tok::kw___attribute: #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" { ConsumeToken(); if (Tok.isNot(tok::l_paren)) @@ -1550,7 +1550,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename, } #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" return TPResult::True; // C11 _Alignas @@ -1594,7 +1594,7 @@ bool Parser::isCXXDeclarationSpecifierAType() { case tok::kw_typeof: case tok::kw_typeof_unqual: #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" return true; // elaborated-type-specifier diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 4d20657d5e517..ef74cd5e8c8b0 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -365,7 +365,7 @@ bool Declarator::isDeclarationOfFunction() const { return false; #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" case TST_typename: case TST_typeof_unqualType: case TST_typeofType: { @@ -573,7 +573,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ case DeclSpec::TST_##Trait: \ return "__" #Trait; -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; case DeclSpec::TST_atomic: return "_Atomic"; case DeclSpec::TST_BFloat16: return "__bf16"; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9b2efd96cb62d..47f2b9f597c72 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6226,7 +6226,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D, case DeclSpec::TST_typeofType: case DeclSpec::TST_typeof_unqualType: #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case DeclSpec::TST_##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" case DeclSpec::TST_atomic: { // Grab the type from the parser. TypeSourceInfo *TSI = nullptr; diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 19bff5abfbdc7..c26a96eae9f66 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -1145,7 +1145,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { case TST_typeof_unqualType: case TST_typeofType: #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" case TST_atomic: { QualType T = DS.getRepAsType().get(); if (!T.isNull() && T->containsUnexpandedParameterPack()) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 0bfb9be9ec644..f7789b7475e8e 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -887,7 +887,7 @@ TSTToUnaryTransformType(DeclSpec::TST SwitchTST) { #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \ case TST_##Trait: \ return UnaryTransformType::Enum; -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" default: llvm_unreachable("attempted to parse a non-unary transform builtin"); } @@ -1307,7 +1307,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { } #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case DeclSpec::TST_##Trait: -#include "clang/Basic/TransformTypeTraits.def" +#include "clang/Basic/Traits.inc" Result = S.GetTypeFromParser(DS.getRepAsType()); assert(!Result.isNull() && "Didn't get a type for the transformation?"); Result = S.BuildUnaryTransformType( diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp index e3ae6095c846c..fe3d3c5acf7be 100644 --- a/clang/lib/Sema/SemaTypeTraits.cpp +++ b/clang/lib/Sema/SemaTypeTraits.cpp @@ -1954,16 +1954,8 @@ ExprResult Sema::BuildExpressionTrait(ExpressionTrait ET, SourceLocation KWLoc, static std::optional<TypeTrait> StdNameToTypeTrait(StringRef Name) { return llvm::StringSwitch<std::optional<TypeTrait>>(Name) - .Case("is_trivially_relocatable", - TypeTrait::UTT_IsCppTriviallyRelocatable) - .Case("is_trivially_copyable", TypeTrait::UTT_IsTriviallyCopyable) - .Case("is_assignable", TypeTrait::BTT_IsAssignable) - .Case("is_empty", TypeTrait::UTT_IsEmpty) - .Case("is_standard_layout", TypeTrait::UTT_IsStandardLayout) - .Case("is_aggregate", TypeTrait::UTT_IsAggregate) - .Case("is_constructible", TypeTrait::TT_IsConstructible) - .Case("is_final", TypeTrait::UTT_IsFinal) - .Case("is_abstract", TypeTrait::UTT_IsAbstract) +#define EMIT_STD_NAME_CASES +#include "clang/Basic/Traits.inc" .Default(std::nullopt); } diff --git a/clang/utils/TableGen/CMakeLists.txt b/clang/utils/TableGen/CMakeLists.txt index 8b5e00c189cb9..722a14bf609ee 100644 --- a/clang/utils/TableGen/CMakeLists.txt +++ b/clang/utils/TableGen/CMakeLists.txt @@ -21,6 +21,7 @@ add_tablegen(clang-tblgen CLANG ClangSACheckersEmitter.cpp ClangSyntaxEmitter.cpp ClangTypeNodesEmitter.cpp + ClangTraitsEmitter.cpp HLSLEmitter.cpp MveEmitter.cpp NeonEmitter.cpp diff --git a/clang/utils/TableGen/ClangTraitsEmitter.cpp b/clang/utils/TableGen/ClangTraitsEmitter.cpp new file mode 100644 index 0000000000000..6ca0aa313f754 --- /dev/null +++ b/clang/utils/TableGen/ClangTraitsEmitter.cpp @@ -0,0 +1,232 @@ +//==--- Traits.td - Generate expression and type traits -------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "TableGenBackends.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/TableGenBackend.h" + +using namespace llvm; + +namespace { + +std::vector<const Record *> +getAllDerivedDefsInDeclOrder(const RecordKeeper &Records, StringRef ClassName) { + std::vector<const Record *> Defs = + Records.getAllDerivedDefinitions(ClassName); + llvm::sort(Defs, [](const Record *A, const Record *B) { + return A->getID() < B->getID(); + }); + return Defs; +} + +void emitKeyFlags(ArrayRef<const Record *> KeyFlags, raw_ostream &OS) { + assert(!KeyFlags.empty() && "KeyFlags should never be empty"); + interleave( + KeyFlags, OS, [&](const Record *KeyFlag) { OS << KeyFlag->getName(); }, + " | "); +} + +StringRef recordKindToMacro(const Record *R) { + auto const Macro = + StringSwitch<StringRef>(R->getType()->getAsString()) + .Case("UnaryTrait", "TYPE_TRAIT_1") + .Case("BinaryTrait", "TYPE_TRAIT_2") + .Case("VariadicTrait", "TYPE_TRAIT_N") + .Case("ArrayTrait", "ARRAY_TYPE_TRAIT") + .Case("ExpressionTrait", "EXPRESSION_TRAIT") + .Case("UnaryExprOrTypeTrait", "UNARY_EXPR_OR_TYPE_TRAIT") + .Case("CXX11UnaryExprOrTypeTrait", "CXX11_UNARY_EXPR_OR_TYPE_TRAIT") + .Case("TransformTypeTrait", "TRANSFORM_TYPE_TRAIT_DEF") + .Case("Alias", "ALIAS") + .Default(""); + assert(!Macro.empty() && "unexpected record class"); + return Macro; +} + +void emitMacro(const Record *R, raw_ostream &OS) { + OS << recordKindToMacro(R) << "("; + if (R->isSubClassOf("TransformTypeTrait")) { + const StringRef StdName = R->getValueAsString("StdName"); + OS << R->getName() << ", " << StdName; + } else if (R->isSubClassOf("Alias")) { + const Record *Primary = R->getValueAsDef("Primary"); + OS << "\"" << R->getValueAsString("Spelling") << "\", " + << Primary->getValueAsString("Spelling") << ", "; + emitKeyFlags(R->getValueAsListOfDefs("KeyFlags"), OS); + } else { + OS << R->getValueAsString("Spelling") << ", " << R->getName() << ", "; + emitKeyFlags(R->getValueAsListOfDefs("KeyFlags"), OS); + } + OS << ")\n"; +} + +void emitMacroDefs(const RecordKeeper &Records, raw_ostream &OS) { + constexpr std::pair<StringRef, StringRef> MacroDefs[] = { + {"TYPE_TRAIT_1", "(I,E,K)"}, + {"TYPE_TRAIT_2", "(I,E,K)"}, + {"TYPE_TRAIT_N", "(I,E,K)"}, + {"ARRAY_TYPE_TRAIT", "(I,E,K)"}, + {"UNARY_EXPR_OR_TYPE_TRAIT", "(I,E,K)"}, + {"CXX11_UNARY_EXPR_OR_TYPE_TRAIT", "(I,E,K)"}, + {"EXPRESSION_TRAIT", "(I,E,K)"}, + {"TRANSFORM_TYPE_TRAIT_DEF", "(K, Trait)"}, + {"ALIAS", "(X,Y,Z)"}}; + + for (const auto &[MacroName, MacroArgs] : MacroDefs) { + OS << "#ifndef " << MacroName << "\n" + << "#define " << MacroName << MacroArgs << "\n" + << "#endif\n"; + } + + OS << '\n'; + + const auto Traits = getAllDerivedDefsInDeclOrder(Records, "Trait"); + const auto Aliases = getAllDerivedDefsInDeclOrder(Records, "Alias"); + for (const Record *R : concat<const Record *const>(Traits, Aliases)) + emitMacro(R, OS); + + for (const auto &[MacroName, _] : reverse(MacroDefs)) + OS << "#undef " << MacroName << "\n"; +} + +template <typename RangeT> +void emitEnumerators(raw_ostream &OS, RangeT &&Range) { + for (const Record *R : Range) + OS << " " << R->getValueAsString("Prefix") << '_' << R->getName() << ",\n"; +} + +void emitEnums(const RecordKeeper &Records, raw_ostream &OS) { + const auto UnaryTraits = getAllDerivedDefsInDeclOrder(Records, "UnaryTrait"); + const auto BinaryTraits = + getAllDerivedDefsInDeclOrder(Records, "BinaryTrait"); + const auto VariadicTraits = + getAllDerivedDefsInDeclOrder(Records, "VariadicTrait"); + + OS << "/// Names for traits that operate specifically on types.\n" + "enum TypeTrait {\n"; + emitEnumerators(OS, UnaryTraits); + OS << " UTT_Last = " << UnaryTraits.size() - 1 + << ", // UTT_Last == last UTT_XX in the enum.\n"; + + emitEnumerators(OS, BinaryTraits); + OS << " BTT_Last = " << UnaryTraits.size() + BinaryTraits.size() - 1 + << ", // BTT_Last == last BTT_XX in the enum.\n"; + + emitEnumerators(OS, VariadicTraits); + OS << " TT_Last = " + << UnaryTraits.size() + BinaryTraits.size() + VariadicTraits.size() - 1 + << " // TT_Last == last TT_XX in the enum.\n" + << "};\n\n"; + + const auto ArrayTraits = getAllDerivedDefsInDeclOrder(Records, "ArrayTrait"); + OS << "/// Names for the array type traits.\n" + "enum ArrayTypeTrait {\n"; + emitEnumerators(OS, ArrayTraits); + OS << " ATT_Last = " << ArrayTraits.size() - 1 + << " // ATT_Last == last ATT\n" + << "};\n\n"; + + const auto UETTs = + getAllDerivedDefsInDeclOrder(Records, "UnaryExprOrTypeTrait"); + const auto CXX11UETTs = + getAllDerivedDefsInDeclOrder(Records, "CXX11UnaryExprOrTypeTrait"); + OS << "/// Names for the \"expression or type\" traits.\n" + "enum UnaryExprOrTypeTrait {\n"; + emitEnumerators(OS, concat<const Record *const>(UETTs, CXX11UETTs)); + OS << " UETT_Last = " << UETTs.size() + CXX11UETTs.size() - 1 + << " // UETT_Last == last UETT_XX in the enum.\n" + << "};\n\n"; +} + +template <typename RangeT> +void emitNamesAndSpellings(raw_ostream &OS, StringRef Name, RangeT Range) { + OS << "static constexpr const char *" << Name << "Names[] = {\n"; + for (const Record *R : Range) { + OS << " \"" << R->getName() << "\",\n"; + } + OS << "};\n\n"; + + OS << "static constexpr const char *" << Name << "Spellings[] = {\n"; + for (const Record *R : Range) { + OS << " \"" << R->getValueAsString("Spelling") << "\",\n"; + } + OS << "};\n\n"; +} + +void emitArrays(const RecordKeeper &Records, raw_ostream &OS) { + const auto UnaryTraits = getAllDerivedDefsInDeclOrder(Records, "UnaryTrait"); + const auto BinaryTraits = + getAllDerivedDefsInDeclOrder(Records, "BinaryTrait"); + const auto VariadicTraits = + getAllDerivedDefsInDeclOrder(Records, "VariadicTrait"); + + emitNamesAndSpellings( + OS, "TypeTrait", + concat<const Record *const>(UnaryTraits, BinaryTraits, VariadicTraits)); + + OS << "static constexpr const unsigned TypeTraitArities[] = {\n"; + interleaveComma(UnaryTraits, OS, [&](auto) { OS << '1'; }); + if (!UnaryTraits.empty()) + OS << ",\n"; + interleaveComma(BinaryTraits, OS, [&](auto) { OS << '2'; }); + if (!BinaryTraits.empty()) + OS << ",\n"; + interleaveComma(VariadicTraits, OS, [&](auto) { OS << '0'; }); + OS << "\n};\n\n"; + + emitNamesAndSpellings(OS, "ArrayTypeTrait", + getAllDerivedDefsInDeclOrder(Records, "ArrayTrait")); + emitNamesAndSpellings( + OS, "UnaryExprOrTypeTrait", + concat<const Record *const>( + getAllDerivedDefsInDeclOrder(Records, "UnaryExprOrTypeTrait"), + getAllDerivedDefsInDeclOrder(Records, "CXX11UnaryExprOrTypeTrait"))); +} + +void emitStdNameCases(const RecordKeeper &Records, raw_ostream &OS) { + for (const Record *R : getAllDerivedDefsInDeclOrder(Records, "TypeTrait")) { + const StringRef StdName = R->getValueAsString("StdName"); + if (StdName.empty()) + continue; + + OS << " .Case(\"" << StdName + << "\", TypeTrait::" << R->getValueAsString("Prefix") << '_' + << R->getName() << ")\n"; + } +} + +} // namespace + +void clang::EmitClangTraits(const RecordKeeper &Records, raw_ostream &OS) { + emitSourceFileHeader("Type and expression traits", OS, Records); + OS << "#if defined(EMIT_ENUMS)\n"; + emitEnums(Records, OS); + + OS << "#elif defined(EMIT_ARRAYS)\n"; + emitArrays(Records, OS); + + OS << "#elif defined(EMIT_STD_NAME_CASES)\n"; + emitStdNameCases(Records, OS); + + OS << "#else\n"; + emitMacroDefs(Records, OS); + + OS << "#endif\n\n" + << R"( +#undef EMIT_ARRAYS +#undef EMIT_ENUMS +#undef EMIT_STD_NAME_CASES + +)"; +} diff --git a/clang/utils/TableGen/TableGen.cpp b/clang/utils/TableGen/TableGen.cpp index cc02b08167894..5ea37d8e160ca 100644 --- a/clang/utils/TableGen/TableGen.cpp +++ b/clang/utils/TableGen/TableGen.cpp @@ -126,7 +126,8 @@ enum ActionType { GenDiagDocs, GenOptDocs, GenDataCollectors, - GenTestPragmaAttributeSupportedAttributes + GenTestPragmaAttributeSupportedAttributes, + GenClangTraits }; namespace { @@ -370,7 +371,9 @@ cl::opt<ActionType> Action( clEnumValN(GenTestPragmaAttributeSupportedAttributes, "gen-clang-test-pragma-attribute-supported-attributes", "Generate a list of attributes supported by #pragma clang " - "attribute for testing purposes"))); + "attribute for testing purposes"), + clEnumValN(GenClangTraits, "gen-clang-traits", + "Generate Traits.inc for clang"))); cl::opt<std::string> ClangComponent("clang-component", @@ -693,6 +696,9 @@ bool ClangTableGenMain(raw_ostream &OS, const RecordKeeper &Records) { case GenTestPragmaAttributeSupportedAttributes: EmitTestPragmaAttributeSupportedAttributes(Records, OS); break; + case GenClangTraits: + EmitClangTraits(Records, OS); + break; } return false; diff --git a/clang/utils/TableGen/TableGenBackends.h b/clang/utils/TableGen/TableGenBackends.h index 87a6ddda2271d..fc71e112f86e7 100644 --- a/clang/utils/TableGen/TableGenBackends.h +++ b/clang/utils/TableGen/TableGenBackends.h @@ -217,6 +217,8 @@ void EmitClangDataCollectors(const llvm::RecordKeeper &Records, void EmitTestPragmaAttributeSupportedAttributes( const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); +void EmitClangTraits(const llvm::RecordKeeper &Records, llvm::raw_ostream &OS); + } // end namespace clang #endif _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
