[clang] [clang][NFC] Introduce `LangOptions::isCompatibleWith(ClangABI)` (PR #201067)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 2 02:05:41 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-codegen
Author: Yanzuo Liu (zwuis)
<details>
<summary>Changes</summary>
This slightly improves readability and reduces the probability of off-by-one errors.
---
Full diff: https://github.com/llvm/llvm-project/pull/201067.diff
10 Files Affected:
- (modified) clang/include/clang/Basic/LangOptions.h (+4)
- (modified) clang/lib/AST/ByteCode/Compiler.cpp (+1-1)
- (modified) clang/lib/AST/DeclCXX.cpp (+1-2)
- (modified) clang/lib/AST/ExprConstant.cpp (+1-1)
- (modified) clang/lib/AST/ItaniumMangle.cpp (+10-12)
- (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+10-11)
- (modified) clang/lib/Basic/TargetInfo.cpp (+3-3)
- (modified) clang/lib/CodeGen/Targets/ARM.cpp (+1-2)
- (modified) clang/lib/CodeGen/Targets/X86.cpp (+8-8)
- (modified) clang/lib/Sema/SemaDeclCXX.cpp (+3-3)
``````````diff
diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h
index 64b12b6fd72c7..9af036156b1ad 100644
--- a/clang/include/clang/Basic/LangOptions.h
+++ b/clang/include/clang/Basic/LangOptions.h
@@ -668,6 +668,10 @@ class LangOptions : public LangOptionsBase {
!ObjCSubscriptingLegacyRuntime;
}
+ bool isCompatibleWith(ClangABI Version) const {
+ return getClangABICompat() <= Version;
+ }
+
bool isCompatibleWithMSVC() const { return MSCompatibilityVersion > 0; }
bool isCompatibleWithMSVC(MSVCMajorVersion MajorVersion) const {
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 774a853950837..25281558dafbf 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2501,7 +2501,7 @@ bool Compiler<Emitter>::VisitEmbedExpr(const EmbedExpr *E) {
static CharUnits AlignOfType(QualType T, const ASTContext &ASTCtx,
UnaryExprOrTypeTrait Kind) {
bool AlignOfReturnsPreferred =
- ASTCtx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
+ ASTCtx.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver7);
// C++ [expr.alignof]p3:
// When alignof is applied to a reference type, the result is the
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 2de8ba8f484f4..fc8a15287f438 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -990,8 +990,7 @@ void CXXRecordDecl::addedMember(Decl *D) {
// T is a class type [...] with [...] no unnamed bit-fields of non-zero
// length
if (data().Empty && !Field->isZeroLengthBitField() &&
- Context.getLangOpts().getClangABICompat() >
- LangOptions::ClangABI::Ver6)
+ !Context.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver6))
data().Empty = false;
return;
}
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 808c9b4f89ed9..b9635deeccb33 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -10243,7 +10243,7 @@ static CharUnits GetAlignOfType(const ASTContext &Ctx, QualType T,
return CharUnits::One();
const bool AlignOfReturnsPreferred =
- Ctx.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver7;
+ Ctx.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver7);
// __alignof is defined to return the preferred alignment.
// Before 8, clang returned the preferred alignment for alignof and _Alignof
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 1cb6fa05f22ac..b7afe64027b91 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -381,7 +381,7 @@ class CXXNameMangler {
ASTContext &getASTContext() const { return Context.getASTContext(); }
bool isCompatibleWith(LangOptions::ClangABI Ver) {
- return Context.getASTContext().getLangOpts().getClangABICompat() <= Ver;
+ return getASTContext().getLangOpts().isCompatibleWith(Ver);
}
bool isStd(const NamespaceDecl *NS);
@@ -698,8 +698,8 @@ ItaniumMangleContextImpl::getEffectiveDeclContext(const Decl *D) {
return getASTContext().getTranslationUnitDecl();
}
- if (const auto *FD = getASTContext().getLangOpts().getClangABICompat() >
- LangOptions::ClangABI::Ver19
+ if (const auto *FD = !getASTContext().getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver19)
? D->getAsFunction()
: dyn_cast<FunctionDecl>(D)) {
if (FD->isExternC())
@@ -707,8 +707,8 @@ ItaniumMangleContextImpl::getEffectiveDeclContext(const Decl *D) {
// Member-like constrained friends are mangled as if they were members of
// the enclosing class.
if (FD->isMemberLikeConstrainedFriend() &&
- getASTContext().getLangOpts().getClangABICompat() >
- LangOptions::ClangABI::Ver17)
+ !getASTContext().getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver17))
return D->getLexicalDeclContext()->getRedeclContext();
}
@@ -2975,13 +2975,13 @@ static bool isTypeSubstitutable(Qualifiers Quals, const Type *Ty,
return true;
// From Clang 18.0 we correctly treat SVE types as substitution candidates.
if (Ty->isSVESizelessBuiltinType() &&
- Ctx.getLangOpts().getClangABICompat() > LangOptions::ClangABI::Ver17)
+ !Ctx.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver17))
return true;
if (Ty->isBuiltinType())
return false;
// Through to Clang 6.0, we accidentally treated undeduced auto types as
// substitution candidates.
- if (Ctx.getLangOpts().getClangABICompat() > LangOptions::ClangABI::Ver6 &&
+ if (!Ctx.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver6) &&
isa<AutoType>(Ty))
return false;
// A placeholder type for class template deduction is substitutable with
@@ -6827,8 +6827,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V,
// Clang 11 and before mangled an array subject to array-to-pointer decay
// as if it were the declaration itself.
bool IsArrayToPointerDecayMangledAsDecl = false;
- if (TopLevel && Ctx.getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver11) {
+ if (TopLevel && isCompatibleWith(LangOptions::ClangABI::Ver11)) {
QualType BType = B.getType();
IsArrayToPointerDecayMangledAsDecl =
BType->isArrayType() && V.getLValuePath().size() == 1 &&
@@ -7567,9 +7566,8 @@ void ItaniumMangleContextImpl::mangleCXXCtorVTable(const CXXRecordDecl *RD,
Mangler.getStream() << "_ZTC";
// Older versions of clang did not add the record as a substitution candidate
// here.
- bool SuppressSubstitution =
- getASTContext().getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver19;
+ bool SuppressSubstitution = getASTContext().getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver19);
Mangler.mangleCXXRecordDecl(RD, SuppressSubstitution);
Mangler.getStream() << Offset;
Mangler.getStream() << '_';
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index f417588accd78..854f88f20b2b6 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -1213,8 +1213,8 @@ ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
auto getBaseOrPreferredBaseAlignFromUnpacked = [&](CharUnits UnpackedAlign) {
// Clang <= 6 incorrectly applied the 'packed' attribute to base classes.
// Per GCC's documentation, it only applies to non-static data members.
- return (Packed && ((Context.getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver6) ||
+ return (Packed && (Context.getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver6) ||
Context.getTargetInfo().getTriple().isPS() ||
Context.getTargetInfo().getTriple().isOSAIX()))
? CharUnits::One()
@@ -1960,13 +1960,13 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
}
}
- bool FieldPacked = (Packed && (!FieldClass || FieldClass->isPOD() ||
- FieldClass->hasAttr<PackedAttr>() ||
- Context.getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver15 ||
- Target.isPS() || Target.isOSDarwin() ||
- Target.isOSAIX())) ||
- D->hasAttr<PackedAttr>();
+ bool FieldPacked =
+ (Packed &&
+ (!FieldClass || FieldClass->isPOD() ||
+ FieldClass->hasAttr<PackedAttr>() ||
+ Context.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver15) ||
+ Target.isPS() || Target.isOSDarwin() || Target.isOSAIX())) ||
+ D->hasAttr<PackedAttr>();
// When used as part of a typedef, or together with a 'packed' attribute, the
// 'aligned' attribute can be used to decrease alignment. In that case, it
@@ -2204,8 +2204,7 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
if (Packed && UnpackedAlignment <= Alignment &&
UnpackedSizeInBits == getSizeInBits() && !HasPackedField &&
(!CXXRD || CXXRD->isPOD() ||
- Context.getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver15))
+ Context.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver15)))
Diag(D->getLocation(), diag::warn_unnecessary_packed)
<< Context.getCanonicalTagType(RD);
}
diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp
index f3ec9a8dd0df8..854d23cadaea2 100644
--- a/clang/lib/Basic/TargetInfo.cpp
+++ b/clang/lib/Basic/TargetInfo.cpp
@@ -635,20 +635,20 @@ TargetInfo::getCallingConvKind(bool ClangABICompat4) const {
bool TargetInfo::callGlobalDeleteInDeletingDtor(
const LangOptions &LangOpts) const {
if (getCXXABI() == TargetCXXABI::Microsoft &&
- LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver21)
+ !LangOpts.isCompatibleWith(LangOptions::ClangABI::Ver21))
return true;
return false;
}
bool TargetInfo::emitVectorDeletingDtors(const LangOptions &LangOpts) const {
if (getCXXABI() == TargetCXXABI::Microsoft &&
- LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver21)
+ !LangOpts.isCompatibleWith(LangOptions::ClangABI::Ver21))
return true;
return false;
}
bool TargetInfo::areDefaultedSMFStillPOD(const LangOptions &LangOpts) const {
- return LangOpts.getClangABICompat() > LangOptions::ClangABI::Ver15;
+ return !LangOpts.isCompatibleWith(LangOptions::ClangABI::Ver15);
}
void TargetInfo::setDependentOpenCLOpts() {
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index 4d05217cafb79..c6435dd6f5a8b 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -353,8 +353,7 @@ bool ARMABIInfo::shouldIgnoreEmptyArg(QualType Ty) const {
return true;
// Clang 19.0 and earlier always ignored empty struct arguments in C++ mode.
- if (getContext().getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver19)
+ if (getContext().getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver19))
return true;
// Otherwise, they are passed as if they have a size of 1 byte.
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 4a57ca7767bd2..cccc68cbf13d9 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -1329,8 +1329,8 @@ class X86_64ABIInfo : public ABIInfo {
/// classify it as INTEGER (for compatibility with older clang compilers).
bool classifyIntegerMMXAsSSE() const {
// Clang <= 3.8 did not do this.
- if (getContext().getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver3_8)
+ if (getContext().getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver3_8))
return false;
const llvm::Triple &Triple = getTarget().getTriple();
@@ -1342,8 +1342,8 @@ class X86_64ABIInfo : public ABIInfo {
// GCC classifies vectors of __int128 as memory.
bool passInt128VectorsInMem() const {
// Clang <= 9.0 did not do this.
- if (getContext().getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver9)
+ if (getContext().getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver9))
return false;
const llvm::Triple &T = getTarget().getTriple();
@@ -1352,8 +1352,8 @@ class X86_64ABIInfo : public ABIInfo {
bool returnCXXRecordGreaterThan128InMem() const {
// Clang <= 20.0 did not do this, and PlayStation does not do this.
- if (getContext().getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver20 ||
+ if (getContext().getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver20) ||
getTarget().getTriple().isPS())
return false;
@@ -2100,8 +2100,8 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
// Classify the fields one at a time, merging the results.
unsigned idx = 0;
- bool UseClang11Compat = getContext().getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver11 ||
+ bool UseClang11Compat = getContext().getLangOpts().isCompatibleWith(
+ LangOptions::ClangABI::Ver11) ||
getContext().getTargetInfo().getTriple().isPS();
bool IsUnion = RT->isUnionType() && !UseClang11Compat;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 9bbe99df064c3..418ff01f3d98a 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -7417,7 +7417,7 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
checkClassLevelCodeSegAttribute(Record);
bool ClangABICompat4 =
- Context.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver4;
+ Context.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver4);
TargetInfo::CallingConvKind CCK =
Context.getTargetInfo().getCallingConvKind(ClangABICompat4);
bool CanPass = canPassInRegisters(*this, Record, CCK);
@@ -10444,8 +10444,8 @@ bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMemberKind CSM,
// Otherwise, if ClangABICompat14 is false, All copy constructors can be
// trivial, if they are not user-provided, regardless of the qualifiers on
// the reference type.
- const bool ClangABICompat14 = Context.getLangOpts().getClangABICompat() <=
- LangOptions::ClangABI::Ver14;
+ const bool ClangABICompat14 =
+ Context.getLangOpts().isCompatibleWith(LangOptions::ClangABI::Ver14);
if (!RT ||
((RT->getPointeeType().getCVRQualifiers() != Qualifiers::Const) &&
ClangABICompat14)) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/201067
More information about the cfe-commits
mailing list