llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangd Author: Dmitry Vasilyev (slydiman) <details> <summary>Changes</summary> Reverts llvm/llvm-project#<!-- -->135119 because of the assert in ASTContext.cpp, line 5619. See #<!-- -->135352 for details. --- Patch is 89.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135354.diff 28 Files Affected: - (modified) clang-tools-extra/clangd/AST.cpp (+1-2) - (modified) clang/docs/ReleaseNotes.rst (-2) - (modified) clang/include/clang/AST/ASTContext.h (+15-31) - (modified) clang/include/clang/AST/PropertiesBase.td (+1-4) - (modified) clang/include/clang/AST/TemplateBase.h (+2-11) - (modified) clang/include/clang/AST/Type.h (+4-3) - (modified) clang/include/clang/AST/TypeProperties.td (+25-5) - (modified) clang/lib/AST/ASTContext.cpp (+107-129) - (modified) clang/lib/AST/ASTDiagnostic.cpp (+4-4) - (modified) clang/lib/AST/ASTImporter.cpp (+13-21) - (modified) clang/lib/AST/DeclTemplate.cpp (+2-5) - (modified) clang/lib/AST/QualTypeNames.cpp (+1-2) - (modified) clang/lib/AST/TemplateBase.cpp (+4-15) - (modified) clang/lib/AST/Type.cpp (+23-27) - (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+10-8) - (modified) clang/lib/Sema/SemaExpr.cpp (+3-17) - (modified) clang/lib/Sema/SemaLookup.cpp (+1-2) - (modified) clang/lib/Sema/SemaTemplate.cpp (+84-78) - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+18-27) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+5-6) - (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+1-2) - (modified) clang/lib/Sema/TreeTransform.h (+4-9) - (modified) clang/test/CXX/class.derived/class.derived.general/p2.cpp (+1-1) - (modified) clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp (+2-2) - (modified) clang/test/SemaCXX/undefined-partial-specialization.cpp (+1-1) - (modified) clang/test/SemaTemplate/make_integer_seq.cpp (+45-16) - (modified) clang/test/SemaTemplate/type_pack_element.cpp (+42-15) - (modified) clang/unittests/AST/TypePrinterTest.cpp (+3-3) ``````````diff diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp index 3b991e5e9013f..66b587f00ff4a 100644 --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -439,8 +439,7 @@ QualType declaredType(const TypeDecl *D) { if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D)) if (const auto *Args = CTSD->getTemplateArgsAsWritten()) return Context.getTemplateSpecializationType( - TemplateName(CTSD->getSpecializedTemplate()), Args->arguments(), - /*CanonicalArgs=*/std::nullopt); + TemplateName(CTSD->getSpecializedTemplate()), Args->arguments()); return Context.getTypeDeclType(D); } diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 69c7369755c67..db8dad268a8a7 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -301,8 +301,6 @@ Improvements to Clang's diagnostics - Clang now better preserves the sugared types of pointers to member. - Clang now better preserves the presence of the template keyword with dependent prefixes. -- Clang now in more cases avoids printing 'type-parameter-X-X' instead of the name of - the template parameter. - Clang now respects the current language mode when printing expressions in diagnostics. This fixes a bunch of `bool` being printed as `_Bool`, and also a bunch of HLSL types being printed as their C++ equivalents. diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index b8ea2af9215d2..b1e6344576eb5 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -367,6 +367,9 @@ class ASTContext : public RefCountedBase<ASTContext> { const ASTContext&> CanonTemplateTemplateParms; + TemplateTemplateParmDecl * + getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; + /// The typedef for the __int128_t type. mutable TypedefDecl *Int128Decl = nullptr; @@ -1808,26 +1811,22 @@ class ASTContext : public RefCountedBase<ASTContext> { bool ParameterPack, TemplateTypeParmDecl *ParmDecl = nullptr) const; - QualType getCanonicalTemplateSpecializationType( - TemplateName T, ArrayRef<TemplateArgument> CanonicalArgs) const; + QualType getTemplateSpecializationType(TemplateName T, + ArrayRef<TemplateArgument> Args, + QualType Canon = QualType()) const; QualType - getTemplateSpecializationType(TemplateName T, - ArrayRef<TemplateArgument> SpecifiedArgs, - ArrayRef<TemplateArgument> CanonicalArgs, - QualType Underlying = QualType()) const; + getCanonicalTemplateSpecializationType(TemplateName T, + ArrayRef<TemplateArgument> Args) const; - QualType - getTemplateSpecializationType(TemplateName T, - ArrayRef<TemplateArgumentLoc> SpecifiedArgs, - ArrayRef<TemplateArgument> CanonicalArgs, - QualType Canon = QualType()) const; + QualType getTemplateSpecializationType(TemplateName T, + ArrayRef<TemplateArgumentLoc> Args, + QualType Canon = QualType()) const; - TypeSourceInfo *getTemplateSpecializationTypeInfo( - TemplateName T, SourceLocation TLoc, - const TemplateArgumentListInfo &SpecifiedArgs, - ArrayRef<TemplateArgument> CanonicalArgs, - QualType Canon = QualType()) const; + TypeSourceInfo * + getTemplateSpecializationTypeInfo(TemplateName T, SourceLocation TLoc, + const TemplateArgumentListInfo &Args, + QualType Canon = QualType()) const; QualType getParenType(QualType NamedType) const; @@ -2943,21 +2942,6 @@ class ASTContext : public RefCountedBase<ASTContext> { TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const; - /// Canonicalize the given template argument list. - /// - /// Returns true if any arguments were non-canonical, false otherwise. - bool - canonicalizeTemplateArguments(MutableArrayRef<TemplateArgument> Args) const; - - /// Canonicalize the given TemplateTemplateParmDecl. - TemplateTemplateParmDecl * - getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const; - - TemplateTemplateParmDecl *findCanonicalTemplateTemplateParmDeclInternal( - TemplateTemplateParmDecl *TTP) const; - TemplateTemplateParmDecl *insertCanonicalTemplateTemplateParmDeclInternal( - TemplateTemplateParmDecl *CanonTTP) const; - /// Type Query functions. If the type is an instance of the specified class, /// return the Type pointer for the underlying maximally pretty type. This /// is a member of ASTContext because this may need to do some amount of diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index 33336d57b6298..90537d47dd9c9 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -877,14 +877,11 @@ let Class = PropertyTypeCase<TemplateArgument, "Expression"> in { def : Property<"expression", ExprRef> { let Read = [{ node.getAsExpr() }]; } - def : Property<"IsCanonical", Bool> { - let Read = [{ node.isCanonicalExpr() }]; - } def : Property<"isDefaulted", Bool> { let Read = [{ node.getIsDefaulted() }]; } def : Creator<[{ - return TemplateArgument(expression, IsCanonical, isDefaulted); + return TemplateArgument(expression, isDefaulted); }]>; } let Class = PropertyTypeCase<TemplateArgument, "Pack"> in { diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index 279feb858e665..bea624eb04942 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -167,8 +167,6 @@ class TemplateArgument { unsigned Kind : 31; LLVM_PREFERRED_TYPE(bool) unsigned IsDefaulted : 1; - LLVM_PREFERRED_TYPE(bool) - unsigned IsCanonicalExpr : 1; uintptr_t V; }; union { @@ -189,8 +187,7 @@ class TemplateArgument { public: /// Construct an empty, invalid template argument. - constexpr TemplateArgument() - : TypeOrValue{Null, /*IsDefaulted=*/0, /*IsCanonicalExpr=*/0, /*V=*/0} {} + constexpr TemplateArgument() : TypeOrValue({Null, 0, /* IsDefaulted */ 0}) {} /// Construct a template type argument. TemplateArgument(QualType T, bool isNullPtr = false, @@ -265,10 +262,9 @@ class TemplateArgument { /// This form of template argument only occurs in template argument /// lists used for dependent types and for expression; it will not /// occur in a non-dependent, canonical template argument list. - TemplateArgument(Expr *E, bool IsCanonical, bool IsDefaulted = false) { + explicit TemplateArgument(Expr *E, bool IsDefaulted = false) { TypeOrValue.Kind = Expression; TypeOrValue.IsDefaulted = IsDefaulted; - TypeOrValue.IsCanonicalExpr = IsCanonical; TypeOrValue.V = reinterpret_cast<uintptr_t>(E); } @@ -411,11 +407,6 @@ class TemplateArgument { return reinterpret_cast<Expr *>(TypeOrValue.V); } - bool isCanonicalExpr() const { - assert(getKind() == Expression && "Unexpected kind"); - return TypeOrValue.IsCanonicalExpr; - } - /// Iterator that traverses the elements of a template argument pack. using pack_iterator = const TemplateArgument *; diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index dc57170bf9160..9f6189440fabf 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -6676,9 +6676,10 @@ class TemplateSpecializationType : public Type, public llvm::FoldingSetNode { /// replacement must, recursively, be one of these). TemplateName Template; - TemplateSpecializationType(TemplateName T, bool IsAlias, + TemplateSpecializationType(TemplateName T, ArrayRef<TemplateArgument> Args, - QualType Underlying); + QualType Canon, + QualType Aliased); public: /// Determine whether any of the given template arguments are dependent. @@ -6746,7 +6747,7 @@ class TemplateSpecializationType : public Type, public llvm::FoldingSetNode { void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx); static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, - ArrayRef<TemplateArgument> Args, QualType Underlying, + ArrayRef<TemplateArgument> Args, const ASTContext &Context); static bool classof(const Type *T) { diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index 3bf9239e9cbf5..66d490850678a 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -737,19 +737,39 @@ let Class = DependentAddressSpaceType in { } let Class = TemplateSpecializationType in { + def : Property<"dependent", Bool> { + let Read = [{ node->isDependentType() }]; + } def : Property<"templateName", TemplateName> { let Read = [{ node->getTemplateName() }]; } - def : Property<"args", Array<TemplateArgument>> { + def : Property<"templateArguments", Array<TemplateArgument>> { let Read = [{ node->template_arguments() }]; } - def : Property<"UnderlyingType", QualType> { - let Read = [{ node->isCanonicalUnqualified() ? QualType() : - node->desugar() }]; + def : Property<"underlyingType", Optional<QualType>> { + let Read = [{ + node->isTypeAlias() + ? std::optional<QualType>(node->getAliasedType()) + : node->isCanonicalUnqualified() + ? std::nullopt + : std::optional<QualType>(node->getCanonicalTypeInternal()) + }]; } def : Creator<[{ - return ctx.getTemplateSpecializationType(templateName, args, std::nullopt, UnderlyingType); + QualType result; + if (!underlyingType) { + result = ctx.getCanonicalTemplateSpecializationType(templateName, + templateArguments); + } else { + result = ctx.getTemplateSpecializationType(templateName, + templateArguments, + *underlyingType); + } + if (dependent) + const_cast<Type *>(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); + return result; }]>; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index b8e6245230475..00e2fa267a460 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -844,31 +844,6 @@ ASTContext::getCanonicalTemplateTemplateParmDecl( return CanonTTP; } -TemplateTemplateParmDecl * -ASTContext::findCanonicalTemplateTemplateParmDeclInternal( - TemplateTemplateParmDecl *TTP) const { - llvm::FoldingSetNodeID ID; - CanonicalTemplateTemplateParm::Profile(ID, *this, TTP); - void *InsertPos = nullptr; - CanonicalTemplateTemplateParm *Canonical = - CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos); - return Canonical ? Canonical->getParam() : nullptr; -} - -TemplateTemplateParmDecl * -ASTContext::insertCanonicalTemplateTemplateParmDeclInternal( - TemplateTemplateParmDecl *CanonTTP) const { - llvm::FoldingSetNodeID ID; - CanonicalTemplateTemplateParm::Profile(ID, *this, CanonTTP); - void *InsertPos = nullptr; - if (auto *Existing = - CanonTemplateTemplateParms.FindNodeOrInsertPos(ID, InsertPos)) - return Existing->getParam(); - CanonTemplateTemplateParms.InsertNode( - new (*this) CanonicalTemplateTemplateParm(CanonTTP), InsertPos); - return CanonTTP; -} - /// Check if a type can have its sanitizer instrumentation elided based on its /// presence within an ignorelist. bool ASTContext::isTypeIgnoredBySanitizer(const SanitizerMask &Mask, @@ -3108,19 +3083,12 @@ static auto getCanonicalTemplateArguments(const ASTContext &C, ArrayRef<TemplateArgument> Args, bool &AnyNonCanonArgs) { SmallVector<TemplateArgument, 16> CanonArgs(Args); - AnyNonCanonArgs |= C.canonicalizeTemplateArguments(CanonArgs); - return CanonArgs; -} - -bool ASTContext::canonicalizeTemplateArguments( - MutableArrayRef<TemplateArgument> Args) const { - bool AnyNonCanonArgs = false; - for (auto &Arg : Args) { + for (auto &Arg : CanonArgs) { TemplateArgument OrigArg = Arg; - Arg = getCanonicalTemplateArgument(Arg); + Arg = C.getCanonicalTemplateArgument(Arg); AnyNonCanonArgs |= !Arg.structurallyEquals(OrigArg); } - return AnyNonCanonArgs; + return CanonArgs; } //===----------------------------------------------------------------------===// @@ -5570,121 +5538,132 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, return QualType(TypeParm, 0); } -TypeSourceInfo *ASTContext::getTemplateSpecializationTypeInfo( - TemplateName Name, SourceLocation NameLoc, - const TemplateArgumentListInfo &SpecifiedArgs, - ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const { - QualType TST = getTemplateSpecializationType(Name, SpecifiedArgs.arguments(), - CanonicalArgs, Underlying); +TypeSourceInfo * +ASTContext::getTemplateSpecializationTypeInfo(TemplateName Name, + SourceLocation NameLoc, + const TemplateArgumentListInfo &Args, + QualType Underlying) const { + assert(!Name.getAsDependentTemplateName() && + "No dependent template names here!"); + QualType TST = + getTemplateSpecializationType(Name, Args.arguments(), Underlying); TypeSourceInfo *DI = CreateTypeSourceInfo(TST); TemplateSpecializationTypeLoc TL = DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>(); TL.setTemplateKeywordLoc(SourceLocation()); TL.setTemplateNameLoc(NameLoc); - TL.setLAngleLoc(SpecifiedArgs.getLAngleLoc()); - TL.setRAngleLoc(SpecifiedArgs.getRAngleLoc()); + TL.setLAngleLoc(Args.getLAngleLoc()); + TL.setRAngleLoc(Args.getRAngleLoc()); for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) - TL.setArgLocInfo(i, SpecifiedArgs[i].getLocInfo()); + TL.setArgLocInfo(i, Args[i].getLocInfo()); return DI; } -QualType ASTContext::getTemplateSpecializationType( - TemplateName Template, ArrayRef<TemplateArgumentLoc> SpecifiedArgs, - ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const { - SmallVector<TemplateArgument, 4> SpecifiedArgVec; - SpecifiedArgVec.reserve(SpecifiedArgs.size()); - for (const TemplateArgumentLoc &Arg : SpecifiedArgs) - SpecifiedArgVec.push_back(Arg.getArgument()); +QualType +ASTContext::getTemplateSpecializationType(TemplateName Template, + ArrayRef<TemplateArgumentLoc> Args, + QualType Underlying) const { + assert(!Template.getAsDependentTemplateName() && + "No dependent template names here!"); - return getTemplateSpecializationType(Template, SpecifiedArgVec, CanonicalArgs, - Underlying); + SmallVector<TemplateArgument, 4> ArgVec; + ArgVec.reserve(Args.size()); + for (const TemplateArgumentLoc &Arg : Args) + ArgVec.push_back(Arg.getArgument()); + + return getTemplateSpecializationType(Template, ArgVec, Underlying); } -[[maybe_unused]] static bool -hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) { +#ifndef NDEBUG +static bool hasAnyPackExpansions(ArrayRef<TemplateArgument> Args) { for (const TemplateArgument &Arg : Args) if (Arg.isPackExpansion()) return true; - return false; -} -QualType ASTContext::getCanonicalTemplateSpecializationType( - TemplateName Template, ArrayRef<TemplateArgument> Args) const { - assert(Template == - getCanonicalTemplateName(Template, /*IgnoreDeduced=*/true)); - assert(!Args.empty()); -#ifndef NDEBUG - for (const auto &Arg : Args) - assert(Arg.structurallyEquals(getCanonicalTemplateArgument(Arg))); -#endif - - llvm::FoldingSetNodeID ID; - TemplateSpecializationType::Profile(ID, Template, Args, QualType(), *this); - void *InsertPos = nullptr; - if (auto *T = TemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(T, 0); - - void *Mem = Allocate(sizeof(TemplateSpecializationType) + - sizeof(TemplateArgument) * Args.size(), - alignof(TemplateSpecializationType)); - auto *Spec = new (Mem) - TemplateSpecializationType(Template, /*IsAlias=*/false, Args, QualType()); - assert(Spec->isDependentType() && - "canonical template specialization must be dependent"); - Types.push_back(Spec); - TemplateSpecializationTypes.InsertNode(Spec, InsertPos); - return QualType(Spec, 0); + return true; } +#endif -QualType ASTContext::getTemplateSpecializationType( - TemplateName Template, ArrayRef<TemplateArgument> SpecifiedArgs, - ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const { - assert(!Template.getUnderlying().getAsDependentTemplateName() && +QualType +ASTContext::getTemplateSpecializationType(TemplateName Template, + ArrayRef<TemplateArgument> Args, + QualType Underlying) const { + assert(!Template.getAsDependentTemplateName() && "No dependent template names here!"); const auto *TD = Template.getAsTemplateDecl(/*IgnoreDeduced=*/true); bool IsTypeAlias = TD && TD->isTypeAlias(); - if (Underlying.isNull()) { - TemplateName CanonTemplate = - getCanonicalTemplateName(Template, /*IgnoreDeduced=*/true); - bool NonCanonical = Template != CanonTemplate; - SmallVector<TemplateArgument, 4> CanonArgsVec; - if (CanonicalArgs.empty()) { - CanonArgsVec = SmallVector<TemplateArgument, 4>(SpecifiedArgs); - NonCanonical |= canonicalizeTemplateArguments(CanonArgsVec); - CanonicalArgs = CanonArgsVec; - } else { - NonCanonical |= !llvm::equal( - SpecifiedArgs, CanonicalArgs, - [](const TemplateArgument &A, const TemplateArgument &B) { - return A.structurallyEquals(B); - }); - } - - // We can get here with an alias template when the specialization - // contains a pack expansion that does not match up with a parameter - // pack, or a builtin template which cannot be resolved due to dependency. - assert((!isa_and_nonnull<TypeAliasTemplateDecl>(TD) || - hasAnyPackExpansions(CanonicalArgs)) && + QualType CanonType; + if (!Underlying.isNull()) + CanonType = getCanonicalType(Underlying); + else { + // We can get here with an alias template when the specialization contains + // a pack expansion that does not match up with a parameter pack. + assert((!IsTypeAlias || hasAnyPackExpansions(Args)) && "Caller must compute aliased type"); IsTypeAlias = false; - - Underlying = - getCanonicalTemplateSpecializationType(CanonTemplate, CanonicalArgs); - if (!NonCanonical) - return Underlying; + CanonType = getCanonicalTemplateSpecializationType(Template, Args); } + + // Allocate the (non-canonical) template specialization type, but don't + // try to unique it: these types typically have location information that + // we don't unique and don't want to lose. void *Mem = Allocate(sizeof(TemplateSpecializationType) + - sizeof(TemplateArgument) * SpecifiedArgs.size() + + sizeof(TemplateArgument) * Args.size() + (IsTypeAlias ? sizeof(QualType) : 0), alignof(TemplateSpecializationType)); - auto *Spec = new (Mem) TemplateSpecializationType(Template, IsTypeAlias, - SpecifiedArgs, Underly... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/135354 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits