aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorNico Weber <thakis@chromium.org>2022-08-14 15:57:38 -0400
committerNico Weber <thakis@chromium.org>2022-08-14 15:58:21 -0400
commitaacf1a9742f714dd432117d82d19a007289c3dee (patch)
treeb41c0f61e159b81a13659a8759223fcdddb04d5d /clang/lib/Sema
parenta8c294d6aae340afba9347ef3d41fbb7a9ab51be (diff)
downloadllvm-aacf1a9742f714dd432117d82d19a007289c3dee.zip
llvm-aacf1a9742f714dd432117d82d19a007289c3dee.tar.gz
llvm-aacf1a9742f714dd432117d82d19a007289c3dee.tar.bz2
Revert "[clang] adds unary type transformations as compiler built-ins"
This reverts commit bc60cf2368de90918719dc7e3d7c63a72cc007ad. Doesn't build on Windows and breaks gcc 9 build, see https://reviews.llvm.org/D116203#3722094 and https://reviews.llvm.org/D116203#3722128 Also revert two follow-ups. One fixed a warning added in bc60cf2368de90918719dc7e3d7c63a72cc007ad, the other makes use of the feature added in bc60cf2368de90918719dc7e3d7c63a72cc007ad in libc++: Revert "[libcxx][NFC] utilises compiler builtins for unary transform type-traits" This reverts commit 06a1d917ef1f507aaa2f6891bb654696c866ea3a. Revert "[Sema] Fix a warning" This reverts commit c85abbe879ef3257de4db862ce249b060cc3d2a4.
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/DeclSpec.cpp9
-rw-r--r--clang/lib/Sema/SemaDecl.cpp6
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp3
-rw-r--r--clang/lib/Sema/SemaType.cpp303
4 files changed, 40 insertions, 281 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index af31105..d4dc790 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -18,7 +18,6 @@
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
-#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/Sema.h"
@@ -390,8 +389,7 @@ bool Declarator::isDeclarationOfFunction() const {
return E->getType()->isFunctionType();
return false;
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case TST_underlyingType:
case TST_typename:
case TST_typeofType: {
QualType QT = DS.getRepAsType().get();
@@ -578,10 +576,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T,
case DeclSpec::TST_auto_type: return "__auto_type";
case DeclSpec::TST_decltype: return "(decltype)";
case DeclSpec::TST_decltype_auto: return "decltype(auto)";
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
- case DeclSpec::TST_##Trait: \
- return "__" #Trait;
-#include "clang/Basic/TransformTypeTraits.def"
+ case DeclSpec::TST_underlyingType: return "__underlying_type";
case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
case DeclSpec::TST_atomic: return "_Atomic";
case DeclSpec::TST_BFloat16: return "__bf16";
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index e689a05..94009d3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -145,8 +145,7 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
case tok::kw___ibm128:
case tok::kw_wchar_t:
case tok::kw_bool:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case tok::kw___##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case tok::kw___underlying_type:
case tok::kw___auto_type:
return true;
@@ -5924,8 +5923,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D,
switch (DS.getTypeSpecType()) {
case DeclSpec::TST_typename:
case DeclSpec::TST_typeofType:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case DeclSpec::TST_##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case DeclSpec::TST_underlyingType:
case DeclSpec::TST_atomic: {
// Grab the type from the parser.
TypeSourceInfo *TSI = nullptr;
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 285bf67..790792f 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -858,8 +858,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
switch (DS.getTypeSpecType()) {
case TST_typename:
case TST_typeofType:
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case TST_underlyingType:
case TST_atomic: {
QualType T = DS.getRepAsType().get();
if (!T.isNull() && T->containsUnexpandedParameterPack())
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index fb339fa..14b2d2e 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -19,11 +19,9 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/AST/TypeLocVisitor.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
@@ -35,7 +33,6 @@
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateInstCallback.h"
-#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
@@ -1250,18 +1247,6 @@ getImageAccess(const ParsedAttributesView &Attrs) {
return OpenCLAccessAttr::Keyword_read_only;
}
-static UnaryTransformType::UTTKind
-TSTToUnaryTransformType(DeclSpec::TST SwitchTST) {
- switch (SwitchTST) {
-#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \
- case TST_##Trait: \
- return UnaryTransformType::Enum;
-#include "clang/Basic/TransformTypeTraits.def"
- default:
- llvm_unreachable("attempted to parse a non-unary transform builtin");
- }
-}
-
/// Convert the specified declspec to the appropriate type
/// object.
/// \param state Specifies the declarator containing the declaration specifier
@@ -1643,13 +1628,12 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
}
break;
}
-#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case DeclSpec::TST_##Trait:
-#include "clang/Basic/TransformTypeTraits.def"
+ case DeclSpec::TST_underlyingType:
Result = S.GetTypeFromParser(DS.getRepAsType());
- assert(!Result.isNull() && "Didn't get a type for the transformation?");
- Result = S.BuildUnaryTransformType(
- Result, TSTToUnaryTransformType(DS.getTypeSpecType()),
- DS.getTypeSpecTypeLoc());
+ assert(!Result.isNull() && "Didn't get a type for __underlying_type?");
+ Result = S.BuildUnaryTransformType(Result,
+ UnaryTransformType::EnumUnderlyingType,
+ DS.getTypeSpecTypeLoc());
if (Result.isNull()) {
Result = Context.IntTy;
declarator.setInvalidType(true);
@@ -6083,7 +6067,8 @@ namespace {
TL.setRParenLoc(DS.getTypeofParensRange().getEnd());
}
void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
- assert(DS.isTransformTypeTrait(DS.getTypeSpecType()));
+ // FIXME: This holds only because we only have one unary transform.
+ assert(DS.getTypeSpecType() == DeclSpec::TST_underlyingType);
TL.setKWLoc(DS.getTypeSpecTypeLoc());
TL.setParensRange(DS.getTypeofParensRange());
assert(DS.getRepAsType());
@@ -9220,257 +9205,39 @@ QualType Sema::BuildDecltypeType(Expr *E, bool AsUnevaluated) {
return Context.getDecltypeType(E, getDecltypeForExpr(E));
}
-static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType,
- SourceLocation Loc) {
- assert(BaseType->isEnumeralType());
- EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
- assert(ED && "EnumType has no EnumDecl");
-
- S.DiagnoseUseOfDecl(ED, Loc);
-
- QualType Underlying = ED->getIntegerType();
- assert(!Underlying.isNull());
-
- return Underlying;
-}
-
-QualType Sema::BuiltinEnumUnderlyingType(QualType BaseType,
- SourceLocation Loc) {
- if (!BaseType->isEnumeralType()) {
- Diag(Loc, diag::err_only_enums_have_underlying_types);
- return QualType();
- }
-
- // The enum could be incomplete if we're parsing its definition or
- // recovering from an error.
- NamedDecl *FwdDecl = nullptr;
- if (BaseType->isIncompleteType(&FwdDecl)) {
- Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
- Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
- return QualType();
- }
-
- return GetEnumUnderlyingType(*this, BaseType, Loc);
-}
-
-QualType Sema::BuiltinAddPointer(QualType BaseType, SourceLocation Loc) {
- QualType Pointer = BaseType.isReferenceable() || BaseType->isVoidType()
- ? BuildPointerType(BaseType.getNonReferenceType(), Loc,
- DeclarationName())
- : BaseType;
-
- return Pointer.isNull() ? QualType() : Pointer;
-}
-
-QualType Sema::BuiltinRemovePointer(QualType BaseType, SourceLocation Loc) {
- // We don't want block pointers or ObjectiveC's id type.
- if (!BaseType->isAnyPointerType() || BaseType->isObjCIdType())
- return BaseType;
-
- return BaseType->getPointeeType();
-}
-
-QualType Sema::BuiltinDecay(QualType BaseType, SourceLocation Loc) {
- QualType Underlying = BaseType.getNonReferenceType();
- if (Underlying->isArrayType())
- return Context.getDecayedType(Underlying);
-
- if (Underlying->isFunctionType())
- return BuiltinAddPointer(BaseType, Loc);
-
- SplitQualType Split = Underlying.getSplitUnqualifiedType();
- // std::decay is supposed to produce 'std::remove_cv', but since 'restrict' is
- // in the same group of qualifiers as 'const' and 'volatile', we're extending
- // '__decay(T)' so that it removes all qualifiers.
- Split.Quals.removeCVRQualifiers();
- return Context.getQualifiedType(Split);
-}
-
-QualType Sema::BuiltinAddReference(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- assert(LangOpts.CPlusPlus);
- QualType Reference =
- BaseType.isReferenceable()
- ? BuildReferenceType(BaseType,
- UKind == UnaryTransformType::AddLvalueReference,
- Loc, DeclarationName())
- : BaseType;
- return Reference.isNull() ? QualType() : Reference;
-}
-
-QualType Sema::BuiltinRemoveExtent(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- if (UKind == UnaryTransformType::RemoveAllExtents)
- return Context.getBaseElementType(BaseType);
-
- if (const auto *AT = Context.getAsArrayType(BaseType))
- return AT->getElementType();
-
- return BaseType;
-}
-
-QualType Sema::BuiltinRemoveReference(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- assert(LangOpts.CPlusPlus);
- QualType T = BaseType.getNonReferenceType();
- if (UKind == UTTKind::RemoveCVRef &&
- (T.isConstQualified() || T.isVolatileQualified())) {
- Qualifiers Quals;
- QualType Unqual = Context.getUnqualifiedArrayType(T, Quals);
- Quals.removeConst();
- Quals.removeVolatile();
- T = Context.getQualifiedType(Unqual, Quals);
- }
- return T;
-}
-
-QualType Sema::BuiltinChangeCVRQualifiers(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- if ((BaseType->isReferenceType() && UKind != UTTKind::RemoveRestrict) ||
- BaseType->isFunctionType())
- return BaseType;
-
- Qualifiers Quals;
- QualType Unqual = Context.getUnqualifiedArrayType(BaseType, Quals);
-
- if (UKind == UTTKind::RemoveConst || UKind == UTTKind::RemoveCV)
- Quals.removeConst();
- if (UKind == UTTKind::RemoveVolatile || UKind == UTTKind::RemoveCV)
- Quals.removeVolatile();
- if (UKind == UTTKind::RemoveRestrict)
- Quals.removeRestrict();
-
- return Context.getQualifiedType(Unqual, Quals);
-}
-
-static QualType ChangeIntegralSignedness(Sema &S, QualType BaseType,
- bool IsMakeSigned,
- SourceLocation Loc) {
- if (BaseType->isEnumeralType()) {
- QualType Underlying = GetEnumUnderlyingType(S, BaseType, Loc);
- if (auto *BitInt = dyn_cast<BitIntType>(Underlying)) {
- unsigned int Bits = BitInt->getNumBits();
- if (Bits > 1)
- return S.Context.getBitIntType(!IsMakeSigned, Bits);
-
- S.Diag(Loc, diag::err_make_signed_integral_only)
- << IsMakeSigned << /*_BitInt(1)*/ true << BaseType << 1 << Underlying;
- return QualType();
- }
- if (Underlying->isBooleanType()) {
- S.Diag(Loc, diag::err_make_signed_integral_only)
- << IsMakeSigned << /*_BitInt(1)*/ false << BaseType << 1
- << Underlying;
- return QualType();
- }
- }
-
- bool Int128Unsupported = !S.Context.getTargetInfo().hasInt128Type();
- std::array<CanQualType *, 6> AllSignedIntegers = {
- &S.Context.SignedCharTy, &S.Context.ShortTy, &S.Context.IntTy,
- &S.Context.LongTy, &S.Context.LongLongTy, &S.Context.Int128Ty};
- ArrayRef<CanQualType *> AvailableSignedIntegers(
- AllSignedIntegers.begin(), AllSignedIntegers.end() - Int128Unsupported);
- std::array<CanQualType *, 6> AllUnsignedIntegers = {
- &S.Context.UnsignedCharTy, &S.Context.UnsignedShortTy,
- &S.Context.UnsignedIntTy, &S.Context.UnsignedLongTy,
- &S.Context.UnsignedLongLongTy, &S.Context.UnsignedInt128Ty};
- ArrayRef<CanQualType *> AvailableUnsignedIntegers(AllUnsignedIntegers.begin(),
- AllUnsignedIntegers.end() -
- Int128Unsupported);
- ArrayRef<CanQualType *> *Consider =
- IsMakeSigned ? &AvailableSignedIntegers : &AvailableUnsignedIntegers;
-
- uint64_t BaseSize = S.Context.getTypeSize(BaseType);
- auto *Result =
- llvm::find_if(*Consider, [&S, BaseSize](const CanQual<Type> *T) {
- return BaseSize == S.Context.getTypeSize(T->getTypePtr());
- });
-
- assert(Result != Consider->end());
- return QualType((*Result)->getTypePtr(), 0);
-}
-
-QualType Sema::BuiltinChangeSignedness(QualType BaseType, UTTKind UKind,
+QualType Sema::BuildUnaryTransformType(QualType BaseType,
+ UnaryTransformType::UTTKind UKind,
SourceLocation Loc) {
- bool IsMakeSigned = UKind == UnaryTransformType::MakeSigned;
- if ((!BaseType->isIntegerType() && !BaseType->isEnumeralType()) ||
- BaseType->isBooleanType() ||
- (BaseType->isBitIntType() &&
- BaseType->getAs<BitIntType>()->getNumBits() < 2)) {
- Diag(Loc, diag::err_make_signed_integral_only)
- << IsMakeSigned << BaseType->isBitIntType() << BaseType << 0;
- return QualType();
- }
+ switch (UKind) {
+ case UnaryTransformType::EnumUnderlyingType:
+ if (!BaseType->isDependentType() && !BaseType->isEnumeralType()) {
+ Diag(Loc, diag::err_only_enums_have_underlying_types);
+ return QualType();
+ } else {
+ QualType Underlying = BaseType;
+ if (!BaseType->isDependentType()) {
+ // The enum could be incomplete if we're parsing its definition or
+ // recovering from an error.
+ NamedDecl *FwdDecl = nullptr;
+ if (BaseType->isIncompleteType(&FwdDecl)) {
+ Diag(Loc, diag::err_underlying_type_of_incomplete_enum) << BaseType;
+ Diag(FwdDecl->getLocation(), diag::note_forward_declaration) << FwdDecl;
+ return QualType();
+ }
- bool IsNonIntIntegral =
- BaseType->isChar16Type() || BaseType->isChar32Type() ||
- BaseType->isWideCharType() || BaseType->isEnumeralType();
+ EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
+ assert(ED && "EnumType has no EnumDecl");
- QualType Underlying =
- IsNonIntIntegral
- ? ChangeIntegralSignedness(*this, BaseType, IsMakeSigned, Loc)
- : IsMakeSigned ? Context.getCorrespondingSignedType(BaseType)
- : Context.getCorrespondingUnsignedType(BaseType);
- if (Underlying.isNull())
- return Underlying;
- return Context.getQualifiedType(Underlying, BaseType.getQualifiers());
-}
+ DiagnoseUseOfDecl(ED, Loc);
-QualType Sema::BuildUnaryTransformType(QualType BaseType, UTTKind UKind,
- SourceLocation Loc) {
- if (BaseType->isDependentType())
- return Context.getUnaryTransformType(BaseType, BaseType, UKind);
- QualType Result;
- switch (UKind) {
- case UnaryTransformType::EnumUnderlyingType: {
- Result = BuiltinEnumUnderlyingType(BaseType, Loc);
- break;
- }
- case UnaryTransformType::AddPointer: {
- Result = BuiltinAddPointer(BaseType, Loc);
- break;
- }
- case UnaryTransformType::RemovePointer: {
- Result = BuiltinRemovePointer(BaseType, Loc);
- break;
- }
- case UnaryTransformType::Decay: {
- Result = BuiltinDecay(BaseType, Loc);
- break;
- }
- case UnaryTransformType::AddLvalueReference:
- case UnaryTransformType::AddRvalueReference: {
- Result = BuiltinAddReference(BaseType, UKind, Loc);
- break;
- }
- case UnaryTransformType::RemoveAllExtents:
- case UnaryTransformType::RemoveExtent: {
- Result = BuiltinRemoveExtent(BaseType, UKind, Loc);
- break;
- }
- case UnaryTransformType::RemoveCVRef:
- case UnaryTransformType::RemoveReference: {
- Result = BuiltinRemoveReference(BaseType, UKind, Loc);
- break;
- }
- case UnaryTransformType::RemoveConst:
- case UnaryTransformType::RemoveCV:
- case UnaryTransformType::RemoveRestrict:
- case UnaryTransformType::RemoveVolatile: {
- Result = BuiltinChangeCVRQualifiers(BaseType, UKind, Loc);
- break;
- }
- case UnaryTransformType::MakeSigned:
- case UnaryTransformType::MakeUnsigned: {
- Result = BuiltinChangeSignedness(BaseType, UKind, Loc);
- break;
- }
+ Underlying = ED->getIntegerType();
+ assert(!Underlying.isNull());
+ }
+ return Context.getUnaryTransformType(BaseType, Underlying,
+ UnaryTransformType::EnumUnderlyingType);
+ }
}
-
- return !Result.isNull()
- ? Context.getUnaryTransformType(BaseType, Result, UKind)
- : Result;
+ llvm_unreachable("unknown unary transform type");
}
QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {