[llvm-branch-commits] [clang] [clang-tools-extra] [clang] implement CWG1980 / part 2 of #190495 : trivial changes (PR #207865)
Matheus Izvekov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Tue Jul 7 08:06:26 PDT 2026
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 <mizvekov at gmail.com>
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());
}
More information about the llvm-branch-commits
mailing list