[clang] [clang-tools-extra] draft Attempt to get the specific_decl_iterator replaced (PR #114135)
Erich Keane via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 29 15:01:42 PDT 2024
https://github.com/erichkeane created https://github.com/llvm/llvm-project/pull/114135
One of the things holding up solutions to https://github.com/llvm/llvm-project/issues/113950 is the pretty rough uses of iterators in a weird way all over the place. This patch set attempted to replace them with a llvm::make_filtered_range + a casting iterator. I only tried to replace 'field_iterator' here plus a couple of for-each type fields, doing some algorithmic symplification where I would.
Good news: it compiles
Bad news: check-clang has ~57 failures, including failing a stack-exhaustion test, so it seems the greater size of the field-iterator (now 2x in size, since it needs to hold an 'end' iterator instead of being able to count on null) has caused our stack size to increase too much.
At the moment, I'm probably abandoning this effort. There IS a bunch of perf that would come from the linked-list-to-vector, mixed with making the local `VarDecl` not have to care about its next-decls or decl-context (thus giving us less to transform), but this is likely a pretty sizable lift.
>From e0b4fe0ade285c876d61c0309c2e691a35a33a96 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Tue, 29 Oct 2024 10:20:33 -0700
Subject: [PATCH 1/4] Replace some uses of specific_decl_iterator with
filtered-range
While working to try to replace the Decl linked-list for the 'next'
item, I discovered that the propsensity of us to use these iterators
ends up causing some pretty significant problems with the transition.
I'm hopeful we can replace specific_decl_iterator and
filtered_decl_iterator with variants that just use
llvm::make_filtered_range.
This patch starts that effort by making an alternative for
specific_iterator, and replaces it in the 'range for' cases that it gets
used.
---
clang/include/clang/AST/DeclBase.h | 40 +++++++++++++++++++
.../TransEmptyStatementsAndDealloc.cpp | 5 +--
clang/lib/ARCMigrate/TransProperties.cpp | 7 +---
clang/lib/ARCMigrate/Transforms.cpp | 5 +--
clang/lib/Analysis/UninitializedValues.cpp | 6 +--
clang/lib/InstallAPI/Visitor.cpp | 4 +-
clang/lib/Sema/SemaCodeComplete.cpp | 7 +---
clang/lib/Sema/SemaDeclCXX.cpp | 3 +-
8 files changed, 49 insertions(+), 28 deletions(-)
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index a3447d19909752..37cb60cda2970c 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -2364,6 +2364,46 @@ class DeclContext {
decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
decl_iterator noload_decls_end() const { return decl_iterator(); }
+ template <typename ItTy, typename SpecificDecl>
+ class decl_cast_iterator : public llvm::mapped_iterator_base<
+ decl_cast_iterator<ItTy, SpecificDecl>, ItTy,
+ SpecificDecl *> {
+ using BaseT =
+ llvm::mapped_iterator_base<decl_cast_iterator<ItTy, SpecificDecl>, ItTy,
+ SpecificDecl *>;
+
+ public:
+ decl_cast_iterator(ItTy Itr) : BaseT(Itr) {}
+
+ SpecificDecl *mapElement(Decl *D) const {
+ return cast<SpecificDecl>(D);
+ }
+ };
+
+ template <typename SpecificDecl, typename ItTy>
+ static decl_cast_iterator<ItTy, SpecificDecl>
+ make_decl_cast_iterator(ItTy Itr) {
+ return decl_cast_iterator<ItTy, SpecificDecl>(Itr);
+ }
+
+ /// Makes a casting filter range for the decls collection.
+ template <typename SpecificDecl> auto specific_decls() {
+ auto filtered_range =
+ llvm::make_filter_range(decls(), llvm::IsaPred<SpecificDecl>);
+ return llvm::make_range(
+ make_decl_cast_iterator<SpecificDecl>(filtered_range.begin()),
+ make_decl_cast_iterator<SpecificDecl>(filtered_range.end()));
+ }
+
+ /// Makes a casting filter range for the decls collection.
+ template <typename SpecificDecl> auto specific_decls() const {
+ auto filtered_range =
+ llvm::make_filter_range(decls(), llvm::IsaPred<SpecificDecl>);
+ return llvm::make_range(
+ make_decl_cast_iterator<SpecificDecl>(filtered_range.begin()),
+ make_decl_cast_iterator<SpecificDecl>(filtered_range.end()));
+ }
+
/// specific_decl_iterator - Iterates over a subrange of
/// declarations stored in a DeclContext, providing only those that
/// are of type SpecificDecl (or a class derived from it). This
diff --git a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
index e9c21b8106d7dd..1a8b0aab0e53ef 100644
--- a/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
+++ b/clang/lib/ARCMigrate/TransEmptyStatementsAndDealloc.cpp
@@ -197,10 +197,7 @@ static void cleanupDeallocOrFinalize(MigrationPass &pass) {
Selector FinalizeSel =
Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize"));
- typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl>
- impl_iterator;
- for (impl_iterator I = impl_iterator(DC->decls_begin()),
- E = impl_iterator(DC->decls_end()); I != E; ++I) {
+ for (auto *I : DC->specific_decls<ObjCImplementationDecl>()) {
ObjCMethodDecl *DeallocM = nullptr;
ObjCMethodDecl *FinalizeM = nullptr;
for (auto *MD : I->instance_methods()) {
diff --git a/clang/lib/ARCMigrate/TransProperties.cpp b/clang/lib/ARCMigrate/TransProperties.cpp
index 6d1d950821a07c..85815ba1d726b0 100644
--- a/clang/lib/ARCMigrate/TransProperties.cpp
+++ b/clang/lib/ARCMigrate/TransProperties.cpp
@@ -99,12 +99,7 @@ class PropertiesRewriter {
for (auto *Ext : iface->visible_extensions())
collectProperties(Ext, AtProps);
- typedef DeclContext::specific_decl_iterator<ObjCPropertyImplDecl>
- prop_impl_iterator;
- for (prop_impl_iterator
- I = prop_impl_iterator(D->decls_begin()),
- E = prop_impl_iterator(D->decls_end()); I != E; ++I) {
- ObjCPropertyImplDecl *implD = *I;
+ for (auto *implD : D->specific_decls<ObjCPropertyImplDecl>()) {
if (implD->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize)
continue;
ObjCPropertyDecl *propD = implD->getPropertyDecl();
diff --git a/clang/lib/ARCMigrate/Transforms.cpp b/clang/lib/ARCMigrate/Transforms.cpp
index fda0e1c932fc0e..a8bcee57e3bd80 100644
--- a/clang/lib/ARCMigrate/Transforms.cpp
+++ b/clang/lib/ARCMigrate/Transforms.cpp
@@ -521,10 +521,7 @@ static void GCRewriteFinalize(MigrationPass &pass) {
Selector FinalizeSel =
Ctx.Selectors.getNullarySelector(&pass.Ctx.Idents.get("finalize"));
- typedef DeclContext::specific_decl_iterator<ObjCImplementationDecl>
- impl_iterator;
- for (impl_iterator I = impl_iterator(DC->decls_begin()),
- E = impl_iterator(DC->decls_end()); I != E; ++I) {
+ for (const auto *I : DC->specific_decls<ObjCImplementationDecl>()) {
for (const auto *MD : I->instance_methods()) {
if (!MD->hasBody())
continue;
diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp
index bf2f7306186507..25dcc478f2f8ff 100644
--- a/clang/lib/Analysis/UninitializedValues.cpp
+++ b/clang/lib/Analysis/UninitializedValues.cpp
@@ -95,10 +95,8 @@ class DeclToIndex {
void DeclToIndex::computeMap(const DeclContext &dc) {
unsigned count = 0;
- DeclContext::specific_decl_iterator<VarDecl> I(dc.decls_begin()),
- E(dc.decls_end());
- for ( ; I != E; ++I) {
- const VarDecl *vd = *I;
+
+ for (const auto *vd : dc.specific_decls<VarDecl>()) {
if (isTrackedVar(vd, &dc))
map[vd] = count++;
}
diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp
index a73ea0b0d124c2..5cb6a4e37557f4 100644
--- a/clang/lib/InstallAPI/Visitor.cpp
+++ b/clang/lib/InstallAPI/Visitor.cpp
@@ -693,9 +693,7 @@ bool InstallAPIVisitor::VisitCXXRecordDecl(const CXXRecordDecl *D) {
return true;
}
- using var_iter = CXXRecordDecl::specific_decl_iterator<VarDecl>;
- using var_range = iterator_range<var_iter>;
- for (const auto *Var : var_range(D->decls())) {
+ for (const auto *Var : D->specific_decls<VarDecl>()) {
// Skip const static member variables.
// \code
// struct S {
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 16a76ff9b5c241..d7afa6b1eebff8 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -6858,11 +6858,8 @@ void SemaCodeCompletion::CodeCompleteNamespaceDecl(Scope *S) {
// extended namespace declaration. Keep track of the most recent
// definition of each namespace.
std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
- for (DeclContext::specific_decl_iterator<NamespaceDecl>
- NS(Ctx->decls_begin()),
- NSEnd(Ctx->decls_end());
- NS != NSEnd; ++NS)
- OrigToLatest[NS->getFirstDecl()] = *NS;
+ for (auto *NS : Ctx->specific_decls<NamespaceDecl>())
+ OrigToLatest[NS->getFirstDecl()] = NS;
// Add the most recent definition (or extended definition) of each
// namespace to the list of results.
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1a691c0e1689d6..725cfad67da900 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -9915,8 +9915,7 @@ static CXXConstructorDecl *findUserDeclaredCtor(CXXRecordDecl *RD) {
return CI;
// Look for constructor templates.
- typedef CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl> tmpl_iter;
- for (tmpl_iter TI(RD->decls_begin()), TE(RD->decls_end()); TI != TE; ++TI) {
+ for (auto *TI : RD->specific_decls<FunctionTemplateDecl>()) {
if (CXXConstructorDecl *CD =
dyn_cast<CXXConstructorDecl>(TI->getTemplatedDecl()))
return CD;
>From c41ea37514f5e3450bfbe2f3a37367d7ac6c301e Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Tue, 29 Oct 2024 14:26:03 -0700
Subject: [PATCH 2/4] WIP, field_iterator to new type
---
clang/include/clang/AST/Decl.h | 17 ++---
clang/include/clang/AST/DeclBase.h | 15 +++--
clang/lib/AST/ASTStructuralEquivalence.cpp | 19 +++---
clang/lib/AST/ComparisonCategories.cpp | 2 +-
clang/lib/AST/Decl.cpp | 6 +-
clang/lib/AST/DeclBase.cpp | 15 ++---
clang/lib/AST/Expr.cpp | 6 +-
clang/lib/AST/ExprConstant.cpp | 22 +++----
clang/lib/AST/RecordLayoutBuilder.cpp | 32 ++++-----
clang/lib/AST/Type.cpp | 2 +-
clang/lib/CodeGen/ABIInfoImpl.cpp | 2 +-
clang/lib/CodeGen/CGDebugInfo.cpp | 25 ++++---
clang/lib/CodeGen/CGExprAgg.cpp | 16 ++---
clang/lib/CodeGen/CGExprConstant.cpp | 14 ++--
clang/lib/CodeGen/CGOpenMPRuntime.cpp | 10 +--
clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp | 2 +-
clang/lib/CodeGen/CGRecordLayoutBuilder.cpp | 26 ++++----
clang/lib/CodeGen/CGStmt.cpp | 10 ++-
clang/lib/CodeGen/CGStmtOpenMP.cpp | 24 ++++---
clang/lib/CodeGen/CodeGenTBAA.cpp | 2 +-
clang/lib/CodeGen/Targets/Mips.cpp | 6 +-
clang/lib/CodeGen/Targets/X86.cpp | 8 +--
clang/lib/Sema/SemaDecl.cpp | 14 ++--
clang/lib/Sema/SemaDeclAttr.cpp | 10 ++-
clang/lib/Sema/SemaDeclCXX.cpp | 7 +-
clang/lib/Sema/SemaDeclObjC.cpp | 2 +-
clang/lib/Sema/SemaInit.cpp | 66 ++++++++++---------
clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 8 +--
28 files changed, 184 insertions(+), 204 deletions(-)
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 7ff35d73df5997..c2ae13655b6c19 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4350,20 +4350,17 @@ class RecordDecl : public TagDecl {
// Iterator access to field members. The field iterator only visits
// the non-static data members of this class, ignoring any static
// data members, functions, constructors, destructors, etc.
- using field_iterator = specific_decl_iterator<FieldDecl>;
- using field_range = llvm::iterator_range<specific_decl_iterator<FieldDecl>>;
+ using field_range =
+ decltype(std::declval<DeclContext>().specific_decls<FieldDecl>());
+ using field_iterator = decltype(std::declval<field_range>().begin());
- field_range fields() const { return field_range(field_begin(), field_end()); }
- field_iterator field_begin() const;
+ field_range fields() const;
+ field_iterator field_begin() const { return fields().begin(); }
- field_iterator field_end() const {
- return field_iterator(decl_iterator());
- }
+ field_iterator field_end() const { return fields().end(); }
// Whether there are any fields (non-static data members) in this record.
- bool field_empty() const {
- return field_begin() == field_end();
- }
+ bool field_empty() const { return fields().empty(); }
/// Note that the definition of this type is now complete.
virtual void completeDefinition();
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 37cb60cda2970c..062244392f15a5 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -2350,19 +2350,20 @@ class DeclContext {
/// decls_begin/decls_end - Iterate over the declarations stored in
/// this context.
- decl_range decls() const { return decl_range(decls_begin(), decls_end()); }
- decl_iterator decls_begin() const;
- decl_iterator decls_end() const { return decl_iterator(); }
- bool decls_empty() const;
+ decl_range decls() const;
+ decl_iterator decls_begin() const { return decls().begin(); }
+ decl_iterator decls_end() const { return decls().end(); }
+ bool decls_empty() const {return decls().empty(); }
/// noload_decls_begin/end - Iterate over the declarations stored in this
/// context that are currently loaded; don't attempt to retrieve anything
/// from an external source.
decl_range noload_decls() const {
- return decl_range(noload_decls_begin(), noload_decls_end());
+ return { decl_iterator(FirstDecl), decl_iterator{}};
}
- decl_iterator noload_decls_begin() const { return decl_iterator(FirstDecl); }
- decl_iterator noload_decls_end() const { return decl_iterator(); }
+
+ decl_iterator noload_decls_begin() const { return noload_decls().begin(); }
+ decl_iterator noload_decls_end() const { return noload_decls().end(); }
template <typename ItTy, typename SpecificDecl>
class decl_cast_iterator : public llvm::mapped_iterator_base<
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 120ddc0f26c0d7..908be1edb37ece 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1834,12 +1834,13 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// Check the fields for consistency.
QualType D2Type = Context.ToCtx.getTypeDeclType(D2);
- RecordDecl::field_iterator Field2 = D2->field_begin(),
- Field2End = D2->field_end();
- for (RecordDecl::field_iterator Field1 = D1->field_begin(),
- Field1End = D1->field_end();
- Field1 != Field1End; ++Field1, ++Field2) {
- if (Field2 == Field2End) {
+ std::optional<FieldDecl*> Field2Opt = std::nullopt;
+
+ for (auto FieldsTuple : llvm::zip_first(D1->fields(), D2->fields())) {
+ FieldDecl *Field1 = std::get<0>(FieldsTuple);
+ std::optional<FieldDecl*> Field2Opt = std::get<1>(FieldsTuple);
+
+ if (!Field2Opt.has_value()) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
@@ -1852,12 +1853,14 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
}
- if (!IsStructurallyEquivalent(Context, *Field1, *Field2, D2Type))
+ FieldDecl *Field2 = std::get<1>(FieldsTuple);
+ if (!IsStructurallyEquivalent(Context, Field1, Field2, D2Type))
return false;
}
- if (Field2 != Field2End) {
+ if (Field2Opt.has_value()) {
if (Context.Complain) {
+ FieldDecl *Field2 = *Field2Opt;
Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
<< Context.ToCtx.getTypeDeclType(D2);
diff --git a/clang/lib/AST/ComparisonCategories.cpp b/clang/lib/AST/ComparisonCategories.cpp
index 28244104d66365..78060a72d914e2 100644
--- a/clang/lib/AST/ComparisonCategories.cpp
+++ b/clang/lib/AST/ComparisonCategories.cpp
@@ -50,7 +50,7 @@ bool ComparisonCategoryInfo::ValueInfo::hasValidIntValue() const {
// actually have one (and only one) field.
const auto *Record = VD->getType()->getAsCXXRecordDecl();
if (std::distance(Record->field_begin(), Record->field_end()) != 1 ||
- !Record->field_begin()->getType()->isIntegralOrEnumerationType())
+ !(*Record->field_begin())->getType()->isIntegralOrEnumerationType())
return false;
return true;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 86913763ef9ff5..452dbb897deb57 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -5086,14 +5086,14 @@ bool RecordDecl::isOrContainsUnion() const {
return false;
}
-RecordDecl::field_iterator RecordDecl::field_begin() const {
+RecordDecl::field_range RecordDecl::fields() const {
if (hasExternalLexicalStorage() && !hasLoadedFieldsFromExternalStorage())
LoadFieldsFromExternalStorage();
// This is necessary for correctness for C++ with modules.
// FIXME: Come up with a test case that breaks without definition.
if (RecordDecl *D = getDefinition(); D && D != this)
- return D->field_begin();
- return field_iterator(decl_iterator(FirstDecl));
+ return D->fields();
+ return specific_decls<FieldDecl>();
}
/// completeDefinition - Notes that the definition of this type is now
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 48b91dca1f6d91..673ce947b6916f 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -500,8 +500,8 @@ bool Decl::isFlexibleArrayMemberLike(
}
// Test that the field is the last in the structure.
- RecordDecl::field_iterator FI(
- DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
+ RecordDecl::field_iterator FI = llvm::find(FD->getParent()->fields(), FD);
+ assert(FI != FD->getParent()->field_end() && "Not contained in own parent?");
return ++FI == FD->getParent()->field_end();
}
@@ -1623,17 +1623,10 @@ ExternalASTSource::SetExternalVisibleDeclsForName(const DeclContext *DC,
return List.getLookupResult();
}
-DeclContext::decl_iterator DeclContext::decls_begin() const {
+DeclContext::decl_range DeclContext::decls() const {
if (hasExternalLexicalStorage())
LoadLexicalDeclsFromExternalStorage();
- return decl_iterator(FirstDecl);
-}
-
-bool DeclContext::decls_empty() const {
- if (hasExternalLexicalStorage())
- LoadLexicalDeclsFromExternalStorage();
-
- return !FirstDecl;
+ return {decl_iterator(FirstDecl), decl_iterator{}};
}
bool DeclContext::containsDecl(Decl *D) const {
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index bf2c1b92fa6b49..1820eb60e0f1ea 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -2039,12 +2039,10 @@ const FieldDecl *CastExpr::getTargetFieldForToUnionCast(QualType unionType,
const FieldDecl *CastExpr::getTargetFieldForToUnionCast(const RecordDecl *RD,
QualType OpType) {
auto &Ctx = RD->getASTContext();
- RecordDecl::field_iterator Field, FieldEnd;
- for (Field = RD->field_begin(), FieldEnd = RD->field_end();
- Field != FieldEnd; ++Field) {
+ for (FieldDecl *Field : RD->fields()) {
if (Ctx.hasSameUnqualifiedType(Field->getType(), OpType) &&
!Field->isUnnamedBitField()) {
- return *Field;
+ return Field;
}
}
return nullptr;
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index d664c503655ba6..e04bf3319501f6 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -6610,7 +6610,7 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
// We might be initializing the same field again if this is an indirect
// field initialization.
if (FieldIt == RD->field_end() ||
- FieldIt->getFieldIndex() > FD->getFieldIndex()) {
+ (*FieldIt)->getFieldIndex() > FD->getFieldIndex()) {
assert(Indirect && "fields out of order?");
return;
}
@@ -6618,10 +6618,10 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
// Default-initialize any fields with no explicit initializer.
for (; !declaresSameEntity(*FieldIt, FD); ++FieldIt) {
assert(FieldIt != RD->field_end() && "missing field?");
- if (!FieldIt->isUnnamedBitField())
+ if (!(*FieldIt)->isUnnamedBitField())
Success &= handleDefaultInitValue(
- FieldIt->getType(),
- Result.getStructField(FieldIt->getFieldIndex()));
+ (*FieldIt)->getType(),
+ Result.getStructField((*FieldIt)->getFieldIndex()));
}
++FieldIt;
};
@@ -6728,10 +6728,10 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
// Default-initialize any remaining fields.
if (!RD->isUnion()) {
for (; FieldIt != RD->field_end(); ++FieldIt) {
- if (!FieldIt->isUnnamedBitField())
+ if (!(*FieldIt)->isUnnamedBitField())
Success &= handleDefaultInitValue(
- FieldIt->getType(),
- Result.getStructField(FieldIt->getFieldIndex()));
+ (*FieldIt)->getType(),
+ Result.getStructField((*FieldIt)->getFieldIndex()));
}
}
@@ -10562,7 +10562,7 @@ bool RecordExprEvaluator::ZeroInitialization(const Expr *E, QualType T) {
if (!HandleLValueMember(Info, E, Subobject, *I))
return false;
Result = APValue(*I);
- ImplicitValueInitExpr VIE(I->getType());
+ ImplicitValueInitExpr VIE((*I)->getType());
return EvaluateInPlace(Result.getUnionValue(), Info, Subobject, &VIE);
}
@@ -10838,19 +10838,19 @@ bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
RecordDecl::field_iterator Field = Record->field_begin();
assert(Field != Record->field_end() &&
- Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
+ Info.Ctx.hasSameType((*Field)->getType()->getPointeeType(),
ArrayType->getElementType()) &&
"Expected std::initializer_list first field to be const E *");
++Field;
assert(Field != Record->field_end() &&
"Expected std::initializer_list to have two fields");
- if (Info.Ctx.hasSameType(Field->getType(), Info.Ctx.getSizeType())) {
+ if (Info.Ctx.hasSameType((*Field)->getType(), Info.Ctx.getSizeType())) {
// Length.
Result.getStructField(1) = APValue(APSInt(ArrayType->getSize()));
} else {
// End pointer.
- assert(Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
+ assert(Info.Ctx.hasSameType((*Field)->getType()->getPointeeType(),
ArrayType->getElementType()) &&
"Expected std::initializer_list second field to be const E *");
if (!HandleLValueArrayAdjustment(Info, E, Array,
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index d9bf62c2bbb04a..8ce600ae26edb4 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -299,14 +299,14 @@ EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info,
}
// Traverse all member variables.
- unsigned FieldNo = 0;
- for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(),
- E = Info->Class->field_end(); I != E; ++I, ++FieldNo) {
+ for (auto FieldCountTuple : llvm::enumerate(Info->Class->fields())) {
+ FieldDecl *I = FieldCountTuple.value();
+ unsigned FieldNo = FieldCountTuple.index();
if (I->isBitField())
continue;
CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo);
- if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset))
+ if (!CanPlaceFieldSubobjectAtOffset(I, FieldOffset))
return false;
}
@@ -346,14 +346,14 @@ void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info,
}
// Traverse all member variables.
- unsigned FieldNo = 0;
- for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(),
- E = Info->Class->field_end(); I != E; ++I, ++FieldNo) {
+ for (auto FieldCountTuple : llvm::enumerate(Info->Class->fields())) {
+ FieldDecl *I = FieldCountTuple.value();
+ unsigned FieldNo = FieldCountTuple.index();
if (I->isBitField())
continue;
CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo);
- UpdateEmptyFieldSubobjects(*I, FieldOffset, PlacingEmptyBase);
+ UpdateEmptyFieldSubobjects(I, FieldOffset, PlacingEmptyBase);
}
}
@@ -411,15 +411,15 @@ EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD,
}
// Traverse all member variables.
- unsigned FieldNo = 0;
- for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
- I != E; ++I, ++FieldNo) {
+ for (auto FieldCountTuple : llvm::enumerate(RD->fields())) {
+ FieldDecl *I = FieldCountTuple.value();
+ unsigned FieldNo = FieldCountTuple.index();
if (I->isBitField())
continue;
CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo);
- if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset))
+ if (!CanPlaceFieldSubobjectAtOffset(I, FieldOffset))
return false;
}
@@ -522,15 +522,15 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(
}
// Traverse all member variables.
- unsigned FieldNo = 0;
- for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
- I != E; ++I, ++FieldNo) {
+ for (auto FieldCountTuple : llvm::enumerate(RD->fields())) {
+ FieldDecl *I = FieldCountTuple.value();
+ unsigned FieldNo = FieldCountTuple.index();
if (I->isBitField())
continue;
CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo);
- UpdateEmptyFieldSubobjects(*I, FieldOffset, PlacingOverlappingField);
+ UpdateEmptyFieldSubobjects(I, FieldOffset, PlacingOverlappingField);
}
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 113d4a100528f8..16eece665daee5 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -5376,7 +5376,7 @@ HLSLAttributedResourceType::findHandleTypeOnResource(const Type *RT) {
const clang::Type *Ty = RT->getUnqualifiedDesugaredType();
if (const RecordDecl *RD = Ty->getAsCXXRecordDecl()) {
if (!RD->fields().empty()) {
- const auto &FirstFD = RD->fields().begin();
+ FieldDecl *FirstFD = *RD->field_begin();
return dyn_cast<HLSLAttributedResourceType>(
FirstFD->getType().getTypePtr());
}
diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp
index 79300df15d0e29..1935023b650dff 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -138,7 +138,7 @@ QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) {
const RecordDecl *UD = UT->getDecl();
if (UD->hasAttr<TransparentUnionAttr>()) {
assert(!UD->field_empty() && "sema created an empty transparent union");
- return UD->field_begin()->getType();
+ return (*UD->field_begin())->getType();
}
}
return Ty;
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index ad64abe7cd40a3..6a5c68115f9d6c 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1718,8 +1718,10 @@ llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
PreviousMDField->getSizeInBits() == 0)
return nullptr;
- auto PreviousBitfield = RD->field_begin();
- std::advance(PreviousBitfield, BitFieldDecl->getFieldIndex() - 1);
+ auto PreviousBitfieldItr = RD->field_begin();
+ std::advance(PreviousBitfieldItr, BitFieldDecl->getFieldIndex() - 1);
+
+ FieldDecl *PreviousBitfield = *PreviousBitfieldItr;
assert(PreviousBitfield->isBitField());
@@ -1743,7 +1745,7 @@ llvm::DIDerivedType *CGDebugInfo::createBitFieldSeparatorIfNeeded(
llvm::DINode::DIFlags Flags =
getAccessFlag(PreviousBitfield->getAccess(), RD);
llvm::DINodeArray Annotations =
- CollectBTFDeclTagAnnotations(*PreviousBitfield);
+ CollectBTFDeclTagAnnotations(PreviousBitfield);
return DBuilder.createBitFieldMemberType(
RecordTy, "", File, Line, 0, StorageOffsetInBits, StorageOffsetInBits,
Flags, DebugType, Annotations);
@@ -1802,12 +1804,8 @@ void CGDebugInfo::CollectRecordLambdaFields(
// has the name and the location of the variable so we should iterate over
// both concurrently.
const ASTRecordLayout &layout = CGM.getContext().getASTRecordLayout(CXXDecl);
- RecordDecl::field_iterator Field = CXXDecl->field_begin();
- unsigned fieldno = 0;
- for (CXXRecordDecl::capture_const_iterator I = CXXDecl->captures_begin(),
- E = CXXDecl->captures_end();
- I != E; ++I, ++Field, ++fieldno) {
- const LambdaCapture &C = *I;
+ for (const auto &[fieldno, C, Field] :
+ llvm::enumerate(CXXDecl->captures(), CXXDecl->fields())) {
if (C.capturesVariable()) {
SourceLocation Loc = C.getLocation();
assert(!Field->isBitField() && "lambdas don't have bitfield members!");
@@ -1824,13 +1822,12 @@ void CGDebugInfo::CollectRecordLambdaFields(
// this of the lambda class and having a field member of 'this' or
// by using AT_object_pointer for the function and having that be
// used as 'this' for semantic references.
- FieldDecl *f = *Field;
- llvm::DIFile *VUnit = getOrCreateFile(f->getLocation());
- QualType type = f->getType();
+ llvm::DIFile *VUnit = getOrCreateFile(Field->getLocation());
+ QualType type = Field->getType();
StringRef ThisName =
CGM.getCodeGenOpts().EmitCodeView ? "__this" : "this";
llvm::DIType *fieldType = createFieldType(
- ThisName, type, f->getLocation(), f->getAccess(),
+ ThisName, type, Field->getLocation(), Field->getAccess(),
layout.getFieldOffset(fieldno), VUnit, RecordTy, CXXDecl);
elements.push_back(fieldType);
@@ -2715,7 +2712,7 @@ static bool isDefinedInClangModule(const RecordDecl *RD) {
// This is a template, check the origin of the first member.
if (CXXDecl->field_begin() == CXXDecl->field_end())
return TemplateKind == TSK_ExplicitInstantiationDeclaration;
- if (!CXXDecl->field_begin()->isFromASTFile())
+ if (!(*CXXDecl->field_begin())->isFromASTFile())
return false;
}
}
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index 2ad6587089f101..86c53d673c379c 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -430,7 +430,7 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
RecordDecl::field_iterator Field = Record->field_begin();
assert(Field != Record->field_end() &&
- Ctx.hasSameType(Field->getType()->getPointeeType(),
+ Ctx.hasSameType((*Field)->getType()->getPointeeType(),
ArrayType->getElementType()) &&
"Expected std::initializer_list first field to be const E *");
@@ -446,14 +446,14 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
llvm::Value *Size = Builder.getInt(ArrayType->getSize());
LValue EndOrLength = CGF.EmitLValueForFieldInitialization(DestLV, *Field);
- if (Ctx.hasSameType(Field->getType(), Ctx.getSizeType())) {
+ if (Ctx.hasSameType((*Field)->getType(), Ctx.getSizeType())) {
// Length.
CGF.EmitStoreThroughLValue(RValue::get(Size), EndOrLength);
} else {
// End pointer.
- assert(Field->getType()->isPointerType() &&
- Ctx.hasSameType(Field->getType()->getPointeeType(),
+ assert((*Field)->getType()->isPointerType() &&
+ Ctx.hasSameType((*Field)->getType()->getPointeeType(),
ArrayType->getElementType()) &&
"Expected std::initializer_list second field to be const E *");
llvm::Value *Zero = llvm::ConstantInt::get(CGF.PtrDiffTy, 0);
@@ -1385,8 +1385,8 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
i != e; ++i, ++CurField) {
// Emit initialization
LValue LV = CGF.EmitLValueForFieldInitialization(SlotLV, *CurField);
- if (CurField->hasCapturedVLAType()) {
- CGF.EmitLambdaVLACapture(CurField->getCapturedVLAType(), LV);
+ if ((*CurField)->hasCapturedVLAType()) {
+ CGF.EmitLambdaVLACapture((*CurField)->getCapturedVLAType(), LV);
continue;
}
@@ -1394,11 +1394,11 @@ AggExprEmitter::VisitLambdaExpr(LambdaExpr *E) {
// Push a destructor if necessary.
if (QualType::DestructionKind DtorKind =
- CurField->getType().isDestructedType()) {
+ (*CurField)->getType().isDestructedType()) {
assert(LV.isSimple());
if (DtorKind)
CGF.pushDestroyAndDeferDeactivation(NormalAndEHCleanup, LV.getAddress(),
- CurField->getType(),
+ (*CurField)->getType(),
CGF.getDestroyer(DtorKind), false);
}
}
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 655fc3dc954c81..0da28ed903d421 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -880,22 +880,20 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
}
}
- unsigned FieldNo = 0;
uint64_t OffsetBits = CGM.getContext().toBits(Offset);
const bool ZeroInitPadding = CGM.shouldZeroInitPadding();
bool ZeroFieldSize = false;
CharUnits SizeSoFar = CharUnits::Zero();
bool AllowOverwrite = false;
- for (RecordDecl::field_iterator Field = RD->field_begin(),
- FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
+ for (const auto &[FieldNo, Field] : llvm::enumerate(RD->fields())) {
// If this is a union, skip all the fields that aren't being initialized.
- if (RD->isUnion() && !declaresSameEntity(Val.getUnionField(), *Field))
+ if (RD->isUnion() && !declaresSameEntity(Val.getUnionField(), Field))
continue;
// Don't emit anonymous bitfields or zero-sized fields.
if (Field->isUnnamedBitField() ||
- isEmptyFieldForLayout(CGM.getContext(), *Field))
+ isEmptyFieldForLayout(CGM.getContext(), Field))
continue;
// Emit the value of the initializer.
@@ -907,7 +905,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
return false;
if (ZeroInitPadding) {
- if (!DoZeroInitPadding(Layout, FieldNo, **Field, AllowOverwrite,
+ if (!DoZeroInitPadding(Layout, FieldNo, *Field, AllowOverwrite,
SizeSoFar, ZeroFieldSize))
return false;
if (ZeroFieldSize)
@@ -917,7 +915,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
if (!Field->isBitField()) {
// Handle non-bitfield members.
- if (!AppendField(*Field, Layout.getFieldOffset(FieldNo) + OffsetBits,
+ if (!AppendField(Field, Layout.getFieldOffset(FieldNo) + OffsetBits,
EltInit, AllowOverwrite))
return false;
// After emitting a non-empty field with [[no_unique_address]], we may
@@ -926,7 +924,7 @@ bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
AllowOverwrite = true;
} else {
// Otherwise we have a bitfield.
- if (!AppendBitField(*Field, Layout.getFieldOffset(FieldNo) + OffsetBits,
+ if (!AppendBitField(Field, Layout.getFieldOffset(FieldNo) + OffsetBits,
EltInit, AllowOverwrite))
return false;
}
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index d714af035d21a2..6b49e68e4fcee6 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -3118,7 +3118,7 @@ static llvm::Value *emitDestructorsFunction(CodeGenModule &CGM,
auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
Base = CGF.EmitLValueForField(Base, *FI);
for (const auto *Field :
- cast<RecordDecl>(FI->getType()->getAsTagDecl())->fields()) {
+ cast<RecordDecl>((*FI)->getType()->getAsTagDecl())->fields()) {
if (QualType::DestructionKind DtorKind =
Field->getType().isDestructedType()) {
LValue FieldLValue = CGF.EmitLValueForField(Base, Field);
@@ -3269,7 +3269,7 @@ static void emitPrivatesInit(CodeGenFunction &CGF,
CGF.ConvertTypeForMem(SharedsTy)),
SharedsTy);
}
- FI = cast<RecordDecl>(FI->getType()->getAsTagDecl())->field_begin();
+ FI = cast<RecordDecl>((*FI)->getType()->getAsTagDecl())->field_begin();
for (const PrivateDataTy &Pair : Privates) {
// Do not initialize private locals.
if (Pair.second.isLocalPrivate()) {
@@ -3683,8 +3683,8 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
std::next(TaskFunction->arg_begin(), 3)->getType();
if (!Privates.empty()) {
auto FI = std::next(KmpTaskTWithPrivatesQTyRD->field_begin());
- TaskPrivatesMap =
- emitTaskPrivateMappingFunction(CGM, Loc, Data, FI->getType(), Privates);
+ TaskPrivatesMap = emitTaskPrivateMappingFunction(
+ CGM, Loc, Data, (*FI)->getType(), Privates);
TaskPrivatesMap = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
TaskPrivatesMap, TaskPrivatesMapTy);
} else {
@@ -9477,7 +9477,7 @@ static void genMapInfoForCaptures(
MappableExprsHandler::DeviceInfoTy::None);
CurInfo.Pointers.push_back(*CV);
CurInfo.Sizes.push_back(CGF.Builder.CreateIntCast(
- CGF.getTypeSize(RI->getType()), CGF.Int64Ty, /*isSigned=*/true));
+ CGF.getTypeSize((*RI)->getType()), CGF.Int64Ty, /*isSigned=*/true));
// Copy to the device as an argument. No need to retrieve it.
CurInfo.Types.push_back(OpenMPOffloadMappingFlags::OMP_MAP_LITERAL |
OpenMPOffloadMappingFlags::OMP_MAP_TARGET_PARAM |
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index 598b946ad88dbb..745d2757f73f45 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -1954,7 +1954,7 @@ llvm::Function *CGOpenMPRuntimeGPU::createParallelDataSharingWrapper(
if (CS.capture_size() > 0) {
ASTContext &CGFContext = CGF.getContext();
for (unsigned I = 0, E = CS.capture_size(); I < E; ++I, ++CI, ++CurField) {
- QualType ElemTy = CurField->getType();
+ QualType ElemTy = (*CurField)->getType();
Address Src = Bld.CreateConstInBoundsGEP(SharedArgListAddress, I + Idx);
Address TypedAddress = Bld.CreatePointerBitCastOrAddrSpaceCast(
Src, CGF.ConvertTypeForMem(CGFContext.getPointerType(ElemTy)),
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index ea44e6f21f3c86..bde7be2ec5da58 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -381,9 +381,9 @@ void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) {
for (RecordDecl::field_iterator Field = D->field_begin(),
FieldEnd = D->field_end();
Field != FieldEnd;) {
- if (Field->isBitField()) {
+ if ((*Field)->isBitField()) {
Field = accumulateBitFields(isNonVirtualBaseType, Field, FieldEnd);
- assert((Field == FieldEnd || !Field->isBitField()) &&
+ assert((Field == FieldEnd || !(*Field)->isBitField()) &&
"Failed to accumulate all the bitfields");
} else if (isEmptyFieldForLayout(Context, *Field)) {
// Empty fields have no storage.
@@ -393,8 +393,8 @@ void CGRecordLowering::accumulateFields(bool isNonVirtualBaseType) {
// as it is done in RecordLayoutBuilder
Members.push_back(MemberInfo(
bitsToCharUnits(getFieldBitOffset(*Field)), MemberInfo::Field,
- Field->isPotentiallyOverlapping()
- ? getStorageType(Field->getType()->getAsCXXRecordDecl())
+ (*Field)->isPotentiallyOverlapping()
+ ? getStorageType((*Field)->getType()->getAsCXXRecordDecl())
: getStorageType(*Field),
*Field));
++Field;
@@ -421,14 +421,14 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
// used to determine if the ASTRecordLayout is treating these two bitfields
// as contiguous. StartBitOffset is offset of the beginning of the Run.
uint64_t StartBitOffset, Tail = 0;
- for (; Field != FieldEnd && Field->isBitField(); ++Field) {
+ for (; Field != FieldEnd && (*Field)->isBitField(); ++Field) {
// Zero-width bitfields end runs.
- if (Field->isZeroLengthBitField(Context)) {
+ if ((*Field)->isZeroLengthBitField(Context)) {
Run = FieldEnd;
continue;
}
uint64_t BitOffset = getFieldBitOffset(*Field);
- llvm::Type *Type = Types.ConvertTypeForMem(Field->getType());
+ llvm::Type *Type = Types.ConvertTypeForMem((*Field)->getType());
// If we don't have a run yet, or don't live within the previous run's
// allocated storage then we allocate some storage and start a new run.
if (Run == FieldEnd || BitOffset >= Tail) {
@@ -536,7 +536,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
bool AtAlignedBoundary = false;
bool Barrier = false;
- if (Field != FieldEnd && Field->isBitField()) {
+ if (Field != FieldEnd && (*Field)->isBitField()) {
uint64_t BitOffset = getFieldBitOffset(*Field);
if (Begin == FieldEnd) {
// Beginning a new span.
@@ -559,7 +559,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
// Bitfield potentially begins a new span. This includes zero-length
// bitfields on non-aligning targets that lie at character boundaries
// (those are barriers to merging).
- if (Field->isZeroLengthBitField(Context))
+ if ((*Field)->isZeroLengthBitField(Context))
Barrier = true;
AtAlignedBoundary = true;
}
@@ -676,7 +676,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
}
if (InstallBest) {
- assert((Field == FieldEnd || !Field->isBitField() ||
+ assert((Field == FieldEnd || !(*Field)->isBitField() ||
(getFieldBitOffset(*Field) % CharBits) == 0) &&
"Installing but not at an aligned bitfield or limit");
CharUnits AccessSize = BestEndOffset - BeginOffset;
@@ -697,7 +697,7 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
}
Members.push_back(StorageInfo(BeginOffset, Type));
for (; Begin != BestEnd; ++Begin)
- if (!Begin->isZeroLengthBitField(Context))
+ if (!(*Begin)->isZeroLengthBitField(Context))
Members.push_back(
MemberInfo(BeginOffset, MemberInfo::Field, nullptr, *Begin));
}
@@ -705,11 +705,11 @@ CGRecordLowering::accumulateBitFields(bool isNonVirtualBaseType,
Field = BestEnd;
Begin = FieldEnd;
} else {
- assert(Field != FieldEnd && Field->isBitField() &&
+ assert(Field != FieldEnd && (*Field)->isBitField() &&
"Accumulating past end of bitfields");
assert(!Barrier && "Accumulating across barrier");
// Accumulate this bitfield into the current (potential) span.
- BitSizeSinceBegin += Field->getBitWidthValue(Context);
+ BitSizeSinceBegin += (*Field)->getBitWidthValue(Context);
++Field;
}
}
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 41dc91c578c800..d22e84c1557847 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -3122,15 +3122,13 @@ LValue CodeGenFunction::InitCapturedStruct(const CapturedStmt &S) {
LValue SlotLV =
MakeAddrLValue(CreateMemTemp(RecordTy, "agg.captured"), RecordTy);
- RecordDecl::field_iterator CurField = RD->field_begin();
- for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
- E = S.capture_init_end();
- I != E; ++I, ++CurField) {
- LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField);
+ for (const auto &[CurField, I] :
+ llvm::zip_equal(RD->fields(), S.capture_inits())) {
+ LValue LV = EmitLValueForFieldInitialization(SlotLV, CurField);
if (CurField->hasCapturedVLAType()) {
EmitLambdaVLACapture(CurField->getCapturedVLAType(), LV);
} else {
- EmitInitializerForField(*CurField, LV, *I);
+ EmitInitializerForField(CurField, LV, I);
}
}
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 1c32a675380c7f..519194ea44ed96 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -378,19 +378,17 @@ llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) {
void CodeGenFunction::GenerateOpenMPCapturedVars(
const CapturedStmt &S, SmallVectorImpl<llvm::Value *> &CapturedVars) {
const RecordDecl *RD = S.getCapturedRecordDecl();
- auto CurField = RD->field_begin();
- auto CurCap = S.captures().begin();
- for (CapturedStmt::const_capture_init_iterator I = S.capture_init_begin(),
- E = S.capture_init_end();
- I != E; ++I, ++CurField, ++CurCap) {
+
+ for (const auto &[CurField, CurCap, I] :
+ llvm::zip_equal(RD->fields(), S.captures(), S.capture_inits())) {
if (CurField->hasCapturedVLAType()) {
const VariableArrayType *VAT = CurField->getCapturedVLAType();
llvm::Value *Val = VLASizeMap[VAT->getSizeExpr()];
CapturedVars.push_back(Val);
- } else if (CurCap->capturesThis()) {
+ } else if (CurCap.capturesThis()) {
CapturedVars.push_back(CXXThisValue);
- } else if (CurCap->capturesVariableByCopy()) {
- llvm::Value *CV = EmitLoadOfScalar(EmitLValue(*I), CurCap->getLocation());
+ } else if (CurCap.capturesVariableByCopy()) {
+ llvm::Value *CV = EmitLoadOfScalar(EmitLValue(I), CurCap.getLocation());
// If the field is not a pointer, we need to save the actual value
// and load it as a void pointer.
@@ -398,13 +396,13 @@ void CodeGenFunction::GenerateOpenMPCapturedVars(
ASTContext &Ctx = getContext();
Address DstAddr = CreateMemTemp(
Ctx.getUIntPtrType(),
- Twine(CurCap->getCapturedVar()->getName(), ".casted"));
+ Twine(CurCap.getCapturedVar()->getName(), ".casted"));
LValue DstLV = MakeAddrLValue(DstAddr, Ctx.getUIntPtrType());
llvm::Value *SrcAddrVal = EmitScalarConversion(
DstAddr.emitRawPointer(*this),
Ctx.getPointerType(Ctx.getUIntPtrType()),
- Ctx.getPointerType(CurField->getType()), CurCap->getLocation());
+ Ctx.getPointerType(CurField->getType()), CurCap.getLocation());
LValue SrcLV =
MakeNaturalAlignAddrLValue(SrcAddrVal, CurField->getType());
@@ -412,12 +410,12 @@ void CodeGenFunction::GenerateOpenMPCapturedVars(
EmitStoreThroughLValue(RValue::get(CV), SrcLV);
// Load the value using the destination type pointer.
- CV = EmitLoadOfScalar(DstLV, CurCap->getLocation());
+ CV = EmitLoadOfScalar(DstLV, CurCap.getLocation());
}
CapturedVars.push_back(CV);
} else {
- assert(CurCap->capturesVariable() && "Expected capture by reference.");
- CapturedVars.push_back(EmitLValue(*I).getAddress().emitRawPointer(*this));
+ assert(CurCap.capturesVariable() && "Expected capture by reference.");
+ CapturedVars.push_back(EmitLValue(I).getAddress().emitRawPointer(*this));
}
}
}
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index ec175b7fabe61f..2870ffe9545104 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -393,7 +393,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
continue;
}
- QualType FieldQTy = i->getType();
+ QualType FieldQTy = (*i)->getType();
if (!CollectFields(Offset, FieldQTy, Fields,
MayAlias || TypeHasMayAlias(FieldQTy)))
return false;
diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp
index 06d9b6d4a57615..9ef750ca51cfad 100644
--- a/clang/lib/CodeGen/Targets/Mips.cpp
+++ b/clang/lib/CodeGen/Targets/Mips.cpp
@@ -156,7 +156,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const {
// double fields.
for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
i != e; ++i, ++idx) {
- const QualType Ty = i->getType();
+ const QualType Ty = (*i)->getType();
const BuiltinType *BT = Ty->getAs<BuiltinType>();
if (!BT || BT->getKind() != BuiltinType::Double)
@@ -263,12 +263,12 @@ MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) {
RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end();
for (; b != e; ++b) {
- const BuiltinType *BT = b->getType()->getAs<BuiltinType>();
+ const BuiltinType *BT = (*b)->getType()->getAs<BuiltinType>();
if (!BT || !BT->isFloatingPoint())
break;
- RTList.push_back(CGT.ConvertType(b->getType()));
+ RTList.push_back(CGT.ConvertType((*b)->getType()));
}
if (b == e)
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 7f73bf2a65266e..f9f83fffcaa4cf 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -2075,14 +2075,12 @@ 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 ||
getContext().getTargetInfo().getTriple().isPS();
bool IsUnion = RT->isUnionType() && !UseClang11Compat;
- for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
- i != e; ++i, ++idx) {
+ for (const auto &[idx, i] : llvm::enumerate(RD->fields())) {
uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
bool BitField = i->isBitField();
@@ -2348,9 +2346,7 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit,
// this could be sped up a lot by being smarter about queried fields,
// however we're only looking at structs up to 16 bytes, so we don't care
// much.
- unsigned idx = 0;
- for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
- i != e; ++i, ++idx) {
+ for (const auto &[idx, i] : llvm::enumerate(RD->fields())) {
unsigned FieldOffset = (unsigned)Layout.getFieldOffset(idx);
// If we found a field after the region we care about, then we're done.
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index f8e5f3c6d309d6..131101269ea9ad 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -15473,14 +15473,14 @@ LambdaScopeInfo *Sema::RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator) {
/*RefersToEnclosingVariableOrCapture*/true, C.getLocation(),
/*EllipsisLoc*/C.isPackExpansion()
? C.getEllipsisLoc() : SourceLocation(),
- I->getType(), /*Invalid*/false);
+ (*I)->getType(), /*Invalid*/false);
} else if (C.capturesThis()) {
- LSI->addThisCapture(/*Nested*/ false, C.getLocation(), I->getType(),
+ LSI->addThisCapture(/*Nested*/ false, C.getLocation(), (*I)->getType(),
C.getCaptureKind() == LCK_StarThis);
} else {
- LSI->addVLATypeCapture(C.getLocation(), I->getCapturedVLAType(),
- I->getType());
+ LSI->addVLATypeCapture(C.getLocation(), (*I)->getCapturedVLAType(),
+ (*I)->getType());
}
++I;
}
@@ -19304,9 +19304,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
bool ZeroSize = true;
bool IsEmpty = true;
unsigned NonBitFields = 0;
- for (RecordDecl::field_iterator I = Record->field_begin(),
- E = Record->field_end();
- (NonBitFields == 0 || ZeroSize) && I != E; ++I) {
+ for (FieldDecl *I : Record->fields()) {
+ if (NonBitFields != 0 && !ZeroSize)
+ break;
IsEmpty = false;
if (I->isUnnamedBitField()) {
if (!I->isZeroLengthBitField(Context))
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 601c6f2eef1d9c..55477bde9b37e9 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3909,14 +3909,12 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
}
- RecordDecl::field_iterator Field = RD->field_begin(),
- FieldEnd = RD->field_end();
- if (Field == FieldEnd) {
+ if (RD->field_empty()) {
S.Diag(AL.getLoc(), diag::warn_transparent_union_attribute_zero_fields);
return;
}
- FieldDecl *FirstField = *Field;
+ FieldDecl *FirstField = *RD->field_begin();
QualType FirstType = FirstField->getType();
if (FirstType->hasFloatingRepresentation() || FirstType->isVectorType()) {
S.Diag(FirstField->getLocation(),
@@ -3929,7 +3927,7 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
return;
uint64_t FirstSize = S.Context.getTypeSize(FirstType);
uint64_t FirstAlign = S.Context.getTypeAlign(FirstType);
- for (; Field != FieldEnd; ++Field) {
+ for (FieldDecl *Field : RD->fields()) {
QualType FieldType = Field->getType();
if (FieldType->isIncompleteType())
return;
@@ -3946,7 +3944,7 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
: S.Context.getTypeAlign(FieldType);
S.Diag(Field->getLocation(),
diag::warn_transparent_union_attribute_field_size_align)
- << isSize << *Field << FieldBits;
+ << isSize << Field << FieldBits;
unsigned FirstBits = isSize ? FirstSize : FirstAlign;
S.Diag(FirstField->getLocation(),
diag::note_transparent_union_first_field_size_align)
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 725cfad67da900..6573afa5557488 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2348,8 +2348,9 @@ static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl,
// allow at most one initializer per member.
bool AnyAnonStructUnionMembers = false;
unsigned Fields = 0;
- for (CXXRecordDecl::field_iterator I = RD->field_begin(),
- E = RD->field_end(); I != E; ++I, ++Fields) {
+ for (auto FieldCountTuple : llvm::enumerate(RD->fields())) {
+ FieldDecl *I = FieldCountTuple.value();
+ Fields = FieldCountTuple.index();
if (I->isAnonymousStructOrUnion()) {
AnyAnonStructUnionMembers = true;
break;
@@ -11826,7 +11827,7 @@ QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind,
// (2) The field is an integral or enumeration type.
auto FIt = Info->Record->field_begin(), FEnd = Info->Record->field_end();
if (std::distance(FIt, FEnd) != 1 ||
- !FIt->getType()->isIntegralOrEnumerationType()) {
+ !(*FIt)->getType()->isIntegralOrEnumerationType()) {
return UnsupportedSTLError();
}
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 78acfeddb78639..fe861f2dd5f661 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -3247,7 +3247,7 @@ static bool tryMatchRecordTypes(ASTContext &Context,
RecordDecl::field_iterator li = left->field_begin(), le = left->field_end();
RecordDecl::field_iterator ri = right->field_begin(), re = right->field_end();
for (; li != le && ri != re; ++li, ++ri) {
- if (!matchTypes(Context, strategy, li->getType(), ri->getType()))
+ if (!matchTypes(Context, strategy, (*li)->getType(), (*ri)->getType()))
return false;
}
return (li == le && ri == re);
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 573e90aced3eea..4fd4c8451f4ba9 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -2287,9 +2287,9 @@ void InitListChecker::CheckStructUnionTypes(
return;
for (RecordDecl::field_iterator FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
- if (Field->hasInClassInitializer() ||
- (Field->isAnonymousStructOrUnion() &&
- Field->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) {
+ if ((*Field)->hasInClassInitializer() ||
+ ((*Field)->isAnonymousStructOrUnion() &&
+ (*Field)->getType()->getAsCXXRecordDecl()->hasInClassInitializer())) {
StructuredList->setInitializedFieldInUnion(*Field);
// FIXME: Actually build a CXXDefaultInitExpr?
return;
@@ -2302,7 +2302,7 @@ void InitListChecker::CheckStructUnionTypes(
// bitfield.
for (RecordDecl::field_iterator FieldEnd = RD->field_end();
Field != FieldEnd; ++Field) {
- if (!Field->isUnnamedBitField()) {
+ if (!(*Field)->isUnnamedBitField()) {
CheckEmptyInitializable(
InitializedEntity::InitializeMember(*Field, &Entity),
IList->getEndLoc());
@@ -2462,10 +2462,10 @@ void InitListChecker::CheckStructUnionTypes(
return;
// Stop if we've hit a flexible array member.
- if (Field->getType()->isIncompleteArrayType())
+ if ((*Field)->getType()->isIncompleteArrayType())
break;
- if (Field->isUnnamedBitField()) {
+ if ((*Field)->isUnnamedBitField()) {
// Don't initialize unnamed bitfields, e.g. "int : 20;"
++Field;
continue;
@@ -2486,7 +2486,7 @@ void InitListChecker::CheckStructUnionTypes(
}
if (!VerifyOnly) {
- QualType ET = SemaRef.Context.getBaseElementType(Field->getType());
+ QualType ET = SemaRef.Context.getBaseElementType((*Field)->getType());
if (checkDestructorReference(ET, InitLoc, SemaRef)) {
hadError = true;
return;
@@ -2495,7 +2495,7 @@ void InitListChecker::CheckStructUnionTypes(
InitializedEntity MemberEntity =
InitializedEntity::InitializeMember(*Field, &Entity);
- CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
+ CheckSubElementType(MemberEntity, IList, (*Field)->getType(), Index,
StructuredList, StructuredIndex);
InitializedSomething = true;
InitializedFields.insert(*Field);
@@ -2525,8 +2525,8 @@ void InitListChecker::CheckStructUnionTypes(
if (HasDesignatedInit && InitializedFields.count(*it))
continue;
- if (!it->isUnnamedBitField() && !it->hasInClassInitializer() &&
- !it->getType()->isIncompleteArrayType()) {
+ if (!(*it)->isUnnamedBitField() && !(*it)->hasInClassInitializer() &&
+ !(*it)->getType()->isIncompleteArrayType()) {
auto Diag = HasDesignatedInit
? diag::warn_missing_designated_field_initializers
: diag::warn_missing_field_initializers;
@@ -2539,9 +2539,9 @@ void InitListChecker::CheckStructUnionTypes(
// Check that any remaining fields can be value-initialized if we're not
// building a structured list. (If we are, we'll check this later.)
if (!StructuredList && Field != FieldEnd && !RD->isUnion() &&
- !Field->getType()->isIncompleteArrayType()) {
+ !(*Field)->getType()->isIncompleteArrayType()) {
for (; Field != FieldEnd && !hadError; ++Field) {
- if (!Field->isUnnamedBitField() && !Field->hasInClassInitializer())
+ if (!(*Field)->isUnnamedBitField() && !(*Field)->hasInClassInitializer())
CheckEmptyInitializable(
InitializedEntity::InitializeMember(*Field, &Entity),
IList->getEndLoc());
@@ -2555,7 +2555,7 @@ void InitListChecker::CheckStructUnionTypes(
RecordDecl::field_iterator I = HasDesignatedInit ? RD->field_begin()
: Field;
for (RecordDecl::field_iterator E = RD->field_end(); I != E; ++I) {
- QualType ET = SemaRef.Context.getBaseElementType(I->getType());
+ QualType ET = SemaRef.Context.getBaseElementType((*I)->getType());
if (checkDestructorReference(ET, IList->getEndLoc(), SemaRef)) {
hadError = true;
return;
@@ -2563,7 +2563,7 @@ void InitListChecker::CheckStructUnionTypes(
}
}
- if (Field == FieldEnd || !Field->getType()->isIncompleteArrayType() ||
+ if (Field == FieldEnd || !(*Field)->getType()->isIncompleteArrayType() ||
Index >= IList->getNumInits())
return;
@@ -2579,10 +2579,10 @@ void InitListChecker::CheckStructUnionTypes(
if (isa<InitListExpr>(IList->getInit(Index)) ||
AggrDeductionCandidateParamTypes)
- CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
+ CheckSubElementType(MemberEntity, IList, (*Field)->getType(), Index,
StructuredList, StructuredIndex);
else
- CheckImplicitInitList(MemberEntity, IList, Field->getType(), Index,
+ CheckImplicitInitList(MemberEntity, IList, (*Field)->getType(), Index,
StructuredList, StructuredIndex);
if (RD->isUnion() && StructuredList) {
@@ -2921,7 +2921,9 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
}
RecordDecl::field_iterator Field =
- RecordDecl::field_iterator(DeclContext::decl_iterator(KnownField));
+ llvm::find(KnownField->getParent()->fields(), KnownField);
+ assert(Field != KnownField->getParent()->field_end() &&
+ "Field not in own parent?");
// All of the fields of a union are located at the same place in
// the initializer list.
@@ -2981,16 +2983,16 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
if (IsFirstDesignator && !VerifyOnly && SemaRef.getLangOpts().CPlusPlus &&
NextField &&
(*NextField == RD->field_end() ||
- (*NextField)->getFieldIndex() > Field->getFieldIndex() + 1)) {
+ (**NextField)->getFieldIndex() > (*Field)->getFieldIndex() + 1)) {
// Find the field that we just initialized.
FieldDecl *PrevField = nullptr;
- for (auto FI = RD->field_begin(); FI != RD->field_end(); ++FI) {
+ for (FieldDecl *FI : RD->fields()) {
if (FI->isUnnamedBitField())
continue;
if (*NextField != RD->field_end() &&
- declaresSameEntity(*FI, **NextField))
+ declaresSameEntity(FI, **NextField))
break;
- PrevField = *FI;
+ PrevField = FI;
}
if (PrevField &&
@@ -3021,7 +3023,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
StructuredList->resizeInits(SemaRef.Context, FieldIndex + 1);
// This designator names a flexible array member.
- if (Field->getType()->isIncompleteArrayType()) {
+ if ((*Field)->getType()->isIncompleteArrayType()) {
bool Invalid = false;
if ((DesigIdx + 1) != DIE->size()) {
// We can't designate an object within the flexible array
@@ -3032,7 +3034,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
SemaRef.Diag(NextD->getBeginLoc(),
diag::err_designator_into_flexible_array_member)
<< SourceRange(NextD->getBeginLoc(), DIE->getEndLoc());
- SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
+ SemaRef.Diag((*Field)->getLocation(), diag::note_flexible_array_member)
<< *Field;
}
Invalid = true;
@@ -3045,7 +3047,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
SemaRef.Diag(DIE->getInit()->getBeginLoc(),
diag::err_flexible_array_init_needs_braces)
<< DIE->getInit()->getSourceRange();
- SemaRef.Diag(Field->getLocation(), diag::note_flexible_array_member)
+ SemaRef.Diag((*Field)->getLocation(), diag::note_flexible_array_member)
<< *Field;
}
Invalid = true;
@@ -3069,7 +3071,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
InitializedEntity MemberEntity =
InitializedEntity::InitializeMember(*Field, &Entity);
- CheckSubElementType(MemberEntity, IList, Field->getType(), Index,
+ CheckSubElementType(MemberEntity, IList, (*Field)->getType(), Index,
StructuredList, newStructuredIndex);
IList->setInit(OldIndex, DIE);
@@ -3083,7 +3085,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
}
} else {
// Recurse to check later designated subobjects.
- QualType FieldType = Field->getType();
+ QualType FieldType = (*Field)->getType();
unsigned newStructuredIndex = FieldIndex;
InitializedEntity MemberEntity =
@@ -3103,7 +3105,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
// If this the first designator, our caller will continue checking
// the rest of this struct/class/union subobject.
if (IsFirstDesignator) {
- if (Field != RD->field_end() && Field->isUnnamedBitField())
+ if (Field != RD->field_end() && (*Field)->isUnnamedBitField())
++Field;
if (NextField)
@@ -8391,8 +8393,8 @@ ExprResult InitializationSequence::Perform(Sema &S,
return InvalidType();
// Start pointer
- if (!Field->getType()->isPointerType() ||
- !S.Context.hasSameType(Field->getType()->getPointeeType(),
+ if (!(*Field)->getType()->isPointerType() ||
+ !S.Context.hasSameType((*Field)->getType()->getPointeeType(),
ElementType.withConst()))
return InvalidType();
@@ -8400,13 +8402,13 @@ ExprResult InitializationSequence::Perform(Sema &S,
return InvalidType();
// Size or end pointer
- if (const auto *PT = Field->getType()->getAs<PointerType>()) {
+ if (const auto *PT = (*Field)->getType()->getAs<PointerType>()) {
if (!S.Context.hasSameType(PT->getPointeeType(),
ElementType.withConst()))
return InvalidType();
} else {
- if (Field->isBitField() ||
- !S.Context.hasSameType(Field->getType(), S.Context.getSizeType()))
+ if ((*Field)->isBitField() ||
+ !S.Context.hasSameType((*Field)->getType(), S.Context.getSizeType()))
return InvalidType();
}
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 674099dd7e1f0f..a850e2ca7a01ab 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2678,18 +2678,18 @@ RegionBindingsRef RegionStoreManager::bindStruct(RegionBindingsConstRef B,
}
}
- RecordDecl::field_iterator FI, FE;
+ RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
- for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI) {
+ for (; FI != FE; ++FI) {
if (VI == VE)
break;
// Skip any unnamed bitfields to stay in sync with the initializers.
- if (FI->isUnnamedBitField())
+ if ((*FI)->isUnnamedBitField())
continue;
- QualType FTy = FI->getType();
+ QualType FTy = (*FI)->getType();
const FieldRegion* FR = MRMgr.getFieldRegion(*FI, R);
if (FTy->isArrayType())
>From e7be9cf47e6556336de9e4422a96f9ea2956f754 Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Tue, 29 Oct 2024 14:40:35 -0700
Subject: [PATCH 3/4] last bits of cleanup for ninja build to work with
field_iterator converted
---
clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp | 4 ++--
clang/include/clang/AST/DeclBase.h | 1 +
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp b/clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp
index 6faeb7a0b76e19..7a719940510624 100644
--- a/clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp
+++ b/clang-tools-extra/clang-tidy/utils/DesignatedInitializers.cpp
@@ -80,12 +80,12 @@ class AggregateDesignatorNames {
return false; // Bases can't be designated. Should we make one up?
if (FieldsIt != FieldsEnd) {
llvm::StringRef FieldName;
- if (const IdentifierInfo *II = FieldsIt->getIdentifier())
+ if (const IdentifierInfo *II = (*FieldsIt)->getIdentifier())
FieldName = II->getName();
// For certain objects, their subobjects may be named directly.
if (ForSubobject &&
- (FieldsIt->isAnonymousStructOrUnion() ||
+ ((*FieldsIt)->isAnonymousStructOrUnion() ||
// std::array<int,3> x = {1,2,3}. Designators not strictly valid!
(OneField && isReservedName(FieldName))))
return true;
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index 062244392f15a5..3be39211131a94 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -2374,6 +2374,7 @@ class DeclContext {
SpecificDecl *>;
public:
+ decl_cast_iterator() : BaseT(ItTy{}) {}
decl_cast_iterator(ItTy Itr) : BaseT(Itr) {}
SpecificDecl *mapElement(Decl *D) const {
>From a703e9e7437135de291036f4dbe3698e149dabce Mon Sep 17 00:00:00 2001
From: erichkeane <ekeane at nvidia.com>
Date: Tue, 29 Oct 2024 14:43:50 -0700
Subject: [PATCH 4/4] Update tests to cet check-clang passing
---
clang/unittests/AST/ASTImporterTest.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index bf7313f882e455..35a51796d0629a 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -8987,9 +8987,9 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportFieldInitializerWithItself) {
Decl *FromTU = getTuDecl(Code, Lang_CXX11);
auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
FromTU, cxxRecordDecl(hasName("A")));
- EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
+ EXPECT_TRUE((*FromA->field_begin())->getInClassInitializer());
auto *ToA = Import(FromA, Lang_CXX11);
- EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
+ EXPECT_TRUE((*ToA->field_begin())->getInClassInitializer());
}
TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer1) {
@@ -9020,7 +9020,7 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer1) {
Decl *FromTU = getTuDecl(Code, Lang_CXX11);
auto *FromA = FirstDeclMatcher<CXXRecordDecl>().match(
FromTU, cxxRecordDecl(hasName("A")));
- EXPECT_TRUE(FromA->field_begin()->getInClassInitializer());
+ EXPECT_TRUE((*FromA->field_begin())->getInClassInitializer());
// auto *ToA = Import(FromA, Lang_CXX11);
// EXPECT_TRUE(ToA->field_begin()->getInClassInitializer());
}
More information about the cfe-commits
mailing list