[clang] bbb0dba - [clang][AST] Add `RecordDecl::getNumFields()` (#170022)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Nov 30 23:33:58 PST 2025
Author: Timm Baeder
Date: 2025-12-01T08:33:54+01:00
New Revision: bbb0dbadfaf292766922f5914f1c8946e2ef8519
URL: https://github.com/llvm/llvm-project/commit/bbb0dbadfaf292766922f5914f1c8946e2ef8519
DIFF: https://github.com/llvm/llvm-project/commit/bbb0dbadfaf292766922f5914f1c8946e2ef8519.diff
LOG: [clang][AST] Add `RecordDecl::getNumFields()` (#170022)
Not sure why that didn't exist yet, but we have quite a few places using
the same `std::distance` pattern.
Added:
Modified:
clang/include/clang/AST/Decl.h
clang/lib/AST/ComparisonCategories.cpp
clang/lib/AST/ExprConstant.cpp
clang/lib/CodeGen/CGHLSLRuntime.cpp
clang/lib/Sema/CodeCompleteConsumer.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index ee2321dd158d4..5394b2558b407 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4524,6 +4524,11 @@ class RecordDecl : public TagDecl {
return field_begin() == field_end();
}
+ /// Returns the number of fields (non-static data members) in this record.
+ unsigned getNumFields() const {
+ return std::distance(field_begin(), field_end());
+ }
+
/// noload_fields - Iterate over the fields stored in this record
/// that are currently loaded; don't attempt to retrieve anything
/// from an external source.
diff --git a/clang/lib/AST/ComparisonCategories.cpp b/clang/lib/AST/ComparisonCategories.cpp
index 0c7a7f4eacbbf..1b9c938e2ace3 100644
--- a/clang/lib/AST/ComparisonCategories.cpp
+++ b/clang/lib/AST/ComparisonCategories.cpp
@@ -49,7 +49,7 @@ bool ComparisonCategoryInfo::ValueInfo::hasValidIntValue() const {
// Before we attempt to get the value of the first field, ensure that we
// actually have one (and only one) field.
const auto *Record = VD->getType()->getAsCXXRecordDecl();
- if (std::distance(Record->field_begin(), Record->field_end()) != 1 ||
+ if (Record->getNumFields() != 1 ||
!Record->field_begin()->getType()->isIntegralOrEnumerationType())
return false;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index b986ee6ca4fa3..e5af4cb049ba9 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3971,8 +3971,7 @@ static bool constructAggregate(EvalInfo &Info, const FPOptions FPO,
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
NumBases = CXXRD->getNumBases();
- *Res = APValue(APValue::UninitStruct(), NumBases,
- std::distance(RD->field_begin(), RD->field_end()));
+ *Res = APValue(APValue::UninitStruct(), NumBases, RD->getNumFields());
SmallVector<std::tuple<APValue *, QualType, unsigned>> ReverseList;
// we need to traverse backwards
@@ -5529,8 +5528,8 @@ static bool handleDefaultInitValue(QualType T, APValue &Result) {
Result = APValue((const FieldDecl *)nullptr);
return true;
}
- Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
- std::distance(RD->field_begin(), RD->field_end()));
+ Result =
+ APValue(APValue::UninitStruct(), RD->getNumBases(), RD->getNumFields());
unsigned Index = 0;
for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
@@ -7184,7 +7183,7 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
if (!Result.hasValue()) {
if (!RD->isUnion())
Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
- std::distance(RD->field_begin(), RD->field_end()));
+ RD->getNumFields());
else
// A union starts with no active member.
Result = APValue((const FieldDecl*)nullptr);
@@ -8135,8 +8134,7 @@ class BufferToAPValueConverter {
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
NumBases = CXXRD->getNumBases();
- APValue ResultVal(APValue::UninitStruct(), NumBases,
- std::distance(RD->field_begin(), RD->field_end()));
+ APValue ResultVal(APValue::UninitStruct(), NumBases, RD->getNumFields());
// Visit the base classes.
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
@@ -11146,7 +11144,7 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E,
assert(!RD->isUnion() && "Expected non-union class type");
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
Result = APValue(APValue::UninitStruct(), CD ? CD->getNumBases() : 0,
- std::distance(RD->field_begin(), RD->field_end()));
+ RD->getNumFields());
if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
@@ -11342,7 +11340,7 @@ bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
if (!Result.hasValue())
Result = APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
- std::distance(RD->field_begin(), RD->field_end()));
+ RD->getNumFields());
unsigned ElementNo = 0;
bool Success = true;
@@ -11549,8 +11547,7 @@ bool RecordExprEvaluator::VisitLambdaExpr(const LambdaExpr *E) {
if (ClosureClass->isInvalidDecl())
return false;
- const size_t NumFields =
- std::distance(ClosureClass->field_begin(), ClosureClass->field_end());
+ const size_t NumFields = ClosureClass->getNumFields();
assert(NumFields == (size_t)std::distance(E->capture_init_begin(),
E->capture_init_end()) &&
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index f5c07fe2e33ff..bbe85986b07fc 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -816,8 +816,7 @@ CGHLSLRuntime::handleStructSemanticLoad(
const llvm::StructType *ST = cast<StructType>(Type);
const clang::RecordDecl *RD = Decl->getType()->getAsRecordDecl();
- assert(std::distance(RD->field_begin(), RD->field_end()) ==
- ST->getNumElements());
+ assert(RD->getNumFields() == ST->getNumElements());
llvm::Value *Aggregate = llvm::PoisonValue::get(Type);
auto FieldDecl = RD->field_begin();
@@ -849,8 +848,7 @@ CGHLSLRuntime::handleStructSemanticStore(
RD = Decl->getType()->getAsRecordDecl();
assert(RD);
- assert(std::distance(RD->field_begin(), RD->field_end()) ==
- ST->getNumElements());
+ assert(RD->getNumFields() == ST->getNumElements());
auto FieldDecl = RD->field_begin();
for (unsigned I = 0; I < ST->getNumElements(); ++I) {
diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp
index e3fc7c11f4594..50a552272f421 100644
--- a/clang/lib/Sema/CodeCompleteConsumer.cpp
+++ b/clang/lib/Sema/CodeCompleteConsumer.cpp
@@ -539,8 +539,7 @@ unsigned CodeCompleteConsumer::OverloadCandidate::getNumParams() const {
return Template->getTemplateParameters()->size();
if (Kind == CK_Aggregate) {
- unsigned Count =
- std::distance(AggregateType->field_begin(), AggregateType->field_end());
+ unsigned Count = AggregateType->getNumFields();
if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType))
Count += CRD->getNumBases();
return Count;
More information about the cfe-commits
mailing list