[clang] [OpenMP] Support capturing structured bindings in OpenMP regions. (PR #190832)

Alexey Bataev via cfe-commits cfe-commits at lists.llvm.org
Sat May 9 09:14:41 PDT 2026


================
@@ -4672,39 +4672,69 @@ static bool
 buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI,
                              SmallVectorImpl<CapturedStmt::Capture> &Captures,
                              SmallVectorImpl<Expr *> &CaptureInits) {
+  llvm::SmallPtrSet<VarDecl *, 4> CapturedDecomposed;
   for (const sema::Capture &Cap : RSI->Captures) {
     if (Cap.isInvalid())
       continue;
 
+    ValueDecl *CapVar = nullptr;
+    if (Cap.isVariableCapture()) {
+      CapVar = Cap.getVariable();
+      if (auto *BD = dyn_cast<BindingDecl>(CapVar)) {
+        VarDecl *DD = cast<VarDecl>(BD->getDecomposedDecl());
+        if (!CapturedDecomposed.insert(DD).second) {
+          continue; // Skip duplicate.
+        }
----------------
alexey-bataev wrote:

Skipping duplicate captures means the resulting `CapturedStmt` has fewer captures than `RSI->Captures` originally tracked. AST consumers (template instantiation, AST dumpers, source-to-source rewriters, libTooling clients) that walk `S.captures()` in lockstep with the original tracked bindings will be off by one or more. Verify this is safe for existing template instantiation paths (e.g. a function template that captures a binding pair in OpenMP, instantiated multiple times) and add a regression test.

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


More information about the cfe-commits mailing list