https://github.com/zmodem created 
https://github.com/llvm/llvm-project/pull/208691

Let's revert this until there's a plan in place for how code is supposed to 
transition to the new spelling.

Reverts llvm/llvm-project#196635

>From 987f8a22ff8e0ae7bd92de335a373e53c2938fdc Mon Sep 17 00:00:00 2001
From: Hans Wennborg <[email protected]>
Date: Fri, 10 Jul 2026 12:50:05 +0200
Subject: [PATCH] =?UTF-8?q?Revert=20"[clang][Sema]=20Deprecate=20`global`/?=
 =?UTF-8?q?`unknown`=20in=20`lifetime=5Fcapture=5Fby`=20(=E2=80=A6"?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This reverts commit a627e7e9c3cc9adab27b1e6ebfd70f40dccacf5c.
---
 clang/docs/ReleaseNotes.md                    |   9 --
 clang/include/clang/Basic/Attr.td             |  12 +--
 clang/include/clang/Basic/AttrDocs.td         |  34 ++----
 .../clang/Basic/DiagnosticSemaKinds.td        |  11 +-
 clang/lib/Sema/CheckExprLifetime.cpp          |  14 ++-
 clang/lib/Sema/SemaChecking.cpp               |   5 +-
 clang/lib/Sema/SemaDeclAttr.cpp               | 101 +++---------------
 clang/test/Sema/LifetimeSafety/capture-by.cpp |  34 ++----
 clang/test/Sema/LifetimeSafety/safety.cpp     |   4 +-
 .../test/SemaCXX/attr-lifetime-capture-by.cpp |  52 ++-------
 10 files changed, 62 insertions(+), 214 deletions(-)

diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 449a3792eb4ba..7676699a9b54d 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -554,15 +554,6 @@ latest release, please see the [Clang Web 
Site](https://clang.llvm.org) or the
 - The `modular_format` attribute now supports the `fixed` aspect for C
   ISO 18037 fixed-point `printf` specifiers.
 
-- The `lifetime_capture_by` attribute now accepts three new spelling forms:
-  `lifetime_capture_by_this`, `lifetime_capture_by_global`, and
-  `lifetime_capture_by_unknown`. These replace passing `this`, `global`, and
-  `unknown` as arguments to `lifetime_capture_by`; that argument form is now
-  deprecated because those names can conflict with user-defined parameters.
-  They will be removed in the next release. Distinct `lifetime_capture_by`
-  spellings may also be combined on the same declaration, but each spelling may
-  appear at most once.
-
 - The `const` and `pure` attributes only apply to functions; they are now
   diagnosed and ignored when applied to anything else.
 
diff --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 1a5bd2301dfc8..de3e0f7b563a7 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2137,19 +2137,9 @@ def LifetimeBound : DeclOrTypeAttr {
 }
 
 def LifetimeCaptureBy : DeclOrTypeAttr {
-  let Spellings = [Clang<"lifetime_capture_by">,
-                   Clang<"lifetime_capture_by_this">,
-                   Clang<"lifetime_capture_by_global">,
-                   Clang<"lifetime_capture_by_unknown">];
+  let Spellings = [Clang<"lifetime_capture_by", 1>];
   let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;
   let Args = [VariadicParamOrParamIdxArgument<"Params">];
-  let Accessors = [Accessor<"isThis", [Clang<"lifetime_capture_by_this">]>,
-                   Accessor<"isGlobal", [Clang<"lifetime_capture_by_global">]>,
-                   Accessor<"isUnknown", 
[Clang<"lifetime_capture_by_unknown">]>,
-                   Accessor<"isStandaloneSpecial",
-                            [Clang<"lifetime_capture_by_this">,
-                             Clang<"lifetime_capture_by_global">,
-                             Clang<"lifetime_capture_by_unknown">]>];
   let Documentation = [LifetimeCaptureByDocs];
   let AdditionalMembers = [{
 private:
diff --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 05e4cb0870652..ba19e61168575 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4701,13 +4701,10 @@ have their lifetimes extended.
 
 def LifetimeCaptureByDocs : Documentation {
   let Category = DocCatFunction;
-  let Heading = "lifetime_capture_by, lifetime_capture_by_this, 
lifetime_capture_by_global, lifetime_capture_by_unknown";
   let Content = [{
-Similar to `lifetimebound`_, the ``lifetime_capture_by`` attribute family on a
-function parameter or implicit object parameter indicates that a capturing
-entity may refer to the object referred to by that parameter. The capturing
-entity can be named in ``lifetime_capture_by(X)`` or selected by one of the
-standalone special forms listed below.
+Similar to `lifetimebound`_, the ``lifetime_capture_by(X)`` attribute on a
+function parameter or implicit object parameter indicates that the capturing
+entity ``X`` may refer to the object referred by that parameter.
 
 Below is a list of types of the parameters and what they're considered to 
refer to:
 
@@ -4739,7 +4736,7 @@ temporary object.
     addToSet(local, s); // Ok.
   }
 
-The capturing entity can be one of the following:
+The capturing entity ``X`` can be one of the following:
 
 - Another (named) function parameter.
 
@@ -4749,30 +4746,28 @@ The capturing entity can be one of the following:
       s.insert(a);
     }
 
-- ``this`` (in case of member functions), written as
-  ``lifetime_capture_by_this``.
+- ``this`` (in case of member functions).
 
   .. code-block:: c++
 
     class S {
-      void addToSet(std::string_view a [[clang::lifetime_capture_by_this]]) {
+      void addToSet(std::string_view a [[clang::lifetime_capture_by(this)]]) {
         s.insert(a);
       }
       std::set<std::string_view> s;
     };
 
-  Note: When applied to a constructor parameter, 
`[[clang::lifetime_capture_by_this]]` is just an alias of 
`[[clang::lifetimebound]]`.
+  Note: When applied to a constructor parameter, 
`[[clang::lifetime_capture_by(this)]]` is just an alias of 
`[[clang::lifetimebound]]`.
 
-- ``global`` and ``unknown``, written as ``lifetime_capture_by_global`` and
-  ``lifetime_capture_by_unknown`` respectively.
+- `global`, `unknown`.
 
   .. code-block:: c++
 
     std::set<std::string_view> s;
-    void addToSet(std::string_view a [[clang::lifetime_capture_by_global]]) {
+    void addToSet(std::string_view a [[clang::lifetime_capture_by(global)]]) {
       s.insert(a);
     }
-    void addSomewhere(std::string_view a 
[[clang::lifetime_capture_by_unknown]]);
+    void addSomewhere(std::string_view a 
[[clang::lifetime_capture_by(unknown)]]);
 
 The attribute can be applied to the implicit ``this`` parameter of a member
 function by writing the attribute after the function type:
@@ -4785,7 +4780,7 @@ function by writing the attribute after the function type:
     }
   };
 
-The parameter-list form supports specifying more than one capturing entity:
+The attribute supports specifying more than one capturing entities:
 
 .. code-block:: c++
 
@@ -4796,13 +4791,6 @@ The parameter-list form supports specifying more than 
one capturing entity:
     s2.insert(a);
   }
 
-Distinct ``lifetime_capture_by`` forms can also be combined on the same
-declaration, but each form can appear at most once. For example,
-``[[clang::lifetime_capture_by(s), clang::lifetime_capture_by_this]]`` is
-allowed, but two ``[[clang::lifetime_capture_by(...)]]`` attributes or two
-``[[clang::lifetime_capture_by_this]]`` attributes on the same declaration are
-rejected.
-
 Limitation: The capturing entity ``X`` is not used by the analysis and is
 used for documentation purposes only. This is because the analysis is
 statement-local and only detects use of a temporary as an argument to the
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 09951730e1570..e57f3e0e14168 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3566,23 +3566,18 @@ def err_callback_callee_is_variadic : Error<
 def err_callback_implicit_this_not_available : Error<
   "'callback' argument at position %0 references unavailable implicit 'this'">;
 
+def err_capture_by_attribute_multiple : Error<
+  "multiple 'lifetime_capture' attributes specified">;
 def err_capture_by_attribute_no_entity : Error<
   "'lifetime_capture_by' attribute specifies no capturing entity">;
 def err_capture_by_implicit_this_not_available : Error<
   "'lifetime_capture_by' argument references unavailable implicit 'this'">;
-def err_capture_by_this_attr_without_implicit_this : Error<
-  "'lifetime_capture_by_this' attribute requires an implicit object 
parameter">;
 def err_capture_by_attribute_argument_unknown : Error<
   "'lifetime_capture_by' attribute argument %0 is not a known function 
parameter"
   "; must be a function parameter, 'this', 'global' or 'unknown'">;
 def err_capture_by_references_itself : Error<"'lifetime_capture_by' argument 
references itself">;
 def err_capture_by_param_uses_reserved_name : Error<
-  "parameter cannot be named '%0' while using 'lifetime_capture_by(%0)'">;
-def err_capture_by_attribute_multiple : Error<
-  "multiple '%0' attributes specified">;
-def warn_deprecated_capture_by_special_entity : Warning<
-  "'lifetime_capture_by(%0)' is deprecated; use '%1' instead">,
-  InGroup<DeprecatedAttributes>;
+  "parameter cannot be named '%select{global|unknown}0' while using 
'lifetime_capture_by(%select{global|unknown}0)'">;
 
 def err_init_method_bad_return_type : Error<
   "init methods must return an object pointer type, not %0">;
diff --git a/clang/lib/Sema/CheckExprLifetime.cpp 
b/clang/lib/Sema/CheckExprLifetime.cpp
index fafee76ec18c3..d15b2c6518cec 100644
--- a/clang/lib/Sema/CheckExprLifetime.cpp
+++ b/clang/lib/Sema/CheckExprLifetime.cpp
@@ -502,14 +502,12 @@ static void visitFunctionCallArguments(IndirectLocalPath 
&Path, Expr *Call,
     if (CheckCoroCall ||
         CanonCallee->getParamDecl(I)->hasAttr<LifetimeBoundAttr>())
       VisitLifetimeBoundArg(CanonCallee->getParamDecl(I), Arg);
-    else if (isa<CXXConstructorDecl>(CanonCallee) &&
-             llvm::any_of(CanonCallee->getParamDecl(I)
-                              ->specific_attrs<LifetimeCaptureByAttr>(),
-                          [](const LifetimeCaptureByAttr *CaptureAttr) {
-                            return llvm::is_contained(
-                                CaptureAttr->params(),
-                                LifetimeCaptureByAttr::This);
-                          }))
+    else if (const auto *CaptureAttr =
+                 
CanonCallee->getParamDecl(I)->getAttr<LifetimeCaptureByAttr>();
+             CaptureAttr && isa<CXXConstructorDecl>(CanonCallee) &&
+             llvm::any_of(CaptureAttr->params(), [](int ArgIdx) {
+               return ArgIdx == LifetimeCaptureByAttr::This;
+             }))
       // `lifetime_capture_by(this)` in a class constructor has the same
       // semantics as `lifetimebound`:
       //
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2a8395e26d0bd..79fec78f88c69 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -4405,9 +4405,8 @@ void Sema::checkLifetimeCaptureBy(FunctionDecl *FD, bool 
IsMemberFunction,
     }
   };
   for (unsigned I = 0; I < FD->getNumParams(); ++I)
-    for (const auto *A :
-         FD->getParamDecl(I)->specific_attrs<LifetimeCaptureByAttr>())
-      HandleCaptureByAttr(A, I + IsMemberFunction);
+    HandleCaptureByAttr(FD->getParamDecl(I)->getAttr<LifetimeCaptureByAttr>(),
+                        I + IsMemberFunction);
   // Check when the implicit object param is captured.
   if (IsMemberFunction) {
     TypeSourceInfo *TSI = FD->getTypeSourceInfo();
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 1b272b5416860..1300635921d5e 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -4411,41 +4411,17 @@ static void handleCallbackAttr(Sema &S, Decl *D, const 
ParsedAttr &AL) {
 
 LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
                                                         StringRef ParamName) {
-  StringRef AttrName = AL.getAttrName()->getName();
-  StringRef SpecialEntity;
-  if (AttrName == "lifetime_capture_by_this")
-    SpecialEntity = "this";
-  else if (AttrName == "lifetime_capture_by_global")
-    SpecialEntity = "global";
-  else if (AttrName == "lifetime_capture_by_unknown")
-    SpecialEntity = "unknown";
-
-  if (!SpecialEntity.empty() && AL.getNumArgs() != 0) {
-    Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << AL << 0;
-    return nullptr;
-  }
-
   // Atleast one capture by is required.
-  if (SpecialEntity.empty() && AL.getNumArgs() == 0) {
+  if (AL.getNumArgs() == 0) {
     Diag(AL.getLoc(), diag::err_capture_by_attribute_no_entity)
         << AL.getRange();
     return nullptr;
   }
-  unsigned N = SpecialEntity.empty() ? AL.getNumArgs() : 1;
+  unsigned N = AL.getNumArgs();
   auto ParamIdents =
       MutableArrayRef<IdentifierInfo *>(new (Context) IdentifierInfo *[N], N);
   auto ParamLocs =
       MutableArrayRef<SourceLocation>(new (Context) SourceLocation[N], N);
-  if (!SpecialEntity.empty()) {
-    ParamIdents[0] = &Context.Idents.get(SpecialEntity);
-    ParamLocs[0] = AL.getRange().getEnd();
-    int FakeParamIndices[] = {LifetimeCaptureByAttr::Invalid};
-    auto *CapturedBy =
-        LifetimeCaptureByAttr::Create(Context, FakeParamIndices, 1, AL);
-    CapturedBy->setArgs(ParamIdents, ParamLocs);
-    return CapturedBy;
-  }
-
   bool IsValid = true;
   for (unsigned I = 0; I < N; ++I) {
     if (AL.isArgExpr(I)) {
@@ -4457,17 +4433,6 @@ LifetimeCaptureByAttr 
*Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
     }
     assert(AL.isArgIdent(I));
     IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
-    StringRef Name = IdLoc->getIdentifierInfo()->getName();
-    StringRef Replacement;
-    if (Name == "this")
-      Replacement = "lifetime_capture_by_this";
-    else if (Name == "global")
-      Replacement = "lifetime_capture_by_global";
-    else if (Name == "unknown")
-      Replacement = "lifetime_capture_by_unknown";
-    if (!Replacement.empty())
-      Diag(IdLoc->getLoc(), diag::warn_deprecated_capture_by_special_entity)
-          << Name << Replacement << IdLoc->getLoc();
     if (IdLoc->getIdentifierInfo()->getName() == ParamName) {
       Diag(IdLoc->getLoc(), diag::err_capture_by_references_itself)
           << IdLoc->getLoc();
@@ -4488,53 +4453,24 @@ LifetimeCaptureByAttr 
*Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
 
 static void handleLifetimeCaptureByAttr(Sema &S, Decl *D,
                                         const ParsedAttr &AL) {
+  // Do not allow multiple attributes.
+  if (D->hasAttr<LifetimeCaptureByAttr>()) {
+    S.Diag(AL.getLoc(), diag::err_capture_by_attribute_multiple)
+        << AL.getRange();
+    return;
+  }
   auto *PVD = dyn_cast<ParmVarDecl>(D);
   assert(PVD);
   auto *CaptureByAttr = S.ParseLifetimeCaptureByAttr(AL, PVD->getName());
-  if (!CaptureByAttr)
-    return;
-
-  enum class SpellingKind { ParameterList, This, Global, Unknown };
-  auto GetSpellingKind = [](const LifetimeCaptureByAttr *A) {
-    if (A->isThis())
-      return SpellingKind::This;
-    if (A->isGlobal())
-      return SpellingKind::Global;
-    if (A->isUnknown())
-      return SpellingKind::Unknown;
-    return SpellingKind::ParameterList;
-  };
-  auto GetSpellingName = [](SpellingKind Kind) -> StringRef {
-    switch (Kind) {
-    case SpellingKind::ParameterList:
-      return "lifetime_capture_by";
-    case SpellingKind::This:
-      return "lifetime_capture_by_this";
-    case SpellingKind::Global:
-      return "lifetime_capture_by_global";
-    case SpellingKind::Unknown:
-      return "lifetime_capture_by_unknown";
-    }
-    llvm_unreachable("unknown lifetime_capture_by spelling kind");
-  };
-
-  SpellingKind NewKind = GetSpellingKind(CaptureByAttr);
-  for (const auto *Existing : D->specific_attrs<LifetimeCaptureByAttr>()) {
-    if (GetSpellingKind(Existing) == NewKind) {
-      S.Diag(AL.getLoc(), diag::err_capture_by_attribute_multiple)
-          << GetSpellingName(NewKind) << AL.getRange();
-      return;
-    }
-  }
-
-  D->addAttr(CaptureByAttr);
+  if (CaptureByAttr)
+    D->addAttr(CaptureByAttr);
 }
 
 void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
   bool HasImplicitThisParam = hasImplicitObjectParameter(FD);
   SmallVector<LifetimeCaptureByAttr *, 1> Attrs;
   for (ParmVarDecl *PVD : FD->parameters())
-    for (auto *A : PVD->specific_attrs<LifetimeCaptureByAttr>())
+    if (auto *A = PVD->getAttr<LifetimeCaptureByAttr>())
       Attrs.push_back(A);
   if (HasImplicitThisParam) {
     TypeSourceInfo *TSI = FD->getTypeSourceInfo();
@@ -4564,7 +4500,7 @@ void 
Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
     for (const ParmVarDecl *PVD : FD->parameters())
       if (PVD->getName() == Reserved)
         Diag(PVD->getLocation(), diag::err_capture_by_param_uses_reserved_name)
-            << PVD->getName();
+            << (PVD->getName() == "unknown");
   };
   for (auto *CapturedBy : Attrs) {
     const auto &Entities = CapturedBy->getArgIdents();
@@ -4573,19 +4509,14 @@ void 
Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
       auto It = NameIdxMapping.find(Name);
       if (It == NameIdxMapping.end()) {
         auto Loc = CapturedBy->getArgLocs()[I];
-        if (!HasImplicitThisParam && Name == "this") {
-          unsigned DiagID =
-              CapturedBy->isStandaloneSpecial()
-                  ? diag::err_capture_by_this_attr_without_implicit_this
-                  : diag::err_capture_by_implicit_this_not_available;
-          Diag(Loc, DiagID) << Loc;
-        } else
+        if (!HasImplicitThisParam && Name == "this")
+          Diag(Loc, diag::err_capture_by_implicit_this_not_available) << Loc;
+        else
           Diag(Loc, diag::err_capture_by_attribute_argument_unknown)
               << Entities[I] << Loc;
         continue;
       }
-      if ((Name == "unknown" || Name == "global") &&
-          !CapturedBy->isStandaloneSpecial())
+      if (Name == "unknown" || Name == "global")
         DisallowReservedParams(Name);
       CapturedBy->setParamIdx(I, It->second);
     }
diff --git a/clang/test/Sema/LifetimeSafety/capture-by.cpp 
b/clang/test/Sema/LifetimeSafety/capture-by.cpp
index e81669fe30782..2877d8d6cd5f9 100644
--- a/clang/test/Sema/LifetimeSafety/capture-by.cpp
+++ b/clang/test/Sema/LifetimeSafety/capture-by.cpp
@@ -85,18 +85,6 @@ void use() {
 }
 } // namespace capture_string_view
 
-namespace multiple_capture_by_attrs {
-struct X {} x1;
-void capture(std::string_view s [[clang::lifetime_capture_by(x1),
-                                  clang::lifetime_capture_by_global]],
-             X &x1);
-
-void use() {
-  capture(std::string(), // expected-warning {{object whose reference is 
captured by 'x1' will be destroyed at the end of the full-expression}} 
expected-warning {{object whose reference is captured will be destroyed at the 
end of the full-expression}}
-          x1);
-}
-} // namespace multiple_capture_by_attrs
-
 // ****************************************************************************
 // Capture pointer (eg: std::string*)
 // ****************************************************************************
@@ -157,7 +145,7 @@ void use() {
 
 namespace temporary_capturing_object {
 struct S {
-  void add(const int& x [[clang::lifetime_capture_by_this]]);
+  void add(const int& x [[clang::lifetime_capture_by(this)]]);
 };
 
 void test() {
@@ -173,8 +161,8 @@ void test() {
 // Capture by Global and Unknown.
 // ****************************************************************************
 namespace capture_by_global_unknown {
-void captureByGlobal(std::string_view s [[clang::lifetime_capture_by_global]]);
-void captureByUnknown(std::string_view s 
[[clang::lifetime_capture_by_unknown]]);
+void captureByGlobal(std::string_view s 
[[clang::lifetime_capture_by(global)]]);
+void captureByUnknown(std::string_view s 
[[clang::lifetime_capture_by(unknown)]]);
 
 std::string_view getLifetimeBoundView(const std::string& s 
[[clang::lifetimebound]]);
 
@@ -200,8 +188,8 @@ void use() {
 // ****************************************************************************
 namespace capture_by_this {
 struct S {
-  void captureInt(const int& x [[clang::lifetime_capture_by_this]]);
-  void captureView(std::string_view sv [[clang::lifetime_capture_by_this]]);
+  void captureInt(const int& x [[clang::lifetime_capture_by(this)]]);
+  void captureView(std::string_view sv [[clang::lifetime_capture_by(this)]]);
 };
 std::string_view getLifetimeBoundView(const std::string& s 
[[clang::lifetimebound]]);
 std::string_view getNotLifetimeBoundView(const std::string& s);
@@ -260,8 +248,8 @@ void useCaptureDefaultArg() {
 namespace containers_no_distinction {
 template<class T>
 struct MySet {
-  void insert(T&& t [[clang::lifetime_capture_by_this]]);
-  void insert(const T& t [[clang::lifetime_capture_by_this]]);
+  void insert(T&& t [[clang::lifetime_capture_by(this)]]);
+  void insert(const T& t [[clang::lifetime_capture_by(this)]]);
 };
 void user_defined_containers() {
   MySet<int> set_of_int;
@@ -281,8 +269,8 @@ template<> struct IsPointerLikeTypeImpl<std::string_view> : 
std::true_type {};
 template<typename T> concept IsPointerLikeType = std::is_pointer<T>::value || 
IsPointerLikeTypeImpl<T>::value;
 
 template<class T> struct MyVector {
-  void push_back(T&& t [[clang::lifetime_capture_by_this]]) requires 
IsPointerLikeType<T>;
-  void push_back(const T& t [[clang::lifetime_capture_by_this]]) requires 
IsPointerLikeType<T>;
+  void push_back(T&& t [[clang::lifetime_capture_by(this)]]) requires 
IsPointerLikeType<T>;
+  void push_back(const T& t [[clang::lifetime_capture_by(this)]]) requires 
IsPointerLikeType<T>;
 
   void push_back(T&& t) requires (!IsPointerLikeType<T>);
   void push_back(const T& t) requires (!IsPointerLikeType<T>);
@@ -440,13 +428,13 @@ void use() {
 
 namespace on_constructor {
 struct T {
-  T(const int& t [[clang::lifetime_capture_by_this]]);
+  T(const int& t [[clang::lifetime_capture_by(this)]]);
 };
 struct T2 {
   T2(const int& t [[clang::lifetime_capture_by(x)]], int& x);
 };
 struct T3 {
-  T3(const T& t [[clang::lifetime_capture_by_this]]);
+  T3(const T& t [[clang::lifetime_capture_by(this)]]);
 };
 
 int foo(const T& t);
diff --git a/clang/test/Sema/LifetimeSafety/safety.cpp 
b/clang/test/Sema/LifetimeSafety/safety.cpp
index 0776fcdf05773..3c9b58c4e4957 100644
--- a/clang/test/Sema/LifetimeSafety/safety.cpp
+++ b/clang/test/Sema/LifetimeSafety/safety.cpp
@@ -3978,7 +3978,7 @@ void test_reference_to_pointer() {
 
 struct [[gsl::Pointer]] MyContainer {
   View stored;
-  void set(View s [[clang::lifetime_capture_by_this]]);
+  void set(View s [[clang::lifetime_capture_by(this)]]);
 };
 
 void member_capture() {
@@ -3993,7 +3993,7 @@ void member_capture() {
 // FIXME: Add support for simple containers without annotations.
 struct SimpleContainer {
   View stored;
-  void set(View s [[clang::lifetime_capture_by_this]]);
+  void set(View s [[clang::lifetime_capture_by(this)]]);
 };
 
 void member_capture_simple_container() {
diff --git a/clang/test/SemaCXX/attr-lifetime-capture-by.cpp 
b/clang/test/SemaCXX/attr-lifetime-capture-by.cpp
index 0848cf98c160b..6b3726a88c8b5 100644
--- a/clang/test/SemaCXX/attr-lifetime-capture-by.cpp
+++ b/clang/test/SemaCXX/attr-lifetime-capture-by.cpp
@@ -2,7 +2,7 @@
 
 struct S {
   const int *x;
-  void captureInt(const int&x [[clang::lifetime_capture_by_this]]) { this->x = 
&x; }
+  void captureInt(const int&x [[clang::lifetime_capture_by(this)]]) { this->x 
= &x; }
 };
 
 ///////////////////////////
@@ -16,14 +16,12 @@ void nonMember(
     const int &x2 [[clang::lifetime_capture_by(12345 + 12)]], // 
expected-error {{'lifetime_capture_by' attribute argument '12345 + 12' is not a 
known function parameter; must be a function parameter, 'this', 'global' or 
'unknown'}}
     const int &x3 [[clang::lifetime_capture_by(abcdefgh)]],   // 
expected-error {{'lifetime_capture_by' attribute argument 'abcdefgh' is not a 
known function parameter; must be a function parameter, 'this', 'global' or 
'unknown'}}
     const int &x4 [[clang::lifetime_capture_by("abcdefgh")]], // 
expected-error {{'lifetime_capture_by' attribute argument '"abcdefgh"' is not a 
known function parameter; must be a function parameter, 'this', 'global' or 
'unknown'}}
-    const int &x5 [[clang::lifetime_capture_by_this]], // expected-error 
{{'lifetime_capture_by_this' attribute requires an implicit object parameter}}
+    const int &x5 [[clang::lifetime_capture_by(this)]], // expected-error 
{{'lifetime_capture_by' argument references unavailable implicit 'this'}}
     const int &x6 [[clang::lifetime_capture_by()]], // expected-error 
{{'lifetime_capture_by' attribute specifies no capturing entity}}
     const int& x7 [[clang::lifetime_capture_by(u,
-                                                x7)]], // expected-error 
{{'lifetime_capture_by' argument references itself}}
-    const int &x8 [[clang::lifetime_capture_by(global)]], // expected-warning 
{{'lifetime_capture_by(global)' is deprecated; use 'lifetime_capture_by_global' 
instead}}
-    const int &x9 [[clang::lifetime_capture_by(unknown)]], // expected-warning 
{{'lifetime_capture_by(unknown)' is deprecated; use 
'lifetime_capture_by_unknown' instead}}
-    const int &x10 [[clang::lifetime_capture_by_global(s)]], // expected-error 
{{'clang::lifetime_capture_by_global' attribute takes no arguments}}
-    const int &x11 [[clang::lifetime_capture_by(this)]],  // expected-error 
{{'lifetime_capture_by' argument references unavailable implicit 'this'}} // 
expected-warning {{'lifetime_capture_by(this)' is deprecated; use 
'lifetime_capture_by_this' instead}}
+                                               x7)]], // expected-error 
{{'lifetime_capture_by' argument references itself}}
+    const int &x8 [[clang::lifetime_capture_by(global)]],
+    const int &x9 [[clang::lifetime_capture_by(unknown)]],
     const int &test_memory_leak[[clang::lifetime_capture_by(x1,x2, x3, x4, x5, 
x6, x7, x8, x9)]],
     const S& u
   )
@@ -32,9 +30,9 @@ void nonMember(
 }
 
 void unknown_param_name(const int& unknown, // expected-error {{parameter 
cannot be named 'unknown' while using 'lifetime_capture_by(unknown)'}}
-                        const int& s [[clang::lifetime_capture_by(unknown)]]); 
// expected-warning {{'lifetime_capture_by(unknown)' is deprecated; use 
'lifetime_capture_by_unknown' instead}}
+                        const int& s [[clang::lifetime_capture_by(unknown)]]);
 void global_param_name(const int& global, // expected-error {{parameter cannot 
be named 'global' while using 'lifetime_capture_by(global)'}}
-                       const int& s [[clang::lifetime_capture_by(global)]]); 
// expected-warning {{'lifetime_capture_by(global)' is deprecated; use 
'lifetime_capture_by_global' instead}}
+                       const int& s [[clang::lifetime_capture_by(global)]]);
 void no_such_param(int i [[clang::lifetime_capture_by(no_such_param)]]); // 
expected-error {{'lifetime_capture_by' attribute argument 'no_such_param' is 
not a known function parameter; must be a function parameter, 'this', 'global' 
or 'unknown'}}
 void use_no_such_param() { no_such_param(0); }
 struct T {
@@ -43,42 +41,12 @@ struct T {
     S &s,
     S &t,
     const int &y [[clang::lifetime_capture_by(s)]],
-    const int &z [[clang::lifetime_capture_by(x, y), 
clang::lifetime_capture_by_this]],
-    const int &u [[clang::lifetime_capture_by(global, unknown, x, s)]]) // 
expected-warning 2 {{deprecated}}
+    const int &z [[clang::lifetime_capture_by(this, x, y)]],
+    const int &u [[clang::lifetime_capture_by(global, unknown, x, s)]])
   {
     s.captureInt(x);
   }
 
   void explicit_this1(this T& self, const int &x 
[[clang::lifetime_capture_by(self)]]);
-  void explicit_this2(this T& self, const int &x 
[[clang::lifetime_capture_by(this)]]); // expected-warning 
{{'lifetime_capture_by(this)' is deprecated; use 'lifetime_capture_by_this' 
instead}} expected-error {{argument references unavailable implicit 'this'}}
-};
-
-void duplicate_parameter_list(
-    const int &x [[clang::lifetime_capture_by(s),
-                  clang::lifetime_capture_by(t)]], // expected-error 
{{multiple 'lifetime_capture_by' attributes specified}}
-    S &s, S &t);
-
-void duplicate_global(
-    const int &x [[clang::lifetime_capture_by_global,
-                  clang::lifetime_capture_by_global]]); // expected-error 
{{multiple 'lifetime_capture_by_global' attributes specified}}
-
-void duplicate_unknown(
-    const int &x [[clang::lifetime_capture_by_unknown,
-                  clang::lifetime_capture_by_unknown]]); // expected-error 
{{multiple 'lifetime_capture_by_unknown' attributes specified}}
-
-struct U {
-  void duplicate_this(
-      const int &x [[clang::lifetime_capture_by_this,
-                    clang::lifetime_capture_by_this]]); // expected-error 
{{multiple 'lifetime_capture_by_this' attributes specified}}
-
-  void different_spellings(
-      const int &x [[clang::lifetime_capture_by(s),
-                    clang::lifetime_capture_by_this,
-                    clang::lifetime_capture_by_global,
-                    clang::lifetime_capture_by_unknown]],
-      S &s);
-
-  void deprecated_this_spelling_is_distinct(
-      const int &x [[clang::lifetime_capture_by(this), // expected-warning 
{{'lifetime_capture_by(this)' is deprecated; use 'lifetime_capture_by_this' 
instead}}
-                    clang::lifetime_capture_by_this]]);
+  void explicit_this2(this T& self, const int &x 
[[clang::lifetime_capture_by(this)]]); // expected-error {{argument references 
unavailable implicit 'this'}}
 };

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to