https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/207865
>From 2e7bd77c557098165a7153f69b217dfe5661e313 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <[email protected]> Date: Sat, 4 Apr 2026 20:44:35 -0300 Subject: [PATCH] trivial changes --- .../clang-tidy/modernize/LoopConvertUtils.cpp | 4 +-- .../clang-tidy/utils/ASTUtils.cpp | 7 ++-- clang-tools-extra/clangd/AST.cpp | 6 +++- clang-tools-extra/clangd/InlayHints.cpp | 2 +- clang/include/clang/AST/ASTContext.h | 10 +++--- clang/include/clang/AST/DeclTemplate.h | 15 ++++---- clang/include/clang/AST/PropertiesBase.td | 6 ++-- clang/include/clang/AST/RecursiveASTVisitor.h | 5 ++- clang/include/clang/AST/TemplateBase.h | 9 ++--- clang/include/clang/AST/TypeLoc.h | 5 ++- .../clang/Serialization/ASTRecordReader.h | 17 ++++++---- .../clang/Serialization/ASTRecordWriter.h | 4 +++ clang/lib/AST/ASTContext.cpp | 32 +++++++++-------- clang/lib/AST/ASTDiagnostic.cpp | 22 +++++++----- clang/lib/AST/ASTImporter.cpp | 5 ++- clang/lib/AST/AttrImpl.cpp | 2 +- clang/lib/AST/DeclTemplate.cpp | 11 +++--- clang/lib/AST/JSONNodeDumper.cpp | 12 +++++-- clang/lib/AST/ODRHash.cpp | 4 --- clang/lib/AST/StmtProfile.cpp | 6 ++-- clang/lib/AST/TemplateBase.cpp | 6 ++-- clang/lib/AST/TemplateName.cpp | 7 +--- clang/lib/AST/TextNodeDumper.cpp | 25 ++++++++++++-- clang/lib/AST/Type.cpp | 25 ++++++++------ clang/lib/AST/TypePrinter.cpp | 3 +- .../Frontend/Rewrite/RewriteModernObjC.cpp | 6 ++-- clang/lib/Sema/SemaCXXScopeSpec.cpp | 1 + clang/lib/Sema/SemaChecking.cpp | 4 +-- clang/lib/Sema/SemaConcept.cpp | 2 +- clang/lib/Sema/SemaExpr.cpp | 2 +- clang/lib/Sema/SemaExprCXX.cpp | 1 + clang/lib/Sema/SemaLookup.cpp | 3 +- clang/lib/Sema/SemaOpenACCAtomic.cpp | 6 ++-- clang/lib/Sema/SemaOpenMP.cpp | 34 +++++++++++-------- clang/lib/Sema/SemaTemplate.cpp | 31 +++++++++-------- clang/lib/Sema/SemaTemplateDeduction.cpp | 16 +++++---- clang/lib/Sema/SemaType.cpp | 4 ++- clang/lib/Sema/TreeTransform.h | 16 ++++----- clang/lib/Serialization/ASTReader.cpp | 7 ++-- clang/lib/Serialization/ASTReaderDecl.cpp | 9 ++--- clang/lib/Serialization/ASTWriter.cpp | 1 + 41 files changed, 231 insertions(+), 162 deletions(-) diff --git a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp index ae97a7e0a0266..9f0d62432e4e9 100644 --- a/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp +++ b/clang-tools-extra/clang-tidy/modernize/LoopConvertUtils.cpp @@ -231,7 +231,7 @@ template <typename ContainerT> static bool containsExpr(ASTContext *Context, const ContainerT *Container, const Expr *E) { llvm::FoldingSetNodeID ID; - E->Profile(ID, *Context, true); + E->Profile(ID, *Context, CanonicalizationKind::Structural); return llvm::any_of(*Container, [&](const auto &I) { return ID == I.second; }); } @@ -470,7 +470,7 @@ void ForLoopIndexUseVisitor::addComponents(const ComponentVector &Components) { void ForLoopIndexUseVisitor::addComponent(const Expr *E) { llvm::FoldingSetNodeID ID; const Expr *Node = E->IgnoreParenImpCasts(); - Node->Profile(ID, *Context, true); + Node->Profile(ID, *Context, CanonicalizationKind::Structural); DependentExprs.emplace_back(Node, ID); } diff --git a/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp b/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp index 4baef7539008a..d01f15512ff6f 100644 --- a/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp +++ b/clang-tools-extra/clang-tidy/utils/ASTUtils.cpp @@ -106,8 +106,11 @@ bool areStatementsIdentical(const Stmt *FirstStmt, const Stmt *SecondStmt, } llvm::FoldingSetNodeID DataFirst, DataSecond; - FirstStmt->Profile(DataFirst, Context, Canonical); - SecondStmt->Profile(DataSecond, Context, Canonical); + auto CanonKind = + Canonical ? CanonicalizationKindOrNone(CanonicalizationKind::Structural) + : std::nullopt; + FirstStmt->Profile(DataFirst, Context, CanonKind); + SecondStmt->Profile(DataSecond, Context, CanonKind); return DataFirst == DataSecond; } diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp index 046bec5d0d5e6..378e3ae40f475 100644 --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -562,8 +562,12 @@ class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> { // decltype(I) J = I; // decltype(J) K = J; const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr()); - while (DT && !DT->getUnderlyingType().isNull()) { + while (DT) { DeducedType = DT->getUnderlyingType(); + if (DeducedType.isNull()) { + DeducedType = DT->getUnderlyingExpr()->getType(); + break; + } DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr()); } return true; diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp index 5bae4cc040210..4fb32f26c17de 100644 --- a/clang-tools-extra/clangd/InlayHints.cpp +++ b/clang-tools-extra/clangd/InlayHints.cpp @@ -400,7 +400,7 @@ class InlayHintVisitor : public RecursiveASTVisitor<InlayHintVisitor> { bool VisitTypeLoc(TypeLoc TL) { if (const auto *DT = llvm::dyn_cast<DecltypeType>(TL.getType())) - if (QualType UT = DT->getUnderlyingType(); !UT->isDependentType()) + if (QualType UT = DT->getUnderlyingType(); !UT.isNull()) addTypeHint(TL.getSourceRange(), UT, ": "); return true; } diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 96f778720474f..00268227b7a50 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -253,8 +253,7 @@ class ASTContext : public RefCountedBase<ASTContext> { FunctionProtoTypes; mutable llvm::ContextualFoldingSet<DependentTypeOfExprType, ASTContext &> DependentTypeOfExprTypes; - mutable llvm::ContextualFoldingSet<DependentDecltypeType, ASTContext &> - DependentDecltypeTypes; + mutable llvm::ContextualFoldingSet<DecltypeType, ASTContext &> DecltypeTypes; mutable llvm::ContextualFoldingSet<PackIndexingType, ASTContext &> DependentPackIndexingTypes; @@ -2020,9 +2019,10 @@ class ASTContext : public RefCountedBase<ASTContext> { Decl *AssociatedDecl, unsigned Index, UnsignedOrNone PackIndex, bool Final) const; - QualType getSubstTemplateTypeParmPackType(Decl *AssociatedDecl, - unsigned Index, bool Final, - const TemplateArgument &ArgPack); + QualType + getSubstTemplateTypeParmPackType(Decl *AssociatedDecl, unsigned Index, + bool Final, + const TemplateArgument &ArgPack) const; QualType getSubstBuiltinTemplatePack(const TemplateArgument &ArgPack); QualType diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 672648c3fc03c..76abe06fa6354 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -2128,7 +2128,6 @@ class ClassTemplatePartialSpecializationDecl SourceLocation IdLoc, TemplateParameterList *Params, const ASTTemplateArgumentListInfo *ArgsAsWritten, ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, - CanQualType CanonInjectedTST, ClassTemplatePartialSpecializationDecl *PrevDecl); ClassTemplatePartialSpecializationDecl(ASTContext &C) @@ -2141,14 +2140,12 @@ class ClassTemplatePartialSpecializationDecl friend class ASTDeclReader; friend class ASTDeclWriter; - static ClassTemplatePartialSpecializationDecl * - Create(ASTContext &Context, TagKind TK, DeclContext *DC, - SourceLocation StartLoc, SourceLocation IdLoc, - TemplateParameterList *Params, - const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, - ClassTemplateDecl *SpecializedTemplate, - ArrayRef<TemplateArgument> Args, CanQualType CanonInjectedTST, - ClassTemplatePartialSpecializationDecl *PrevDecl); + static ClassTemplatePartialSpecializationDecl *Create( + ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, + SourceLocation IdLoc, TemplateParameterList *Params, + const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, + ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, + ClassTemplatePartialSpecializationDecl *PrevDecl); static ClassTemplatePartialSpecializationDecl * CreateDeserialized(ASTContext &C, GlobalDeclID ID); diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index 4cfda71873383..5b8e72739702b 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -906,14 +906,14 @@ let Class = PropertyTypeCase<TemplateArgument, "Expression"> in { def : Property<"expression", ExprRef> { let Read = [{ node.getAsExpr() }]; } - def : Property<"IsCanonical", Bool> { - let Read = [{ node.isCanonicalExpr() }]; + def : Property<"CanonKind", CanonicalizationKindOrNone> { + let Read = [{ node.getExprCanonKind() }]; } def : Property<"isDefaulted", Bool> { let Read = [{ node.getIsDefaulted() }]; } def : Creator<[{ - return TemplateArgument(expression, IsCanonical, isDefaulted); + return TemplateArgument(expression, CanonKind, isDefaulted); }]>; } let Class = PropertyTypeCase<TemplateArgument, "Pack"> in { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 222dbf5559e12..dc0a8084bcf05 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -1466,9 +1466,8 @@ DEF_TRAVERSE_TYPELOC(TypeOfType, { }) // FIXME: location of underlying expr -DEF_TRAVERSE_TYPELOC(DecltypeType, { - TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); -}) +DEF_TRAVERSE_TYPELOC(DecltypeType, + { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); }) DEF_TRAVERSE_TYPELOC(PackIndexingType, { TRY_TO(TraverseType(TL.getPattern())); diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index 5d4723045f208..9e00469e6a8bf 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -167,8 +167,8 @@ class TemplateArgument { unsigned Kind : 31; LLVM_PREFERRED_TYPE(bool) unsigned IsDefaulted : 1; - LLVM_PREFERRED_TYPE(bool) - unsigned IsCanonicalExpr : 1; + LLVM_PREFERRED_TYPE(CanonicalizationKindOrNone) + unsigned ExprCanonKind : 2; uintptr_t V; }; union { @@ -269,10 +269,11 @@ 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) { + TemplateArgument(Expr *E, CanonicalizationKindOrNone CanonKind, + bool IsDefaulted = false) { TypeOrValue.Kind = Expression; TypeOrValue.IsDefaulted = IsDefaulted; - TypeOrValue.IsCanonicalExpr = IsCanonical; + TypeOrValue.ExprCanonKind = CanonKind.toInternalRepresentation(); TypeOrValue.V = reinterpret_cast<uintptr_t>(E); } diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 24df18dbaace4..92c099b474956 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -2275,6 +2275,7 @@ class TypeOfTypeLoc // FIXME: add LParenLoc, it is tricky to support due to the limitation of // annotated-decltype token. struct DecltypeTypeLocInfo { + Expr *UnderlyingExpr; SourceLocation DecltypeLoc; SourceLocation RParenLoc; }; @@ -2282,7 +2283,8 @@ class DecltypeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType, DecltypeTypeLocInfo> { public: - Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } + Expr *getUnderlyingExpr() const { return getLocalData()->UnderlyingExpr; } + void setUnderlyingExpr(Expr *E) { getLocalData()->UnderlyingExpr = E; } SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; } void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; } @@ -2295,6 +2297,7 @@ class DecltypeTypeLoc } void initializeLocal(ASTContext &Context, SourceLocation Loc) { + setUnderlyingExpr(getTypePtr()->getUnderlyingExpr()); setDecltypeLoc(Loc); setRParenLoc(Loc); } diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h index aed1b7d309001..caba5917721cb 100644 --- a/clang/include/clang/Serialization/ASTRecordReader.h +++ b/clang/include/clang/Serialization/ASTRecordReader.h @@ -233,11 +233,10 @@ class ASTRecordReader /// Read a template argument, advancing Idx. (inherited) // TemplateArgument readTemplateArgument(); using DataStreamBasicReader::readTemplateArgument; - TemplateArgument readTemplateArgument(bool Canonicalize) { + TemplateArgument readTemplateArgument(CanonicalizationKindOrNone CanonKind) { TemplateArgument Arg = readTemplateArgument(); - if (Canonicalize) { - Arg = getContext().getCanonicalTemplateArgument(Arg); - } + if (CanonKind) + Arg = getContext().getCanonicalTemplateArgument(Arg, *CanonKind); return Arg; } @@ -245,8 +244,9 @@ class ASTRecordReader TemplateParameterList *readTemplateParameterList(); /// Read a template argument array, advancing Idx. - void readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, - bool Canonicalize = false); + void + readTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, + CanonicalizationKindOrNone CanonKind = std::nullopt); /// Read a UnresolvedSet structure, advancing Idx. void readUnresolvedSet(LazyASTUnresolvedSet &Set); @@ -324,6 +324,11 @@ class ASTRecordReader return UnsignedOrNone::fromInternalRepresentation(unsigned(readInt())); } + CanonicalizationKindOrNone readCanonicalizationKindOrNone() { + return CanonicalizationKindOrNone::fromInternalRepresentation( + unsigned(readInt())); + } + /// Read a string, advancing Idx. std::string readString() { return Reader->ReadString(Record, Idx); diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h index 9849ea6b395ab..43e09d1682622 100644 --- a/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/clang/include/clang/Serialization/ASTRecordWriter.h @@ -193,6 +193,10 @@ class ASTRecordWriter Record->push_back(Value.toInternalRepresentation()); } + void writeCanonicalizationKindOrNone(CanonicalizationKindOrNone Value) { + Record->push_back(Value.toInternalRepresentation()); + } + /// Emit an integral value. void AddAPInt(const llvm::APInt &Value) { writeAPInt(Value); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index e238e7fece16a..bf1ba2d6846cf 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -935,7 +935,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, DependentAddressSpaceTypes(this_()), DependentVectorTypes(this_()), DependentSizedMatrixTypes(this_()), FunctionProtoTypes(this_(), FunctionProtoTypesLog2InitSize), - DependentTypeOfExprTypes(this_()), DependentDecltypeTypes(this_()), + DependentTypeOfExprTypes(this_()), DecltypeTypes(this_()), DependentPackIndexingTypes(this_()), TemplateSpecializationTypes(this_()), AttributedTypes(this_()), DependentBitIntTypes(this_()), SubstTemplateTemplateParmPacks(this_()), DeducedTemplates(this_()), @@ -5978,10 +5978,9 @@ QualType ASTContext::getSubstTemplateTypeParmType(QualType Replacement, return QualType(SubstParm, 0); } -QualType -ASTContext::getSubstTemplateTypeParmPackType(Decl *AssociatedDecl, - unsigned Index, bool Final, - const TemplateArgument &ArgPack) { +QualType ASTContext::getSubstTemplateTypeParmPackType( + Decl *AssociatedDecl, unsigned Index, bool Final, + const TemplateArgument &ArgPack) const { #ifndef NDEBUG for (const auto &P : ArgPack.pack_elements()) assert(P.getKind() == TemplateArgument::Type && "Pack contains a non-type"); @@ -6347,7 +6346,7 @@ TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) const { if (NTTP->isParameterPack()) E = new (*this) PackExpansionExpr(E, NTTP->getLocation(), std::nullopt); - Arg = TemplateArgument(E, /*IsCanonical=*/false); + Arg = TemplateArgument(E, /*CanonKind=*/std::nullopt); } else { auto *TTP = cast<TemplateTemplateParmDecl>(Param); TemplateName Name = getQualifiedTemplateName( @@ -7631,8 +7630,10 @@ bool ASTContext::isSameConstraintExpr(const Expr *XCE, const Expr *YCE) const { return true; llvm::FoldingSetNodeID XCEID, YCEID; - XCE->Profile(XCEID, *this, /*Canonical=*/true, /*ProfileLambdaExpr=*/true); - YCE->Profile(YCEID, *this, /*Canonical=*/true, /*ProfileLambdaExpr=*/true); + XCE->Profile(XCEID, *this, CanonicalizationKind::Functional, + /*ProfileLambdaExpr=*/true); + YCE->Profile(YCEID, *this, CanonicalizationKind::Functional, + /*ProfileLambdaExpr=*/true); return XCEID == YCEID; } @@ -7744,9 +7745,10 @@ bool ASTContext::isSameDefaultTemplateArgument(const NamedDecl *X, NTTPX->getDefaultArgument().getArgument().getAsExpr()->IgnoreImpCasts(); Expr *DefaultArgumentY = NTTPY->getDefaultArgument().getArgument().getAsExpr()->IgnoreImpCasts(); + // FIXME: This should probably use functional equivalence instead. llvm::FoldingSetNodeID XID, YID; - DefaultArgumentX->Profile(XID, *this, /*Canonical=*/true); - DefaultArgumentY->Profile(YID, *this, /*Canonical=*/true); + DefaultArgumentX->Profile(XID, *this, CanonicalizationKind::Structural); + DefaultArgumentY->Profile(YID, *this, CanonicalizationKind::Structural); return XID == YID; } @@ -7829,8 +7831,10 @@ static bool hasSameOverloadableAttrs(const FunctionDecl *A, Cand1ID.clear(); Cand2ID.clear(); - (*Cand1A)->getCond()->Profile(Cand1ID, A->getASTContext(), true); - (*Cand2A)->getCond()->Profile(Cand2ID, B->getASTContext(), true); + (*Cand1A)->getCond()->Profile(Cand1ID, A->getASTContext(), + CanonicalizationKind::Structural); + (*Cand2A)->getCond()->Profile(Cand2ID, B->getASTContext(), + CanonicalizationKind::Structural); // Return false if any of the enable_if expressions of A and B are // different. @@ -8191,8 +8195,8 @@ bool ASTContext::isSameTemplateArgument(const TemplateArgument &Arg1, case TemplateArgument::Expression: { llvm::FoldingSetNodeID ID1, ID2; - Arg1.getAsExpr()->Profile(ID1, *this, /*Canonical=*/true); - Arg2.getAsExpr()->Profile(ID2, *this, /*Canonical=*/true); + Arg1.getAsExpr()->Profile(ID1, *this, CanonicalizationKind::Structural); + Arg2.getAsExpr()->Profile(ID2, *this, CanonicalizationKind::Structural); return ID1 == ID2; } diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp index f7888f58985db..33593f12be07b 100644 --- a/clang/lib/AST/ASTDiagnostic.cpp +++ b/clang/lib/AST/ASTDiagnostic.cpp @@ -126,7 +126,7 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT, ShouldAKA = true; QT = Context.getTemplateSpecializationType( TST->getKeyword(), TST->getTemplateName(), Args, - /*CanonicalArgs=*/{}, QT); + /*CanonicalArgs=*/{}, QT.getCanonicalType()); } break; } @@ -1534,8 +1534,8 @@ class TemplateDiff { return false; llvm::FoldingSetNodeID FromID, ToID; - FromExpr->Profile(FromID, Context, true); - ToExpr->Profile(ToID, Context, true); + FromExpr->Profile(FromID, Context, CanonicalizationKind::Structural); + ToExpr->Profile(ToID, Context, CanonicalizationKind::Structural); return FromID == ToID; } @@ -2149,15 +2149,21 @@ class TemplateDiff { return; } + TemplateDecl *FromOrigTD = FromOrigTST->getTemplateName().getAsTemplateDecl( + /*IgnoreDeduced=*/true); + TemplateDecl *ToOrigTD = ToOrigTST->getTemplateName().getAsTemplateDecl( + /*IgnoreDeduced=*/true); + // If either side does not have a template declaration, then there are no + // template parameters, and nothing further to diff. + if (!FromOrigTD || !ToOrigTD) + return; + FromQual -= QualType(FromOrigTST, 0).getQualifiers(); ToQual -= QualType(ToOrigTST, 0).getQualifiers(); // Same base template, but different arguments. - Tree.SetTemplateDiff( - FromOrigTST->getTemplateName().getAsTemplateDecl( - /*IgnoreDeduced=*/true), - ToOrigTST->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true), - FromQual, ToQual, false /*FromDefault*/, false /*ToDefault*/); + Tree.SetTemplateDiff(FromOrigTD, ToOrigTD, FromQual, ToQual, + false /*FromDefault*/, false /*ToDefault*/); DiffTemplate(FromOrigTST, ToOrigTST); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 08751f02ec36d..55223a4a945c4 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -917,7 +917,7 @@ ASTNodeImporter::import(const TemplateArgument &From) { case TemplateArgument::Expression: if (ExpectedExpr ToExpr = import(From.getAsExpr())) - return TemplateArgument(*ToExpr, From.isCanonicalExpr(), + return TemplateArgument(*ToExpr, From.getExprCanonKind(), From.getIsDefaulted()); else return ToExpr.takeError(); @@ -1723,7 +1723,7 @@ ExpectedType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) { return ToUnderlyingTypeOrErr.takeError(); return Importer.getToContext().getDecltypeType( - *ToExprOrErr, *ToUnderlyingTypeOrErr); + *ToExprOrErr, T->getExprCanonicalizationKind(), *ToUnderlyingTypeOrErr); } ExpectedType @@ -6560,7 +6560,6 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl( ASTTemplateArgumentListInfo::Create(Importer.getToContext(), ToTAInfo), ClassTemplate, ArrayRef(TemplateArgs), - /*CanonInjectedTST=*/CanQualType(), cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl))) return D2; diff --git a/clang/lib/AST/AttrImpl.cpp b/clang/lib/AST/AttrImpl.cpp index cfd47e82b04b5..82d6f51fbabdb 100644 --- a/clang/lib/AST/AttrImpl.cpp +++ b/clang/lib/AST/AttrImpl.cpp @@ -442,7 +442,7 @@ inline void profileAttrArg<Attr *>(llvm::FoldingSetNodeID &ID, template <> inline void profileAttrArg<Expr *>(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx, Expr *E) { - E->Profile(ID, Ctx, /*Canonical=*/true); + E->Profile(ID, Ctx, CanonicalizationKind::Functional); } template <> diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index e127a08e8620a..8fe9a7c27cd16 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -1157,15 +1157,13 @@ ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl( SourceLocation IdLoc, TemplateParameterList *Params, const ASTTemplateArgumentListInfo *ArgsAsWritten, ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, - CanQualType CanonInjectedTST, ClassTemplatePartialSpecializationDecl *PrevDecl) : ClassTemplateSpecializationDecl( Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc, // Tracking StrictPackMatch for Partial // Specializations is not needed. SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl), - InstantiatedFromMember(nullptr, false), - CanonInjectedTST(CanonInjectedTST) { + InstantiatedFromMember(nullptr, false) { setSpecializationKind(TSK_ExplicitSpecialization); setExplicitSpecializationInfo(Params, ArgsAsWritten); } @@ -1176,12 +1174,11 @@ ClassTemplatePartialSpecializationDecl::Create( SourceLocation IdLoc, TemplateParameterList *Params, const ASTTemplateArgumentListInfo *ArgsAsWritten, ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args, - CanQualType CanonInjectedTST, ClassTemplatePartialSpecializationDecl *PrevDecl) { assert(!Params->empty() && "template with no template parameters"); return new (Context, DC) ClassTemplatePartialSpecializationDecl( Context, TK, DC, StartLoc, IdLoc, Params, ArgsAsWritten, - SpecializedTemplate, Args, CanonInjectedTST, PrevDecl); + SpecializedTemplate, Args, PrevDecl); } ClassTemplatePartialSpecializationDecl * @@ -1194,11 +1191,13 @@ CanQualType ClassTemplatePartialSpecializationDecl::getCanonicalInjectedSpecializationType( const ASTContext &Ctx) const { if (CanonInjectedTST.isNull()) { + SmallVector<TemplateArgument, 4> CanonicalArgs(getTemplateArgs().asArray()); + Ctx.canonicalizeTemplateArguments(CanonicalArgs); CanonInjectedTST = CanQualType::CreateUnsafe(Ctx.getCanonicalTemplateSpecializationType( ElaboratedTypeKeyword::None, TemplateName(getSpecializedTemplate()->getCanonicalDecl()), - getTemplateArgs().asArray())); + CanonicalArgs)); } return CanonInjectedTST; } diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp index ffb3d74f6b9f4..e7f8da368c26b 100644 --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -1791,8 +1791,16 @@ void JSONNodeDumper::VisitTemplateExpansionTemplateArgument( void JSONNodeDumper::VisitExpressionTemplateArgument( const TemplateArgument &TA) { JOS.attribute("isExpr", true); - if (TA.isCanonicalExpr()) - JOS.attribute("isCanonical", true); + if (auto Kind = TA.getExprCanonKind()) { + switch (*Kind) { + case CanonicalizationKind::Structural: + JOS.attribute("CanonicalKind", "Structural"); + break; + case CanonicalizationKind::Functional: + JOS.attribute("CanonicalKind", "Functional"); + break; + } + } } void JSONNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) { JOS.attribute("isPack", true); diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 1f20e2aee0619..1eab0fc3c2cd1 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -1000,10 +1000,6 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> { VisitType(T); } - void VisitDependentDecltypeType(const DependentDecltypeType *T) { - VisitDecltypeType(T); - } - void VisitDeducedType(const DeducedType *T) { AddQualType(T->getDeducedType()); VisitType(T); diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 371a6bdbbefa6..1341a71dffc0e 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -1428,10 +1428,10 @@ void StmtProfiler::VisitConstantExpr(const ConstantExpr *S) { void StmtProfiler::VisitDeclRefExpr(const DeclRefExpr *S) { VisitExpr(S); - if (!Canonical) + if (!CanonKind) VisitNestedNameSpecifier(S->getQualifier()); VisitDecl(S->getDecl()); - if (!Canonical) { + if (!CanonKind) { ID.AddBoolean(S->hasExplicitTemplateArgs()); if (S->hasExplicitTemplateArgs()) VisitTemplateArguments(S->getTemplateArgs(), S->getNumTemplateArgs()); @@ -1585,7 +1585,7 @@ void StmtProfiler::VisitCallExpr(const CallExpr *S) { void StmtProfiler::VisitMemberExpr(const MemberExpr *S) { VisitExpr(S); VisitDecl(S->getMemberDecl()); - if (!Canonical) + if (!CanonKind) VisitNestedNameSpecifier(S->getQualifier()); ID.AddBoolean(S->isArrow()); } diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 0ddf49bb19b5c..100e91f454d84 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -449,7 +449,7 @@ bool TemplateArgument::structurallyEquals(const TemplateArgument &Other) const { return TypeOrValue.V == Other.TypeOrValue.V; case Expression: return TypeOrValue.V == Other.TypeOrValue.V && - TypeOrValue.IsCanonicalExpr == Other.TypeOrValue.IsCanonicalExpr; + TypeOrValue.ExprCanonKind == Other.TypeOrValue.ExprCanonKind; case Template: case TemplateExpansion: @@ -495,7 +495,7 @@ TemplateArgument TemplateArgument::getPackExpansionPattern() const { case Expression: return TemplateArgument(cast<PackExpansionExpr>(getAsExpr())->getPattern(), - isCanonicalExpr()); + getExprCanonKind()); case TemplateExpansion: return TemplateArgument(getAsTemplateOrTemplatePattern()); @@ -568,7 +568,7 @@ void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out, case Expression: { PrintingPolicy ExprPolicy = Policy; - ExprPolicy.PrintAsCanonical = isCanonicalExpr(); + ExprPolicy.PrintAsCanonical = bool(getExprCanonKind()); getAsExpr()->printPretty(Out, nullptr, ExprPolicy); break; } diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index 797a354c5d0fa..a1e90fdc78301 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -361,12 +361,7 @@ TemplateNameDependence TemplateName::getDependence() const { if (TTP->isParameterPack()) D |= TemplateNameDependence::UnexpandedPack; } - // FIXME: Hack, getDeclContext() can be null if Template is still - // initializing due to PCH reading, so we check it before using it. - // Should probably modify TemplateSpecializationType to allow constructing - // it without the isDependent() checking. - if (Template->getDeclContext() && - Template->getDeclContext()->isDependentContext()) + if (Template->getDeclContext()->isDependentContext()) D |= TemplateNameDependence::DependentInstantiation; return D; } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index d90090b82fb7a..6d5ac8b1a8aeb 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1399,8 +1399,16 @@ void TextNodeDumper::VisitTemplateExpansionTemplateArgument( void TextNodeDumper::VisitExpressionTemplateArgument( const TemplateArgument &TA) { OS << " expr"; - if (TA.isCanonicalExpr()) - OS << " canonical"; + if (auto Kind = TA.getExprCanonKind()) { + switch (*Kind) { + case CanonicalizationKind::Structural: + OS << " canonical"; + break; + case CanonicalizationKind::Functional: + OS << " canonical-functional"; + break; + } + } dumpTemplateArgument(TA); } @@ -2180,6 +2188,19 @@ void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) { VisitFunctionType(T); } +void TextNodeDumper::VisitDecltypeType(const DecltypeType *T) { + if (auto K = T->getExprCanonicalizationKind()) { + switch (*K) { + case CanonicalizationKind::Structural: + OS << " structural-expr"; + break; + case CanonicalizationKind::Functional: + OS << " functional-expr"; + break; + } + } +} + void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { if (ElaboratedTypeKeyword K = T->getKeyword(); K != ElaboratedTypeKeyword::None) diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index d501681f0342c..34ed7797a3ba3 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -310,7 +310,7 @@ void ConstantArrayType::Profile(llvm::FoldingSetNodeID &ID, ID.AddInteger(TypeQuals); ID.AddBoolean(SizeExpr != nullptr); if (SizeExpr) - SizeExpr->Profile(ID, Context, true); + SizeExpr->Profile(ID, Context, CanonicalizationKind::Structural); } QualType ArrayParameterType::getConstantArrayType(const ASTContext &Ctx) const { @@ -332,7 +332,7 @@ void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID, ID.AddInteger(llvm::to_underlying(SizeMod)); ID.AddInteger(TypeQuals); if (E) - E->Profile(ID, Context, true); + E->Profile(ID, Context, CanonicalizationKind::Structural); } DependentVectorType::DependentVectorType(QualType ElementType, @@ -353,7 +353,7 @@ void DependentVectorType::Profile(llvm::FoldingSetNodeID &ID, VectorKind VecKind) { ID.AddPointer(ElementType.getAsOpaquePtr()); ID.AddInteger(llvm::to_underlying(VecKind)); - SizeExpr->Profile(ID, Context, true); + SizeExpr->Profile(ID, Context, CanonicalizationKind::Structural); } DependentSizedExtVectorType::DependentSizedExtVectorType(QualType ElementType, @@ -372,7 +372,7 @@ void DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, Expr *SizeExpr) { ID.AddPointer(ElementType.getAsOpaquePtr()); - SizeExpr->Profile(ID, Context, true); + SizeExpr->Profile(ID, Context, CanonicalizationKind::Structural); } DependentAddressSpaceType::DependentAddressSpaceType(QualType PointeeType, @@ -391,7 +391,7 @@ void DependentAddressSpaceType::Profile(llvm::FoldingSetNodeID &ID, QualType PointeeType, Expr *AddrSpaceExpr) { ID.AddPointer(PointeeType.getAsOpaquePtr()); - AddrSpaceExpr->Profile(ID, Context, true); + AddrSpaceExpr->Profile(ID, Context, CanonicalizationKind::Structural); } MatrixType::MatrixType(TypeClass tc, QualType matrixType, QualType canonType, @@ -437,8 +437,8 @@ void DependentSizedMatrixType::Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, Expr *RowExpr, Expr *ColumnExpr) { ID.AddPointer(ElementType.getAsOpaquePtr()); - RowExpr->Profile(ID, CTX, true); - ColumnExpr->Profile(ID, CTX, true); + RowExpr->Profile(ID, CTX, CanonicalizationKind::Structural); + ColumnExpr->Profile(ID, CTX, CanonicalizationKind::Structural); } VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType, @@ -486,7 +486,7 @@ void DependentBitIntType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool IsUnsigned, Expr *NumBitsExpr) { ID.AddBoolean(IsUnsigned); - NumBitsExpr->Profile(ID, Context, true); + NumBitsExpr->Profile(ID, Context, CanonicalizationKind::Structural); } bool BoundsAttributedType::referencesFieldDecls() const { @@ -4063,7 +4063,10 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, for (QualType Ex : epi.ExceptionSpec.Exceptions) ID.AddPointer(Ex.getAsOpaquePtr()); } else if (isComputedNoexcept(epi.ExceptionSpec.Type)) { - epi.ExceptionSpec.NoexceptExpr->Profile(ID, Context, Canonical); + epi.ExceptionSpec.NoexceptExpr->Profile( + ID, Context, + Canonical ? CanonicalizationKindOrNone(CanonicalizationKind::Structural) + : std::nullopt); } else if (epi.ExceptionSpec.Type == EST_Uninstantiated || epi.ExceptionSpec.Type == EST_Unevaluated) { ID.AddPointer(epi.ExceptionSpec.SourceDecl->getCanonicalDecl()); @@ -4252,7 +4255,7 @@ QualType TypeOfExprType::desugar() const { void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, Expr *E, bool IsUnqual) { - E->Profile(ID, Context, true); + E->Profile(ID, Context, CanonicalizationKind::Structural); ID.AddBoolean(IsUnqual); } @@ -4361,7 +4364,7 @@ void PackIndexingType::Profile(llvm::FoldingSetNodeID &ID, Expr *E, bool FullySubstituted, ArrayRef<QualType> Expansions) { - E->Profile(ID, Context, true); + E->Profile(ID, Context, CanonicalizationKind::Structural); ID.AddBoolean(FullySubstituted); if (!Expansions.empty()) { ID.AddInteger(Expansions.size()); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index e8fbffb9f954d..7a11b044ebf9c 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1364,7 +1364,8 @@ void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) { OS << "decltype("; if (const Expr *E = T->getUnderlyingExpr()) { PrintingPolicy ExprPolicy = Policy; - ExprPolicy.PrintAsCanonical = T->isCanonicalUnqualified(); + // FIXME: Support printing as functionally equivalent canonical type. + ExprPolicy.PrintAsCanonical = bool(T->getExprCanonicalizationKind()); E->printPretty(OS, nullptr, ExprPolicy); } OS << ')'; diff --git a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp index 12442040b13bb..8c576008d263e 100644 --- a/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp +++ b/clang/lib/Frontend/Rewrite/RewriteModernObjC.cpp @@ -883,7 +883,8 @@ RewriteModernObjC::getIvarAccessString(ObjCIvarDecl *D) { ICIS_NoInit); MemberExpr *ME = MemberExpr::CreateImplicit( *Context, PE, true, FD, FD->getType(), VK_LValue, OK_Ordinary); - IvarT = Context->getDecltypeType(ME, ME->getType()); + IvarT = Context->getDecltypeType(ME, /*ExprCanonKind=*/std::nullopt, + ME->getType()); } } convertObjCTypeToCStyleType(IvarT); @@ -7484,7 +7485,8 @@ Stmt *RewriteModernObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV) { /*Mutable=*/true, ICIS_NoInit); MemberExpr *ME = MemberExpr::CreateImplicit( *Context, PE, true, FD, FD->getType(), VK_LValue, OK_Ordinary); - IvarT = Context->getDecltypeType(ME, ME->getType()); + IvarT = Context->getDecltypeType(ME, /*ExprCanonKind=*/std::nullopt, + ME->getType()); } } convertObjCTypeToCStyleType(IvarT); diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index cd0040b3c9fa6..49c0679c28bae 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -855,6 +855,7 @@ bool Sema::ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS, TypeLocBuilder TLB; DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T); + DecltypeTL.setUnderlyingExpr(DS.getRepAsExpr()); DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd()); SS.Make(Context, TLB.getTypeLocInContext(Context, T), ColonColonLoc); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index d52c12670a57b..6d8bc19509fe0 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -11120,10 +11120,10 @@ bool Sema::CheckSizeofMemaccessArgument(const Expr *LenExpr, const Expr *Dest, QualType PointeeTy = DestPtrTy->getPointeeType(); if (SizeOfArgID == llvm::FoldingSetNodeID()) - SizeOfArg->Profile(SizeOfArgID, Context, true); + SizeOfArg->Profile(SizeOfArgID, Context, CanonicalizationKind::Structural); llvm::FoldingSetNodeID DestID; - Dest->Profile(DestID, Context, true); + Dest->Profile(DestID, Context, CanonicalizationKind::Structural); if (DestID == SizeOfArgID) { // TODO: For strncpy() and friends, this could suggest sizeof(dst) // over sizeof(src) as well. diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp index 0d2b5c44f6db9..0e1040d126066 100644 --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -182,7 +182,7 @@ struct SatisfactionStackRAII { static bool DiagRecursiveConstraintEval( Sema &S, llvm::FoldingSetNodeID &ID, const NamedDecl *Templ, const Expr *E, const MultiLevelTemplateArgumentList *MLTAL = nullptr) { - E->Profile(ID, S.Context, /*Canonical=*/true); + E->Profile(ID, S.Context, CanonicalizationKind::Functional); if (MLTAL) { for (const auto &List : *MLTAL) for (const auto &TemplateArg : List.Args) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 274973c78da81..30a58e0ceac2e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2356,7 +2356,7 @@ Sema::ActOnStringLiteral(ArrayRef<Token> StringToks, Scope *UDLScope) { case LOLR_Template: { TemplateArgumentListInfo ExplicitArgs; - TemplateArgument Arg(Lit, /*IsCanonical=*/false); + TemplateArgument Arg(Lit, /*CanonKind=*/std::nullopt); TemplateArgumentLocInfo ArgInfo(Lit); ExplicitArgs.addArgument(TemplateArgumentLoc(Arg, ArgInfo)); return BuildLiteralOperatorCall(R, OpNameInfo, {}, StringTokLocs.back(), diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index b6099b37104f8..2af98bdcd523f 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -7427,6 +7427,7 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base, case DeclSpec::TST_decltype: { T = BuildDecltypeType(DS.getRepAsExpr(), /*AsUnevaluated=*/false); DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T); + DecltypeTL.setUnderlyingExpr(DS.getRepAsExpr()); DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd()); break; diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 65b60964d1192..1292680f9cd22 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -3754,7 +3754,8 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R, SFINAETrap Trap(*this); CheckTemplateArgumentInfo CTAI; TemplateArgumentLoc Arg( - TemplateArgument(StringLit, /*IsCanonical=*/false), StringLit); + TemplateArgument(StringLit, /*CanonKind=*/std::nullopt), + StringLit); if (CheckTemplateArgument( Params->getParam(0), Arg, FD, R.getNameLoc(), R.getNameLoc(), /*ArgumentPackIndex=*/0, CTAI, CTAK_Specified) || diff --git a/clang/lib/Sema/SemaOpenACCAtomic.cpp b/clang/lib/Sema/SemaOpenACCAtomic.cpp index dbe7e9739c2f9..f381b96d1678d 100644 --- a/clang/lib/Sema/SemaOpenACCAtomic.cpp +++ b/clang/lib/Sema/SemaOpenACCAtomic.cpp @@ -424,9 +424,9 @@ class AtomicOperandChecker { llvm::FoldingSetNodeID LHS_ID, InnerLHS_ID, InnerRHS_ID; AssignInf.LHS->Profile(LHS_ID, SemaRef.getASTContext(), - /*Canonical=*/true); + CanonicalizationKind::Structural); BinInf->LHS->Profile(InnerLHS_ID, SemaRef.getASTContext(), - /*Canonical=*/true); + CanonicalizationKind::Structural); // This is X = X binop expr; // Check the RHS is an expression. @@ -440,7 +440,7 @@ class AtomicOperandChecker { IDACInfo::AssignBinOp, AssignInf.LHS}; BinInf->RHS->Profile(InnerRHS_ID, SemaRef.getASTContext(), - /*Canonical=*/true); + CanonicalizationKind::Structural); // This is X = expr binop X; // Check the LHS is an expression if (LHS_ID == InnerRHS_ID) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 61da3398137d0..29a26e7918780 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -3513,13 +3513,14 @@ getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; llvm::FoldingSetNodeID AEId; const Expr *AE = Allocator->IgnoreParenImpCasts(); - AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true); + AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), + CanonicalizationKind::Structural); for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); llvm::FoldingSetNodeID DAEId; DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(), - /*Canonical=*/true); + CanonicalizationKind::Structural); if (AEId == DAEId) { AllocatorKindRes = AllocatorKind; break; @@ -11835,11 +11836,11 @@ bool OpenMPAtomicUpdateChecker::checkBinaryOperation( Expr *RHS = AtomicInnerBinOp->getRHS(); llvm::FoldingSetNodeID XId, LHSId, RHSId; X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), - /*Canonical=*/true); + CanonicalizationKind::Structural); LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), - /*Canonical=*/true); + CanonicalizationKind::Structural); RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), - /*Canonical=*/true); + CanonicalizationKind::Structural); if (XId == LHSId) { E = RHS; IsXLHSInRHSPart = true; @@ -11981,7 +11982,8 @@ bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, /// Get the node id of the fixed point of an expression \a S. llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) { llvm::FoldingSetNodeID Id; - S->IgnoreParenImpCasts()->Profile(Id, Context, true); + S->IgnoreParenImpCasts()->Profile(Id, Context, + CanonicalizationKind::Structural); return Id; } @@ -13208,8 +13210,10 @@ StmtResult SemaOpenMP::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, // Check that the first expression has form v = x. Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); llvm::FoldingSetNodeID XId, PossibleXId; - Checker.getX()->Profile(XId, Context, /*Canonical=*/true); - PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); + Checker.getX()->Profile(XId, Context, + CanonicalizationKind::Structural); + PossibleX->Profile(PossibleXId, Context, + CanonicalizationKind::Structural); IsUpdateExprFound = XId == PossibleXId; if (IsUpdateExprFound) { V = BinOp->getLHS(); @@ -13239,8 +13243,10 @@ StmtResult SemaOpenMP::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, // Check that the second expression has form v = x. Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); llvm::FoldingSetNodeID XId, PossibleXId; - Checker.getX()->Profile(XId, Context, /*Canonical=*/true); - PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); + Checker.getX()->Profile(XId, Context, + CanonicalizationKind::Structural); + PossibleX->Profile(PossibleXId, Context, + CanonicalizationKind::Structural); IsUpdateExprFound = XId == PossibleXId; if (IsUpdateExprFound) { V = BinOp->getLHS(); @@ -13283,10 +13289,10 @@ StmtResult SemaOpenMP::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, Expr *PossibleXLHSInSecond = SecondBinOp->getLHS()->IgnoreParenImpCasts(); llvm::FoldingSetNodeID X1Id, X2Id; - PossibleXRHSInFirst->Profile(X1Id, Context, - /*Canonical=*/true); - PossibleXLHSInSecond->Profile(X2Id, Context, - /*Canonical=*/true); + PossibleXRHSInFirst->Profile( + X1Id, Context, CanonicalizationKind::Structural); + PossibleXLHSInSecond->Profile( + X2Id, Context, CanonicalizationKind::Structural); IsUpdateExprFound = X1Id == X2Id; if (IsUpdateExprFound) { V = FirstBinOp->getLHS(); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 0365183ee1b09..1d63ba76c0d46 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -950,7 +950,8 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef, case ParsedTemplateArgument::NonType: { Expr *E = Arg.getAsExpr(); - return TemplateArgumentLoc(TemplateArgument(E, /*IsCanonical=*/false), E); + return TemplateArgumentLoc(TemplateArgument(E, /*CanonKind=*/std::nullopt), + E); } case ParsedTemplateArgument::Template: { @@ -1647,7 +1648,7 @@ NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, Param->setDefaultArgument( Context, getTrivialTemplateArgumentLoc( - TemplateArgument(Default, /*IsCanonical=*/false), + TemplateArgument(Default, /*CanonKind=*/std::nullopt), QualType(), SourceLocation())); } @@ -5644,7 +5645,7 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc, // If the resulting expression is new, then use it in place of the // old expression in the template argument. if (R != E) { - TemplateArgument TA(R, /*IsCanonical=*/false); + TemplateArgument TA(R, /*CanonKind=*/std::nullopt); ArgLoc = TemplateArgumentLoc(TA, R); } break; @@ -6893,7 +6894,7 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction( // Stop checking the precise nature of the argument if it is value dependent, // it should be checked when instantiated. if (Arg->isValueDependent()) { - SugaredConverted = TemplateArgument(ArgIn, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(ArgIn, /*CanonKind=*/std::nullopt); CanonicalConverted = S.Context.getCanonicalTemplateArgument(SugaredConverted); return false; @@ -7082,7 +7083,7 @@ static bool CheckTemplateArgumentPointerToMember( if (VD->getType()->isMemberPointerType()) { if (isa<NonTypeTemplateParmDecl>(VD)) { if (Arg->isTypeDependent() || Arg->isValueDependent()) { - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = S.Context.getCanonicalTemplateArgument(SugaredConverted); } else { @@ -7148,7 +7149,7 @@ static bool CheckTemplateArgumentPointerToMember( // Okay: this is the address of a non-static member, and therefore // a member pointer constant. if (Arg->isTypeDependent() || Arg->isValueDependent()) { - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = S.Context.getCanonicalTemplateArgument(SugaredConverted); } else { @@ -7273,7 +7274,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, return ExprError(); setDeductionArg(E.get()); } - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = TemplateArgument( Context.getCanonicalTemplateArgument(SugaredConverted)); return Arg; @@ -7304,7 +7305,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, // normal template rules apply: we accept the template if it would be valid // for any number of expansions (i.e. none). if (ArgPE && !StrictCheck) { - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = TemplateArgument( Context.getCanonicalTemplateArgument(SugaredConverted)); return Arg; @@ -7330,7 +7331,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, return Arg; } if (isa<NonTypeTemplateParmDecl>(ND)) { - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = Context.getCanonicalTemplateArgument(SugaredConverted); return Arg; @@ -7387,7 +7388,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, // permitted (and expected) to be unable to determine a value. if (ArgResult.get()->isValueDependent()) { setDeductionArg(ArgResult.get()); - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = Context.getCanonicalTemplateArgument(SugaredConverted); return Arg; @@ -7425,7 +7426,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, Value.getLValuePath()[0].getAsArrayIndex() == 0 && !Value.isLValueOnePastTheEnd() && ParamType->isPointerType()) { if (ArgPE) { - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = Context.getCanonicalTemplateArgument(SugaredConverted); } else { @@ -7456,7 +7457,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, return Diag(StartLoc, diag::err_non_type_template_arg_addr_label_diff); if (ArgPE) { - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = Context.getCanonicalTemplateArgument(SugaredConverted); } else { @@ -7504,7 +7505,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, // We can't check arbitrary value-dependent arguments. if (Arg->isValueDependent()) { - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = Context.getCanonicalTemplateArgument(SugaredConverted); return Arg; @@ -7593,7 +7594,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, if (Arg->isValueDependent()) { // The argument is value-dependent. Create a new // TemplateArgument with the converted expression. - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = Context.getCanonicalTemplateArgument(SugaredConverted); return Arg; @@ -7764,7 +7765,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType, // Deal with parameters of type std::nullptr_t. if (ParamType->isNullPtrType()) { if (Arg->isTypeDependent() || Arg->isValueDependent()) { - SugaredConverted = TemplateArgument(Arg, /*IsCanonical=*/false); + SugaredConverted = TemplateArgument(Arg, /*CanonKind=*/std::nullopt); CanonicalConverted = Context.getCanonicalTemplateArgument(SugaredConverted); return Arg; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index 1b353d0e0092d..fbf478e91612f 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -546,8 +546,9 @@ DeduceNullPtrTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, : CK_NullToPointer) .get(); return DeduceNonTypeTemplateArgument( - S, TemplateParams, NTTP, TemplateArgument(Value, /*IsCanonical=*/false), - Value->getType(), Info, PartialOrdering, Deduced, HasDeducedAnyParam); + S, TemplateParams, NTTP, + TemplateArgument(Value, /*CanonKind=*/std::nullopt), Value->getType(), + Info, PartialOrdering, Deduced, HasDeducedAnyParam); } /// Deduce the value of the given non-type template parameter @@ -561,8 +562,9 @@ DeduceNonTypeTemplateArgument(Sema &S, TemplateParameterList *TemplateParams, SmallVectorImpl<DeducedTemplateArgument> &Deduced, bool *HasDeducedAnyParam) { return DeduceNonTypeTemplateArgument( - S, TemplateParams, NTTP, TemplateArgument(Value, /*IsCanonical=*/false), - Value->getType(), Info, PartialOrdering, Deduced, HasDeducedAnyParam); + S, TemplateParams, NTTP, + TemplateArgument(Value, /*CanonKind=*/std::nullopt), Value->getType(), + Info, PartialOrdering, Deduced, HasDeducedAnyParam); } /// Deduce the value of the given non-type template parameter @@ -2870,7 +2872,8 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, NTTPType = Arg.getParamTypeForDecl(); Expr *E = BuildExpressionFromDeclTemplateArgument(Arg, NTTPType, Loc) .getAs<Expr>(); - return TemplateArgumentLoc(TemplateArgument(E, /*IsCanonical=*/false), E); + return TemplateArgumentLoc(TemplateArgument(E, /*CanonKind=*/std::nullopt), + E); } case TemplateArgument::NullPtr: { @@ -2885,7 +2888,8 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, case TemplateArgument::Integral: case TemplateArgument::StructuralValue: { Expr *E = BuildExpressionFromNonTypeTemplateArgument(Arg, Loc).get(); - return TemplateArgumentLoc(TemplateArgument(E, /*IsCanonical=*/false), E); + return TemplateArgumentLoc(TemplateArgument(E, /*CanonKind=*/std::nullopt), + E); } case TemplateArgument::Template: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index d27130438a500..119c962b07d62 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -6082,6 +6082,7 @@ namespace { } void VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { assert(DS.getTypeSpecType() == DeclSpec::TST_decltype); + TL.setUnderlyingExpr(DS.getRepAsExpr()); TL.setDecltypeLoc(DS.getTypeSpecTypeLoc()); TL.setRParenLoc(DS.getTypeofParensRange().getEnd()); } @@ -10083,7 +10084,8 @@ QualType Sema::BuildDecltypeType(Expr *E, bool AsUnevaluated) { // used to build SFINAE gadgets. Diag(E->getExprLoc(), diag::warn_side_effects_unevaluated_context); } - return Context.getDecltypeType(E, getDecltypeForExpr(E)); + return Context.getDecltypeType(E, /*ExprCanonKind=*/std::nullopt, + getDecltypeForExpr(E)); } QualType Sema::ActOnPackIndexingType(QualType Pattern, Expr *IndexExpr, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 49e643e04c426..bdf1ab4204ee3 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4077,7 +4077,7 @@ class TreeTransform { return TemplateArgumentLoc(); return TemplateArgumentLoc(TemplateArgument(Result.get(), - /*IsCanonical=*/false), + /*CanonKind=*/std::nullopt), Result.get()); } @@ -5108,7 +5108,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument( if (E.isInvalid()) return true; Output = TemplateArgumentLoc( - TemplateArgument(E.get(), /*IsCanonical=*/false), E.get()); + TemplateArgument(E.get(), /*CanonKind=*/std::nullopt), E.get()); return false; } } @@ -7056,17 +7056,15 @@ QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB, return Result; } -template<typename Derived> +template <typename Derived> QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, DecltypeTypeLoc TL) { - const DecltypeType *T = TL.getTypePtr(); - // decltype expressions are not potentially evaluated contexts EnterExpressionEvaluationContext Unevaluated( SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, Sema::ExpressionEvaluationContextRecord::EK_Decltype); - ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr()); + ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr()); if (E.isInvalid()) return QualType(); @@ -16561,7 +16559,7 @@ TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) { ArgStorage = TemplateArgument( new (getSema().Context) PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt), - /*IsCanonical=*/false); + /*CanonKind=*/std::nullopt); } PackArgs = ArgStorage; } @@ -16779,9 +16777,11 @@ ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr( Replacement = E->getReplacement(); } + // FIXME: Track in SubstNonTypeTemplateParmExpr the canonical kind of the + // expression. return getDerived().RebuildSubstNonTypeTemplateParmExpr( AssociatedDecl, E->getIndex(), ParamType, E->getNameLoc(), - TemplateArgument(Replacement.get(), /*IsCanonical=*/false), + TemplateArgument(Replacement.get(), /*CanonKind=*/std::nullopt), E->getPackIndex(), E->getFinal()); } diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index b01b18fe3e0ec..866dfa592ca4c 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -7635,6 +7635,7 @@ void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { } void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { + TL.setUnderlyingExpr(Reader.readExpr()); TL.setDecltypeLoc(readSourceLocation()); TL.setRParenLoc(readSourceLocation()); } @@ -10272,12 +10273,12 @@ ASTRecordReader::readTemplateParameterList() { } void ASTRecordReader::readTemplateArgumentList( - SmallVectorImpl<TemplateArgument> &TemplArgs, - bool Canonicalize) { + SmallVectorImpl<TemplateArgument> &TemplArgs, + CanonicalizationKindOrNone CanonKind) { unsigned NumTemplateArgs = readInt(); TemplArgs.reserve(NumTemplateArgs); while (NumTemplateArgs--) - TemplArgs.push_back(readTemplateArgument(Canonicalize)); + TemplArgs.push_back(readTemplateArgument(CanonKind)); } /// Read a UnresolvedSet structure. diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 25598683d1d62..ed520b1dd05dd 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -948,7 +948,8 @@ void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { // Template arguments. SmallVector<TemplateArgument, 8> TemplArgs; - Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true); + Record.readTemplateArgumentList(TemplArgs, + CanonicalizationKind::Structural); const TemplateParameterList *TemplateParams = Record.readBool() ? Record.readTemplateParameterList() : nullptr; @@ -2454,7 +2455,7 @@ void ASTDeclReader::VisitImplicitConceptSpecializationDecl( VisitDecl(D); llvm::SmallVector<TemplateArgument, 4> Args; for (unsigned I = 0; I < D->NumTemplateArgs; ++I) - Args.push_back(Record.readTemplateArgument(/*Canonicalize=*/false)); + Args.push_back(Record.readTemplateArgument()); D->setTemplateArguments(Args); } @@ -2557,7 +2558,7 @@ RedeclarableResult ASTDeclReader::VisitClassTemplateSpecializationDeclImpl( } SmallVector<TemplateArgument, 8> TemplArgs; - Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true); + Record.readTemplateArgumentList(TemplArgs, CanonicalizationKind::Functional); D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs); D->PointOfInstantiation = readSourceLocation(); D->SpecializationKind = (TemplateSpecializationKind)Record.readInt(); @@ -2658,7 +2659,7 @@ RedeclarableResult ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( } SmallVector<TemplateArgument, 8> TemplArgs; - Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true); + Record.readTemplateArgumentList(TemplArgs, CanonicalizationKind::Functional); D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs); D->PointOfInstantiation = readSourceLocation(); D->SpecializationKind = (TemplateSpecializationKind)Record.readInt(); diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index ecf935e3b3548..31a6022698ece 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -518,6 +518,7 @@ void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { } void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { + Record.AddStmt(TL.getUnderlyingExpr()); addSourceLocation(TL.getDecltypeLoc()); addSourceLocation(TL.getRParenLoc()); } _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
