This revision was automatically updated to reflect the committed changes.
Closed by commit rG78e636b3f2f0: [clang][NFC] Generate the 
{Type,ArrayType,UnaryExprOrType,Expression}Traits... (authored by riccibruno).

Changed prior to commit:
  https://reviews.llvm.org/D81455?vs=269467&id=270121#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D81455/new/

https://reviews.llvm.org/D81455

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/ExpressionTraits.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Basic/TypeTraits.h
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
  clang/lib/ASTMatchers/Dynamic/Marshallers.h
  clang/lib/Basic/CMakeLists.txt
  clang/lib/Basic/ExpressionTraits.cpp
  clang/lib/Basic/TypeTraits.cpp
  clang/lib/Sema/SemaExpr.cpp

Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -3971,7 +3971,7 @@
        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 @@
   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 @@
   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 @@
 
   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 @@
 
   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;
   }
 
Index: clang/lib/Basic/TypeTraits.cpp
===================================================================
--- /dev/null
+++ clang/lib/Basic/TypeTraits.cpp
@@ -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];
+}
Index: clang/lib/Basic/ExpressionTraits.cpp
===================================================================
--- /dev/null
+++ clang/lib/Basic/ExpressionTraits.cpp
@@ -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];
+}
Index: clang/lib/Basic/CMakeLists.txt
===================================================================
--- clang/lib/Basic/CMakeLists.txt
+++ clang/lib/Basic/CMakeLists.txt
@@ -45,6 +45,7 @@
   Diagnostic.cpp
   DiagnosticIDs.cpp
   DiagnosticOptions.cpp
+  ExpressionTraits.cpp
   FileManager.cpp
   FileSystemStatCache.cpp
   FixedPoint.cpp
@@ -87,6 +88,7 @@
   Targets/X86.cpp
   Targets/XCore.cpp
   TokenKinds.cpp
+  TypeTraits.cpp
   Version.cpp
   Warnings.cpp
   XRayInstr.cpp
Index: clang/lib/ASTMatchers/Dynamic/Marshallers.h
===================================================================
--- clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -219,14 +219,12 @@
 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);
   }
 
Index: clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
===================================================================
--- clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
+++ clang/lib/ASTMatchers/Dynamic/Marshallers.cpp
@@ -101,9 +101,9 @@
 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),
Index: clang/lib/AST/TextNodeDumper.cpp
===================================================================
--- clang/lib/AST/TextNodeDumper.cpp
+++ clang/lib/AST/TextNodeDumper.cpp
@@ -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::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());
 }
Index: clang/lib/AST/StmtPrinter.cpp
===================================================================
--- clang/lib/AST/StmtPrinter.cpp
+++ clang/lib/AST/StmtPrinter.cpp
@@ -1281,29 +1281,20 @@
   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 @@
     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::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 << ')';
 }
Index: clang/lib/AST/JSONNodeDumper.cpp
===================================================================
--- clang/lib/AST/JSONNodeDumper.cpp
+++ clang/lib/AST/JSONNodeDumper.cpp
@@ -1235,14 +1235,7 @@
 
 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()));
 }
Index: clang/include/clang/Basic/TypeTraits.h
===================================================================
--- clang/include/clang/Basic/TypeTraits.h
+++ clang/include/clang/Basic/TypeTraits.h
@@ -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 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
Index: clang/include/clang/Basic/TokenKinds.def
===================================================================
--- clang/include/clang/Basic/TokenKinds.def
+++ clang/include/clang/Basic/TokenKinds.def
@@ -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(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 @@
 
 // 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(_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 @@
 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 @@
 // 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("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(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 @@
 #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
Index: clang/include/clang/Basic/ExpressionTraits.h
===================================================================
--- clang/include/clang/Basic/ExpressionTraits.h
+++ clang/include/clang/Basic/ExpressionTraits.h
@@ -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
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6009,24 +6009,16 @@
             "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<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to