xref: /llvm-project/clang/lib/Basic/TypeTraits.cpp (revision a9605730a481707623358d3b12220f05cfdc50a8)
178e636b3SBruno Ricci //===--- TypeTraits.cpp - Type Traits Support -----------------------------===//
278e636b3SBruno Ricci //
378e636b3SBruno Ricci // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
478e636b3SBruno Ricci // See https://llvm.org/LICENSE.txt for license information.
578e636b3SBruno Ricci // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
678e636b3SBruno Ricci //
778e636b3SBruno Ricci //===----------------------------------------------------------------------===//
878e636b3SBruno Ricci //
978e636b3SBruno Ricci //  This file implements the type traits support functions.
1078e636b3SBruno Ricci //
1178e636b3SBruno Ricci //===----------------------------------------------------------------------===//
1278e636b3SBruno Ricci 
1378e636b3SBruno Ricci #include "clang/Basic/TypeTraits.h"
1478e636b3SBruno Ricci #include "llvm/Support/ErrorHandling.h"
1578e636b3SBruno Ricci #include <cassert>
16*a9605730SHaojian Wu #include <cstring>
1778e636b3SBruno Ricci using namespace clang;
1878e636b3SBruno Ricci 
1978e636b3SBruno Ricci static constexpr const char *TypeTraitNames[] = {
2078e636b3SBruno Ricci #define TYPE_TRAIT_1(Spelling, Name, Key) #Name,
2178e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
2278e636b3SBruno Ricci #define TYPE_TRAIT_2(Spelling, Name, Key) #Name,
2378e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
2478e636b3SBruno Ricci #define TYPE_TRAIT_N(Spelling, Name, Key) #Name,
2578e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
2678e636b3SBruno Ricci };
2778e636b3SBruno Ricci 
2878e636b3SBruno Ricci static constexpr const char *TypeTraitSpellings[] = {
2978e636b3SBruno Ricci #define TYPE_TRAIT_1(Spelling, Name, Key) #Spelling,
3078e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
3178e636b3SBruno Ricci #define TYPE_TRAIT_2(Spelling, Name, Key) #Spelling,
3278e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
3378e636b3SBruno Ricci #define TYPE_TRAIT_N(Spelling, Name, Key) #Spelling,
3478e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
3578e636b3SBruno Ricci };
3678e636b3SBruno Ricci 
3778e636b3SBruno Ricci static constexpr const char *ArrayTypeTraitNames[] = {
3878e636b3SBruno Ricci #define ARRAY_TYPE_TRAIT(Spelling, Name, Key) #Name,
3978e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
4078e636b3SBruno Ricci };
4178e636b3SBruno Ricci 
4278e636b3SBruno Ricci static constexpr const char *ArrayTypeTraitSpellings[] = {
4378e636b3SBruno Ricci #define ARRAY_TYPE_TRAIT(Spelling, Name, Key) #Spelling,
4478e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
4578e636b3SBruno Ricci };
4678e636b3SBruno Ricci 
4778e636b3SBruno Ricci static constexpr const char *UnaryExprOrTypeTraitNames[] = {
4878e636b3SBruno Ricci #define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Name,
4978e636b3SBruno Ricci #define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Name,
5078e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
5178e636b3SBruno Ricci };
5278e636b3SBruno Ricci 
5378e636b3SBruno Ricci static constexpr const char *UnaryExprOrTypeTraitSpellings[] = {
5478e636b3SBruno Ricci #define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Spelling,
5578e636b3SBruno Ricci #define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) #Spelling,
5678e636b3SBruno Ricci #include "clang/Basic/TokenKinds.def"
5778e636b3SBruno Ricci };
5878e636b3SBruno Ricci 
59e5825190SYingChi Long static constexpr const unsigned TypeTraitArities[] = {
60e5825190SYingChi Long #define TYPE_TRAIT_1(Spelling, Name, Key) 1,
61e5825190SYingChi Long #include "clang/Basic/TokenKinds.def"
62e5825190SYingChi Long #define TYPE_TRAIT_2(Spelling, Name, Key) 2,
63e5825190SYingChi Long #include "clang/Basic/TokenKinds.def"
64e5825190SYingChi Long #define TYPE_TRAIT_N(Spelling, Name, Key) 0,
65e5825190SYingChi Long #include "clang/Basic/TokenKinds.def"
66e5825190SYingChi Long };
67e5825190SYingChi Long 
getTraitName(TypeTrait T)6878e636b3SBruno Ricci const char *clang::getTraitName(TypeTrait T) {
6978e636b3SBruno Ricci   assert(T <= TT_Last && "invalid enum value!");
7078e636b3SBruno Ricci   return TypeTraitNames[T];
7178e636b3SBruno Ricci }
7278e636b3SBruno Ricci 
getTraitName(ArrayTypeTrait T)7378e636b3SBruno Ricci const char *clang::getTraitName(ArrayTypeTrait T) {
7478e636b3SBruno Ricci   assert(T <= ATT_Last && "invalid enum value!");
7578e636b3SBruno Ricci   return ArrayTypeTraitNames[T];
7678e636b3SBruno Ricci }
7778e636b3SBruno Ricci 
getTraitName(UnaryExprOrTypeTrait T)7878e636b3SBruno Ricci const char *clang::getTraitName(UnaryExprOrTypeTrait T) {
7978e636b3SBruno Ricci   assert(T <= UETT_Last && "invalid enum value!");
8078e636b3SBruno Ricci   return UnaryExprOrTypeTraitNames[T];
8178e636b3SBruno Ricci }
8278e636b3SBruno Ricci 
getTraitSpelling(TypeTrait T)8378e636b3SBruno Ricci const char *clang::getTraitSpelling(TypeTrait T) {
8478e636b3SBruno Ricci   assert(T <= TT_Last && "invalid enum value!");
85*a9605730SHaojian Wu   if (T == BTT_IsDeducible) {
86*a9605730SHaojian Wu     // The __is_deducible is an internal-only type trait. To hide it from
87*a9605730SHaojian Wu     // external users, we define it with an empty spelling name, preventing the
88*a9605730SHaojian Wu     // clang parser from recognizing its token kind.
89*a9605730SHaojian Wu     // However, other components such as the AST dump still require the real
90*a9605730SHaojian Wu     // type trait name. Therefore, we return the real name when needed.
91*a9605730SHaojian Wu     assert(std::strlen(TypeTraitSpellings[T]) == 0);
92*a9605730SHaojian Wu     return "__is_deducible";
93*a9605730SHaojian Wu   }
9478e636b3SBruno Ricci   return TypeTraitSpellings[T];
9578e636b3SBruno Ricci }
9678e636b3SBruno Ricci 
getTraitSpelling(ArrayTypeTrait T)9778e636b3SBruno Ricci const char *clang::getTraitSpelling(ArrayTypeTrait T) {
9878e636b3SBruno Ricci   assert(T <= ATT_Last && "invalid enum value!");
9978e636b3SBruno Ricci   return ArrayTypeTraitSpellings[T];
10078e636b3SBruno Ricci }
10178e636b3SBruno Ricci 
getTraitSpelling(UnaryExprOrTypeTrait T)10278e636b3SBruno Ricci const char *clang::getTraitSpelling(UnaryExprOrTypeTrait T) {
10378e636b3SBruno Ricci   assert(T <= UETT_Last && "invalid enum value!");
10478e636b3SBruno Ricci   return UnaryExprOrTypeTraitSpellings[T];
10578e636b3SBruno Ricci }
106e5825190SYingChi Long 
getTypeTraitArity(TypeTrait T)107e5825190SYingChi Long unsigned clang::getTypeTraitArity(TypeTrait T) {
108e5825190SYingChi Long   assert(T <= TT_Last && "invalid enum value!");
109e5825190SYingChi Long   return TypeTraitArities[T];
110e5825190SYingChi Long }
111