================ @@ -2400,7 +2402,66 @@ bool Type::isWebAssemblyTableType() const { return false; } -bool Type::isSizelessType() const { return isSizelessBuiltinType(); } +bool Type::isSizelessType() const { + // Check if this type or any of its constituents are sizeless, due to + // being a builtin type or individually having the user attribute. + // As structs can be recursive, we iterate through without repeats. + SmallVector<const Type *, 1> todo = {this}; + llvm::SmallPtrSet<const Type *, 1> done; + + while (todo.size()) { + auto current = todo.pop_back_val(); + if (done.count(current)) + continue; + done.insert(current); + + // If either this is a known sizeless type from being a builtin + // or as marked by the user, this is a sizeless type. + if (current->isSizelessBuiltinType()) + return true; + if (current->hasAttr(attr::SizelessType)) + return true; + + // Otherwise return true if any inner types are sizeless. + switch (current->CanonicalType->getTypeClass()) { + default: + break; + case Record: { + // A struct with sizeless types is itself sizeless. + RecordDecl *Rec = cast<RecordType>(current->CanonicalType)->getDecl(); + + // skip incomplete structs + if (!Rec->isCompleteDefinition()) + break; + + // a struct marked sizeless explicitly is sizeless + if (Rec->hasAttr<clang::SizelessTypeAttr>()) + return true; + + // A struct is sizeless if it contains a sizeless field + for (auto field : Rec->fields()) + todo.push_back(field->getType().getTypePtr()); + + // A class is sizeless if it contains a sizeless base + if (auto CXXRec = dyn_cast<CXXRecordDecl>(Rec)) ---------------- tbaederr wrote:
```suggestion if (const auto *CXXRec = dyn_cast<CXXRecordDecl>(Rec)) ``` https://github.com/llvm/llvm-project/pull/71894 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits