[clang] Reapply "[clang] Introduce [[clang::lifetime_capture_by(X)]] (PR #115823)

Haojian Wu via cfe-commits cfe-commits at lists.llvm.org
Tue Nov 12 12:40:01 PST 2024


================
@@ -3867,6 +3869,117 @@ static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
       S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
 }
 
+LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
+                                                        StringRef ParamName) {
+  // Atleast one capture by is required.
+  if (AL.getNumArgs() == 0) {
+    Diag(AL.getLoc(), diag::err_capture_by_attribute_no_entity)
+        << AL.getRange();
+    return nullptr;
+  }
+  unsigned N = AL.getNumArgs();
+  IdentifierInfo **ParamIdents = new (Context) IdentifierInfo *[N];
+  SourceLocation *ParamLocs = new (Context) SourceLocation[N];
+  bool IsValid = true;
+  for (unsigned I = 0; I < N; ++I) {
+    if (AL.isArgExpr(I)) {
+      Expr *E = AL.getArgAsExpr(I);
+      Diag(E->getExprLoc(), diag::err_capture_by_attribute_argument_unknown)
+          << E << E->getExprLoc();
+      IsValid = false;
+      continue;
+    }
+    assert(AL.isArgIdent(I));
+    IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
+    if (IdLoc->Ident->getName() == ParamName) {
+      Diag(IdLoc->Loc, diag::err_capture_by_references_itself) << IdLoc->Loc;
+      IsValid = false;
+      continue;
+    }
+    ParamIdents[I] = IdLoc->Ident;
+    ParamLocs[I] = IdLoc->Loc;
+  }
+  if (!IsValid)
+    return nullptr;
+  SmallVector<int> FakeParamIndices(N, LifetimeCaptureByAttr::INVALID);
+  LifetimeCaptureByAttr *CapturedBy = ::new (Context) LifetimeCaptureByAttr(
----------------
hokein wrote:

Instead of using the raw new operator, I think the common practice is to use the `LifetimeCaptureByAttr::Create` API to create an object.

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


More information about the cfe-commits mailing list