mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-25 13:05:04 +00:00
[clang][NFC] Generate the {Type,ArrayType,UnaryExprOrType,Expression}Traits...
...enumerations from TokenKinds.def and use the new macros from TokenKinds.def to remove the hard-coded lists of traits. All the information needed to generate these enumerations is already present in TokenKinds.def. The motivation here is to be able to dump the trait spelling without hard-coding the list in yet another place. Note that this change the order of the enumerators in the enumerations (except that in the TypeTrait enumeration all unary type traits are before all binary type traits, and all binary type traits are before all n-ary type traits). Apart from the aforementioned ordering which is relied upon, after this patch no code in clang or in the various clang tools depend on the specific ordering of the enumerators. No functional changes intended. Differential Revision: https://reviews.llvm.org/D81455 Reviewed By: aaron.ballman
This commit is contained in:
parent
f45c65aa41
commit
78e636b3f2
@ -6009,24 +6009,16 @@ def err_atomic_specifier_bad_type
|
||||
"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<
|
||||
|
@ -14,12 +14,24 @@
|
||||
#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
|
||||
|
@ -50,6 +50,18 @@
|
||||
#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
|
||||
@ -292,7 +304,7 @@ KEYWORD(restrict , KEYC99)
|
||||
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)
|
||||
@ -364,7 +376,8 @@ CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
|
||||
|
||||
// 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)
|
||||
@ -406,7 +419,9 @@ KEYWORD(_Decimal32 , KEYALL)
|
||||
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)
|
||||
@ -494,8 +509,8 @@ KEYWORD(__underlying_type , KEYCXX)
|
||||
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)
|
||||
@ -524,8 +539,8 @@ 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)
|
||||
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)
|
||||
|
||||
@ -571,7 +586,7 @@ ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX)
|
||||
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)
|
||||
@ -579,7 +594,7 @@ 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)
|
||||
@ -871,6 +886,10 @@ ANNOTATION(header_unit)
|
||||
#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
|
||||
|
@ -14,97 +14,59 @@
|
||||
#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 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 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 the array type traits.
|
||||
enum ArrayTypeTrait {
|
||||
ATT_ArrayRank,
|
||||
ATT_ArrayExtent
|
||||
};
|
||||
/// 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 "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 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;
|
||||
|
||||
/// 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
|
||||
|
@ -1235,14 +1235,7 @@ void JSONNodeDumper::VisitCallExpr(const CallExpr *CE) {
|
||||
|
||||
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()));
|
||||
}
|
||||
|
@ -1281,29 +1281,20 @@ void StmtPrinter::VisitOffsetOfExpr(OffsetOfExpr *Node) {
|
||||
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);
|
||||
@ -2212,37 +2203,8 @@ void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
|
||||
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 << ", ";
|
||||
@ -2252,13 +2214,13 @@ void StmtPrinter::VisitTypeTraitExpr(TypeTraitExpr *E) {
|
||||
}
|
||||
|
||||
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 << ')';
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "clang/Basic/Module.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
#include "clang/Basic/TypeTraits.h"
|
||||
|
||||
using namespace clang;
|
||||
|
||||
@ -833,23 +834,8 @@ void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) {
|
||||
|
||||
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());
|
||||
}
|
||||
|
@ -101,9 +101,9 @@ llvm::Optional<std::string>
|
||||
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),
|
||||
|
@ -219,14 +219,12 @@ template <> struct ArgTypeTraits<UnaryExprOrTypeTrait> {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ add_clang_library(clangBasic
|
||||
Diagnostic.cpp
|
||||
DiagnosticIDs.cpp
|
||||
DiagnosticOptions.cpp
|
||||
ExpressionTraits.cpp
|
||||
FileManager.cpp
|
||||
FileSystemStatCache.cpp
|
||||
FixedPoint.cpp
|
||||
@ -87,6 +88,7 @@ add_clang_library(clangBasic
|
||||
Targets/X86.cpp
|
||||
Targets/XCore.cpp
|
||||
TokenKinds.cpp
|
||||
TypeTraits.cpp
|
||||
Version.cpp
|
||||
Warnings.cpp
|
||||
XRayInstr.cpp
|
||||
|
36
clang/lib/Basic/ExpressionTraits.cpp
Normal file
36
clang/lib/Basic/ExpressionTraits.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
//===--- 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];
|
||||
}
|
86
clang/lib/Basic/TypeTraits.cpp
Normal file
86
clang/lib/Basic/TypeTraits.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
//===--- 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];
|
||||
}
|
@ -3971,7 +3971,7 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType 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;
|
||||
}
|
||||
|
||||
@ -3980,7 +3980,7 @@ static bool CheckExtensionTraitOperandType(Sema &S, QualType T,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -4059,13 +4059,13 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -4075,7 +4075,7 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(Expr *E,
|
||||
|
||||
if (ExprTy->isFunctionType()) {
|
||||
Diag(E->getExprLoc(), diag::err_sizeof_alignof_function_type)
|
||||
<< ExprKind << E->getSourceRange();
|
||||
<< getTraitSpelling(ExprKind) << E->getSourceRange();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4164,12 +4164,12 @@ bool Sema::CheckUnaryExprOrTypeTraitOperand(QualType ExprType,
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user