================ @@ -268,6 +268,69 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT, updateStringLiteralType(Str, DeclT); } +template <class Predicate, class RecordFilter> +std::enable_if_t<std::is_void_v<decltype(std::declval<Predicate &>()( + std::declval<const FieldDecl *>()))>, + size_t> +forEachFieldRecursive(const RecordDecl *Record, Predicate FieldPred, + RecordFilter RecordPreFilter) { + size_t NumFound = 0; + SmallVector<const RecordDecl *> Stack; + llvm::SmallDenseSet<const RecordDecl *> Seen; + Stack.push_back(Record); + while (!Stack.empty()) { + const RecordDecl *RD = Stack.back(); + Stack.pop_back(); + const size_t OldStackSize = Stack.size(); + if (RD) { + RD = dyn_cast_if_present<RecordDecl>(RD->getCanonicalDecl()); + } + if (RD && Seen.insert(RD).second && RecordPreFilter(RD)) { + for (const FieldDecl *Field : RD->fields()) { + FieldPred(Field); + ++NumFound; + QualType FieldType = Field->getType(); + if (!FieldType.isNull()) { + const RecordDecl *FieldRD = FieldType->getAsRecordDecl(); + if (FieldRD && !Seen.contains(FieldRD) && RecordPreFilter(FieldRD)) { + Stack.push_back(FieldRD); + } + } + } + if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { + CXXRD->forallBases([&](const CXXRecordDecl *Base) { + if (Base) { + Base = Base->getCanonicalDecl(); + } + if (Base && !Seen.contains(Base) && RecordPreFilter(Base)) { + Stack.push_back(Base); + } + return true; + }); + } + } + // Preserve push order when popping + std::reverse(Stack.begin() + OldStackSize, Stack.end()); + } + return NumFound; +} + +size_t emitUninitializedExplicitInitFields(Sema &S, const RecordDecl *R) { ---------------- erichkeane wrote:
What is the return value used for here? https://github.com/llvm/llvm-project/pull/102040 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits