"1 byte of precision|with a non power of 2 precision}0">;
// Expressions.
-def select_unary_expr_or_type_trait_kind : TextSubstitution<
- "%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align|"
- "__alignof}0">;
def ext_sizeof_alignof_function_type : Extension<
- "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
- "to a function type">, InGroup<PointerArith>;
+ "invalid application of '%0' to a function type">, InGroup<PointerArith>;
def ext_sizeof_alignof_void_type : Extension<
- "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
- "to a void type">, InGroup<PointerArith>;
+ "invalid application of '%0' to a void type">, InGroup<PointerArith>;
def err_opencl_sizeof_alignof_type : Error<
- "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
- "to a void type">;
+ "invalid application of '%0' to a void type">;
def err_sizeof_alignof_incomplete_or_sizeless_type : Error<
- "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
- "to %select{an incomplete|sizeless}1 type %2">;
+ "invalid application of '%0' to %select{an incomplete|sizeless}1 type %2">;
def err_sizeof_alignof_function_type : Error<
- "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' "
- "to a function type">;
+ "invalid application of '%0' to a function type">;
def err_openmp_default_simd_align_expr : Error<
"invalid application of '__builtin_omp_required_simd_align' to an expression, only type is allowed">;
def err_sizeof_alignof_typeof_bitfield : Error<
#ifndef LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H
#define LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H
+#include "llvm/Support/Compiler.h"
+
namespace clang {
- enum ExpressionTrait {
- ET_IsLValueExpr,
- ET_IsRValueExpr
- };
-}
+enum ExpressionTrait {
+#define EXPRESSION_TRAIT(Spelling, Name, Key) ET_##Name,
+#include "clang/Basic/TokenKinds.def"
+ ET_Last = -1 // ET_Last == last ET_XX in the enum.
+#define EXPRESSION_TRAIT(Spelling, Name, Key) +1
+#include "clang/Basic/TokenKinds.def"
+};
+
+/// Return the internal name of type trait \p T. Never null.
+const char *getTraitName(ExpressionTrait T) LLVM_READONLY;
+
+/// Return the spelling of the type trait \p TT. Never null.
+const char *getTraitSpelling(ExpressionTrait T) LLVM_READONLY;
+
+} // namespace clang
#endif
#ifndef TYPE_TRAIT_N
#define TYPE_TRAIT_N(I,E,K) TYPE_TRAIT(0,I,K)
#endif
+#ifndef ARRAY_TYPE_TRAIT
+#define ARRAY_TYPE_TRAIT(I,E,K) KEYWORD(I,K)
+#endif
+#ifndef UNARY_EXPR_OR_TYPE_TRAIT
+#define UNARY_EXPR_OR_TYPE_TRAIT(I,E,K) KEYWORD(I,K)
+#endif
+#ifndef CXX11_UNARY_EXPR_OR_TYPE_TRAIT
+#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(I,E,K) CXX11_KEYWORD(I,K)
+#endif
+#ifndef EXPRESSION_TRAIT
+#define EXPRESSION_TRAIT(I,E,K) KEYWORD(I,K)
+#endif
#ifndef ALIAS
#define ALIAS(X,Y,Z)
#endif
KEYWORD(return , KEYALL)
KEYWORD(short , KEYALL)
KEYWORD(signed , KEYALL)
-KEYWORD(sizeof , KEYALL)
+UNARY_EXPR_OR_TYPE_TRAIT(sizeof, SizeOf, KEYALL)
KEYWORD(static , KEYALL)
KEYWORD(struct , KEYALL)
KEYWORD(switch , KEYALL)
// C++11 keywords
CXX11_KEYWORD(alignas , 0)
-CXX11_KEYWORD(alignof , 0)
+// alignof and _Alignof return the required ABI alignment
+CXX11_UNARY_EXPR_OR_TYPE_TRAIT(alignof, AlignOf, 0)
CXX11_KEYWORD(char16_t , KEYNOMS18)
CXX11_KEYWORD(char32_t , KEYNOMS18)
CXX11_KEYWORD(constexpr , 0)
KEYWORD(_Decimal64 , KEYALL)
KEYWORD(_Decimal128 , KEYALL)
KEYWORD(__null , KEYCXX)
-KEYWORD(__alignof , KEYALL)
+// __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)
TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX)
// Embarcadero Expression Traits
-KEYWORD(__is_lvalue_expr , KEYCXX)
-KEYWORD(__is_rvalue_expr , KEYCXX)
+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)
// Embarcadero Binary Type Traits
TYPE_TRAIT_2(__is_same, IsSame, KEYCXX)
TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX)
-KEYWORD(__array_rank , KEYCXX)
-KEYWORD(__array_extent , 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)
ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX)
// OpenCL builtins
KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX)
-KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR)
+UNARY_EXPR_OR_TYPE_TRAIT(vec_step, VecStep, KEYOPENCLC | KEYALTIVEC | KEYZVECTOR)
#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX)
#include "clang/Basic/OpenCLImageTypes.def"
KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX)
KEYWORD(addrspace_cast , KEYOPENCLCXX)
// OpenMP Type Traits
-KEYWORD(__builtin_omp_required_simd_align, KEYALL)
+UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL)
// Borland Extensions.
KEYWORD(__pascal , KEYALL)
#undef CXX_KEYWORD_OPERATOR
#undef PPKEYWORD
#undef ALIAS
+#undef EXPRESSION_TRAIT
+#undef CXX11_UNARY_EXPR_OR_TYPE_TRAIT
+#undef UNARY_EXPR_OR_TYPE_TRAIT
+#undef ARRAY_TYPE_TRAIT
#undef TYPE_TRAIT_N
#undef TYPE_TRAIT_2
#undef TYPE_TRAIT_1
#ifndef LLVM_CLANG_BASIC_TYPETRAITS_H
#define LLVM_CLANG_BASIC_TYPETRAITS_H
+#include "llvm/Support/Compiler.h"
+
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"
+};
+
+/// 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"
+};
- /// Names for traits that operate specifically on types.
- enum TypeTrait {
- UTT_HasNothrowAssign,
- UTT_HasNothrowMoveAssign,
- UTT_HasNothrowCopy,
- UTT_HasNothrowConstructor,
- UTT_HasTrivialAssign,
- UTT_HasTrivialMoveAssign,
- UTT_HasTrivialCopy,
- UTT_HasTrivialDefaultConstructor,
- UTT_HasTrivialMoveConstructor,
- UTT_HasTrivialDestructor,
- UTT_HasVirtualDestructor,
- UTT_IsAbstract,
- UTT_IsAggregate,
- UTT_IsArithmetic,
- UTT_IsArray,
- UTT_IsClass,
- UTT_IsCompleteType,
- UTT_IsCompound,
- UTT_IsConst,
- UTT_IsDestructible,
- UTT_IsEmpty,
- UTT_IsEnum,
- UTT_IsFinal,
- UTT_IsFloatingPoint,
- UTT_IsFunction,
- UTT_IsFundamental,
- UTT_IsIntegral,
- UTT_IsInterfaceClass,
- UTT_IsLiteral,
- UTT_IsLvalueReference,
- UTT_IsMemberFunctionPointer,
- UTT_IsMemberObjectPointer,
- UTT_IsMemberPointer,
- UTT_IsNothrowDestructible,
- UTT_IsObject,
- UTT_IsPOD,
- UTT_IsPointer,
- UTT_IsPolymorphic,
- UTT_IsReference,
- UTT_IsRvalueReference,
- UTT_IsScalar,
- UTT_IsSealed,
- UTT_IsSigned,
- UTT_IsStandardLayout,
- UTT_IsTrivial,
- UTT_IsTriviallyCopyable,
- UTT_IsTriviallyDestructible,
- UTT_IsUnion,
- UTT_IsUnsigned,
- UTT_IsVoid,
- UTT_IsVolatile,
- UTT_HasUniqueObjectRepresentations,
- UTT_Last = UTT_HasUniqueObjectRepresentations,
- BTT_IsBaseOf,
- BTT_IsConvertible,
- BTT_IsConvertibleTo,
- BTT_IsSame,
- BTT_TypeCompatible,
- BTT_IsAssignable,
- BTT_IsNothrowAssignable,
- BTT_IsTriviallyAssignable,
- BTT_ReferenceBindsToTemporary,
- BTT_Last = BTT_ReferenceBindsToTemporary,
- TT_IsConstructible,
- TT_IsNothrowConstructible,
- TT_IsTriviallyConstructible
- };
+/// 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"
+};
- /// Names for the array type traits.
- enum ArrayTypeTrait {
- ATT_ArrayRank,
- ATT_ArrayExtent
- };
+/// Return the internal name of type trait \p T. Never null.
+const char *getTraitName(TypeTrait T) LLVM_READONLY;
+const char *getTraitName(ArrayTypeTrait T) LLVM_READONLY;
+const char *getTraitName(UnaryExprOrTypeTrait T) LLVM_READONLY;
- /// Names for the "expression or type" traits.
- enum UnaryExprOrTypeTrait {
- UETT_SizeOf,
- /// Used for C's _Alignof and C++'s alignof.
- /// _Alignof and alignof return the required ABI alignment.
- UETT_AlignOf,
- UETT_VecStep,
- UETT_OpenMPRequiredSimdAlign,
- /// Used for GCC's __alignof.
- /// __alignof returns the preferred alignment of a type, the alignment
- /// clang will attempt to give an object of the type if allowed by ABI.
- UETT_PreferredAlignOf,
- };
-}
+/// Return the spelling of the type trait \p TT. Never null.
+const char *getTraitSpelling(TypeTrait T) LLVM_READONLY;
+const char *getTraitSpelling(ArrayTypeTrait T) LLVM_READONLY;
+const char *getTraitSpelling(UnaryExprOrTypeTrait T) LLVM_READONLY;
+} // namespace clang
#endif
void JSONNodeDumper::VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *TTE) {
- switch (TTE->getKind()) {
- case UETT_SizeOf: JOS.attribute("name", "sizeof"); break;
- case UETT_AlignOf: JOS.attribute("name", "alignof"); break;
- case UETT_VecStep: JOS.attribute("name", "vec_step"); break;
- case UETT_PreferredAlignOf: JOS.attribute("name", "__alignof"); break;
- case UETT_OpenMPRequiredSimdAlign:
- JOS.attribute("name", "__builtin_omp_required_simd_align"); break;
- }
+ JOS.attribute("name", getTraitSpelling(TTE->getKind()));
if (TTE->isArgumentType())
JOS.attribute("argType", createQualType(TTE->getArgumentType()));
}
OS << ")";
}
-void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){
- switch(Node->getKind()) {
- case UETT_SizeOf:
- OS << "sizeof";
- break;
- case UETT_AlignOf:
+void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(
+ UnaryExprOrTypeTraitExpr *Node) {
+ const char *Spelling = getTraitSpelling(Node->getKind());
+ if (Node->getKind() == UETT_AlignOf) {
if (Policy.Alignof)
- OS << "alignof";
+ Spelling = "alignof";
else if (Policy.UnderscoreAlignof)
- OS << "_Alignof";
+ Spelling = "_Alignof";
else
- OS << "__alignof";
- break;
- case UETT_PreferredAlignOf:
- OS << "__alignof";
- break;
- case UETT_VecStep:
- OS << "vec_step";
- break;
- case UETT_OpenMPRequiredSimdAlign:
- OS << "__builtin_omp_required_simd_align";
- break;
+ Spelling = "__alignof";
}
+
+ OS << Spelling;
+
if (Node->isArgumentType()) {
OS << '(';
Node->getArgumentType().print(OS, Policy);
printTemplateArgumentList(OS, Node->template_arguments(), Policy);
}
-static const char *getTypeTraitName(TypeTrait TT) {
- switch (TT) {
-#define TYPE_TRAIT_1(Spelling, Name, Key) \
-case clang::UTT_##Name: return #Spelling;
-#define TYPE_TRAIT_2(Spelling, Name, Key) \
-case clang::BTT_##Name: return #Spelling;
-#define TYPE_TRAIT_N(Spelling, Name, Key) \
- case clang::TT_##Name: return #Spelling;
-#include "clang/Basic/TokenKinds.def"
- }
- llvm_unreachable("Type trait not covered by switch");
-}
-
-static const char *getTypeTraitName(ArrayTypeTrait ATT) {
- switch (ATT) {
- case ATT_ArrayRank: return "__array_rank";
- case ATT_ArrayExtent: return "__array_extent";
- }
- llvm_unreachable("Array type trait not covered by switch");
-}
-
-static const char *getExpressionTraitName(ExpressionTrait ET) {
- switch (ET) {
- case ET_IsLValueExpr: return "__is_lvalue_expr";
- case ET_IsRValueExpr: return "__is_rvalue_expr";
- }
- llvm_unreachable("Expression type trait not covered by switch");
-}
-
void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
- OS << getTypeTraitName(E->getTrait()) << "(";
+ OS << getTraitSpelling(E->getTrait()) << "(";
for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
if (I > 0)
OS << ", ";
}
void StmtPrinter::VisitArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
- OS << getTypeTraitName(E->getTrait()) << '(';
+ OS << getTraitSpelling(E->getTrait()) << '(';
E->getQueriedType().print(OS, Policy);
OS << ')';
}
void StmtPrinter::VisitExpressionTraitExpr(ExpressionTraitExpr *E) {
- OS << getExpressionTraitName(E->getTrait()) << '(';
+ OS << getTraitSpelling(E->getTrait()) << '(';
PrintExpr(E->getQueriedExpression());
OS << ')';
}
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TypeTraits.h"
using namespace clang;
void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr(
const UnaryExprOrTypeTraitExpr *Node) {
- switch (Node->getKind()) {
- case UETT_SizeOf:
- OS << " sizeof";
- break;
- case UETT_AlignOf:
- OS << " alignof";
- break;
- case UETT_VecStep:
- OS << " vec_step";
- break;
- case UETT_OpenMPRequiredSimdAlign:
- OS << " __builtin_omp_required_simd_align";
- break;
- case UETT_PreferredAlignOf:
- OS << " __alignof";
- break;
- }
+ OS << " " << getTraitSpelling(Node->getKind());
+
if (Node->isArgumentType())
dumpType(Node->getArgumentType());
}
clang::ast_matchers::dynamic::internal::ArgTypeTraits<
clang::UnaryExprOrTypeTrait>::getBestGuess(const VariantValue &Value) {
static constexpr llvm::StringRef Allowed[] = {
- "UETT_SizeOf", "UETT_AlignOf",
- "UETT_VecStep", "UETT_OpenMPRequiredSimdAlign",
- "UETT_PreferredAlignOf",
+#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"
};
if (Value.isString())
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed),
private:
static Optional<UnaryExprOrTypeTrait>
getUnaryOrTypeTraitKind(llvm::StringRef ClauseKind) {
- // FIXME: Type traits should probably be in a `.def` to make less error
- // prone.
return llvm::StringSwitch<Optional<UnaryExprOrTypeTrait>>(ClauseKind)
- .Case("UETT_SizeOf", UETT_SizeOf)
- .Case("UETT_AlignOf", UETT_AlignOf)
- .Case("UETT_VecStep", UETT_VecStep)
- .Case("UETT_OpenMPRequiredSimdAlign", UETT_OpenMPRequiredSimdAlign)
- .Case("UETT_PreferredAlignOf", UETT_PreferredAlignOf)
+#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \
+ .Case("UETT_" #Name, UETT_##Name)
+#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) \
+ .Case("UETT_" #Name, UETT_##Name)
+#include "clang/Basic/TokenKinds.def"
.Default(llvm::None);
}
Diagnostic.cpp
DiagnosticIDs.cpp
DiagnosticOptions.cpp
+ ExpressionTraits.cpp
FileManager.cpp
FileSystemStatCache.cpp
FixedPoint.cpp
Targets/X86.cpp
Targets/XCore.cpp
TokenKinds.cpp
+ TypeTraits.cpp
Version.cpp
Warnings.cpp
XRayInstr.cpp
--- /dev/null
+//===--- ExpressionTraits.cpp - Expression Traits Support -----------------===//
+//
+// 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 implements the expression traits support functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/ExpressionTraits.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+using namespace clang;
+
+static constexpr const char *ExpressionTraitNames[] = {
+#define EXPRESSION_TRAIT(Spelling, Name, Key) #Name,
+#include "clang/Basic/TokenKinds.def"
+};
+
+static constexpr const char *ExpressionTraitSpellings[] = {
+#define EXPRESSION_TRAIT(Spelling, Name, Key) #Spelling,
+#include "clang/Basic/TokenKinds.def"
+};
+
+const char *clang::getTraitName(ExpressionTrait T) {
+ assert(T <= ET_Last && "invalid enum value!");
+ return ExpressionTraitNames[T];
+}
+
+const char *clang::getTraitSpelling(ExpressionTrait T) {
+ assert(T <= ET_Last && "invalid enum value!");
+ return ExpressionTraitSpellings[T];
+}
--- /dev/null
+//===--- TypeTraits.cpp - Type Traits Support -----------------------------===//
+//
+// 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 implements the type traits support functions.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/TypeTraits.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <cassert>
+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"
+};
+
+const char *clang::getTraitName(TypeTrait T) {
+ assert(T <= TT_Last && "invalid enum value!");
+ return TypeTraitNames[T];
+}
+
+const char *clang::getTraitName(ArrayTypeTrait T) {
+ assert(T <= ATT_Last && "invalid enum value!");
+ return ArrayTypeTraitNames[T];
+}
+
+const char *clang::getTraitName(UnaryExprOrTypeTrait T) {
+ assert(T <= UETT_Last && "invalid enum value!");
+ return UnaryExprOrTypeTraitNames[T];
+}
+
+const char *clang::getTraitSpelling(TypeTrait T) {
+ assert(T <= TT_Last && "invalid enum value!");
+ return TypeTraitSpellings[T];
+}
+
+const char *clang::getTraitSpelling(ArrayTypeTrait T) {
+ assert(T <= ATT_Last && "invalid enum value!");
+ return ArrayTypeTraitSpellings[T];
+}
+
+const char *clang::getTraitSpelling(UnaryExprOrTypeTrait T) {
+ assert(T <= UETT_Last && "invalid enum value!");
+ return UnaryExprOrTypeTraitSpellings[T];
+}
TraitKind == UETT_PreferredAlignOf)) {
// sizeof(function)/alignof(function) is allowed as an extension.
S.Diag(Loc, diag::ext_sizeof_alignof_function_type)
- << TraitKind << ArgRange;
+ << getTraitSpelling(TraitKind) << ArgRange;
return false;
}
if (T->isVoidType()) {
unsigned DiagID = S.LangOpts.OpenCL ? diag::err_opencl_sizeof_alignof_type
: diag::ext_sizeof_alignof_void_type;
- S.Diag(Loc, DiagID) << TraitKind << ArgRange;
+ S.Diag(Loc, DiagID) << getTraitSpelling(TraitKind) << ArgRange;
return false;
}
if (ExprKind == UETT_AlignOf || ExprKind == UETT_PreferredAlignOf) {
if (RequireCompleteSizedType(
E->getExprLoc(), Context.getBaseElementType(E->getType()),
- diag::err_sizeof_alignof_incomplete_or_sizeless_type, ExprKind,
- E->getSourceRange()))
+ diag::err_sizeof_alignof_incomplete_or_sizeless_type,
+ getTraitSpelling(ExprKind), E->getSourceRange()))
return true;
} else {
if (RequireCompleteSizedExprType(
- E, diag::err_sizeof_alignof_incomplete_or_sizeless_type, ExprKind,
- E->getSourceRange()))
+ E, diag::err_sizeof_alignof_incomplete_or_sizeless_type,
+ getTraitSpelling(ExprKind), E->getSourceRange()))
return true;
}
if (ExprTy->isFunctionType()) {
Diag(E->getExprLoc(), diag::err_sizeof_alignof_function_type)
- << ExprKind << E->getSourceRange();
+ << getTraitSpelling(ExprKind) << E->getSourceRange();
return true;
}
if (RequireCompleteSizedType(
OpLoc, ExprType, diag::err_sizeof_alignof_incomplete_or_sizeless_type,
- ExprKind, ExprRange))
+ getTraitSpelling(ExprKind), ExprRange))
return true;
if (ExprType->isFunctionType()) {
Diag(OpLoc, diag::err_sizeof_alignof_function_type)
- << ExprKind << ExprRange;
+ << getTraitSpelling(ExprKind) << ExprRange;
return true;
}