[clang] [Clang][P1061] Add stuctured binding packs (PR #121417)

Younan Zhang via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 16 21:55:34 PST 2025


================
@@ -1508,23 +1612,52 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,
     Qualifiers Q = DecompType.getQualifiers();
     if (FD->isMutable())
       Q.removeConst();
-    B->setBinding(S.BuildQualifiedType(FD->getType(), Loc, Q), E.get());
+    Walker.commitAndAdvance(S.BuildQualifiedType(FD->getType(), Loc, Q),
+                            E.get());
   }
 
-  if (I != Bindings.size())
-    return DiagnoseBadNumberOfBindings();
-
   return false;
 }
 
+unsigned Sema::GetDecompositionElementCount(QualType DecompType) {
+  assert(!DecompType->isDependentType() && "expecting non-dependent type");
+  SourceLocation Loc = SourceLocation(); // FIXME
+  DecompType = DecompType.getNonReferenceType();
+  if (auto *CAT = Context.getAsConstantArrayType(DecompType))
+    return CAT->getSize().getLimitedValue(UINT_MAX);
+  if (auto *VT = DecompType->getAs<VectorType>())
+    return VT->getNumElements();
+  if (auto *CT = DecompType->getAs<ComplexType>())
+    return 2;
+  llvm::APSInt TupleSize(32);
+  if (IsTupleLike TL = isTupleLike(*this, Loc, DecompType, TupleSize);
+      TL == IsTupleLike::TupleLike)
+    return (unsigned)TupleSize.getLimitedValue(UINT_MAX);
+
+  if (CXXRecordDecl *RD = DecompType->getAsCXXRecordDecl();
+      RD && !RD->isUnion()) {
+    CXXCastPath BasePath;
+    DeclAccessPair BasePair =
+        findDecomposableBaseClass(*this, Loc, RD, BasePath);
+    RD = cast_or_null<CXXRecordDecl>(BasePair.getDecl());
+    if (RD)
+      return llvm::count_if(
+          RD->fields(), [](FieldDecl *FD) { return !FD->isUnnamedBitField(); });
+  }
+
+  llvm_unreachable("unknown type for decomposition");
+}
+
 void Sema::CheckCompleteDecompositionDeclaration(DecompositionDecl *DD) {
   QualType DecompType = DD->getType();
 
   // If the type of the decomposition is dependent, then so is the type of
   // each binding.
   if (DecompType->isDependentType()) {
-    for (auto *B : DD->bindings())
-      B->setType(Context.DependentTy);
+    for (auto *B : DD->bindings()) {
+      if (B->getType().isNull())
+        B->setType(Context.DependentTy);
+    }
----------------
zyn0217 wrote:

Can we clarify the intent here, e.g. `!isa<PackExpansionType>(B->getType())`?

https://github.com/llvm/llvm-project/pull/121417


More information about the cfe-commits mailing list