diff options
Diffstat (limited to 'clang/lib/AST/Type.cpp')
-rw-r--r-- | clang/lib/AST/Type.cpp | 276 |
1 files changed, 181 insertions, 95 deletions
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 0f168a518707..a713d6e3bd03 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -42,7 +42,6 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/None.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" @@ -51,6 +50,7 @@ #include <cassert> #include <cstdint> #include <cstring> +#include <optional> #include <type_traits> using namespace clang; @@ -525,6 +525,10 @@ template <> const TypedefType *Type::getAs() const { return getAsSugar<TypedefType>(this); } +template <> const UsingType *Type::getAs() const { + return getAsSugar<UsingType>(this); +} + template <> const TemplateSpecializationType *Type::getAs() const { return getAsSugar<TemplateSpecializationType>(this); } @@ -1073,7 +1077,7 @@ public: if (exceptionChanged) { info.ExceptionSpec.Exceptions = - llvm::makeArrayRef(exceptionTypes).copy(Ctx); + llvm::ArrayRef(exceptionTypes).copy(Ctx); } } @@ -1166,8 +1170,9 @@ public: == T->getReplacementType().getAsOpaquePtr()) return QualType(T, 0); - return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(), - replacementType); + return Ctx.getSubstTemplateTypeParmType(replacementType, + T->getAssociatedDecl(), + T->getIndex(), T->getPackIndex()); } // FIXME: Non-trivial to implement, but important for C++ @@ -1214,10 +1219,10 @@ public: !typeArgChanged) return QualType(T, 0); - return Ctx.getObjCObjectType(baseType, typeArgs, - llvm::makeArrayRef(T->qual_begin(), - T->getNumProtocols()), - T->isKindOfTypeAsWritten()); + return Ctx.getObjCObjectType( + baseType, typeArgs, + llvm::ArrayRef(T->qual_begin(), T->getNumProtocols()), + T->isKindOfTypeAsWritten()); } TRIVIAL_TYPE_CLASS(ObjCInterface) @@ -1369,7 +1374,7 @@ struct SubstObjCTypeArgsVisitor if (exceptionChanged) { info.ExceptionSpec.Exceptions = - llvm::makeArrayRef(exceptionTypes).copy(Ctx); + llvm::ArrayRef(exceptionTypes).copy(Ctx); } } @@ -1479,6 +1484,25 @@ struct StripObjCKindOfTypeVisitor } // namespace +bool QualType::UseExcessPrecision(const ASTContext &Ctx) { + const BuiltinType *BT = getTypePtr()->getAs<BuiltinType>(); + if (BT) { + switch (BT->getKind()) { + case BuiltinType::Kind::Float16: { + const TargetInfo &TI = Ctx.getTargetInfo(); + if (TI.hasFloat16Type() && !TI.hasLegalHalfType() && + Ctx.getLangOpts().getFloat16ExcessPrecision() != + Ctx.getLangOpts().ExcessPrecisionKind::FPP_None) + return true; + return false; + } + default: + return false; + } + } + return false; +} + /// Substitute the given type arguments for Objective-C type /// parameters within the given type, recursively. QualType QualType::substObjCTypeArgs(ASTContext &ctx, @@ -1510,8 +1534,8 @@ QualType QualType::getAtomicUnqualifiedType() const { return getUnqualifiedType(); } -Optional<ArrayRef<QualType>> Type::getObjCSubstitutions( - const DeclContext *dc) const { +std::optional<ArrayRef<QualType>> +Type::getObjCSubstitutions(const DeclContext *dc) const { // Look through method scopes. if (const auto method = dyn_cast<ObjCMethodDecl>(dc)) dc = method->getDeclContext(); @@ -1526,23 +1550,23 @@ Optional<ArrayRef<QualType>> Type::getObjCSubstitutions( // substitution to do. dcTypeParams = dcClassDecl->getTypeParamList(); if (!dcTypeParams) - return None; + return std::nullopt; } else { // If we are in neither a class nor a category, there's no // substitution to perform. dcCategoryDecl = dyn_cast<ObjCCategoryDecl>(dc); if (!dcCategoryDecl) - return None; + return std::nullopt; // If the category does not have any type parameters, there's no // substitution to do. dcTypeParams = dcCategoryDecl->getTypeParamList(); if (!dcTypeParams) - return None; + return std::nullopt; dcClassDecl = dcCategoryDecl->getClassInterface(); if (!dcClassDecl) - return None; + return std::nullopt; } assert(dcTypeParams && "No substitutions to perform"); assert(dcClassDecl && "No class context"); @@ -2320,6 +2344,20 @@ bool Type::isSizelessBuiltinType() const { bool Type::isSizelessType() const { return isSizelessBuiltinType(); } +bool Type::isSVESizelessBuiltinType() const { + if (const BuiltinType *BT = getAs<BuiltinType>()) { + switch (BT->getKind()) { + // SVE Types +#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id: +#include "clang/Basic/AArch64SVEACLETypes.def" + return true; + default: + return false; + } + } + return false; +} + bool Type::isVLSTBuiltinType() const { if (const BuiltinType *BT = getAs<BuiltinType>()) { switch (BT->getKind()) { @@ -2777,39 +2815,6 @@ bool Type::isStdByteType() const { return false; } -bool Type::isPromotableIntegerType() const { - if (const auto *BT = getAs<BuiltinType>()) - switch (BT->getKind()) { - case BuiltinType::Bool: - case BuiltinType::Char_S: - case BuiltinType::Char_U: - case BuiltinType::SChar: - case BuiltinType::UChar: - case BuiltinType::Short: - case BuiltinType::UShort: - case BuiltinType::WChar_S: - case BuiltinType::WChar_U: - case BuiltinType::Char8: - case BuiltinType::Char16: - case BuiltinType::Char32: - return true; - default: - return false; - } - - // Enumerated types are promotable to their compatible integer types - // (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2). - if (const auto *ET = getAs<EnumType>()){ - if (this->isDependentType() || ET->getDecl()->getPromotionType().isNull() - || ET->getDecl()->isScoped()) - return false; - - return true; - } - - return false; -} - bool Type::isSpecifierType() const { // Note that this intentionally does not use the canonical type. switch (getTypeClass()) { @@ -2928,7 +2933,7 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType( DependentTemplateSpecializationTypeBits.NumArgs = Args.size(); assert((!NNS || NNS->isDependent()) && "DependentTemplateSpecializatonType requires dependent qualifier"); - TemplateArgument *ArgBuffer = getArgBuffer(); + auto *ArgBuffer = const_cast<TemplateArgument *>(template_arguments().data()); for (const TemplateArgument &Arg : Args) { addDependence(toTypeDependence(Arg.getDependence() & TemplateArgumentDependence::UnexpandedPack)); @@ -3084,7 +3089,7 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { case Char32: return "char32_t"; case NullPtr: - return "std::nullptr_t"; + return Policy.NullptrTypeInNamespace ? "std::nullptr_t" : "nullptr_t"; case Overload: return "<overloaded function type>"; case BoundMember: @@ -3434,25 +3439,34 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, } TypedefType::TypedefType(TypeClass tc, const TypedefNameDecl *D, - QualType underlying, QualType can) - : Type(tc, can, toSemanticDependence(underlying->getDependence())), + QualType Underlying, QualType can) + : Type(tc, can, toSemanticDependence(can->getDependence())), Decl(const_cast<TypedefNameDecl *>(D)) { assert(!isa<TypedefType>(can) && "Invalid canonical type"); + TypedefBits.hasTypeDifferentFromDecl = !Underlying.isNull(); + if (!typeMatchesDecl()) + *getTrailingObjects<QualType>() = Underlying; } QualType TypedefType::desugar() const { - return getDecl()->getUnderlyingType(); + return typeMatchesDecl() ? Decl->getUnderlyingType() + : *getTrailingObjects<QualType>(); } UsingType::UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon) - : Type(Using, Canon, toSemanticDependence(Underlying->getDependence())), + : Type(Using, Canon, toSemanticDependence(Canon->getDependence())), Found(const_cast<UsingShadowDecl *>(Found)) { - assert(Underlying == getUnderlyingType()); + UsingBits.hasTypeDifferentFromDecl = !Underlying.isNull(); + if (!typeMatchesDecl()) + *getTrailingObjects<QualType>() = Underlying; } QualType UsingType::getUnderlyingType() const { - return QualType(cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl(), 0); + return typeMatchesDecl() + ? QualType( + cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl(), 0) + : *getTrailingObjects<QualType>(); } QualType MacroQualifiedType::desugar() const { return getUnderlyingType(); } @@ -3469,27 +3483,37 @@ QualType MacroQualifiedType::getModifiedType() const { return Inner; } -TypeOfExprType::TypeOfExprType(Expr *E, QualType can) - : Type(TypeOfExpr, can, +TypeOfExprType::TypeOfExprType(Expr *E, TypeOfKind Kind, QualType Can) + : Type(TypeOfExpr, + // We have to protect against 'Can' being invalid through its + // default argument. + Kind == TypeOfKind::Unqualified && !Can.isNull() + ? Can.getAtomicUnqualifiedType() + : Can, toTypeDependence(E->getDependence()) | (E->getType()->getDependence() & TypeDependence::VariablyModified)), - TOExpr(E) {} + TOExpr(E) { + TypeOfBits.IsUnqual = Kind == TypeOfKind::Unqualified; +} bool TypeOfExprType::isSugared() const { return !TOExpr->isTypeDependent(); } QualType TypeOfExprType::desugar() const { - if (isSugared()) - return getUnderlyingExpr()->getType(); - + if (isSugared()) { + QualType QT = getUnderlyingExpr()->getType(); + return TypeOfBits.IsUnqual ? QT.getAtomicUnqualifiedType() : QT; + } return QualType(this, 0); } void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, - const ASTContext &Context, Expr *E) { + const ASTContext &Context, Expr *E, + bool IsUnqual) { E->Profile(ID, Context, true); + ID.AddBoolean(IsUnqual); } DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) @@ -3539,7 +3563,7 @@ TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) decl(const_cast<TagDecl *>(D)) {} static TagDecl *getInterestingTagDecl(TagDecl *decl) { - for (auto I : decl->redecls()) { + for (auto *I : decl->redecls()) { if (I->isCompleteDefinition() || I->isBeingDefined()) return I; } @@ -3649,28 +3673,80 @@ IdentifierInfo *TemplateTypeParmType::getIdentifier() const { return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier(); } +static const TemplateTypeParmDecl *getReplacedParameter(Decl *D, + unsigned Index) { + if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(D)) + return TTP; + return cast<TemplateTypeParmDecl>( + getReplacedTemplateParameterList(D)->getParam(Index)); +} + +SubstTemplateTypeParmType::SubstTemplateTypeParmType( + QualType Replacement, Decl *AssociatedDecl, unsigned Index, + std::optional<unsigned> PackIndex) + : Type(SubstTemplateTypeParm, Replacement.getCanonicalType(), + Replacement->getDependence()), + AssociatedDecl(AssociatedDecl) { + SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType = + Replacement != getCanonicalTypeInternal(); + if (SubstTemplateTypeParmTypeBits.HasNonCanonicalUnderlyingType) + *getTrailingObjects<QualType>() = Replacement; + + SubstTemplateTypeParmTypeBits.Index = Index; + SubstTemplateTypeParmTypeBits.PackIndex = PackIndex ? *PackIndex + 1 : 0; + assert(AssociatedDecl != nullptr); +} + +const TemplateTypeParmDecl * +SubstTemplateTypeParmType::getReplacedParameter() const { + return ::getReplacedParameter(getAssociatedDecl(), getIndex()); +} + SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType( - const TemplateTypeParmType *Param, QualType Canon, + QualType Canon, Decl *AssociatedDecl, unsigned Index, bool Final, const TemplateArgument &ArgPack) : Type(SubstTemplateTypeParmPack, Canon, TypeDependence::DependentInstantiation | TypeDependence::UnexpandedPack), - Replaced(Param), Arguments(ArgPack.pack_begin()) { + Arguments(ArgPack.pack_begin()), + AssociatedDeclAndFinal(AssociatedDecl, Final) { + SubstTemplateTypeParmPackTypeBits.Index = Index; SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size(); + assert(AssociatedDecl != nullptr); +} + +Decl *SubstTemplateTypeParmPackType::getAssociatedDecl() const { + return AssociatedDeclAndFinal.getPointer(); +} + +bool SubstTemplateTypeParmPackType::getFinal() const { + return AssociatedDeclAndFinal.getInt(); +} + +const TemplateTypeParmDecl * +SubstTemplateTypeParmPackType::getReplacedParameter() const { + return ::getReplacedParameter(getAssociatedDecl(), getIndex()); +} + +IdentifierInfo *SubstTemplateTypeParmPackType::getIdentifier() const { + return getReplacedParameter()->getIdentifier(); } TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const { - return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs())); + return TemplateArgument(llvm::ArrayRef(Arguments, getNumArgs())); } void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getReplacedParameter(), getArgumentPack()); + Profile(ID, getAssociatedDecl(), getIndex(), getFinal(), getArgumentPack()); } void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID, - const TemplateTypeParmType *Replaced, + const Decl *AssociatedDecl, + unsigned Index, bool Final, const TemplateArgument &ArgPack) { - ID.AddPointer(Replaced); + ID.AddPointer(AssociatedDecl); + ID.AddInteger(Index); + ID.AddBoolean(Final); ID.AddInteger(ArgPack.pack_size()); for (const auto &P : ArgPack.pack_elements()) ID.AddPointer(P.getAsType().getAsOpaquePtr()); @@ -3740,10 +3816,22 @@ TemplateSpecializationType::TemplateSpecializationType( // Store the aliased type if this is a type alias template specialization. if (isTypeAlias()) { auto *Begin = reinterpret_cast<TemplateArgument *>(this + 1); - *reinterpret_cast<QualType*>(Begin + getNumArgs()) = AliasedType; + *reinterpret_cast<QualType *>(Begin + Args.size()) = AliasedType; } } +QualType TemplateSpecializationType::getAliasedType() const { + assert(isTypeAlias() && "not a type alias template specialization"); + return *reinterpret_cast<const QualType *>(template_arguments().end()); +} + +void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, + const ASTContext &Ctx) { + Profile(ID, Template, template_arguments(), Ctx); + if (isTypeAlias()) + getAliasedType().Profile(ID); +} + void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, TemplateName T, @@ -3780,14 +3868,14 @@ void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID, for (auto typeArg : typeArgs) ID.AddPointer(typeArg.getAsOpaquePtr()); ID.AddInteger(protocols.size()); - for (auto proto : protocols) + for (auto *proto : protocols) ID.AddPointer(proto); ID.AddBoolean(isKindOf); } void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getBaseType(), getTypeArgsAsWritten(), - llvm::makeArrayRef(qual_begin(), getNumProtocols()), + llvm::ArrayRef(qual_begin(), getNumProtocols()), isKindOfTypeAsWritten()); } @@ -3798,13 +3886,13 @@ void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID, ID.AddPointer(OTPDecl); ID.AddPointer(CanonicalType.getAsOpaquePtr()); ID.AddInteger(protocols.size()); - for (auto proto : protocols) + for (auto *proto : protocols) ID.AddPointer(proto); } void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getDecl(), getCanonicalTypeInternal(), - llvm::makeArrayRef(qual_begin(), getNumProtocols())); + llvm::ArrayRef(qual_begin(), getNumProtocols())); } namespace { @@ -4091,8 +4179,7 @@ LinkageInfo Type::getLinkageAndVisibility() const { return LinkageComputer{}.getTypeLinkageAndVisibility(this); } -Optional<NullabilityKind> -Type::getNullability(const ASTContext &Context) const { +std::optional<NullabilityKind> Type::getNullability() const { QualType Type(this, 0); while (const auto *AT = Type->getAs<AttributedType>()) { // Check whether this is an attributed type with nullability @@ -4102,7 +4189,7 @@ Type::getNullability(const ASTContext &Context) const { Type = AT->getEquivalentType(); } - return None; + return std::nullopt; } bool Type::canHaveNullability(bool ResultIfUnknown) const { @@ -4233,8 +4320,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const { llvm_unreachable("bad type kind!"); } -llvm::Optional<NullabilityKind> -AttributedType::getImmediateNullability() const { +std::optional<NullabilityKind> AttributedType::getImmediateNullability() const { if (getAttrKind() == attr::TypeNonNull) return NullabilityKind::NonNull; if (getAttrKind() == attr::TypeNullable) @@ -4243,10 +4329,11 @@ AttributedType::getImmediateNullability() const { return NullabilityKind::Unspecified; if (getAttrKind() == attr::TypeNullableResult) return NullabilityKind::NullableResult; - return None; + return std::nullopt; } -Optional<NullabilityKind> AttributedType::stripOuterNullability(QualType &T) { +std::optional<NullabilityKind> +AttributedType::stripOuterNullability(QualType &T) { QualType AttrTy = T; if (auto MacroTy = dyn_cast<MacroQualifiedType>(T)) AttrTy = MacroTy->getUnderlyingType(); @@ -4258,7 +4345,7 @@ Optional<NullabilityKind> AttributedType::stripOuterNullability(QualType &T) { } } - return None; + return std::nullopt; } bool Type::isBlockCompatibleObjCPointerType(ASTContext &ctx) const { @@ -4320,20 +4407,13 @@ bool Type::isObjCARCImplicitlyUnretainedType() const { } bool Type::isObjCNSObjectType() const { - const Type *cur = this; - while (true) { - if (const auto *typedefType = dyn_cast<TypedefType>(cur)) - return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>(); - - // Single-step desugar until we run out of sugar. - QualType next = cur->getLocallyUnqualifiedSingleStepDesugaredType(); - if (next.getTypePtr() == cur) return false; - cur = next.getTypePtr(); - } + if (const auto *typedefType = getAs<TypedefType>()) + return typedefType->getDecl()->hasAttr<ObjCNSObjectAttr>(); + return false; } bool Type::isObjCIndependentClassType() const { - if (const auto *typedefType = dyn_cast<TypedefType>(this)) + if (const auto *typedefType = getAs<TypedefType>()) return typedefType->getDecl()->hasAttr<ObjCIndependentClassAttr>(); return false; } @@ -4465,7 +4545,8 @@ AutoType::AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, AutoTypeBits.NumArgs = TypeConstraintArgs.size(); this->TypeConstraintConcept = TypeConstraintConcept; if (TypeConstraintConcept) { - TemplateArgument *ArgBuffer = getArgBuffer(); + auto *ArgBuffer = + const_cast<TemplateArgument *>(getTypeConstraintArguments().data()); for (const TemplateArgument &Arg : TypeConstraintArgs) { addDependence( toSyntacticDependence(toTypeDependence(Arg.getDependence()))); @@ -4486,3 +4567,8 @@ void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, for (const TemplateArgument &Arg : Arguments) Arg.Profile(ID, Context); } + +void AutoType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { + Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(), + getTypeConstraintConcept(), getTypeConstraintArguments()); +} |