diff --git a/clang/include/clang/AST/TransformTypeTraits.def b/clang/include/clang/AST/TransformTypeTraits.def new file mode 100644 --- /dev/null +++ b/clang/include/clang/AST/TransformTypeTraits.def @@ -0,0 +1,27 @@ +// +// 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 defines transform type traits' names. +// +//===----------------------------------------------------------------------===// + +TRANSFORM_TYPE_TRAIT_DEF(AddLvalueReference, add_lvalue_reference) +TRANSFORM_TYPE_TRAIT_DEF(AddPointer, add_pointer) +TRANSFORM_TYPE_TRAIT_DEF(AddRvalueReference, add_rvalue_reference) +TRANSFORM_TYPE_TRAIT_DEF(Decay, decay) +TRANSFORM_TYPE_TRAIT_DEF(MakeSigned, make_signed) +TRANSFORM_TYPE_TRAIT_DEF(MakeUnsigned, make_unsigned) +TRANSFORM_TYPE_TRAIT_DEF(RemoveAllExtents, remove_all_extents) +TRANSFORM_TYPE_TRAIT_DEF(RemoveConst, remove_const) +TRANSFORM_TYPE_TRAIT_DEF(RemoveCV, remove_cv) +TRANSFORM_TYPE_TRAIT_DEF(RemoveCVRef, remove_cvref) +TRANSFORM_TYPE_TRAIT_DEF(RemoveExtent, remove_extent) +TRANSFORM_TYPE_TRAIT_DEF(RemovePointer, remove_pointer) +TRANSFORM_TYPE_TRAIT_DEF(RemoveReference, remove_reference) +TRANSFORM_TYPE_TRAIT_DEF(RemoveRestrict, remove_restrict) +TRANSFORM_TYPE_TRAIT_DEF(RemoveVolatile, remove_volatile) +TRANSFORM_TYPE_TRAIT_DEF(EnumUnderlyingType, underlying_type) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -741,6 +741,9 @@ return Value.getPointer().isNull(); } + // Determines if a type can form `T&`. + bool isReferenceable(bool IsCPlusPlus) const; + /// Determine whether this particular QualType instance has the /// "const" qualifier set, without looking through typedefs that may have /// added "const" at a different level. @@ -4561,7 +4564,22 @@ class UnaryTransformType : public Type { public: enum UTTKind { - EnumUnderlyingType + EnumUnderlyingType, + AddLvalueReference, + AddPointer, + AddRvalueReference, + Decay, + MakeSigned, + MakeUnsigned, + RemoveConst, + RemoveCV, + RemoveCVRef, + RemoveAllExtents, + RemoveExtent, + RemovePointer, + RemoveReference, + RemoveRestrict, + RemoveVolatile, }; private: @@ -6501,6 +6519,24 @@ return (isNull() ? nullptr : getCommonPtr()->BaseType); } +inline bool QualType::isReferenceable(bool IsCPlusPlus) const { + // C++ [defns.referenceable] + // type that is either an object type, a function type that does not have + // cv-qualifiers or a ref-qualifier, or a reference type. + assert(!isNull() && "QualType must be valid in order to be referenceable"); + (void)IsCPlusPlus; + assert(IsCPlusPlus && "Referenceable types only make sense in C++"); + const Type &Self = **this; + if (Self.isObjectType() || Self.isReferenceType()) + return true; + if (!Self.isFunctionType()) + return false; + + const auto *F = Self.getAs(); + assert(F != nullptr); + return F->getMethodQuals().empty() && F->getRefQualifier() == RQ_None; +} + inline SplitQualType QualType::split() const { if (!hasLocalNonFastQualifiers()) return SplitQualType(getTypePtrUnsafe(), diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -8648,6 +8648,9 @@ "a vector of such types is required">; def err_cast_selector_expr : Error< "cannot type cast @selector expression">; +def err_make_signed_integral_only : Error< + "'%select{make_unsigned|make_signed}0' is only compatible with non-bool " + "integers and enum types, but was given %1">; def ext_typecheck_cond_incompatible_pointers : ExtWarn< "pointer type mismatch%diff{ ($ and $)|}0,1">, InGroup>; @@ -11589,4 +11592,3 @@ def err_hlsl_attribute_param_mismatch : Error<"%0 attribute parameters do not match the previous declaration">; } // end of sema component. - diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -53,41 +53,43 @@ TST_unspecified, TST_void, TST_char, - TST_wchar, // C++ wchar_t - TST_char8, // C++20 char8_t (proposed) - TST_char16, // C++11 char16_t - TST_char32, // C++11 char32_t + TST_wchar, // C++ wchar_t + TST_char8, // C++20 char8_t (proposed) + TST_char16, // C++11 char16_t + TST_char32, // C++11 char32_t TST_int, TST_int128, - TST_bitint, // Bit-precise integer types. - TST_half, // OpenCL half, ARM NEON __fp16 - TST_Float16, // C11 extension ISO/IEC TS 18661-3 - TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension + TST_bitint, // Bit-precise integer types. + TST_half, // OpenCL half, ARM NEON __fp16 + TST_Float16, // C11 extension ISO/IEC TS 18661-3 + TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension TST_Fract, TST_BFloat16, TST_float, TST_double, TST_float128, TST_ibm128, - TST_bool, // _Bool - TST_decimal32, // _Decimal32 - TST_decimal64, // _Decimal64 - TST_decimal128, // _Decimal128 + TST_bool, // _Bool + TST_decimal32, // _Decimal32 + TST_decimal64, // _Decimal64 + TST_decimal128, // _Decimal128 TST_enum, TST_union, TST_struct, - TST_class, // C++ class type - TST_interface, // C++ (Microsoft-specific) __interface type - TST_typename, // Typedef, C++ class-name or enum name, etc. + TST_class, // C++ class type + TST_interface, // C++ (Microsoft-specific) __interface type + TST_typename, // Typedef, C++ class-name or enum name, etc. TST_typeofType, TST_typeofExpr, - TST_decltype, // C++11 decltype - TST_underlyingType, // __underlying_type for C++11 - TST_auto, // C++11 auto - TST_decltype_auto, // C++1y decltype(auto) - TST_auto_type, // __auto_type extension - TST_unknown_anytype, // __unknown_anytype extension - TST_atomic, // C11 _Atomic + TST_decltype, // C++11 decltype +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait, +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF + TST_auto, // C++11 auto + TST_decltype_auto, // C++1y decltype(auto) + TST_auto_type, // __auto_type extension + TST_unknown_anytype, // __unknown_anytype extension + TST_atomic, // C11 _Atomic #define GENERIC_IMAGE_TYPE(ImgType, Id) TST_##ImgType##_t, // OpenCL image types #include "clang/Basic/OpenCLImageTypes.def" TST_error // erroneous type @@ -96,8 +98,8 @@ /// Structure that packs information about the type specifiers that /// were written in a particular type specifier sequence. struct WrittenBuiltinSpecs { - static_assert(TST_error < 1 << 6, "Type bitfield not wide enough for TST"); - /*DeclSpec::TST*/ unsigned Type : 6; + static_assert(TST_error < 1 << 7, "Type bitfield not wide enough for TST"); + /*DeclSpec::TST*/ unsigned Type : 7; /*DeclSpec::TSS*/ unsigned Sign : 2; /*TypeSpecifierWidth*/ unsigned Width : 2; unsigned ModeAttr : 1; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -508,7 +508,10 @@ TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX) TYPE_TRAIT_1(__has_unique_object_representations, HasUniqueObjectRepresentations, KEYCXX) -KEYWORD(__underlying_type , KEYCXX) + +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) KEYWORD(__##Trait, KEYCXX) +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF // Clang-only C++ Type Traits TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -2868,7 +2868,6 @@ void AnnotateExistingDecltypeSpecifier(const DeclSpec &DS, SourceLocation StartLoc, SourceLocation EndLoc); - void ParseUnderlyingTypeSpecifier(DeclSpec &DS); void ParseAtomicSpecifier(DeclSpec &DS); ExprResult ParseAlignArgument(SourceLocation Start, @@ -2966,6 +2965,8 @@ SourceLocation &EllipsisLoc); void ParseBracketDeclarator(Declarator &D); void ParseMisplacedBracketDeclarator(Declarator &D); + bool ParseTypeTransformTypeSpecifier(DeclSpec &DS); + DeclSpec::TST TypeTransformTokToDeclSpec(); //===--------------------------------------------------------------------===// // C++ 7: Declarations [dcl.dcl] diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -32,6 +32,7 @@ #include "clang/Lex/Token.h" #include "clang/Sema/Ownership.h" #include "clang/Sema/ParsedAttr.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" @@ -290,7 +291,10 @@ static const TST TST_typeofExpr = clang::TST_typeofExpr; static const TST TST_decltype = clang::TST_decltype; static const TST TST_decltype_auto = clang::TST_decltype_auto; - static const TST TST_underlyingType = clang::TST_underlyingType; +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ + static const TST TST_##Trait = clang::TST_##Trait; +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF static const TST TST_auto = clang::TST_auto; static const TST TST_auto_type = clang::TST_auto_type; static const TST TST_unknown_anytype = clang::TST_unknown_anytype; @@ -333,7 +337,7 @@ /*TypeSpecifierWidth*/ unsigned TypeSpecWidth : 2; /*TSC*/unsigned TypeSpecComplex : 2; /*TSS*/unsigned TypeSpecSign : 2; - /*TST*/unsigned TypeSpecType : 6; + /*TST*/ unsigned TypeSpecType : 7; unsigned TypeAltiVecVector : 1; unsigned TypeAltiVecPixel : 1; unsigned TypeAltiVecBool : 1; @@ -400,8 +404,15 @@ ObjCDeclSpec *ObjCQualifiers; static bool isTypeRep(TST T) { - return (T == TST_typename || T == TST_typeofType || - T == TST_underlyingType || T == TST_atomic); + static const llvm::SmallVector validTSTs = { + TST_atomic, +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait, +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF + TST_typename, + TST_typeofType, + }; + return llvm::any_of(validTSTs, [T](TST X) { return X == T; }); } static bool isExprRep(TST T) { return (T == TST_typeofExpr || T == TST_decltype || T == TST_bitint); @@ -521,7 +532,7 @@ } SourceRange getTypeofParensRange() const { return TypeofParensRange; } - void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } + void setTypeArgumentRange(SourceRange range) { TypeofParensRange = range; } bool hasAutoTypeSpec() const { return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type || diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2417,8 +2417,23 @@ /// If AsUnevaluated is false, E is treated as though it were an evaluated /// context, such as when building a type for decltype(auto). QualType BuildDecltypeType(Expr *E, bool AsUnevaluated = true); - QualType BuildUnaryTransformType(QualType BaseType, - UnaryTransformType::UTTKind UKind, + + using UTTKind = UnaryTransformType::UTTKind; + QualType BuildUnaryTransformType(QualType BaseType, UTTKind UKind, + SourceLocation Loc); + QualType BuiltinEnumUnderlyingType(QualType BaseType, SourceLocation Loc); + QualType BuiltinAddPointer(QualType BaseType, SourceLocation Loc); + QualType BuiltinRemovePointer(QualType BaseType, SourceLocation Loc); + QualType BuiltinDecay(QualType BaseType, SourceLocation Loc); + QualType BuiltinAddReference(QualType BaseType, UTTKind UKind, + SourceLocation Loc); + QualType BuiltinRemoveExtent(QualType BaseType, UTTKind UKind, + SourceLocation Loc); + QualType BuiltinRemoveReference(QualType BaseType, UTTKind UKind, + SourceLocation Loc); + QualType BuiltinChangeCVQualifiers(QualType BaseType, UTTKind UKind, + SourceLocation Loc); + QualType BuiltinChangeSignedness(QualType BaseType, UTTKind UKind, SourceLocation Loc); //===--------------------------------------------------------------------===// diff --git a/clang/include/clang/module.modulemap b/clang/include/clang/module.modulemap --- a/clang/include/clang/module.modulemap +++ b/clang/include/clang/module.modulemap @@ -20,6 +20,7 @@ textual header "AST/BuiltinTypes.def" textual header "AST/CXXRecordDeclDefinitionBits.def" textual header "AST/OperationKinds.def" + textual header "AST/TransformTypeTraits.def" textual header "AST/TypeLocNodes.def" module * { export * } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -3952,13 +3952,18 @@ // 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 << "Uu"; + StringRef BuiltinName; switch (T->getUTTKind()) { - case UnaryTransformType::EnumUnderlyingType: - Out << "3eut"; - break; +#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \ + case UnaryTransformType::Enum: \ + BuiltinName = "__" #Trait; \ + break; +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF } + Out << BuiltinName.size() << BuiltinName; } mangleType(T->getBaseType()); diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -1,4 +1,5 @@ #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" @@ -662,9 +663,12 @@ void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType *UTT) { switch (UTT->getUTTKind()) { - case UnaryTransformType::EnumUnderlyingType: - JOS.attribute("transformKind", "underlying_type"); +#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \ + case UnaryTransformType::Enum: \ + JOS.attribute("transformKind", #Trait); \ break; +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF } } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1546,9 +1546,12 @@ void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) { switch (T->getUTTKind()) { - case UnaryTransformType::EnumUnderlyingType: - OS << " underlying_type"; +#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \ + case UnaryTransformType::Enum: \ + OS << " " #Trait; \ break; +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF } } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -22,6 +22,7 @@ #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" @@ -32,6 +33,7 @@ #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" @@ -1118,28 +1120,21 @@ raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); - switch (T->getUTTKind()) { - case UnaryTransformType::EnumUnderlyingType: - OS << "__underlying_type("; - print(T->getBaseType(), OS, StringRef()); - OS << ')'; - spaceBeforePlaceHolder(OS); - return; - } - - printBefore(T->getBaseType(), OS); + static llvm::DenseMap Transformation = {{ +#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \ + {UnaryTransformType::Enum, "__" #Trait}, +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF + }}; + OS << Transformation[T->getUTTKind()] << '('; + print(T->getBaseType(), OS, StringRef()); + OS << ')'; + spaceBeforePlaceHolder(OS); } void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T, 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) { diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp --- a/clang/lib/Format/FormatToken.cpp +++ b/clang/lib/Format/FormatToken.cpp @@ -56,7 +56,9 @@ case tok::kw___ibm128: case tok::kw_wchar_t: case tok::kw_bool: - case tok::kw___underlying_type: +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF case tok::annot_typename: case tok::kw_char8_t: case tok::kw_char16_t: diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -1660,7 +1660,9 @@ .Case("__array_rank", true) .Case("__array_extent", true) .Case("__reference_binds_to_temporary", true) - .Case("__underlying_type", true) +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) .Case("__" #Trait, true) +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF .Default(false); } else { return llvm::StringSwitch(II->getName()) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3609,7 +3609,7 @@ } } ConsumedEnd = Tok.getLocation(); - DS.setTypeofParensRange(Tracker.getRange()); + DS.setTypeArgumentRange(Tracker.getRange()); // Even if something went wrong above, continue as if we've seen // `decltype(auto)`. isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec, @@ -4146,8 +4146,10 @@ HandlePragmaMSPointersToMembers(); continue; - case tok::kw___underlying_type: - ParseUnderlyingTypeSpecifier(DS); +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF + ParseTypeTransformTypeSpecifier(DS); continue; case tok::kw__Atomic: @@ -7360,7 +7362,7 @@ ExprResult Operand = Actions.CorrectDelayedTyposInExpr( ParseExprAfterUnaryExprOrTypeTrait(OpTok, isCastExpr, CastTy, CastRange)); if (hasParens) - DS.setTypeofParensRange(CastRange); + DS.setTypeArgumentRange(CastRange); if (CastRange.getEnd().isInvalid()) // FIXME: Not accurate, the range gets one token more than it should. @@ -7430,7 +7432,7 @@ if (T.getCloseLocation().isInvalid()) return; - DS.setTypeofParensRange(T.getRange()); + DS.setTypeArgumentRange(T.getRange()); DS.SetRangeEnd(T.getCloseLocation()); const char *PrevSpec = nullptr; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1016,7 +1016,7 @@ EndLoc = Tok.getAnnotationEndLoc(); // Unfortunately, we don't know the LParen source location as the annotated // token doesn't have it. - DS.setTypeofParensRange(SourceRange(SourceLocation(), EndLoc)); + DS.setTypeArgumentRange(SourceRange(SourceLocation(), EndLoc)); ConsumeAnnotationToken(); if (Result.isInvalid()) { DS.SetTypeSpecError(); @@ -1080,7 +1080,7 @@ // Match the ')' T.consumeClose(); - DS.setTypeofParensRange(T.getRange()); + DS.setTypeArgumentRange(T.getRange()); if (T.getCloseLocation().isInvalid()) { DS.SetTypeSpecError(); // FIXME: this should return the location of the last token @@ -1139,16 +1139,25 @@ PP.AnnotateCachedTokens(Tok); } -void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { - assert(Tok.is(tok::kw___underlying_type) && - "Not an underlying type specifier"); +DeclSpec::TST Parser::TypeTransformTokToDeclSpec() { + switch (Tok.getKind()) { +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ + case tok::kw___##Trait: \ + return DeclSpec::TST_##Trait; +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF + default: + assert(false && "passed in an unhandled type transformation built-in"); + } +} +void Parser::ParseTypeTransformTypeSpecifier(DeclSpec &DS) { + DeclSpec::TST TypeTransformTST = TypeTransformTokToDeclSpec(); SourceLocation StartLoc = ConsumeToken(); BalancedDelimiterTracker T(*this, tok::l_paren); - if (T.expectAndConsume(diag::err_expected_lparen_after, - "__underlying_type", tok::r_paren)) { + if (T.expectAndConsume(diag::err_expected_lparen_after, Tok.getName(), + tok::r_paren)) return; - } TypeResult Result = ParseTypeName(); if (Result.isInvalid()) { @@ -1156,18 +1165,17 @@ return; } - // Match the ')' T.consumeClose(); if (T.getCloseLocation().isInvalid()) return; const char *PrevSpec = nullptr; unsigned DiagID; - if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec, - DiagID, Result.get(), + if (DS.SetTypeSpecType(TypeTransformTST, StartLoc, PrevSpec, DiagID, + Result.get(), Actions.getASTContext().getPrintingPolicy())) Diag(StartLoc, DiagID) << PrevSpec; - DS.setTypeofParensRange(T.getRange()); + DS.setTypeArgumentRange(T.getRange()); } /// ParseBaseTypeSpecifier - Parse a C++ base-type-specifier which is either a @@ -1518,61 +1526,63 @@ // C++11 attributes SourceLocation AttrFixitLoc = Tok.getLocation(); - if (TagType == DeclSpec::TST_struct && - Tok.isNot(tok::identifier) && - !Tok.isAnnotation() && - Tok.getIdentifierInfo() && - Tok.isOneOf(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_volatile)) + if (TagType == DeclSpec::TST_struct && Tok.isNot(tok::identifier) && + !Tok.isAnnotation() && Tok.getIdentifierInfo() && + Tok.isOneOf( // clang-format off +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) tok::kw___##Trait, +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_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_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_volatile)) // clang-format on // GNU libstdc++ 4.2 and libc++ use certain intrinsic names as the // name of struct templates, but some are keywords in GCC >= 4.3 // and Clang. Therefore, when we see the token sequence "struct diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1062,6 +1062,8 @@ RevertibleTypeTraits[PP.getIdentifierInfo(#Name)] \ = RTT_JOIN(tok::kw_,Name) + REVERTIBLE_TYPE_TRAIT(__add_lvalue_reference); + REVERTIBLE_TYPE_TRAIT(__add_rvalue_reference); REVERTIBLE_TYPE_TRAIT(__is_abstract); REVERTIBLE_TYPE_TRAIT(__is_aggregate); REVERTIBLE_TYPE_TRAIT(__is_arithmetic); @@ -1113,6 +1115,10 @@ REVERTIBLE_TYPE_TRAIT(__is_unsigned); REVERTIBLE_TYPE_TRAIT(__is_void); REVERTIBLE_TYPE_TRAIT(__is_volatile); + REVERTIBLE_TYPE_TRAIT(__remove_const); + REVERTIBLE_TYPE_TRAIT(__remove_cv); + REVERTIBLE_TYPE_TRAIT(__remove_reference); + REVERTIBLE_TYPE_TRAIT(__remove_volatile); #undef REVERTIBLE_TYPE_TRAIT #undef RTT_JOIN } diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -18,6 +18,7 @@ #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" @@ -389,7 +390,9 @@ return E->getType()->isFunctionType(); return false; - case TST_underlyingType: +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF case TST_typename: case TST_typeofType: { QualType QT = DS.getRepAsType().get(); @@ -576,7 +579,11 @@ case DeclSpec::TST_auto_type: return "__auto_type"; case DeclSpec::TST_decltype: return "(decltype)"; case DeclSpec::TST_decltype_auto: return "decltype(auto)"; - case DeclSpec::TST_underlyingType: return "__underlying_type"; +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \ + case DeclSpec::TST_##Trait: \ + return "__" #Trait; +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF 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 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -144,7 +144,9 @@ case tok::kw___ibm128: case tok::kw_wchar_t: case tok::kw_bool: - case tok::kw___underlying_type: +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait: +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF case tok::kw___auto_type: return true; @@ -5776,7 +5778,9 @@ switch (DS.getTypeSpecType()) { case DeclSpec::TST_typename: case DeclSpec::TST_typeofType: - case DeclSpec::TST_underlyingType: +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case DeclSpec::TST_##Trait: +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF 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 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -860,7 +860,9 @@ switch (DS.getTypeSpecType()) { case TST_typename: case TST_typeofType: - case TST_underlyingType: +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait: +#include "clang/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_DEF 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 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -19,9 +19,11 @@ #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" @@ -1265,6 +1267,19 @@ 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/AST/TransformTypeTraits.def" +#undef TRANSFORM_TYPE_TRAIT_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 @@ -1647,12 +1662,13 @@ } break; } - case DeclSpec::TST_underlyingType: +#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case DeclSpec::TST_##Trait: +#include "clang/AST/TransformTypeTraits.def" Result = S.GetTypeFromParser(DS.getRepAsType()); - assert(!Result.isNull() && "Didn't get a type for __underlying_type?"); - Result = S.BuildUnaryTransformType(Result, - UnaryTransformType::EnumUnderlyingType, - DS.getTypeSpecTypeLoc()); + assert(!Result.isNull() && "Didn't get a type for the transformation?"); + Result = S.BuildUnaryTransformType( + Result, TSTToUnaryTransformType(DS.getTypeSpecType()), + DS.getTypeSpecTypeLoc()); if (Result.isNull()) { Result = Context.IntTy; declarator.setInvalidType(true); @@ -6014,8 +6030,9 @@ TL.setRParenLoc(DS.getTypeofParensRange().getEnd()); } void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { - // FIXME: This holds only because we only have one unary transform. - assert(DS.getTypeSpecType() == DeclSpec::TST_underlyingType); + // Make sure it is a unary transform type. + assert(DS.getTypeSpecType() >= DeclSpec::TST_add_lvalue_reference && + DS.getTypeSpecType() <= DeclSpec::TST_underlying_type); TL.setKWLoc(DS.getTypeSpecTypeLoc()); TL.setParensRange(DS.getTypeofParensRange()); assert(DS.getRepAsType()); @@ -9080,37 +9097,189 @@ return Context.getDecltypeType(E, getDecltypeForExpr(E)); } -QualType Sema::BuildUnaryTransformType(QualType BaseType, - UnaryTransformType::UTTKind UKind, +QualType Sema::BuiltinEnumUnderlyingType(QualType BaseType, + SourceLocation Loc) { + constexpr auto UKind = UTTKind::EnumUnderlyingType; + 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(); + } + + EnumDecl *ED = BaseType->castAs()->getDecl(); + assert(ED && "EnumType has no EnumDecl"); + + DiagnoseUseOfDecl(ED, Loc); + + QualType Underlying = ED->getIntegerType(); + assert(!Underlying.isNull()); + return Context.getUnaryTransformType(BaseType, Underlying, UKind); +} + +QualType Sema::BuiltinAddPointer(QualType BaseType, SourceLocation Loc) { + DeclarationName EntityName(BaseType.getBaseTypeIdentifier()); + QualType PointerToT = + BaseType.isReferenceable(LangOpts.CPlusPlus) || BaseType->isVoidType() + ? BuildPointerType(BaseType.getNonReferenceType(), Loc, EntityName) + : BaseType; + return Context.getUnaryTransformType(BaseType, PointerToT, + UTTKind::AddPointer); +} + +QualType Sema::BuiltinRemovePointer(QualType BaseType, SourceLocation Loc) { + constexpr auto UKind = UTTKind::RemovePointer; + if (!BaseType->isPointerType() && !BaseType->isObjCObjectPointerType()) + return Context.getUnaryTransformType(BaseType, BaseType, UKind); + return Context.getUnaryTransformType(BaseType, BaseType->getPointeeType(), + UKind); +} + +QualType Sema::BuiltinDecay(QualType BaseType, SourceLocation Loc) { + constexpr auto UKind = UnaryTransformType::Decay; + QualType Underlying = BaseType.getNonReferenceType(); + if (Underlying->isArrayType() || Underlying->isFunctionType()) + return Context.getUnaryTransformType( + BaseType, Context.getDecayedType(Underlying), UKind); + + Qualifiers Quals = Underlying.getQualifiers(); + Quals.removeCVRQualifiers(); + return Context.getUnaryTransformType( + BaseType, + QualType(Underlying.getSplitUnqualifiedType().Ty, + Quals.getAsOpaqueValue()), + UKind); +} + +QualType Sema::BuiltinAddReference(QualType BaseType, UTTKind UKind, + SourceLocation Loc) { + DeclarationName EntityName(BaseType.getBaseTypeIdentifier()); + QualType PointerToT = + QualType(BaseType).isReferenceable(LangOpts.CPlusPlus) + ? BuildReferenceType(BaseType, + UKind == UnaryTransformType::AddLvalueReference, + Loc, EntityName) + : BaseType; + return Context.getUnaryTransformType(BaseType, PointerToT, UKind); +} + +QualType Sema::BuiltinRemoveExtent(QualType BaseType, UTTKind UKind, + SourceLocation Loc) { + if (!BaseType->isArrayType()) + return Context.getUnaryTransformType(BaseType, BaseType, UKind); + const ArrayType *ArrayType = BaseType->getAsArrayTypeUnsafe(); + QualType ElementType = + UKind == UnaryTransformType::RemoveAllExtents + ? QualType(ArrayType->getBaseElementTypeUnsafe(), {}) + : ArrayType->getElementType(); + QualType Underlying = {ElementType.getSplitUnqualifiedType().Ty, + BaseType.getCVRQualifiers()}; + return Context.getUnaryTransformType(BaseType, Underlying, UKind); +} + +QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind, + SourceLocation Loc) { + QualType Underlying = BaseType.getNonReferenceType(); + Qualifiers Quals = Underlying.getQualifiers(); + if (UKind == UnaryTransformType::RemoveCVRef) { + Quals.removeConst(); + Quals.removeVolatile(); + } + return Context.getUnaryTransformType( + BaseType, + QualType(Underlying.getSplitUnqualifiedType().Ty, + Quals.getAsOpaqueValue()), + UKind); +} + +QualType Sema::BuiltinChangeCVQualifiers(QualType BaseType, UTTKind UKind, + SourceLocation Loc) { + SplitQualType Split = BaseType.getSplitUnqualifiedType(); + Qualifiers Quals = BaseType.getQualifiers(); + if ((BaseType->isReferenceType() && UKind != UTTKind::RemoveRestrict) || + BaseType->isFunctionType()) + return Context.getUnaryTransformType(BaseType, BaseType, UKind); + + if (UKind == UnaryTransformType::RemoveConst || + UKind == UnaryTransformType::RemoveCV) + Quals.removeConst(); + if (UKind == UnaryTransformType::RemoveVolatile || + UKind == UnaryTransformType::RemoveCV) + Quals.removeVolatile(); + if (UKind == UnaryTransformType::RemoveRestrict) + Quals.removeRestrict(); + + QualType Underlying(Split.Ty, Quals.getAsOpaqueValue()); + return Context.getUnaryTransformType(BaseType, Underlying, UKind); +} + +QualType Sema::BuiltinChangeSignedness(QualType BaseType, UTTKind UKind, SourceLocation Loc) { - 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(); - } + if (BaseType->isDependentType()) + return Context.getUnaryTransformType(BaseType, BaseType, UKind); + bool IsMakeSigned = UKind == UnaryTransformType::MakeSigned; + if ((!BaseType->isIntegerType() && !BaseType->isEnumeralType()) || + BaseType->isBooleanType()) { + Diag(Loc, diag::err_make_signed_integral_only) << IsMakeSigned << BaseType; + return QualType(); + } + bool IsSigned = BaseType->isSignedIntegerType(); + bool IsNonCharIntegral = BaseType->isCharType() || BaseType->isEnumeralType(); - EnumDecl *ED = BaseType->castAs()->getDecl(); - assert(ED && "EnumType has no EnumDecl"); + // Clang doesn't seem to have a way to distinguish `char` from `signed char` + // and `unsigned char` + if (IsMakeSigned == IsSigned && !IsNonCharIntegral) + return Context.getUnaryTransformType(BaseType, BaseType, UKind); - DiagnoseUseOfDecl(ED, Loc); + QualType Underlying = + BaseType->isBitIntType() + ? Context.getBitIntType(!IsMakeSigned, Context.getIntWidth(BaseType)) + : Context.getIntTypeForBitwidth(Context.getIntWidth(BaseType), + IsMakeSigned); + Qualifiers Quals = Underlying.getQualifiers(); + Quals.setCVRQualifiers(BaseType.getCVRQualifiers()); + Underlying = QualType(Underlying.getSplitUnqualifiedType().Ty, + Quals.getAsOpaqueValue()); + return Context.getUnaryTransformType(BaseType, Underlying, UKind); +} - Underlying = ED->getIntegerType(); - assert(!Underlying.isNull()); - } - return Context.getUnaryTransformType(BaseType, Underlying, - UnaryTransformType::EnumUnderlyingType); - } +QualType Sema::BuildUnaryTransformType(QualType BaseType, UTTKind UKind, + SourceLocation Loc) { + if (BaseType->isDependentType()) + return Context.getUnaryTransformType(BaseType, BaseType, UKind); + switch (UKind) { + case UnaryTransformType::EnumUnderlyingType: + return BuiltinEnumUnderlyingType(BaseType, Loc); + case UnaryTransformType::AddPointer: + return BuiltinAddPointer(BaseType, Loc); + case UnaryTransformType::RemovePointer: + return BuiltinRemovePointer(BaseType, Loc); + case UnaryTransformType::Decay: + return BuiltinDecay(BaseType, Loc); + case UnaryTransformType::AddLvalueReference: + case UnaryTransformType::AddRvalueReference: + return BuiltinAddReference(BaseType, UKind, Loc); + case UnaryTransformType::RemoveAllExtents: + case UnaryTransformType::RemoveExtent: + return BuiltinRemoveExtent(BaseType, UKind, Loc); + case UnaryTransformType::RemoveCVRef: + case UnaryTransformType::RemoveReference: + return BuiltinRemoveReference(BaseType, UKind, Loc); + case UnaryTransformType::RemoveConst: + case UnaryTransformType::RemoveCV: + case UnaryTransformType::RemoveRestrict: + case UnaryTransformType::RemoveVolatile: + return BuiltinChangeCVQualifiers(BaseType, UKind, Loc); + case UnaryTransformType::MakeSigned: + case UnaryTransformType::MakeUnsigned: + return BuiltinChangeSignedness(BaseType, UKind, Loc); } llvm_unreachable("unknown unary transform type"); } diff --git a/clang/test/CodeGenCXX/mangle.cpp b/clang/test/CodeGenCXX/mangle.cpp --- a/clang/test/CodeGenCXX/mangle.cpp +++ b/clang/test/CodeGenCXX/mangle.cpp @@ -51,7 +51,7 @@ namespace N { int h(); void g() { static int a = h(); } } // CHECK-LABEL: define{{.*}} void @_Z1fno -void f(__int128_t, __uint128_t) { } +void f(__int128_t, __uint128_t) {} template struct S1 {}; @@ -101,13 +101,13 @@ void g1() { // CHECK: @_Z3ft1IidEvT0_T_ ft1(1, 0); - + // CHECK: @_Z3ft2IcEvT_PFvS0_ES2_ ft2(1, 0, 0); - + // CHECK: @_Z3ft3IiEvP2S4IT_2S1IS1_EE ft3(0); - + // CHECK: @_ZN2NS3ft1IiEEvT_ NS::ft1(1); } @@ -119,14 +119,14 @@ void g2() { // CHECK: @_Z3ft4ILi10EEv2S5IXT_EE ft4(S5<10>()); - + // CHECK: @_Z3ft4ILi20EEv2S5IXT_EE ft4(S5<20>()); } extern "C++" { // CHECK: @_Z1hv - void h() { } +void h() {} } // PR5019 @@ -208,7 +208,7 @@ struct S7 { S7(); - + struct S { S(); }; struct { S s; @@ -276,7 +276,7 @@ Ops& operator-(const Ops&); Ops& operator&(const Ops&); Ops& operator*(const Ops&); - + void *v; }; @@ -493,7 +493,7 @@ struct A { void f(...); }; - + // CHECK: @_ZN6test111A1fEz void A::f(...) { } } @@ -832,9 +832,9 @@ namespace test35 { // Dependent operator names of unknown arity. - struct A { - template A operator+(U) const; - }; +struct A { + template A operator+(U) const; +}; template void f1(decltype(sizeof(&T::template operator+))) {} @@ -1110,7 +1110,7 @@ void fn(T, __underlying_type(T)) {} template void fn(E, __underlying_type(E)); -// CHECK-LABEL: @_ZN6test552fnINS_1EEEEvT_U3eutS2_ +// CHECK-LABEL: @_ZN6test552fnINS_1EEEEvT_Uu17__underlying_typeS2_ } namespace test56 { @@ -1155,3 +1155,99 @@ // CHECK-LABEL: @_ZN6test601fIiEEvDTplL_ZNS_1aEEcvT__EE template void f(int); } + +namespace test61 { +template void f(T, __add_lvalue_reference(T)) {} +template void f(int, __add_lvalue_reference(int)); +// CHECK-LABEL: @_ZN6test611fIiEEvT_Uu22__add_lvalue_referenceS1_ +} // namespace test61 + +namespace test62 { +template void f(T, __add_pointer(T)) {} +template void f(int, __add_pointer(int)); +// CHECK-LABEL: @_ZN6test621fIiEEvT_Uu13__add_pointerS1_ +} // namespace test62 + +namespace test63 { +template void f(T, __add_rvalue_reference(T)) {} +template void f(int, __add_rvalue_reference(int)); +// CHECK-LABEL: @_ZN6test631fIiEEvT_Uu22__add_rvalue_referenceS1_ +} // namespace test63 + +namespace test64 { +template void f(T, __decay(T)) {} +template void f(int, __decay(int)); +// CHECK-LABEL: @_ZN6test641fIiEEvT_Uu7__decayS1_ +} // namespace test64 + +namespace test65 { +template void f(T, __make_signed(T)) {} +template void f(int, __make_signed(int)); +// CHECK-LABEL: @_ZN6test651fIiEEvT_Uu13__make_signedS1_ +} // namespace test65 + +namespace test66 { +template void f(T, __make_unsigned(T)) {} +template void f(int, __make_unsigned(int)); +// CHECK-LABEL: @_ZN6test661fIiEEvT_Uu15__make_unsignedS1_ +} // namespace test66 + +namespace test67 { +template void f(T, __remove_const(T)) {} +template void f(int, __remove_const(int)); +// CHECK-LABEL: @_ZN6test671fIiEEvT_Uu14__remove_constS1_ +} // namespace test67 + +namespace test68 { +template void f(T, __remove_cv(T)) {} +template void f(int, __remove_cv(int)); +// CHECK-LABEL: @_ZN6test681fIiEEvT_Uu11__remove_cvS1_ +} // namespace test68 + +namespace test69 { +template void f(T, __remove_cvref(T)) {} +template void f(int, __remove_cvref(int)); +// CHECK-LABEL: @_ZN6test691fIiEEvT_Uu14__remove_cvrefS1_ +} // namespace test69 + +namespace test70 { +template void f(T, __remove_volatile(T)) {} +template void f(int, __remove_volatile(int)); +// CHECK-LABEL: @_ZN6test701fIiEEvT_Uu17__remove_volatileS1_ +} // namespace test70 + +namespace test71 { +template void f(T, __remove_extent(T)) {} +template void f(int, __remove_extent(int)); +// CHECK-LABEL: @_ZN6test711fIiEEvT_Uu15__remove_extentS1_ +} // namespace test71 + +namespace test72 { +template void f(T, __remove_all_extents(T)) {} +template void f(int, __remove_all_extents(int)); +// CHECK-LABEL: @_ZN6test721fIiEEvT_Uu20__remove_all_extentsS1_ +} // namespace test72 + +namespace test73 { +template void f(T, __remove_pointer(T)) {} +template void f(int, __remove_pointer(int)); +// CHECK-LABEL: @_ZN6test731fIiEEvT_Uu16__remove_pointerS1_ +} // namespace test73 + +namespace test74 { +template void f(T, __remove_reference(T)) {} +template void f(int, __remove_reference(int)); +// CHECK-LABEL: @_ZN6test741fIiEEvT_Uu18__remove_referenceS1_ +} // namespace test74 + +namespace test75 { +template void f(T, __remove_volatile(T)) {} +template void f(int, __remove_volatile(int)); +// CHECK-LABEL: @_ZN6test751fIiEEvT_Uu17__remove_volatileS1_ +} // namespace test75 + +namespace test76 { +template void f(T, __remove_restrict(T)) {} +template void f(int, __remove_restrict(int)); +// CHECK-LABEL: @_ZN6test761fIiEEvT_Uu17__remove_restrictS1_ +} // namespace test76 diff --git a/clang/test/SemaCXX/remove_pointer.mm b/clang/test/SemaCXX/remove_pointer.mm new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/remove_pointer.mm @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++11 -fms-extensions -Wno-microsoft %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++14 -fms-extensions -Wno-microsoft %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -std=gnu++1z -fms-extensions -Wno-microsoft %s + +// expected-no-diagnostics + +template using remove_pointer_t = __remove_pointer(T); + +#define T(b) (b) ? 1 : -1 +#define F(b) (b) ? -1 : 1 + +void remove_pointer() { + { int a[T(__is_same(remove_pointer_t, void))]; } + { int a[T(__is_same(remove_pointer_t, const void))]; } + { int a[T(__is_same(remove_pointer_t, volatile void))]; } + { int a[T(__is_same(remove_pointer_t, const volatile void))]; } + { int a[T(__is_same(remove_pointer_t, int))]; } + { int a[T(__is_same(remove_pointer_t, const int))]; } + { int a[T(__is_same(remove_pointer_t, volatile int))]; } + { int a[T(__is_same(remove_pointer_t, const volatile int))]; } + { int a[T(__is_same(remove_pointer_t, int))]; } + { int a[T(__is_same(remove_pointer_t, int &))]; } + { int a[T(__is_same(remove_pointer_t, int &&))]; } + { int a[T(__is_same(remove_pointer_t, int()))]; } + { int a[T(__is_same(remove_pointer_t, int()))]; } + { int a[T(__is_same(remove_pointer_t, int (&)()))]; } + + struct S {}; + { int a[T(__is_same(remove_pointer_t, S))]; } + { int a[T(__is_same(remove_pointer_t, const S))]; } + { int a[T(__is_same(remove_pointer_t, volatile S))]; } + { int a[T(__is_same(remove_pointer_t, const volatile S))]; } + { int a[T(__is_same(remove_pointer_t, int S::*))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)()))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() &))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() &&))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const &))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const &&))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() volatile))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const volatile &&))]; } +} diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -14,6 +14,9 @@ enum Enum { EV }; enum SignedEnum : signed int { }; enum UnsignedEnum : unsigned int { }; +enum class EnumClass { EV }; +enum class SignedEnumClass : signed int {}; +enum class UnsignedEnumClass : unsigned int {}; struct POD { Enum e; int i; float f; NonPOD* p; }; struct Empty {}; struct IncompleteStruct; @@ -2854,3 +2857,994 @@ #undef T16384 #undef T32768 } // namespace type_trait_expr_numargs_overflow + +struct S {}; +template using remove_const_t = __remove_const(T); + +void check_remove_const() { + { int a[T(__is_same(remove_const_t, void))]; } + { int a[T(__is_same(remove_const_t, void))]; } + { int a[T(__is_same(remove_const_t, int))]; } + { int a[T(__is_same(remove_const_t, int))]; } + { int a[T(__is_same(remove_const_t, volatile int))]; } + { int a[T(__is_same(remove_const_t, volatile int))]; } + { int a[T(__is_same(remove_const_t, int *))]; } + { int a[T(__is_same(remove_const_t, int *))]; } + { int a[T(__is_same(remove_const_t, int const *))]; } + { int a[T(__is_same(remove_const_t, int const *__restrict))]; } + { int a[T(__is_same(remove_const_t, int &))]; } + { int a[T(__is_same(remove_const_t, int const &))]; } + { int a[T(__is_same(remove_const_t, int &&))]; } + { int a[T(__is_same(remove_const_t, int const &&))]; } + { int a[T(__is_same(remove_const_t, int()))]; } + { int a[T(__is_same(remove_const_t, int (*)()))]; } + { int a[T(__is_same(remove_const_t, int (&)()))]; } + + { int a[T(__is_same(remove_const_t, S))]; } + { int a[T(__is_same(remove_const_t, S))]; } + { int a[T(__is_same(remove_const_t, volatile S))]; } + { int a[T(__is_same(remove_const_t, S *__restrict))]; } + { int a[T(__is_same(remove_const_t, volatile S))]; } + { int a[T(__is_same(remove_const_t, S *volatile __restrict))]; } + { int a[T(__is_same(remove_const_t, int S::*))]; } + { int a[T(__is_same(remove_const_t, int(S::*)()))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() &))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() &&))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() const))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() const &))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() const &&))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() volatile))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(remove_const_t, int(S::*)() const volatile &&))]; } +} + +template using remove_restrict_t = __remove_restrict(T); + +void check_remove_restrict() { + { int a[T(__is_same(remove_restrict_t, void))]; } + { int a[T(__is_same(remove_restrict_t, int))]; } + { int a[T(__is_same(remove_restrict_t, const int))]; } + { int a[T(__is_same(remove_restrict_t, volatile int))]; } + { int a[T(__is_same(remove_restrict_t, int *))]; } + { int a[T(__is_same(remove_restrict_t, int *const volatile))]; } + { int a[T(__is_same(remove_restrict_t, int *))]; } + { int a[T(__is_same(remove_restrict_t, int *))]; } + { int a[T(__is_same(remove_restrict_t, int &))]; } + { int a[T(__is_same(remove_restrict_t, int &))]; } + { int a[T(__is_same(remove_restrict_t, int &&))]; } + { int a[T(__is_same(remove_restrict_t, int &&))]; } + { int a[T(__is_same(remove_restrict_t, int()))]; } + { int a[T(__is_same(remove_restrict_t, int (*const volatile)()))]; } + { int a[T(__is_same(remove_restrict_t, int (&)()))]; } + + { int a[T(__is_same(remove_restrict_t, S))]; } + { int a[T(__is_same(remove_restrict_t, const S))]; } + { int a[T(__is_same(remove_restrict_t, volatile S))]; } + { int a[T(__is_same(remove_restrict_t, S *))]; } + { int a[T(__is_same(remove_restrict_t, S *const volatile))]; } + { int a[T(__is_same(remove_restrict_t, int S::*))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)()))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() &))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() &&))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() const))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() const &))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() const &&))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() volatile))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() volatile &))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() volatile &&))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() const volatile))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() const volatile &))]; } + { int a[T(__is_same(remove_restrict_t, int(S::*const volatile)() const volatile &&))]; } +} + +template using remove_volatile_t = __remove_volatile(T); + +void check_remove_volatile() { + { int a[T(__is_same(remove_volatile_t, void))]; } + { int a[T(__is_same(remove_volatile_t, void))]; } + { int a[T(__is_same(remove_volatile_t, int))]; } + { int a[T(__is_same(remove_volatile_t, const int))]; } + { int a[T(__is_same(remove_volatile_t, int))]; } + { int a[T(__is_same(remove_volatile_t, int *__restrict))]; } + { int a[T(__is_same(remove_volatile_t, const int))]; } + { int a[T(__is_same(remove_volatile_t, int *const __restrict))]; } + { int a[T(__is_same(remove_volatile_t, int *))]; } + { int a[T(__is_same(remove_volatile_t, int *))]; } + { int a[T(__is_same(remove_volatile_t, int volatile *))]; } + { int a[T(__is_same(remove_volatile_t, int &))]; } + { int a[T(__is_same(remove_volatile_t, int volatile &))]; } + { int a[T(__is_same(remove_volatile_t, int &&))]; } + { int a[T(__is_same(remove_volatile_t, int volatile &&))]; } + { int a[T(__is_same(remove_volatile_t, int()))]; } + { int a[T(__is_same(remove_volatile_t, int (*)()))]; } + { int a[T(__is_same(remove_volatile_t, int (&)()))]; } + + { int a[T(__is_same(remove_volatile_t, S))]; } + { int a[T(__is_same(remove_volatile_t, const S))]; } + { int a[T(__is_same(remove_volatile_t, S))]; } + { int a[T(__is_same(remove_volatile_t, const S))]; } + { int a[T(__is_same(remove_volatile_t, int S::*))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)()))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() &))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() &&))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() const))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() const &))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() const &&))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() volatile))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(remove_volatile_t, int(S::*)() const volatile &&))]; } +} + +template using remove_cv_t = __remove_cv(T); + +void check_remove_cv() { + { int a[T(__is_same(remove_cv_t, void))]; } + { int a[T(__is_same(remove_cv_t, void))]; } + { int a[T(__is_same(remove_cv_t, int))]; } + { int a[T(__is_same(remove_cv_t, int))]; } + { int a[T(__is_same(remove_cv_t, int))]; } + { int a[T(__is_same(remove_cv_t, int))]; } + { int a[T(__is_same(remove_cv_t, int *))]; } + { int a[T(__is_same(remove_cv_t, int *))]; } + { int a[T(__is_same(remove_cv_t, int const *))]; } + { int a[T(__is_same(remove_cv_t, int &))]; } + { int a[T(__is_same(remove_cv_t, int const volatile &))]; } + { int a[T(__is_same(remove_cv_t, int &&))]; } + { int a[T(__is_same(remove_cv_t, int const volatile &&))]; } + { int a[T(__is_same(remove_cv_t, int()))]; } + { int a[T(__is_same(remove_cv_t, int (*)()))]; } + { int a[T(__is_same(remove_cv_t, int (&)()))]; } + + { int a[T(__is_same(remove_cv_t, S))]; } + { int a[T(__is_same(remove_cv_t, S))]; } + { int a[T(__is_same(remove_cv_t, S))]; } + { int a[T(__is_same(remove_cv_t, S))]; } + { int a[T(__is_same(remove_cv_t, int S::*))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)()))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() &))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() &&))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() const))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() const &))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() const &&))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() volatile))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(remove_cv_t, int(S::*)() const volatile &&))]; } +} + +template using add_pointer_t = __add_pointer(T); + +void add_pointer() { + { int a[T(__is_same(add_pointer_t, void *))]; } + { int a[T(__is_same(add_pointer_t, const void *))]; } + { int a[T(__is_same(add_pointer_t, volatile void *))]; } + { int a[T(__is_same(add_pointer_t, const volatile void *))]; } + { int a[T(__is_same(add_pointer_t, int *))]; } + { int a[T(__is_same(add_pointer_t, const int *))]; } + { int a[T(__is_same(add_pointer_t, volatile int *))]; } + { int a[T(__is_same(add_pointer_t, const volatile int *))]; } + { int a[T(__is_same(add_pointer_t, int **))]; } + { int a[T(__is_same(add_pointer_t, int *))]; } + { int a[T(__is_same(add_pointer_t, int *))]; } + { int a[T(__is_same(add_pointer_t, int (*)()))]; } + { int a[T(__is_same(add_pointer_t, int (**)()))]; } + { int a[T(__is_same(add_pointer_t, int (*)()))]; } + + { int a[T(__is_same(add_pointer_t, S *))]; } + { int a[T(__is_same(add_pointer_t, const S *))]; } + { int a[T(__is_same(add_pointer_t, volatile S *))]; } + { int a[T(__is_same(add_pointer_t, const volatile S *))]; } + { int a[T(__is_same(add_pointer_t, int S::**))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)()))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() &))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() &&))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() const))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() const &))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() const &&))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() volatile))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() volatile &))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() volatile &&))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() const volatile))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() const volatile &))]; } + { int a[T(__is_same(add_pointer_t, int(S::**)() const volatile &&))]; } +} + +template using remove_pointer_t = __remove_pointer(T); + +void remove_pointer() { + { int a[T(__is_same(remove_pointer_t, void))]; } + { int a[T(__is_same(remove_pointer_t, const void))]; } + { int a[T(__is_same(remove_pointer_t, volatile void))]; } + { int a[T(__is_same(remove_pointer_t, const volatile void))]; } + { int a[T(__is_same(remove_pointer_t, int))]; } + { int a[T(__is_same(remove_pointer_t, const int))]; } + { int a[T(__is_same(remove_pointer_t, volatile int))]; } + { int a[T(__is_same(remove_pointer_t, const volatile int))]; } + { int a[T(__is_same(remove_pointer_t, int))]; } + { int a[T(__is_same(remove_pointer_t, int &))]; } + { int a[T(__is_same(remove_pointer_t, int &&))]; } + { int a[T(__is_same(remove_pointer_t, int()))]; } + { int a[T(__is_same(remove_pointer_t, int()))]; } + { int a[T(__is_same(remove_pointer_t, int (&)()))]; } + + { int a[T(__is_same(remove_pointer_t, S))]; } + { int a[T(__is_same(remove_pointer_t, const S))]; } + { int a[T(__is_same(remove_pointer_t, volatile S))]; } + { int a[T(__is_same(remove_pointer_t, const volatile S))]; } + { int a[T(__is_same(remove_pointer_t, int S::*))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)()))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() &))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() &&))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const &))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const &&))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() volatile))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(remove_pointer_t, int(S::*)() const volatile &&))]; } +} + +template using add_lvalue_reference_t = __add_lvalue_reference(T); + +void add_lvalue_reference() { + { int a[T(__is_same(add_lvalue_reference_t, void))]; } + { int a[T(__is_same(add_lvalue_reference_t, const void))]; } + { int a[T(__is_same(add_lvalue_reference_t, volatile void))]; } + { int a[T(__is_same(add_lvalue_reference_t, const volatile void))]; } + { int a[T(__is_same(add_lvalue_reference_t, int &))]; } + { int a[T(__is_same(add_lvalue_reference_t, const int &))]; } + { int a[T(__is_same(add_lvalue_reference_t, volatile int &))]; } + { int a[T(__is_same(add_lvalue_reference_t, const volatile int &))]; } + { int a[T(__is_same(add_lvalue_reference_t, int *&))]; } + { int a[T(__is_same(add_lvalue_reference_t, int &))]; } + { int a[T(__is_same(add_lvalue_reference_t, int &))]; } // reference collapsing + { int a[T(__is_same(add_lvalue_reference_t, int (&)()))]; } + { int a[T(__is_same(add_lvalue_reference_t, int (*&)()))]; } + { int a[T(__is_same(add_lvalue_reference_t, int (&)()))]; } + + { int a[T(__is_same(add_lvalue_reference_t, S &))]; } + { int a[T(__is_same(add_lvalue_reference_t, const S &))]; } + { int a[T(__is_same(add_lvalue_reference_t, volatile S &))]; } + { int a[T(__is_same(add_lvalue_reference_t, const volatile S &))]; } + { int a[T(__is_same(add_lvalue_reference_t, int S::*&))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)()))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() &))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() &&))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() const))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() const &))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() const &&))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() volatile))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() volatile &))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() volatile &&))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() const volatile))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() const volatile &))]; } + { int a[T(__is_same(add_lvalue_reference_t, int(S::*&)() const volatile &&))]; } +} + +template using add_rvalue_reference_t = __add_rvalue_reference(T); + +void add_rvalue_reference() { + { int a[T(__is_same(add_rvalue_reference_t, void))]; } + { int a[T(__is_same(add_rvalue_reference_t, const void))]; } + { int a[T(__is_same(add_rvalue_reference_t, volatile void))]; } + { int a[T(__is_same(add_rvalue_reference_t, const volatile void))]; } + { int a[T(__is_same(add_rvalue_reference_t, int &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, const int &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, volatile int &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, const volatile int &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, int *&&))]; } + { int a[T(__is_same(add_rvalue_reference_t, int &))]; } // reference collapsing + { int a[T(__is_same(add_rvalue_reference_t, int &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(&&)()))]; } + { int a[T(__is_same(add_rvalue_reference_t, int (*&&)()))]; } + { int a[T(__is_same(add_rvalue_reference_t, int (&)()))]; } // reference collapsing + + { int a[T(__is_same(add_rvalue_reference_t, S &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, const S &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, volatile S &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, const volatile S &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, int S::*&&))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)()))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() &))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() const))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() const &))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() const &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() volatile))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() volatile &))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() volatile &&))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() const volatile))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() const volatile &))]; } + { int a[T(__is_same(add_rvalue_reference_t, int(S::* &&)() const volatile &&))]; } +} + +template using remove_reference_t = __remove_reference(T); + +void check_remove_reference() { + { int a[T(__is_same(remove_reference_t, void))]; } + { int a[T(__is_same(remove_reference_t, const volatile void))]; } + { int a[T(__is_same(remove_reference_t, int))]; } + { int a[T(__is_same(remove_reference_t, const int))]; } + { int a[T(__is_same(remove_reference_t, volatile int))]; } + { int a[T(__is_same(remove_reference_t, const volatile int))]; } + { int a[T(__is_same(remove_reference_t, int *))]; } + { int a[T(__is_same(remove_reference_t, int *const volatile))]; } + { int a[T(__is_same(remove_reference_t, int const *const volatile))]; } + { int a[T(__is_same(remove_reference_t, int))]; } + { int a[T(__is_same(remove_reference_t, int const volatile))]; } + { int a[T(__is_same(remove_reference_t, int))]; } + { int a[T(__is_same(remove_reference_t, int const volatile))]; } + { int a[T(__is_same(remove_reference_t, int()))]; } + { int a[T(__is_same(remove_reference_t, int (*const volatile)()))]; } + { int a[T(__is_same(remove_reference_t, int()))]; } + + { int a[T(__is_same(remove_reference_t, S))]; } + { int a[T(__is_same(remove_reference_t, S))]; } + { int a[T(__is_same(remove_reference_t, S))]; } + { int a[T(__is_same(remove_reference_t, const S))]; } + { int a[T(__is_same(remove_reference_t, const S))]; } + { int a[T(__is_same(remove_reference_t, const S))]; } + { int a[T(__is_same(remove_reference_t, volatile S))]; } + { int a[T(__is_same(remove_reference_t, volatile S))]; } + { int a[T(__is_same(remove_reference_t, volatile S))]; } + { int a[T(__is_same(remove_reference_t, const volatile S))]; } + { int a[T(__is_same(remove_reference_t, const volatile S))]; } + { int a[T(__is_same(remove_reference_t, const volatile S))]; } + { int a[T(__is_same(remove_reference_t, int S::*const volatile))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)()))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() &))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() &&))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const &))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const &&))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() volatile))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() volatile &))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() volatile &&))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const volatile))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const volatile &))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const volatile &&))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)()))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() &))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() &&))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const &))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const &&))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() volatile))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() volatile &))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() volatile &&))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const volatile))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const volatile &))]; } + { int a[T(__is_same(remove_reference_t, int(S::*const volatile)() const volatile &&))]; } +} + +template using remove_cvref_t = __remove_cvref(T); + +void check_remove_cvref() { + { int a[T(__is_same(remove_cvref_t, void))]; } + { int a[T(__is_same(remove_cvref_t, void))]; } + { int a[T(__is_same(remove_cvref_t, int))]; } + { int a[T(__is_same(remove_cvref_t, int))]; } + { int a[T(__is_same(remove_cvref_t, int))]; } + { int a[T(__is_same(remove_cvref_t, int))]; } + { int a[T(__is_same(remove_cvref_t, int *))]; } + { int a[T(__is_same(remove_cvref_t, int *))]; } + { int a[T(__is_same(remove_cvref_t, int const *))]; } + { int a[T(__is_same(remove_cvref_t, int))]; } + { int a[T(__is_same(remove_cvref_t, int))]; } + { int a[T(__is_same(remove_cvref_t, int))]; } + { int a[T(__is_same(remove_cvref_t, int))]; } + { int a[T(__is_same(remove_cvref_t, int()))]; } + { int a[T(__is_same(remove_cvref_t, int (*)()))]; } + { int a[T(__is_same(remove_cvref_t, int()))]; } + + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, S))]; } + { int a[T(__is_same(remove_cvref_t, int S::*))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)()))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile &&))]; } + { int a[T(__is_same(remove_cvref_t, int S::*))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)()))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile &&))]; } + { int a[T(__is_same(remove_cvref_t, int S::*))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)()))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(remove_cvref_t, int(S::*)() const volatile &&))]; } +} + +template using decay_t = __decay(T); + +void check_decay() { + { int a[T(__is_same(decay_t, void))]; } + { int a[T(__is_same(decay_t, void))]; } + { int a[T(__is_same(decay_t, int))]; } + { int a[T(__is_same(decay_t, int))]; } + { int a[T(__is_same(decay_t, int))]; } + { int a[T(__is_same(decay_t, int))]; } + { int a[T(__is_same(decay_t, int *))]; } + { int a[T(__is_same(decay_t, int *))]; } + { int a[T(__is_same(decay_t, int const *))]; } + { int a[T(__is_same(decay_t, int))]; } + { int a[T(__is_same(decay_t, int))]; } + { int a[T(__is_same(decay_t, int))]; } + { int a[T(__is_same(decay_t, int))]; } + { int a[T(__is_same(decay_t, int (*)()))]; } + { int a[T(__is_same(decay_t, int (*)()))]; } + { int a[T(__is_same(decay_t, int (*)()))]; } + { int a[T(__is_same(decay_t, int (*)()))]; } + { int a[T(__is_same(decay_t, int (*)()))]; } + { int a[T(__is_same(decay_t, int (*)()))]; } + { int a[T(__is_same(decay_t, int *))]; } + { int a[T(__is_same(decay_t, int *))]; } + + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, S))]; } + { int a[T(__is_same(decay_t, int S::*))]; } + { int a[T(__is_same(decay_t, int(S::*)()))]; } + { int a[T(__is_same(decay_t, int(S::*)() &))]; } + { int a[T(__is_same(decay_t, int(S::*)() &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() const))]; } + { int a[T(__is_same(decay_t, int(S::*)() const &))]; } + { int a[T(__is_same(decay_t, int(S::*)() const &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile &&))]; } + { int a[T(__is_same(decay_t, int S::*))]; } + { int a[T(__is_same(decay_t, int(S::*)()))]; } + { int a[T(__is_same(decay_t, int(S::*)() &))]; } + { int a[T(__is_same(decay_t, int(S::*)() &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() const))]; } + { int a[T(__is_same(decay_t, int(S::*)() const &))]; } + { int a[T(__is_same(decay_t, int(S::*)() const &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile &&))]; } + { int a[T(__is_same(decay_t, int S::*))]; } + { int a[T(__is_same(decay_t, int(S::*)()))]; } + { int a[T(__is_same(decay_t, int(S::*)() &))]; } + { int a[T(__is_same(decay_t, int(S::*)() &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() const))]; } + { int a[T(__is_same(decay_t, int(S::*)() const &))]; } + { int a[T(__is_same(decay_t, int(S::*)() const &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile &))]; } + { int a[T(__is_same(decay_t, int(S::*)() volatile &&))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile &))]; } + { int a[T(__is_same(decay_t, int(S::*)() const volatile &&))]; } +} + +template struct CheckAbominableFunction {}; +template +struct CheckAbominableFunction { + static void checks() { + { int a[T(__is_same(add_lvalue_reference_t, M))]; } + { int a[T(__is_same(add_pointer_t, M))]; } + { int a[T(__is_same(add_rvalue_reference_t, M))]; } + { int a[T(__is_same(remove_const_t, M))]; } + { int a[T(__is_same(remove_volatile_t, M))]; } + { int a[T(__is_same(remove_cv_t, M))]; } + { int a[T(__is_same(remove_cvref_t, M))]; } + { int a[T(__is_same(remove_pointer_t, M))]; } + { int a[T(__is_same(remove_reference_t, M))]; } + } +}; + +void check_abominable_function() { + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } + { CheckAbominableFunction x; } +} + +template using make_signed_t = __make_signed(T); + +void make_signed() { + { int a[T(__is_same(make_signed_t, signed char))]; } + { int a[T(__is_same(make_signed_t, const signed char))]; } + { int a[T(__is_same(make_signed_t, volatile signed char))]; } + { int a[T(__is_same(make_signed_t, const volatile signed char))]; } + + { int a[T(__is_same(make_signed_t, signed char))]; } + { int a[T(__is_same(make_signed_t, const signed char))]; } + { int a[T(__is_same(make_signed_t, volatile signed char))]; } + { int a[T(__is_same(make_signed_t, const volatile signed char))]; } + + { int a[T(__is_same(make_signed_t, signed char))]; } + { int a[T(__is_same(make_signed_t, const signed char))]; } + { int a[T(__is_same(make_signed_t, volatile signed char))]; } + { int a[T(__is_same(make_signed_t, const volatile signed char))]; } + + { int a[T(__is_same(make_signed_t, short))]; } + { int a[T(__is_same(make_signed_t, const short))]; } + { int a[T(__is_same(make_signed_t, volatile short))]; } + { int a[T(__is_same(make_signed_t, const volatile short))]; } + + { int a[T(__is_same(make_signed_t, short))]; } + { int a[T(__is_same(make_signed_t, const short))]; } + { int a[T(__is_same(make_signed_t, volatile short))]; } + { int a[T(__is_same(make_signed_t, const volatile short))]; } + + { int a[T(__is_same(make_signed_t, int))]; } + { int a[T(__is_same(make_signed_t, const int))]; } + { int a[T(__is_same(make_signed_t, volatile int))]; } + { int a[T(__is_same(make_signed_t, const volatile int))]; } + + { int a[T(__is_same(make_signed_t, int))]; } + { int a[T(__is_same(make_signed_t, const int))]; } + { int a[T(__is_same(make_signed_t, volatile int))]; } + { int a[T(__is_same(make_signed_t, const volatile int))]; } + + { int a[T(__is_same(make_signed_t, long))]; } + { int a[T(__is_same(make_signed_t, const long))]; } + { int a[T(__is_same(make_signed_t, volatile long))]; } + { int a[T(__is_same(make_signed_t, const volatile long))]; } + + { int a[T(__is_same(make_signed_t, long))]; } + { int a[T(__is_same(make_signed_t, const long))]; } + { int a[T(__is_same(make_signed_t, volatile long))]; } + { int a[T(__is_same(make_signed_t, const volatile long))]; } + + { int a[T(__is_same(make_signed_t, long long))]; } // remains unchanged + { int a[T(__is_same(make_signed_t, const long long))]; } // remains unchanged + { int a[T(__is_same(make_signed_t, volatile long long))]; } // remains unchanged + { int a[T(__is_same(make_signed_t, const volatile long long))]; } // remains unchanged + + { int a[T(__is_same(make_signed_t, long))]; } + { int a[T(__is_same(make_signed_t, const long))]; } + { int a[T(__is_same(make_signed_t, volatile long))]; } + { int a[T(__is_same(make_signed_t, const volatile long))]; } + + { int a[T(__is_same(make_signed_t<__int128>, __int128))]; } + { int a[T(__is_same(make_signed_t, const __int128))]; } + { int a[T(__is_same(make_signed_t, volatile __int128))]; } + { int a[T(__is_same(make_signed_t, const volatile __int128))]; } + + { int a[T(__is_same(make_signed_t<__uint128_t>, __int128))]; } + { int a[T(__is_same(make_signed_t, const __int128))]; } + { int a[T(__is_same(make_signed_t, volatile __int128))]; } + { int a[T(__is_same(make_signed_t, const volatile __int128))]; } + + { int a[T(__is_same(make_signed_t<_BitInt(65)>, _BitInt(65)))]; } + { int a[T(__is_same(make_signed_t, const _BitInt(65)))]; } + { int a[T(__is_same(make_signed_t, volatile _BitInt(65)))]; } + { int a[T(__is_same(make_signed_t, const volatile _BitInt(65)))]; } + + { int a[T(__is_same(make_signed_t, _BitInt(65)))]; } + { int a[T(__is_same(make_signed_t, const _BitInt(65)))]; } + { int a[T(__is_same(make_signed_t, volatile _BitInt(65)))]; } + { int a[T(__is_same(make_signed_t, const volatile _BitInt(65)))]; } + + { int a[T(__is_same(make_signed_t, int))]; } + { int a[T(__is_same(make_signed_t, int))]; } + { int a[T(__is_same(make_signed_t, const int))]; } + { int a[T(__is_same(make_signed_t, volatile int))]; } + { int a[T(__is_same(make_signed_t, const volatile int))]; } + { int a[T(__is_same(make_signed_t, int))]; } + { int a[T(__is_same(make_signed_t, const int))]; } + { int a[T(__is_same(make_signed_t, volatile int))]; } + { int a[T(__is_same(make_signed_t, const volatile int))]; } + + { int a[T(__is_same(make_signed_t, int))]; } + { int a[T(__is_same(make_signed_t, int))]; } + { int a[T(__is_same(make_signed_t, const int))]; } + { int a[T(__is_same(make_signed_t, volatile int))]; } + { int a[T(__is_same(make_signed_t, const volatile int))]; } + { int a[T(__is_same(make_signed_t, int))]; } + { int a[T(__is_same(make_signed_t, const int))]; } + { int a[T(__is_same(make_signed_t, volatile int))]; } + { int a[T(__is_same(make_signed_t, const volatile int))]; } + + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'bool'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int[]'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int[5]'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'void'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int *'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int &'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'float'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'double'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'long double'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'S'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'S *'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int S::*'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)()'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() &'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const &'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() volatile'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() volatile &'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() volatile &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const volatile'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const volatile &'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const volatile &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} +} + +template using make_unsigned_t = __make_unsigned(T); + +void make_unsigned() { + { int a[T(__is_same(make_unsigned_t, unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned char))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned char))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned char))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned char))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned short))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned short))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned short))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned short))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned short))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned short))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned short))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned short))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned int))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned int))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned long))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned long))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned long))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned long))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned long long))]; } // remains unchanged + { int a[T(__is_same(make_unsigned_t, const unsigned long long))]; } // remains unchanged + { int a[T(__is_same(make_unsigned_t, volatile unsigned long long))]; } // remains unchanged + { int a[T(__is_same(make_unsigned_t, const volatile unsigned long long))]; } // remains unchanged + + { int a[T(__is_same(make_unsigned_t<__int128>, __uint128_t))]; } + { int a[T(__is_same(make_unsigned_t, const __uint128_t))]; } + { int a[T(__is_same(make_unsigned_t, volatile __uint128_t))]; } + { int a[T(__is_same(make_unsigned_t, const volatile __uint128_t))]; } + + { int a[T(__is_same(make_unsigned_t<__uint128_t>, __uint128_t))]; } + { int a[T(__is_same(make_unsigned_t, const __uint128_t))]; } + { int a[T(__is_same(make_unsigned_t, volatile __uint128_t))]; } + { int a[T(__is_same(make_unsigned_t, const volatile __uint128_t))]; } + + { int a[T(__is_same(make_unsigned_t<_BitInt(65)>, unsigned _BitInt(65)))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned _BitInt(65)))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned _BitInt(65)))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned _BitInt(65)))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned _BitInt(65)))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned _BitInt(65)))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned _BitInt(65)))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned _BitInt(65)))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned int))]; } + + { int a[T(__is_same(make_unsigned_t, unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, volatile unsigned int))]; } + { int a[T(__is_same(make_unsigned_t, const volatile unsigned int))]; } + + { using ExpectedError = make_signed_t; } + // expected-error@*:*{{'make_signed' is only compatible with non-bool integers and enum types, but was given 'bool'}} + // expected-note@-2{{in instantiation of template type alias 'make_signed_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int[]'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int[5]'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'void'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int *'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int &'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'float'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'double'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'long double'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'S'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'S *'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int S::*'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)()'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() &'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const &'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() volatile'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() volatile &'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() volatile &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const volatile'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const volatile &'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} + { using ExpectedError = make_unsigned_t; } + // expected-error@*:*{{'make_unsigned' is only compatible with non-bool integers and enum types, but was given 'int (S::*)() const volatile &&'}} + // expected-note@-2{{in instantiation of template type alias 'make_unsigned_t' requested here}} +} + +template using remove_extent_t = __remove_extent(T); + +void remove_extent() { + { int x[T(__is_same(remove_extent_t, void))]; } + { int x[T(__is_same(remove_extent_t, int))]; } + { int x[T(__is_same(remove_extent_t, int))]; } + { int x[T(__is_same(remove_extent_t, int))]; } + { int x[T(__is_same(remove_extent_t, int[2]))]; } + { int x[T(__is_same(remove_extent_t, int[2]))]; } + { int x[T(__is_same(remove_extent_t, const int))]; } + { int x[T(__is_same(remove_extent_t, const int))]; } + { int x[T(__is_same(remove_extent_t, const int[2]))]; } + { int x[T(__is_same(remove_extent_t, const int[2]))]; } + { int x[T(__is_same(remove_extent_t, volatile int))]; } + { int x[T(__is_same(remove_extent_t, volatile int))]; } + { int x[T(__is_same(remove_extent_t, volatile int[2]))]; } + { int x[T(__is_same(remove_extent_t, volatile int[2]))]; } + { int x[T(__is_same(remove_extent_t, const volatile int))]; } + { int x[T(__is_same(remove_extent_t, const volatile int))]; } + { int x[T(__is_same(remove_extent_t, const volatile int[2]))]; } + { int x[T(__is_same(remove_extent_t, const volatile int[2]))]; } + { int x[T(__is_same(remove_extent_t, int *))]; } + { int x[T(__is_same(remove_extent_t, int &))]; } + { int x[T(__is_same(remove_extent_t, int &&))]; } + { int x[T(__is_same(remove_extent_t, int()))]; } + { int x[T(__is_same(remove_extent_t, int (*)()))]; } + { int x[T(__is_same(remove_extent_t, int (&)()))]; } + + { int x[T(__is_same(remove_extent_t, S))]; } + { int x[T(__is_same(remove_extent_t, int S::*))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)()))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() &))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() &&))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() const))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() const &))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() const &&))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() volatile))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() volatile &))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() volatile &&))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() const volatile))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() const volatile &))]; } + { int x[T(__is_same(remove_extent_t, int(S::*)() const volatile &&))]; } +} + +template using remove_all_extents_t = __remove_all_extents(T); + +void remove_all_extents() { + { int x[T(__is_same(remove_all_extents_t, void))]; } + { int x[T(__is_same(remove_all_extents_t, int))]; } + { int x[T(__is_same(remove_all_extents_t, const int))]; } + { int x[T(__is_same(remove_all_extents_t, volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, const volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, int))]; } + { int x[T(__is_same(remove_all_extents_t, int))]; } + { int x[T(__is_same(remove_all_extents_t, int))]; } + { int x[T(__is_same(remove_all_extents_t, int))]; } + { int x[T(__is_same(remove_all_extents_t, const int))]; } + { int x[T(__is_same(remove_all_extents_t, const int))]; } + { int x[T(__is_same(remove_all_extents_t, const int))]; } + { int x[T(__is_same(remove_all_extents_t, const int))]; } + { int x[T(__is_same(remove_all_extents_t, volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, const volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, const volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, const volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, const volatile int))]; } + { int x[T(__is_same(remove_all_extents_t, int *))]; } + { int x[T(__is_same(remove_all_extents_t, int &))]; } + { int x[T(__is_same(remove_all_extents_t, int &&))]; } + { int x[T(__is_same(remove_all_extents_t, int()))]; } + { int x[T(__is_same(remove_all_extents_t, int (*)()))]; } + { int x[T(__is_same(remove_all_extents_t, int (&)()))]; } + + { int x[T(__is_same(remove_all_extents_t, S))]; } + { int x[T(__is_same(remove_all_extents_t, int S::*))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)()))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() &))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() &&))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() const))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() const &))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() const &&))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() volatile))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() volatile &))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() volatile &&))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() const volatile))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() const volatile &))]; } + { int x[T(__is_same(remove_all_extents_t, int(S::*)() const volatile &&))]; } +} diff --git a/clang/utils/ClangVisualizers/clang.natvis b/clang/utils/ClangVisualizers/clang.natvis --- a/clang/utils/ClangVisualizers/clang.natvis +++ b/clang/utils/ClangVisualizers/clang.natvis @@ -2,7 +2,7 @@ @@ -11,8 +11,8 @@ {(clang::Decl::Kind)DeclContextBits.DeclKind,en}Decl @@ -201,7 +201,7 @@ {{InheritedInitializer}} = {this,view(DefaultArg)na} - {*this,view(TorC)} {*this,view(MaybeEllipses)}{Name,view(cpp)} {this,view(Initializer)na} + {*this,view(TorC)} {*this,view(MaybeEllipses)}{Name,view(cpp)} {this,view(Initializer)na} {*TemplatedDecl,view(cpp)} @@ -694,7 +694,7 @@ C++ Constructor {{{(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask),view(cpp)na}}} C++ Destructor {{*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)}} C++ Conversion function {{*(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask)}} - C++ Operator {{*(clang::detail::CXXOperatorIdName *)(Ptr & ~PtrMask)}} + C++ Operator {{*(clang::detail::CXXOperatorIdName *)(Ptr & ~PtrMask)}} {*(clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask),view(cpp)} {{Extra ({*(clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask)})}} @@ -706,7 +706,7 @@ *(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask),na *(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask),na *(clang::detail::CXXSpecialNameExtra *)(Ptr & ~PtrMask),na - *(clang::detail::CXXOperatorIdName *)(Ptr & ~PtrMask),na + *(clang::detail::CXXOperatorIdName *)(Ptr & ~PtrMask),na (clang::detail::DeclarationNameExtra *)(Ptr & ~PtrMask),na @@ -718,7 +718,7 @@ {(CXXDeductionGuideNameExtra *)this,nand} C++ Literal operator - C++ Using directive + C++ Using directive {(clang::detail::DeclarationNameExtra::ExtraKind)ExtraKindOrNumArgs,en}{" ",sb}{*this,view(cpp)} (CXXDeductionGuideNameExtra *)this @@ -809,7 +809,7 @@ [{this,view(default)na}{this,view(capture0)na}] - + , [{TypeRep}] @@ -823,7 +823,7 @@ (clang::DeclSpec::SCS)StorageClassSpec (clang::TypeSpecifierType)TypeSpecType - + TypeRep