[clang] [Clang][Sema] Use llvm::dyn_cast instead of dyn_cast on PointerUnion (PR #216353)
Marc Auberer via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 14 09:46:33 PDT 2026
https://github.com/marcauberer created https://github.com/llvm/llvm-project/pull/216353
This is part of the migration from `PointerUnion<PTs>::dyn_cast<T>()` to `llvm::dyn_cast<T>(PointerUnion)`.
The dyn_cast method on PointerUnion is simply a wrapper around `llvm::dyn_cast_if_present`, which means that it can be replaced with `llvm::dyn_cast` for all non-optional types.
>From 130a2655d14e1e66ea117c0dd02bbff6f7da4cd2 Mon Sep 17 00:00:00 2001
From: Marc Auberer <marc.auberer at chillibits.com>
Date: Fri, 14 Aug 2026 18:45:19 +0200
Subject: [PATCH] [Clang][Sema] Use llvm::dyn_cast instead of dyn_cast on
PointerUnion
---
clang/lib/Sema/SemaConcept.cpp | 9 ++---
clang/lib/Sema/SemaDeclCXX.cpp | 8 ++---
clang/lib/Sema/SemaLifetimeSafety.h | 4 +--
clang/lib/Sema/SemaOverload.cpp | 6 ++--
clang/lib/Sema/SemaSYCL.cpp | 4 +--
clang/lib/Sema/SemaTemplate.cpp | 10 +++---
clang/lib/Sema/SemaTemplateInstantiate.cpp | 12 +++----
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 +--
clang/lib/Sema/SemaTemplateVariadic.cpp | 35 ++++++++-----------
clang/lib/Sema/TreeTransform.h | 2 +-
10 files changed, 43 insertions(+), 51 deletions(-)
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index ce91099cd037c..fd80277fb2bc6 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1318,7 +1318,7 @@ bool Sema::CheckConstraintSatisfaction(
OutSatisfaction.IsSatisfied = true;
return false;
}
- const auto *Template = Entity.dyn_cast<const NamedDecl *>();
+ const auto *Template = dyn_cast<const NamedDecl *>(Entity);
if (!Template) {
return ::CheckConstraintSatisfaction(
*this, nullptr, AssociatedConstraints, TemplateArgsLists,
@@ -2047,9 +2047,7 @@ static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
static void diagnoseUnsatisfiedConstraintExpr(
Sema &S, const UnsatisfiedConstraintRecord &Record, SourceLocation Loc,
bool First, concepts::NestedRequirement *Req) {
- if (auto *Diag =
- Record
- .template dyn_cast<const ConstraintSubstitutionDiagnostic *>()) {
+ if (auto *Diag = dyn_cast<const ConstraintSubstitutionDiagnostic *>(Record)) {
if (Req)
S.Diag(Diag->first, diag::note_nested_requirement_substitution_error)
<< (int)First << Req->getInvalidConstraintEntity() << Diag->second;
@@ -2551,8 +2549,7 @@ const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints(
}
// FIXME: ConstrainedDeclOrNestedReq is never a NestedRequirement!
- const NamedDecl *ND =
- ConstrainedDeclOrNestedReq.dyn_cast<const NamedDecl *>();
+ const NamedDecl *ND = dyn_cast<const NamedDecl *>(ConstrainedDeclOrNestedReq);
auto CacheEntry = NormalizationCache.find(ConstrainedDeclOrNestedReq);
if (CacheEntry == NormalizationCache.end()) {
auto *Normalized = NormalizedConstraint::fromAssociatedConstraints(
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5c425a176ff41..dffe9b07f4910 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -9632,7 +9632,7 @@ bool SpecialMemberDeletionInfo::isAccessible(Subobject Subobj,
/// type of this special member.
CanQualType objectTy;
AccessSpecifier access = target->getAccess();
- if (CXXBaseSpecifier *base = Subobj.dyn_cast<CXXBaseSpecifier*>()) {
+ if (CXXBaseSpecifier *base = dyn_cast<CXXBaseSpecifier *>(Subobj)) {
objectTy = S.Context.getCanonicalTagType(MD->getParent());
access = CXXRecordDecl::MergeAccess(base->getAccessSpecifier(), access);
@@ -9651,7 +9651,7 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
Subobject Subobj, Sema::SpecialMemberOverloadResult SMOR,
bool IsDtorCallInCtor) {
CXXMethodDecl *Decl = SMOR.getMethod();
- FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
+ FieldDecl *Field = dyn_cast<FieldDecl *>(Subobj);
enum {
NotSet = -1,
@@ -9730,7 +9730,7 @@ bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
/// direct or virtual base class or non-static data member of class type M.
bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
CXXRecordDecl *Class, Subobject Subobj, unsigned Quals) {
- FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
+ FieldDecl *Field = dyn_cast<FieldDecl *>(Subobj);
bool IsMutable = Field && Field->isMutable();
// C++11 [class.ctor]p5:
@@ -14134,7 +14134,7 @@ bool SpecialMemberExceptionSpecInfo::visitField(FieldDecl *FD) {
void SpecialMemberExceptionSpecInfo::visitClassSubobject(CXXRecordDecl *Class,
Subobject Subobj,
unsigned Quals) {
- FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
+ FieldDecl *Field = dyn_cast<FieldDecl *>(Subobj);
bool IsMutable = Field && Field->isMutable();
visitSubobjectCall(Subobj, lookupIn(Class, Quals, IsMutable));
}
diff --git a/clang/lib/Sema/SemaLifetimeSafety.h b/clang/lib/Sema/SemaLifetimeSafety.h
index bffe1d61b0234..6d8dc1016626d 100644
--- a/clang/lib/Sema/SemaLifetimeSafety.h
+++ b/clang/lib/Sema/SemaLifetimeSafety.h
@@ -308,11 +308,11 @@ class LifetimeSafetySemaHelperImpl : public LifetimeSafetySemaHelper {
<< ParmToAnnotate->getSourceRange()
<< FixItHint::CreateInsertion(InsertionPoint, FixItText);
- if (const auto *EscapeExpr = Target.dyn_cast<const Expr *>())
+ if (const auto *EscapeExpr = dyn_cast<const Expr *>(Target))
S.Diag(EscapeExpr->getBeginLoc(),
diag::note_lifetime_safety_suggestion_returned_here)
<< EscapeExpr->getSourceRange();
- else if (const auto *EscapeField = Target.dyn_cast<const FieldDecl *>())
+ else if (const auto *EscapeField = dyn_cast<const FieldDecl *>(Target))
S.Diag(EscapeField->getLocation(),
diag::note_lifetime_safety_escapes_to_field_here)
<< EscapeField->getSourceRange();
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 403bd784ddc7b..9a163bbe4349b 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -12410,9 +12410,9 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated,
bool TakingCandidateAddress) {
TemplateParameter Param = DeductionFailure.getTemplateParameter();
NamedDecl *ParamD;
- (ParamD = Param.dyn_cast<TemplateTypeParmDecl*>()) ||
- (ParamD = Param.dyn_cast<NonTypeTemplateParmDecl*>()) ||
- (ParamD = Param.dyn_cast<TemplateTemplateParmDecl*>());
+ (ParamD = dyn_cast<TemplateTypeParmDecl *>(Param)) ||
+ (ParamD = dyn_cast<NonTypeTemplateParmDecl *>(Param)) ||
+ (ParamD = dyn_cast<TemplateTemplateParmDecl *>(Param));
switch (DeductionFailure.getResult()) {
case TemplateDeductionResult::Success:
llvm_unreachable(
diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp
index b942f19761f40..e180b3655bd73 100644
--- a/clang/lib/Sema/SemaSYCL.cpp
+++ b/clang/lib/Sema/SemaSYCL.cpp
@@ -676,7 +676,7 @@ class KernelParamsChecker : public ConstSubobjectVisitor<KernelParamsChecker> {
void emitObjectAccessPathNotes() {
for (auto Parent : llvm::reverse(ObjectAccessPath)) {
- if (auto *FD = Parent.dyn_cast<const FieldDecl *>()) {
+ if (auto *FD = dyn_cast<const FieldDecl *>(Parent)) {
const CXXRecordDecl *ParentRD = cast<CXXRecordDecl>(FD->getParent());
if (ParentRD->isLambda()) {
SemaSYCLRef.Diag(ParentRD->getLocation(), diag::note_within_capture)
@@ -686,7 +686,7 @@ class KernelParamsChecker : public ConstSubobjectVisitor<KernelParamsChecker> {
diag::note_within_field_of_type)
<< ParentRD;
}
- } else if (auto *BS = Parent.dyn_cast<const CXXBaseSpecifier *>()) {
+ } else if (auto *BS = dyn_cast<const CXXBaseSpecifier *>(Parent)) {
CXXRecordDecl *RD = BS->getType()->getAsCXXRecordDecl();
assert(RD);
SemaSYCLRef.Diag(BS->getBeginLoc(), diag::note_within_base_of_type)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 643392833759d..104502aa97083 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5964,7 +5964,7 @@ bool Sema::CheckTemplateArgumentList(
llvm::SmallVector<UnexpandedParameterPack> Unexpanded;
collectUnexpandedParameterPacks(TL.getPatternLoc(), Unexpanded);
for (const auto &UPP : Unexpanded) {
- auto *TST = UPP.first.dyn_cast<const TemplateSpecializationType *>();
+ auto *TST = dyn_cast<const TemplateSpecializationType *>(UPP.first);
if (!TST)
continue;
assert(isPackProducingBuiltinTemplateName(TST->getTemplateName()));
@@ -11896,10 +11896,10 @@ class ExplicitSpecializationVisibilityChecker {
return;
auto From = SD->getSpecializedTemplateOrPartial();
- if (auto *TD = From.dyn_cast<ClassTemplateDecl *>())
+ if (auto *TD = dyn_cast<ClassTemplateDecl *>(From))
checkTemplate(TD);
else if (auto *TD =
- From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
+ dyn_cast<ClassTemplatePartialSpecializationDecl *>(From)) {
if (!CheckDeclaration(TD))
diagnose(TD, true);
checkTemplate(TD);
@@ -11912,10 +11912,10 @@ class ExplicitSpecializationVisibilityChecker {
return;
auto From = SD->getSpecializedTemplateOrPartial();
- if (auto *TD = From.dyn_cast<VarTemplateDecl *>())
+ if (auto *TD = dyn_cast<VarTemplateDecl *>(From))
checkTemplate(TD);
else if (auto *TD =
- From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
+ dyn_cast<VarTemplatePartialSpecializationDecl *>(From)) {
if (!CheckDeclaration(TD))
diagnose(TD, true);
checkTemplate(TD);
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 3e8695a0085ad..e954afe7af5da 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -257,8 +257,8 @@ HandleClassTemplateSpec(const ClassTemplateSpecializationDecl *ClassTemplSpec,
// specialization, as the ClassTemplateSpecializationDecl's
// DeclContext/LexicalDeclContext will be for the primary template.
if (auto *InstFromPartialTempl =
- ClassTemplSpec->getSpecializedTemplateOrPartial()
- .dyn_cast<ClassTemplatePartialSpecializationDecl *>())
+ dyn_cast<ClassTemplatePartialSpecializationDecl *>(
+ ClassTemplSpec->getSpecializedTemplateOrPartial()))
return Response::ChangeDecl(
InstFromPartialTempl->getLexicalDeclContext());
}
@@ -1415,7 +1415,7 @@ namespace {
(SemaRef.inConstraintSubstitution() ||
SemaRef.inParameterMappingSubstitution())) {
for (UnexpandedParameterPack ParmPack : Unexpanded) {
- NamedDecl *VD = ParmPack.first.dyn_cast<NamedDecl *>();
+ NamedDecl *VD = dyn_cast<NamedDecl *>(ParmPack.first);
if (auto *PVD = dyn_cast_if_present<ParmVarDecl>(VD);
PVD && maybeInstantiateFunctionParameterToScope(PVD))
return true;
@@ -2819,7 +2819,7 @@ TemplateInstantiator::TransformExprRequirement(concepts::ExprRequirement *Req) {
}
}
assert(TransRetReq && "All code paths leading here must set TransRetReq");
- if (Expr *E = TransExpr.dyn_cast<Expr *>())
+ if (Expr *E = dyn_cast<Expr *>(TransExpr))
return RebuildExprRequirement(E, Req->isSimple(), Req->getNoexceptLoc(),
std::move(*TransRetReq));
return RebuildExprRequirement(
@@ -3406,7 +3406,7 @@ PreparePackForExpansion(Sema &S, const CXXBaseSpecifier &Base,
// that required a substituion first.
bool SawPackTypes =
llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
- return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
+ return dyn_cast<const SubstBuiltinTemplatePackType *>(P.first);
});
if (!SawPackTypes) {
Info.Expand = false;
@@ -4129,7 +4129,7 @@ static ActionResult<CXXRecordDecl *> getPatternForClassTemplateSpecialization(
CXXRecordDecl *Pattern = nullptr;
Specialized = ClassTemplateSpec->getSpecializedTemplateOrPartial();
if (auto *PartialSpec =
- Specialized.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
+ dyn_cast<ClassTemplatePartialSpecializationDecl *>(Specialized)) {
// Instantiate using the best class template partial specialization.
while (PartialSpec->getInstantiatedFromMember()) {
// If we've found an explicit specialization of this class template,
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 79d106168e9d0..c38589f698850 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -6557,7 +6557,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
VarTemplatePartialSpecializationDecl *> PatternPtr =
VarSpec->getSpecializedTemplateOrPartial();
if (VarTemplatePartialSpecializationDecl *Partial =
- PatternPtr.dyn_cast<VarTemplatePartialSpecializationDecl *>())
+ dyn_cast<VarTemplatePartialSpecializationDecl *>(PatternPtr))
cast<VarTemplateSpecializationDecl>(Var)->setInstantiationOf(
Partial, &VarSpec->getTemplateInstantiationArgs());
@@ -6995,7 +6995,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
// declarations to their instantiations.
if (CurrentInstantiationScope) {
if (auto Found = CurrentInstantiationScope->findInstantiationOf(D)) {
- if (Decl *FD = Found->dyn_cast<Decl *>()) {
+ if (Decl *FD = dyn_cast<Decl *>(*Found)) {
if (auto *BD = dyn_cast<BindingDecl>(FD);
BD && BD->isParameterPack() && ArgPackSubstIndex) {
return BD->getBindingPackDecls()[*ArgPackSubstIndex];
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index aa818aad7ff68..580435fa55ae4 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -446,7 +446,7 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
if (sema::CapturingScopeInfo *CSI = getEnclosingLambdaOrBlock()) {
for (auto &Pack : Unexpanded) {
auto DeclaresThisPack = [&](NamedDecl *LocalPack) {
- if (auto *TTPT = Pack.first.dyn_cast<const TemplateTypeParmType *>()) {
+ if (auto *TTPT = dyn_cast<const TemplateTypeParmType *>(Pack.first)) {
auto *TTPD = dyn_cast<TemplateTypeParmDecl>(LocalPack);
return TTPD && TTPD->getTypeForDecl() == TTPT;
}
@@ -498,10 +498,10 @@ Sema::DiagnoseUnexpandedParameterPacks(SourceLocation Loc,
for (unsigned I = 0, N = Unexpanded.size(); I != N; ++I) {
IdentifierInfo *Name = nullptr;
- if (const TemplateTypeParmType *TTP
- = Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>())
+ if (const TemplateTypeParmType *TTP =
+ dyn_cast<const TemplateTypeParmType *>(Unexpanded[I].first))
Name = TTP->getIdentifier();
- else if (NamedDecl *ND = Unexpanded[I].first.dyn_cast<NamedDecl *>())
+ else if (NamedDecl *ND = dyn_cast<NamedDecl *>(Unexpanded[I].first))
Name = ND->getIdentifier();
if (Name && NamesKnown.insert(Name).second)
@@ -576,7 +576,7 @@ bool Sema::DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE) {
llvm::SmallPtrSet<NamedDecl *, 8> ParmSet(llvm::from_range, Parms);
SmallVector<UnexpandedParameterPack, 2> UnexpandedParms;
for (auto Parm : Unexpanded)
- if (ParmSet.contains(Parm.first.dyn_cast<NamedDecl *>()))
+ if (ParmSet.contains(dyn_cast<NamedDecl *>(Parm.first)))
UnexpandedParms.push_back(Parm);
if (UnexpandedParms.empty())
return false;
@@ -861,13 +861,12 @@ bool Sema::CheckParameterPacksForExpansion(
FunctionParmPackExpr *BindingPack = nullptr;
std::optional<unsigned> NumPrecomputedArguments;
- if (auto *TTP = ParmPack.first.dyn_cast<const TemplateTypeParmType *>()) {
+ if (auto *TTP = dyn_cast<const TemplateTypeParmType *>(ParmPack.first)) {
Depth = TTP->getDepth();
Index = TTP->getIndex();
Name = TTP->getIdentifier();
- } else if (auto *TST =
- ParmPack.first
- .dyn_cast<const TemplateSpecializationType *>()) {
+ } else if (auto *TST = dyn_cast<const TemplateSpecializationType *>(
+ ParmPack.first)) {
assert(isPackProducingBuiltinTemplateName(TST->getTemplateName()));
// Delay expansion, substitution is required to know the size.
ShouldExpand = false;
@@ -882,9 +881,8 @@ bool Sema::CheckParameterPacksForExpansion(
: EllipsisLoc,
diag::err_unsupported_builtin_template_pack_expansion)
<< TST->getTemplateName();
- } else if (auto *S =
- ParmPack.first
- .dyn_cast<const SubstBuiltinTemplatePackType *>()) {
+ } else if (auto *S = dyn_cast<const SubstBuiltinTemplatePackType *>(
+ ParmPack.first)) {
Name = nullptr;
NumPrecomputedArguments = S->getNumArgs();
} else {
@@ -1074,20 +1072,17 @@ UnsignedOrNone Sema::getNumArgumentsInExpansionFromUnexpanded(
unsigned Index;
if (const TemplateTypeParmType *TTP =
- Unexpanded[I].first.dyn_cast<const TemplateTypeParmType *>()) {
+ dyn_cast<const TemplateTypeParmType *>(Unexpanded[I].first)) {
Depth = TTP->getDepth();
Index = TTP->getIndex();
- } else if (auto *TST =
- Unexpanded[I]
- .first.dyn_cast<const TemplateSpecializationType *>()) {
+ } else if (auto *TST = dyn_cast<const TemplateSpecializationType *>(
+ Unexpanded[I].first)) {
// This is a dependent pack, we are not ready to expand it yet.
assert(isPackProducingBuiltinTemplateName(TST->getTemplateName()));
(void)TST;
return std::nullopt;
- } else if (auto *PST =
- Unexpanded[I]
- .first
- .dyn_cast<const SubstBuiltinTemplatePackType *>()) {
+ } else if (auto *PST = dyn_cast<const SubstBuiltinTemplatePackType *>(
+ Unexpanded[I].first)) {
assert((!Result || *Result == PST->getNumArgs()) &&
"inconsistent pack sizes");
Result = PST->getNumArgs();
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index e6abb3ad577c6..3604edefb1de7 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -5335,7 +5335,7 @@ bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
// that required a substituion first.
bool SawPackTypes =
llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
- return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
+ return dyn_cast<const SubstBuiltinTemplatePackType *>(P.first);
});
if (!SawPackTypes) {
Info.Expand = false;
More information about the cfe-commits
mailing list