aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2022-08-14 15:57:38 -0400
committerNico Weber <thakis@chromium.org>2022-08-14 15:58:21 -0400
commitaacf1a9742f714dd432117d82d19a007289c3dee (patch)
treeb41c0f61e159b81a13659a8759223fcdddb04d5d /clang/lib
parenta8c294d6aae340afba9347ef3d41fbb7a9ab51be (diff)
downloadllvm-aacf1a9742f714dd432117d82d19a007289c3dee.zip
llvm-aacf1a9742f714dd432117d82d19a007289c3dee.tar.gz
llvm-aacf1a9742f714dd432117d82d19a007289c3dee.tar.bz2
Revert "[clang] adds unary type transformations as compiler built-ins"
This reverts commit bc60cf2368de90918719dc7e3d7c63a72cc007ad. Doesn't build on Windows and breaks gcc 9 build, see https://reviews.llvm.org/D116203#3722094 and https://reviews.llvm.org/D116203#3722128 Also revert two follow-ups. One fixed a warning added in bc60cf2368de90918719dc7e3d7c63a72cc007ad, the other makes use of the feature added in bc60cf2368de90918719dc7e3d7c63a72cc007ad in libc++: Revert "[libcxx][NFC] utilises compiler builtins for unary transform type-traits" This reverts commit 06a1d917ef1f507aaa2f6891bb654696c866ea3a. Revert "[Sema] Fix a warning" This reverts commit c85abbe879ef3257de4db862ce249b060cc3d2a4.
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp27
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp14
-rw-r--r--clang/lib/AST/JSONNodeDumper.cpp7
-rw-r--r--clang/lib/AST/TextNodeDumper.cpp6
-rw-r--r--clang/lib/AST/TypePrinter.cpp32
-rw-r--r--clang/lib/Format/FormatToken.cpp3
-rw-r--r--clang/lib/Format/FormatToken.h3
-rw-r--r--clang/lib/Format/TokenAnnotator.cpp6
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp3
-rw-r--r--clang/lib/Parse/ParseDecl.cpp18
-rw-r--r--clang/lib/Parse/ParseDeclCXX.cpp116
-rw-r--r--clang/lib/Parse/ParseExpr.cpp22
-rw-r--r--clang/lib/Parse/ParseExprCXX.cpp20
-rw-r--r--clang/lib/Parse/ParseStmt.cpp18
-rw-r--r--clang/lib/Parse/ParseTentative.cpp11
-rw-r--r--clang/lib/Sema/DeclSpec.cpp9
-rw-r--r--clang/lib/Sema/SemaDecl.cpp6
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp3
-rw-r--r--clang/lib/Sema/SemaType.cpp303
19 files changed, 134 insertions, 493 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 45ec85f..2c2f466 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -10782,8 +10782,7 @@ unsigned ASTContext::getIntWidth(QualType T) const {
}
QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
- assert((T->hasIntegerRepresentation() || T->isEnumeralType() ||
- T->isFixedPointType()) &&
+ assert((T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) &&
"Unexpected type");
// Turn <4 x signed int> -> <4 x unsigned int>
@@ -10801,11 +10800,8 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
T = ETy->getDecl()->getIntegerType();
switch (T->castAs<BuiltinType>()->getKind()) {
- case BuiltinType::Char_U:
- // Plain `char` is mapped to `unsigned char` even if it's already unsigned
case BuiltinType::Char_S:
case BuiltinType::SChar:
- case BuiltinType::Char8:
return UnsignedCharTy;
case BuiltinType::Short:
return UnsignedShortTy;
@@ -10819,7 +10815,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
return UnsignedInt128Ty;
// wchar_t is special. It is either signed or not, but when it's signed,
// there's no matching "unsigned wchar_t". Therefore we return the unsigned
- // version of its underlying type instead.
+ // version of it's underlying type instead.
case BuiltinType::WChar_S:
return getUnsignedWCharType();
@@ -10848,16 +10844,13 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
case BuiltinType::SatLongFract:
return SatUnsignedLongFractTy;
default:
- assert((T->hasUnsignedIntegerRepresentation() ||
- T->isUnsignedFixedPointType()) &&
- "Unexpected signed integer or fixed point type");
- return T;
+ llvm_unreachable("Unexpected signed integer or fixed point type");
}
}
QualType ASTContext::getCorrespondingSignedType(QualType T) const {
- assert((T->hasIntegerRepresentation() || T->isEnumeralType() ||
- T->isFixedPointType()) &&
+ assert((T->hasUnsignedIntegerRepresentation() ||
+ T->isUnsignedFixedPointType()) &&
"Unexpected type");
// Turn <4 x unsigned int> -> <4 x signed int>
@@ -10875,11 +10868,8 @@ QualType ASTContext::getCorrespondingSignedType(QualType T) const {
T = ETy->getDecl()->getIntegerType();
switch (T->castAs<BuiltinType>()->getKind()) {
- case BuiltinType::Char_S:
- // Plain `char` is mapped to `signed char` even if it's already signed
case BuiltinType::Char_U:
case BuiltinType::UChar:
- case BuiltinType::Char8:
return SignedCharTy;
case BuiltinType::UShort:
return ShortTy;
@@ -10893,7 +10883,7 @@ QualType ASTContext::getCorrespondingSignedType(QualType T) const {
return Int128Ty;
// wchar_t is special. It is either unsigned or not, but when it's unsigned,
// there's no matching "signed wchar_t". Therefore we return the signed
- // version of its underlying type instead.
+ // version of it's underlying type instead.
case BuiltinType::WChar_U:
return getSignedWCharType();
@@ -10922,10 +10912,7 @@ QualType ASTContext::getCorrespondingSignedType(QualType T) const {
case BuiltinType::SatULongFract:
return SatLongFractTy;
default:
- assert(
- (T->hasSignedIntegerRepresentation() || T->isSignedFixedPointType()) &&
- "Unexpected signed integer or fixed point type");
- return T;
+ llvm_unreachable("Unexpected unsigned integer or fixed point type");
}
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 46229a0..fc5a590 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3980,22 +3980,16 @@ void CXXNameMangler::mangleType(const UnaryTransformType *T) {
// If this is dependent, we need to record that. If not, we simply
// mangle it as the underlying type since they are equivalent.
if (T->isDependentType()) {
- Out << "u";
+ Out << 'U';
- StringRef BuiltinName;
switch (T->getUTTKind()) {
-#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
- case UnaryTransformType::Enum: \
- BuiltinName = "__" #Trait; \
- break;
-#include "clang/Basic/TransformTypeTraits.def"
+ case UnaryTransformType::EnumUnderlyingType:
+ Out << "3eut";
+ break;
}
- Out << BuiltinName.size() << BuiltinName;
}
- Out << "I";
mangleType(T->getBaseType());
- Out << "E";
}
void CXXNameMangler::mangleType(const AutoType *T) {
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index ae9c85e..74ef4c3 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -1,5 +1,4 @@
#include "clang/AST/JSONNodeDumper.h"
-#include "clang/AST/Type.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Lex/Lexer.h"
@@ -663,11 +662,9 @@ void JSONNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *UUT) {
void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType *UTT) {
switch (UTT->getUTTKind()) {
-#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
- case UnaryTransformType::Enum: \
- JOS.attribute("transformKind", #Trait); \
+ case UnaryTransformType::EnumUnderlyingType:
+ JOS.attribute("transformKind", "underlying_type");
break;
-#include "clang/Basic/TransformTypeTraits.def"
}
}
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index f9f149b..c3da5a4 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1551,11 +1551,9 @@ void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
switch (T->getUTTKind()) {
-#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
- case UnaryTransformType::Enum: \
- OS << " " #Trait; \
+ case UnaryTransformType::EnumUnderlyingType:
+ OS << " underlying_type";
break;
-#include "clang/Basic/TransformTypeTraits.def"
}
}
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index a7da9fd..3cb2001 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -22,7 +22,6 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/TemplateName.h"
-#include "clang/AST/TextNodeDumper.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/ExceptionSpecificationType.h"
@@ -33,7 +32,6 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
@@ -1142,19 +1140,29 @@ void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,
raw_ostream &OS) {
IncludeStrongLifetimeRAII Strong(Policy);
- static llvm::DenseMap<int, const char *> Transformation = {{
-#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
- {UnaryTransformType::Enum, "__" #Trait},
-#include "clang/Basic/TransformTypeTraits.def"
- }};
- OS << Transformation[T->getUTTKind()] << '(';
- print(T->getBaseType(), OS, StringRef());
- OS << ')';
- spaceBeforePlaceHolder(OS);
+ switch (T->getUTTKind()) {
+ case UnaryTransformType::EnumUnderlyingType:
+ OS << "__underlying_type(";
+ print(T->getBaseType(), OS, StringRef());
+ OS << ')';
+ spaceBeforePlaceHolder(OS);
+ return;
+ }
+
+ printBefore(T->getBaseType(), OS);
}
void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,
- raw_ostream &OS) {}
+ raw_ostream &OS) {
+ IncludeStrongLifetimeRAII Strong(Policy);
+
+ switch (T->getUTTKind()) {
+ case UnaryTransformType::EnumUnderlyingType:
+ return;
+ }
+
+ printAfter(T->getBaseType(), OS);
+}
void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {
// If the type has been deduced, do not print 'auto'.
diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp
index f9f0d71..832af46 100644
--- a/clang/lib/Format/FormatToken.cpp
+++ b/clang/lib/Format/FormatToken.cpp
@@ -56,8 +56,7 @@ bool FormatToken::isSimpleTypeSpecifier() const {
case tok::kw___ibm128:
case tok::kw_wchar_t:
case tok::kw_bool:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case tok::kw___underlying_type:
case tok::annot_typename:
case tok::kw_char8_t:
case tok::kw_char16_t:
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index 1ce64f7..7d963cf 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -677,8 +677,7 @@ public:
case tok::kw_static_assert:
case tok::kw__Atomic:
case tok::kw___attribute:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case tok::kw___underlying_type:
case tok::kw_requires:
return true;
default:
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index eb0ee91..b0a1c69 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -317,10 +317,8 @@ private:
if (PrevNonComment->is(tok::kw___attribute)) {
OpeningParen.setType(TT_AttributeParen);
} 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"
- tok::kw__Atomic)) {
+ tok::kw_typeof, tok::kw__Atomic,
+ tok::kw___underlying_type)) {
OpeningParen.setType(TT_TypeDeclarationParen);
// decltype() and typeof() usually contain expressions.
if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 78ab8ba..f3be210 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1663,8 +1663,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
.Case("__array_rank", true)
.Case("__array_extent", true)
.Case("__reference_binds_to_temporary", true)
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) .Case("__" #Trait, true)
-#include "clang/Basic/TransformTypeTraits.def"
+ .Case("__underlying_type", true)
.Default(false);
} else {
return llvm::StringSwitch<bool>(II->getName())
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 70dd5e2..39ba93e 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3471,8 +3471,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// typedef-name
case tok::kw___super:
case tok::kw_decltype:
- case tok::identifier:
- ParseIdentifier: {
+ case tok::identifier: {
// This identifier can only be a typedef name if we haven't already seen
// a type-specifier. Without this check we misparse:
// typedef int X; struct Y { short X; }; as 'short int'.
@@ -3665,7 +3664,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
}
}
ConsumedEnd = Tok.getLocation();
- DS.setTypeArgumentRange(Tracker.getRange());
+ DS.setTypeofParensRange(Tracker.getRange());
// Even if something went wrong above, continue as if we've seen
// `decltype(auto)`.
isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec,
@@ -4207,13 +4206,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
HandlePragmaMSPointersToMembers();
continue;
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
- // 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.
- if (!MaybeParseTypeTransformTypeSpecifier(DS))
- goto ParseIdentifier;
+ case tok::kw___underlying_type:
+ ParseUnderlyingTypeSpecifier(DS);
continue;
case tok::kw__Atomic:
@@ -7451,7 +7445,7 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) {
ExprResult Operand = Actions.CorrectDelayedTyposInExpr(
ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange));
if (hasParens)
- DS.setTypeArgumentRange(CastRange);
+ DS.setTypeofParensRange(CastRange);
if (CastRange.getEnd().isInvalid())
// FIXME: Not accurate, the range gets one token more than it should.
@@ -7521,7 +7515,7 @@ void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
if (T.getCloseLocation().isInvalid())
return;
- DS.setTypeArgumentRange(T.getRange());
+ DS.setTypeofParensRange(T.getRange());
DS.SetRangeEnd(T.getCloseLocation());
const char *PrevSpec = nullptr;
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 4510ff8..8dfa91e 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -18,7 +18,6 @@
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Basic/TokenKinds.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
@@ -1022,7 +1021,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
EndLoc = Tok.getAnnotationEndLoc();
// Unfortunately, we don't know the LParen source location as the annotated
// token doesn't have it.
- DS.setTypeArgumentRange(SourceRange(SourceLocation(), EndLoc));
+ DS.setTypeofParensRange(SourceRange(SourceLocation(), EndLoc));
ConsumeAnnotationToken();
if (Result.isInvalid()) {
DS.SetTypeSpecError();
@@ -1086,7 +1085,7 @@ SourceLocation Parser::ParseDecltypeSpecifier(DeclSpec &DS) {
// Match the ')'
T.consumeClose();
- DS.setTypeArgumentRange(T.getRange());
+ DS.setTypeofParensRange(T.getRange());
if (T.getCloseLocation().isInvalid()) {
DS.SetTypeSpecError();
// FIXME: this should return the location of the last token
@@ -1143,48 +1142,35 @@ void Parser::AnnotateExistingDecltypeSpecifier(const DeclSpec &DS,
PP.AnnotateCachedTokens(Tok);
}
-DeclSpec::TST Parser::TypeTransformTokToDeclSpec() {
- switch (Tok.getKind()) {
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
- case tok::kw___##Trait: \
- return DeclSpec::TST_##Trait;
-#include "clang/Basic/TransformTypeTraits.def"
- default:
- llvm_unreachable("passed in an unhandled type transformation built-in");
- }
-}
+void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) {
+ assert(Tok.is(tok::kw___underlying_type) &&
+ "Not an underlying type specifier");
-bool Parser::MaybeParseTypeTransformTypeSpecifier(DeclSpec &DS) {
- if (!NextToken().is(tok::l_paren)) {
- Tok.setKind(tok::identifier);
- return false;
- }
- DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec();
SourceLocation StartLoc = ConsumeToken();
-
BalancedDelimiterTracker T(*this, tok::l_paren);
- if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.getName(),
- tok::r_paren))
- return true;
+ if (T.expectAndConsume(diag::err_expected_lparen_after, "__underlying_type",
+ tok::r_paren)) {
+ return;
+ }
TypeResult Result = ParseTypeName();
if (Result.isInvalid()) {
SkipUntil(tok::r_paren, StopAtSemi);
- return true;
+ return;
}
+ // Match the ')'
T.consumeClose();
if (T.getCloseLocation().isInvalid())
- return true;
+ return;
const char *PrevSpec = nullptr;
unsigned DiagID;
- if (DS.SetTypeSpecType(TypeTransformTST, StartLoc, PrevSpec, DiagID,
- Result.get(),
+ if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec,
+ DiagID, Result.get(),
Actions.getASTContext().getPrintingPolicy()))
Diag(StartLoc, DiagID) << PrevSpec;
- DS.setTypeArgumentRange(T.getRange());
- return true;
+ DS.setTypeofParensRange(T.getRange());
}
/// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a
@@ -1539,58 +1525,28 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
if (TagType == DeclSpec::TST_struct && Tok.isNot(tok::identifier) &&
!Tok.isAnnotation() && Tok.getIdentifierInfo() &&
Tok.isOneOf(
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait,
-#include "clang/Basic/TransformTypeTraits.def"
- tok::kw___is_abstract,
- tok::kw___is_aggregate,
- tok::kw___is_arithmetic,
- tok::kw___is_array,
- tok::kw___is_assignable,
- tok::kw___is_base_of,
- tok::kw___is_class,
- tok::kw___is_complete_type,
- tok::kw___is_compound,
- tok::kw___is_const,
- tok::kw___is_constructible,
- tok::kw___is_convertible,
- tok::kw___is_convertible_to,
- tok::kw___is_destructible,
- tok::kw___is_empty,
- tok::kw___is_enum,
- tok::kw___is_floating_point,
- tok::kw___is_final,
- tok::kw___is_function,
- tok::kw___is_fundamental,
- tok::kw___is_integral,
- tok::kw___is_interface_class,
- tok::kw___is_literal,
- tok::kw___is_lvalue_expr,
- tok::kw___is_lvalue_reference,
- tok::kw___is_member_function_pointer,
- tok::kw___is_member_object_pointer,
- tok::kw___is_member_pointer,
- tok::kw___is_nothrow_assignable,
- tok::kw___is_nothrow_constructible,
- tok::kw___is_nothrow_destructible,
- tok::kw___is_object,
- tok::kw___is_pod,
- tok::kw___is_pointer,
- tok::kw___is_polymorphic,
- tok::kw___is_reference,
- tok::kw___is_rvalue_expr,
- tok::kw___is_rvalue_reference,
- tok::kw___is_same,
- tok::kw___is_scalar,
- tok::kw___is_sealed,
- tok::kw___is_signed,
- tok::kw___is_standard_layout,
- tok::kw___is_trivial,
+ tok::kw___is_abstract, tok::kw___is_aggregate,
+ tok::kw___is_arithmetic, tok::kw___is_array, tok::kw___is_assignable,
+ tok::kw___is_base_of, tok::kw___is_class, tok::kw___is_complete_type,
+ tok::kw___is_compound, tok::kw___is_const, tok::kw___is_constructible,
+ tok::kw___is_convertible, tok::kw___is_convertible_to,
+ tok::kw___is_destructible, tok::kw___is_empty, tok::kw___is_enum,
+ tok::kw___is_floating_point, tok::kw___is_final,
+ tok::kw___is_function, tok::kw___is_fundamental,
+ tok::kw___is_integral, tok::kw___is_interface_class,
+ tok::kw___is_literal, tok::kw___is_lvalue_expr,
+ tok::kw___is_lvalue_reference, tok::kw___is_member_function_pointer,
+ tok::kw___is_member_object_pointer, tok::kw___is_member_pointer,
+ tok::kw___is_nothrow_assignable, tok::kw___is_nothrow_constructible,
+ tok::kw___is_nothrow_destructible, tok::kw___is_object,
+ tok::kw___is_pod, tok::kw___is_pointer, tok::kw___is_polymorphic,
+ tok::kw___is_reference, tok::kw___is_rvalue_expr,
+ tok::kw___is_rvalue_reference, tok::kw___is_same, tok::kw___is_scalar,
+ tok::kw___is_sealed, tok::kw___is_signed,
+ tok::kw___is_standard_layout, tok::kw___is_trivial,
tok::kw___is_trivially_assignable,
- tok::kw___is_trivially_constructible,
- tok::kw___is_trivially_copyable,
- tok::kw___is_union,
- tok::kw___is_unsigned,
- tok::kw___is_void,
+ tok::kw___is_trivially_constructible, tok::kw___is_trivially_copyable,
+ tok::kw___is_union, tok::kw___is_unsigned, tok::kw___is_void,
tok::kw___is_volatile))
// GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the
// name of struct templates, but some are keywords in GCC >= 4.3
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 588f4cf..354908a 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1038,10 +1038,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast,
isVectorLiteral, NotPrimaryExpression);
- case tok::identifier:
- ParseIdentifier: { // primary-expression: identifier
- // unqualified-id: identifier
- // constant: enumeration-constant
+ case tok::identifier: { // primary-expression: identifier
+ // unqualified-id: identifier
+ // constant: enumeration-constant
// Turn a potentially qualified name into a annot_typename or
// annot_cxxscope if it would be valid. This handles things like x::y, etc.
if (getLangOpts().CPlusPlus) {
@@ -1114,9 +1113,6 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
REVERTIBLE_TYPE_TRAIT(__is_unsigned);
REVERTIBLE_TYPE_TRAIT(__is_void);
REVERTIBLE_TYPE_TRAIT(__is_volatile);
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
- REVERTIBLE_TYPE_TRAIT(RTT_JOIN(__, Trait));
-#include "clang/Basic/TransformTypeTraits.def"
#undef REVERTIBLE_TYPE_TRAIT
#undef RTT_JOIN
}
@@ -1743,17 +1739,6 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
PreferredType.get(Tok.getLocation()));
return ExprError();
}
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
- // 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)) {
- Tok.setKind(tok::identifier);
- Diag(Tok, diag::ext_keyword_as_ident)
- << Tok.getIdentifierInfo()->getName() << 0;
- goto ParseIdentifier;
- }
- goto ExpectedExpression;
case tok::l_square:
if (getLangOpts().CPlusPlus11) {
if (getLangOpts().ObjC) {
@@ -1781,7 +1766,6 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
}
[[fallthrough]];
default:
- ExpectedExpression:
NotCastExpr = true;
return ExprError();
}
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index b2e9aa1..2f30075 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -14,7 +14,6 @@
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
#include "clang/Basic/PrettyStackTrace.h"
-#include "clang/Basic/TokenKinds.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
@@ -22,7 +21,6 @@
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Scope.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include <numeric>
@@ -2821,7 +2819,6 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
// identifier
// template-id (when it hasn't already been annotated)
if (Tok.is(tok::identifier)) {
- ParseIdentifier:
// Consume the identifier.
IdentifierInfo *Id = Tok.getIdentifierInfo();
SourceLocation IdLoc = ConsumeToken();
@@ -3056,20 +3053,9 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType,
return false;
}
- switch (Tok.getKind()) {
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
- if (!NextToken().is(tok::l_paren)) {
- Tok.setKind(tok::identifier);
- Diag(Tok, diag::ext_keyword_as_ident)
- << Tok.getIdentifierInfo()->getName() << 0;
- goto ParseIdentifier;
- }
- LLVM_FALLTHROUGH;
- default:
- Diag(Tok, diag::err_expected_unqualified_id) << getLangOpts().CPlusPlus;
- return true;
- }
+ Diag(Tok, diag::err_expected_unqualified_id)
+ << getLangOpts().CPlusPlus;
+ return true;
}
/// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp
index fc515f1..530e0de 100644
--- a/clang/lib/Parse/ParseStmt.cpp
+++ b/clang/lib/Parse/ParseStmt.cpp
@@ -14,7 +14,6 @@
#include "clang/AST/PrettyDeclStackTrace.h"
#include "clang/Basic/Attributes.h"
#include "clang/Basic/PrettyStackTrace.h"
-#include "clang/Basic/TokenKinds.h"
#include "clang/Parse/LoopHint.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
@@ -189,8 +188,7 @@ Retry:
Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement);
return StmtError();
- case tok::identifier:
- ParseIdentifier: {
+ case tok::identifier: {
Token Next = NextToken();
if (Next.is(tok::colon)) { // C99 6.8.1: labeled-statement
// Both C++11 and GNU attributes preceding the label appertain to the
@@ -263,19 +261,7 @@ Retry:
return StmtError();
}
- switch (Tok.getKind()) {
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
- if (NextToken().is(tok::less)) {
- Tok.setKind(tok::identifier);
- Diag(Tok, diag::ext_keyword_as_ident)
- << Tok.getIdentifierInfo()->getName() << 0;
- goto ParseIdentifier;
- }
- LLVM_FALLTHROUGH;
- default:
- return ParseExprStatement(StmtCtx);
- }
+ return ParseExprStatement(StmtCtx);
}
case tok::kw___attribute: {
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index 9cd405a..8f45584 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -161,9 +161,7 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
[[fallthrough]];
case tok::kw_typeof:
case tok::kw___attribute:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
- {
+ case tok::kw___underlying_type: {
ConsumeToken();
if (Tok.isNot(tok::l_paren))
return TPResult::Error;
@@ -1684,8 +1682,8 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
return TPResult::True;
}
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ // C++0x type traits support
+ case tok::kw___underlying_type:
return TPResult::True;
// C11 _Atomic
@@ -1723,8 +1721,7 @@ bool Parser::isCXXDeclarationSpecifierAType() {
case tok::annot_template_id:
case tok::annot_typename:
case tok::kw_typeof:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case tok::kw___underlying_type:
return true;
// elaborated-type-specifier
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index af31105..d4dc790 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -18,7 +18,6 @@
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Sema.h"
@@ -390,8 +389,7 @@ bool Declarator::isDeclarationOfFunction() const {
return E->getType()->isFunctionType();
return false;
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case TST_underlyingType:
case TST_typename:
case TST_typeofType: {
QualType QT = DS.getRepAsType().get();
@@ -578,10 +576,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_auto_type: return "__auto_type";
case DeclSpec::TST_decltype: return "(decltype)";
case DeclSpec::TST_decltype_auto: return "decltype(auto)";
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
- case DeclSpec::TST_##Trait: \
- return "__" #Trait;
-#include "clang/Basic/TransformTypeTraits.def"
+ case DeclSpec::TST_underlyingType: return "__underlying_type";
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 e689a05..94009d3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -145,8 +145,7 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
case tok::kw___ibm128:
case tok::kw_wchar_t:
case tok::kw_bool:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case tok::kw___underlying_type:
case tok::kw___auto_type:
return true;
@@ -5924,8 +5923,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
switch (DS.getTypeSpecType()) {
case DeclSpec::TST_typename:
case DeclSpec::TST_typeofType:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case DeclSpec::TST_##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case DeclSpec::TST_underlyingType:
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 285bf67..790792f 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -858,8 +858,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
switch (DS.getTypeSpecType()) {
case TST_typename:
case TST_typeofType:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case TST_underlyingType:
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 fb339fa..14b2d2e 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -19,11 +19,9 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
@@ -35,7 +33,6 @@
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateInstCallback.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
@@ -1250,18 +1247,6 @@ getImageAccess(const ParsedAttributesView &Attrs) {
return OpenCLAccessAttr::Keyword_read_only;
}
-static UnaryTransformType::UTTKind
-TSTToUnaryTransformType(DeclSpec::TST SwitchTST) {
- switch (SwitchTST) {
-#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
- case TST_##Trait: \
- return UnaryTransformType::Enum;
-#include "clang/Basic/TransformTypeTraits.def"
- default:
- llvm_unreachable("attempted to parse a non-unary transform builtin");
- }
-}
-
/// Convert the specified declspec to the appropriate type
/// object.
/// \param state Specifies the declarator containing the declaration specifier
@@ -1643,13 +1628,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
}
break;
}
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case DeclSpec::TST_##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case DeclSpec::TST_underlyingType:
Result = S.GetTypeFromParser(DS.getRepAsType());
- assert(!Result.isNull() && "Didn't get a type for the transformation?");
- Result = S.BuildUnaryTransformType(
- Result, TSTToUnaryTransformType(DS.getTypeSpecType()),
- DS.getTypeSpecTypeLoc());
+ assert(!Result.isNull() && "Didn't get a type for __underlying_type?");
+ Result = S.BuildUnaryTransformType(Result,
+ UnaryTransformType::EnumUnderlyingType,
+ DS.getTypeSpecTypeLoc());
if (Result.isNull()) {
Result = Context.IntTy;
declarator.setInvalidType(true);
@@ -6083,7 +6067,8 @@ namespace {
TL.setRParenLoc(DS.getTypeofParensRange().getEnd());
}
void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
- assert(DS.isTransformTypeTrait(DS.getTypeSpecType()));
+ // FIXME: This holds only because we only have one unary transform.
+ assert(DS.getTypeSpecType() == DeclSpec::TST_underlyingType);
TL.setKWLoc(DS.getTypeSpecTypeLoc());
TL.setParensRange(DS.getTypeofParensRange());
assert(DS.getRepAsType());
@@ -9220,257 +9205,39 @@ QualType Sema::BuildDecltypeType(Expr *E, bool AsUnevaluated) {
return Context.getDecltypeType(E, getDecltypeForExpr(E));
}
-static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType,
- SourceLocation Loc) {
- assert(BaseType->isEnumeralType());
- EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
- assert(ED && "EnumType has no EnumDecl");
-
- S.DiagnoseUseOfDecl(ED, Loc);
-
- QualType Underlying = ED->getIntegerType();
- assert(!Underlying.isNull());
-
- return Underlying;
-}
-
-QualType Sema::BuiltinEnumUnderlyingType(QualType BaseType,
- SourceLocation Loc) {
- if (!BaseType->isEnumeralType()) {
- Diag(Loc, diag::err_only_enums_have_underlying_types);
- return QualType();
- }
-
- // The enum could be incomplete if we're parsing its definition or
- // recovering from an error.
- NamedDecl *FwdDecl = nullptr;
- if (BaseType->isIncompleteType(&FwdDecl)) {
- Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
- Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
- return QualType();
- }
-
- return GetEnumUnderlyingType(*this, BaseType, Loc);
-}
-
-QualType Sema::BuiltinAddPointer(QualType BaseType, SourceLocation Loc) {
- QualType Pointer = BaseType.isReferenceable() || BaseType->isVoidType()
- ? BuildPointerType(BaseType.getNonReferenceType(), Loc,
- DeclarationName())
- : BaseType;
-
- return Pointer.isNull() ? QualType() : Pointer;
-}
-
-QualType Sema::BuiltinRemovePointer(QualType BaseType, SourceLocation Loc) {
- // We don't want block pointers or ObjectiveC's id type.
- if (!BaseType->isAnyPointerType() || BaseType->isObjCIdType())
- return BaseType;
-
- return BaseType->getPointeeType();
-}
-
-QualType Sema::BuiltinDecay(QualType BaseType, SourceLocation Loc) {
- QualType Underlying = BaseType.getNonReferenceType();
- if (Underlying->isArrayType())
- return Context.getDecayedType(Underlying);
-
- if (Underlying->isFunctionType())
- return BuiltinAddPointer(BaseType, Loc);
-
- SplitQualType Split = Underlying.getSplitUnqualifiedType();
- // std::decay is supposed to produce 'std::remove_cv', but since 'restrict' is
- // in the same group of qualifiers as 'const' and 'volatile', we're extending
- // '__decay(T)' so that it removes all qualifiers.
- Split.Quals.removeCVRQualifiers();
- return Context.getQualifiedType(Split);
-}
-
-QualType Sema::BuiltinAddReference(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- assert(LangOpts.CPlusPlus);
- QualType Reference =
- BaseType.isReferenceable()
- ? BuildReferenceType(BaseType,
- UKind == UnaryTransformType::AddLvalueReference,
- Loc, DeclarationName())
- : BaseType;
- return Reference.isNull() ? QualType() : Reference;
-}
-
-QualType Sema::BuiltinRemoveExtent(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- if (UKind == UnaryTransformType::RemoveAllExtents)
- return Context.getBaseElementType(BaseType);
-
- if (const auto *AT = Context.getAsArrayType(BaseType))
- return AT->getElementType();
-
- return BaseType;
-}
-
-QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- assert(LangOpts.CPlusPlus);
- QualType T = BaseType.getNonReferenceType();
- if (UKind == UTTKind::RemoveCVRef &&
- (T.isConstQualified() || T.isVolatileQualified())) {
- Qualifiers Quals;
- QualType Unqual = Context.getUnqualifiedArrayType(T, Quals);
- Quals.removeConst();
- Quals.removeVolatile();
- T = Context.getQualifiedType(Unqual, Quals);
- }
- return T;
-}
-
-QualType Sema::BuiltinChangeCVRQualifiers(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- if ((BaseType->isReferenceType() && UKind != UTTKind::RemoveRestrict) ||
- BaseType->isFunctionType())
- return BaseType;
-
- Qualifiers Quals;
- QualType Unqual = Context.getUnqualifiedArrayType(BaseType, Quals);
-
- if (UKind == UTTKind::RemoveConst || UKind == UTTKind::RemoveCV)
- Quals.removeConst();
- if (UKind == UTTKind::RemoveVolatile || UKind == UTTKind::RemoveCV)
- Quals.removeVolatile();
- if (UKind == UTTKind::RemoveRestrict)
- Quals.removeRestrict();
-
- return Context.getQualifiedType(Unqual, Quals);
-}
-
-static QualType ChangeIntegralSignedness(Sema &S, QualType BaseType,
- bool IsMakeSigned,
- SourceLocation Loc) {
- if (BaseType->isEnumeralType()) {
- QualType Underlying = GetEnumUnderlyingType(S, BaseType, Loc);
- if (auto *BitInt = dyn_cast<BitIntType>(Underlying)) {
- unsigned int Bits = BitInt->getNumBits();
- if (Bits > 1)
- return S.Context.getBitIntType(!IsMakeSigned, Bits);
-
- S.Diag(Loc, diag::err_make_signed_integral_only)
- << IsMakeSigned << /*_BitInt(1)*/ true << BaseType << 1 << Underlying;
- return QualType();
- }
- if (Underlying->isBooleanType()) {
- S.Diag(Loc, diag::err_make_signed_integral_only)
- << IsMakeSigned << /*_BitInt(1)*/ false << BaseType << 1
- << Underlying;
- return QualType();
- }
- }
-
- bool Int128Unsupported = !S.Context.getTargetInfo().hasInt128Type();
- std::array<CanQualType *, 6> AllSignedIntegers = {
- &S.Context.SignedCharTy, &S.Context.ShortTy, &S.Context.IntTy,
- &S.Context.LongTy, &S.Context.LongLongTy, &S.Context.Int128Ty};
- ArrayRef<CanQualType *> AvailableSignedIntegers(
- AllSignedIntegers.begin(), AllSignedIntegers.end() - Int128Unsupported);
- std::array<CanQualType *, 6> AllUnsignedIntegers = {
- &S.Context.UnsignedCharTy, &S.Context.UnsignedShortTy,
- &S.Context.UnsignedIntTy, &S.Context.UnsignedLongTy,
- &S.Context.UnsignedLongLongTy, &S.Context.UnsignedInt128Ty};
- ArrayRef<CanQualType *> AvailableUnsignedIntegers(AllUnsignedIntegers.begin(),
- AllUnsignedIntegers.end() -
- Int128Unsupported);
- ArrayRef<CanQualType *> *Consider =
- IsMakeSigned ? &AvailableSignedIntegers : &AvailableUnsignedIntegers;
-
- uint64_t BaseSize = S.Context.getTypeSize(BaseType);
- auto *Result =
- llvm::find_if(*Consider, [&S, BaseSize](const CanQual<Type> *T) {
- return BaseSize == S.Context.getTypeSize(T->getTypePtr());
- });
-
- assert(Result != Consider->end());
- return QualType((*Result)->getTypePtr(), 0);
-}
-
-QualType Sema::BuiltinChangeSignedness(QualType BaseType, UTTKind UKind,
+QualType Sema::BuildUnaryTransformType(QualType BaseType,
+ UnaryTransformType::UTTKind UKind,
SourceLocation Loc) {
- bool IsMakeSigned = UKind == UnaryTransformType::MakeSigned;
- if ((!BaseType->isIntegerType() && !BaseType->isEnumeralType()) ||
- BaseType->isBooleanType() ||
- (BaseType->isBitIntType() &&
- BaseType->getAs<BitIntType>()->getNumBits() < 2)) {
- Diag(Loc, diag::err_make_signed_integral_only)
- << IsMakeSigned << BaseType->isBitIntType() << BaseType << 0;
- return QualType();
- }
+ switch (UKind) {
+ case UnaryTransformType::EnumUnderlyingType:
+ if (!BaseType->isDependentType() && !BaseType->isEnumeralType()) {
+ Diag(Loc, diag::err_only_enums_have_underlying_types);
+ return QualType();
+ } else {
+ QualType Underlying = BaseType;
+ if (!BaseType->isDependentType()) {
+ // The enum could be incomplete if we're parsing its definition or
+ // recovering from an error.
+ NamedDecl *FwdDecl = nullptr;
+ if (BaseType->isIncompleteType(&FwdDecl)) {
+ Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
+ Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
+ return QualType();
+ }
- bool IsNonIntIntegral =
- BaseType->isChar16Type() || BaseType->isChar32Type() ||
- BaseType->isWideCharType() || BaseType->isEnumeralType();
+ EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
+ assert(ED && "EnumType has no EnumDecl");
- QualType Underlying =
- IsNonIntIntegral
- ? ChangeIntegralSignedness(*this, BaseType, IsMakeSigned, Loc)
- : IsMakeSigned ? Context.getCorrespondingSignedType(BaseType)
- : Context.getCorrespondingUnsignedType(BaseType);
- if (Underlying.isNull())
- return Underlying;
- return Context.getQualifiedType(Underlying, BaseType.getQualifiers());
-}
+ DiagnoseUseOfDecl(ED, Loc);
-QualType Sema::BuildUnaryTransformType(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- if (BaseType->isDependentType())
- return Context.getUnaryTransformType(BaseType, BaseType, UKind);
- QualType Result;
- switch (UKind) {
- case UnaryTransformType::EnumUnderlyingType: {
- Result = BuiltinEnumUnderlyingType(BaseType, Loc);
- break;
- }
- case UnaryTransformType::AddPointer: {
- Result = BuiltinAddPointer(BaseType, Loc);
- break;
- }
- case UnaryTransformType::RemovePointer: {
- Result = BuiltinRemovePointer(BaseType, Loc);
- break;
- }
- case UnaryTransformType::Decay: {
- Result = BuiltinDecay(BaseType, Loc);
- break;
- }
- case UnaryTransformType::AddLvalueReference:
- case UnaryTransformType::AddRvalueReference: {
- Result = BuiltinAddReference(BaseType, UKind, Loc);
- break;
- }
- case UnaryTransformType::RemoveAllExtents:
- case UnaryTransformType::RemoveExtent: {
- Result = BuiltinRemoveExtent(BaseType, UKind, Loc);
- break;
- }
- case UnaryTransformType::RemoveCVRef:
- case UnaryTransformType::RemoveReference: {
- Result = BuiltinRemoveReference(BaseType, UKind, Loc);
- break;
- }
- case UnaryTransformType::RemoveConst:
- case UnaryTransformType::RemoveCV:
- case UnaryTransformType::RemoveRestrict:
- case UnaryTransformType::RemoveVolatile: {
- Result = BuiltinChangeCVRQualifiers(BaseType, UKind, Loc);
- break;
- }
- case UnaryTransformType::MakeSigned:
- case UnaryTransformType::MakeUnsigned: {
- Result = BuiltinChangeSignedness(BaseType, UKind, Loc);
- break;
- }
+ Underlying = ED->getIntegerType();
+ assert(!Underlying.isNull());
+ }
+ return Context.getUnaryTransformType(BaseType, Underlying,
+ UnaryTransformType::EnumUnderlyingType);
+ }
}
-
- return !Result.isNull()
- ? Context.getUnaryTransformType(BaseType, Result, UKind)
- : Result;
+ llvm_unreachable("unknown unary transform type");
}
QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {