Skip to content

Commit 3a03513

Browse files
committed
Revert "[clang] Introduce [[clang::lifetime_capture_by(X)]] (#111499)"
This reverts commit 8c4331c. Causes a large compile-time regression, see: https://llvm-compile-time-tracker.com/compare.php?from=4a68e4cbd2423dcacada8162ab7c4bb8d7f7e2cf&to=8c4331c1abeb33eabf3cdbefa7f2b6e0540e7f4f&stat=instructions:u
1 parent 582a479 commit 3a03513

11 files changed

+0
-322
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -449,9 +449,6 @@ Attribute Changes in Clang
449449
- Fix a bug where clang doesn't automatically apply the ``[[gsl::Owner]]`` or
450450
``[[gsl::Pointer]]`` to STL explicit template specialization decls. (#GH109442)
451451

452-
- Clang now supports ``[[clang::lifetime_capture_by(X)]]``. Similar to lifetimebound, this can be
453-
used to specify when a reference to a function parameter is captured by another capturing entity ``X``.
454-
455452
Improvements to Clang's diagnostics
456453
-----------------------------------
457454

clang/include/clang/Basic/Attr.td

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,39 +1889,6 @@ def LifetimeBound : DeclOrTypeAttr {
18891889
let SimpleHandler = 1;
18901890
}
18911891

1892-
def LifetimeCaptureBy : DeclOrTypeAttr {
1893-
let Spellings = [Clang<"lifetime_capture_by", 0>];
1894-
let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>;
1895-
let Args = [VariadicParamOrParamIdxArgument<"Params">];
1896-
let Documentation = [LifetimeCaptureByDocs];
1897-
let AdditionalMembers = [{
1898-
private:
1899-
SmallVector<IdentifierInfo*, 1> ArgIdents;
1900-
SmallVector<SourceLocation, 1> ArgLocs;
1901-
1902-
public:
1903-
static constexpr int THIS = 0;
1904-
static constexpr int INVALID = -1;
1905-
static constexpr int UNKNOWN = -2;
1906-
static constexpr int GLOBAL = -3;
1907-
1908-
void setArgs(SmallVector<IdentifierInfo*>&& Idents,
1909-
SmallVector<SourceLocation>&& Locs) {
1910-
assert(Idents.size() == Locs.size());
1911-
assert(Idents.size() == params_Size);
1912-
ArgIdents = std::move(Idents);
1913-
ArgLocs = std::move(Locs);
1914-
}
1915-
1916-
ArrayRef<IdentifierInfo*> getArgIdents() const { return ArgIdents; }
1917-
ArrayRef<SourceLocation> getArgLocs() const { return ArgLocs; }
1918-
void setParamIdx(size_t Idx, int Val) {
1919-
assert(Idx < params_Size);
1920-
params_[Idx] = Val;
1921-
}
1922-
}];
1923-
}
1924-
19251892
def TrivialABI : InheritableAttr {
19261893
// This attribute does not have a C [[]] spelling because it requires the
19271894
// CPlusPlus language option.

clang/include/clang/Basic/AttrDocs.td

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -3918,75 +3918,6 @@ have their lifetimes extended.
39183918
}];
39193919
}
39203920

3921-
def LifetimeCaptureByDocs : Documentation {
3922-
let Category = DocCatFunction;
3923-
let Content = [{
3924-
Similar to `lifetimebound`_, the ``lifetime_capture_by(X)`` attribute on a function
3925-
parameter or implicit object parameter indicates that that objects that are referred to
3926-
by that parameter may also be referred to by the capturing entity ``X``.
3927-
3928-
By default, a reference is considered to refer to its referenced object, a
3929-
pointer is considered to refer to its pointee, a ``std::initializer_list<T>``
3930-
is considered to refer to its underlying array, and aggregates (arrays and
3931-
simple ``struct``\s) are considered to refer to all objects that their
3932-
transitive subobjects refer to.
3933-
3934-
The capturing entity ``X`` can be one of the following:
3935-
- Another (named) function parameter.
3936-
3937-
.. code-block:: c++
3938-
3939-
void addToSet(std::string_view a [[clang::lifetime_capture_by(s)]], std::set<std::string_view>& s) {
3940-
s.insert(a);
3941-
}
3942-
3943-
- ``this`` (in case of member functions).
3944-
3945-
.. code-block:: c++
3946-
3947-
class S {
3948-
void addToSet(std::string_view a [[clang::lifetime_capture_by(this)]]) {
3949-
s.insert(a);
3950-
}
3951-
std::set<std::string_view> s;
3952-
};
3953-
3954-
- 'global', 'unknown' (without quotes).
3955-
3956-
.. code-block:: c++
3957-
3958-
std::set<std::string_view> s;
3959-
void addToSet(std::string_view a [[clang::lifetime_capture_by(global)]]) {
3960-
s.insert(a);
3961-
}
3962-
void addSomewhere(std::string_view a [[clang::lifetime_capture_by(unknown)]]);
3963-
3964-
The attribute can be applied to the implicit ``this`` parameter of a member
3965-
function by writing the attribute after the function type:
3966-
3967-
.. code-block:: c++
3968-
3969-
struct S {
3970-
const char *data(std::set<S*>& s) [[clang::lifetime_capture_by(s)]] {
3971-
s.insert(this);
3972-
}
3973-
};
3974-
3975-
The attribute supports specifying more than one capturing entities:
3976-
3977-
.. code-block:: c++
3978-
3979-
void addToSets(std::string_view a [[clang::lifetime_capture_by(s1, s2)]],
3980-
std::set<std::string_view>& s1,
3981-
std::set<std::string_view>& s2) {
3982-
s1.insert(a);
3983-
s2.insert(a);
3984-
}
3985-
3986-
.. _`lifetimebound`: https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
3987-
}];
3988-
}
3989-
39903921
def TrivialABIDocs : Documentation {
39913922
let Category = DocCatDecl;
39923923
let Content = [{

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3383,20 +3383,6 @@ def err_callback_callee_is_variadic : Error<
33833383
"'callback' attribute callee may not be variadic">;
33843384
def err_callback_implicit_this_not_available : Error<
33853385
"'callback' argument at position %0 references unavailable implicit 'this'">;
3386-
3387-
def err_capture_by_attribute_multiple : Error<
3388-
"multiple 'lifetime_capture' attributes specified">;
3389-
def err_capture_by_attribute_no_entity : Error<
3390-
"'lifetime_capture_by' attribute specifies no capturing entity">;
3391-
def err_capture_by_implicit_this_not_available : Error<
3392-
"'lifetime_capture_by' argument references unavailable implicit 'this'">;
3393-
def err_capture_by_attribute_argument_unknown : Error<
3394-
"'lifetime_capture_by' attribute argument %0 is not a known function parameter"
3395-
"; must be a function parameter, 'this', 'global' or 'unknown'">;
3396-
def err_capture_by_references_itself : Error<"'lifetime_capture_by' argument references itself">;
3397-
def err_capture_by_param_uses_reserved_name : Error<
3398-
"parameter cannot be named '%select{global|unknown}0' while using 'lifetime_capture_by(%select{global|unknown}0)'">;
3399-
34003386
def err_init_method_bad_return_type : Error<
34013387
"init methods must return an object pointer type, not %0">;
34023388
def err_attribute_invalid_size : Error<

clang/include/clang/Sema/Sema.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,14 +1760,6 @@ class Sema final : public SemaBase {
17601760
/// Add [[gsl::Pointer]] attributes for std:: types.
17611761
void inferGslPointerAttribute(TypedefNameDecl *TD);
17621762

1763-
LifetimeCaptureByAttr *ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
1764-
StringRef ParamName);
1765-
// Processes the argument 'X' in [[clang::lifetime_capture_by(X)]]. Since 'X'
1766-
// can be the name of a function parameter, we need to parse the function
1767-
// declaration and rest of the parameters before processesing 'X'. Therefore
1768-
// do this lazily instead of processing while parsing the annotation itself.
1769-
void LazyProcessLifetimeCaptureByParams(FunctionDecl *FD);
1770-
17711763
/// Add _Nullable attributes for std:: types.
17721764
void inferNullableClassAttribute(CXXRecordDecl *CRD);
17731765

clang/lib/AST/TypePrinter.cpp

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "clang/AST/TextNodeDumper.h"
2626
#include "clang/AST/Type.h"
2727
#include "clang/Basic/AddressSpaces.h"
28-
#include "clang/Basic/AttrKinds.h"
2928
#include "clang/Basic/ExceptionSpecificationType.h"
3029
#include "clang/Basic/IdentifierTable.h"
3130
#include "clang/Basic/LLVM.h"
@@ -1910,19 +1909,6 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
19101909
OS << " [[clang::lifetimebound]]";
19111910
return;
19121911
}
1913-
if (T->getAttrKind() == attr::LifetimeCaptureBy) {
1914-
OS << " [[clang::lifetime_capture_by(";
1915-
if (auto *attr = dyn_cast_or_null<LifetimeCaptureByAttr>(T->getAttr())) {
1916-
auto Idents = attr->getArgIdents();
1917-
for (unsigned I = 0; I < Idents.size(); ++I) {
1918-
OS << Idents[I]->getName();
1919-
if (I != Idents.size() - 1)
1920-
OS << ", ";
1921-
}
1922-
}
1923-
OS << ")]]";
1924-
return;
1925-
}
19261912

19271913
// The printing of the address_space attribute is handled by the qualifier
19281914
// since it is still stored in the qualifier. Return early to prevent printing
@@ -1990,7 +1976,6 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
19901976
case attr::SizedBy:
19911977
case attr::SizedByOrNull:
19921978
case attr::LifetimeBound:
1993-
case attr::LifetimeCaptureBy:
19941979
case attr::TypeNonNull:
19951980
case attr::TypeNullable:
19961981
case attr::TypeNullableResult:

clang/lib/Sema/SemaDecl.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16687,7 +16687,6 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
1668716687
}
1668816688
}
1668916689

16690-
LazyProcessLifetimeCaptureByParams(FD);
1669116690
inferLifetimeBoundAttribute(FD);
1669216691
AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction(FD);
1669316692

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "clang/AST/ASTContext.h"
1515
#include "clang/AST/ASTMutationListener.h"
1616
#include "clang/AST/CXXInheritance.h"
17-
#include "clang/AST/Decl.h"
1817
#include "clang/AST/DeclCXX.h"
1918
#include "clang/AST/DeclObjC.h"
2019
#include "clang/AST/DeclTemplate.h"
@@ -3868,113 +3867,6 @@ static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
38683867
S.Context, AL, EncodingIndices.data(), EncodingIndices.size()));
38693868
}
38703869

3871-
LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
3872-
StringRef ParamName) {
3873-
// Atleast one capture by is required.
3874-
if (AL.getNumArgs() == 0) {
3875-
Diag(AL.getLoc(), diag::err_capture_by_attribute_no_entity)
3876-
<< AL.getRange();
3877-
return nullptr;
3878-
}
3879-
SmallVector<IdentifierInfo *, 1> ParamIdents;
3880-
SmallVector<SourceLocation, 1> ParamLocs;
3881-
for (unsigned I = 0; I < AL.getNumArgs(); ++I) {
3882-
if (AL.isArgExpr(I)) {
3883-
Expr *E = AL.getArgAsExpr(I);
3884-
Diag(E->getExprLoc(), diag::err_capture_by_attribute_argument_unknown)
3885-
<< E << E->getExprLoc();
3886-
continue;
3887-
}
3888-
assert(AL.isArgIdent(I));
3889-
IdentifierLoc *IdLoc = AL.getArgAsIdent(I);
3890-
if (IdLoc->Ident->getName() == ParamName) {
3891-
Diag(IdLoc->Loc, diag::err_capture_by_references_itself) << IdLoc->Loc;
3892-
continue;
3893-
}
3894-
ParamIdents.push_back(IdLoc->Ident);
3895-
ParamLocs.push_back(IdLoc->Loc);
3896-
}
3897-
SmallVector<int, 1> FakeParamIndices(ParamIdents.size(),
3898-
LifetimeCaptureByAttr::INVALID);
3899-
LifetimeCaptureByAttr *CapturedBy = ::new (Context) LifetimeCaptureByAttr(
3900-
Context, AL, FakeParamIndices.data(), FakeParamIndices.size());
3901-
CapturedBy->setArgs(std::move(ParamIdents), std::move(ParamLocs));
3902-
return CapturedBy;
3903-
}
3904-
3905-
static void HandleLifetimeCaptureByAttr(Sema &S, Decl *D,
3906-
const ParsedAttr &AL) {
3907-
// Do not allow multiple attributes.
3908-
if (D->hasAttr<LifetimeCaptureByAttr>()) {
3909-
S.Diag(AL.getLoc(), diag::err_capture_by_attribute_multiple)
3910-
<< AL.getRange();
3911-
return;
3912-
}
3913-
auto *PVD = dyn_cast<ParmVarDecl>(D);
3914-
assert(PVD);
3915-
auto *CaptureByAttr = S.ParseLifetimeCaptureByAttr(AL, PVD->getName());
3916-
if (CaptureByAttr)
3917-
D->addAttr(CaptureByAttr);
3918-
}
3919-
3920-
void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
3921-
bool HasImplicitThisParam = isInstanceMethod(FD);
3922-
3923-
llvm::StringMap<int> NameIdxMapping;
3924-
NameIdxMapping["global"] = LifetimeCaptureByAttr::GLOBAL;
3925-
NameIdxMapping["unknown"] = LifetimeCaptureByAttr::UNKNOWN;
3926-
int Idx = 0;
3927-
if (HasImplicitThisParam) {
3928-
NameIdxMapping["this"] = 0;
3929-
Idx++;
3930-
}
3931-
for (const ParmVarDecl *PVD : FD->parameters())
3932-
NameIdxMapping[PVD->getName()] = Idx++;
3933-
auto DisallowReservedParams = [&](StringRef Reserved) {
3934-
for (const ParmVarDecl *PVD : FD->parameters())
3935-
if (PVD->getName() == Reserved)
3936-
Diag(PVD->getLocation(), diag::err_capture_by_param_uses_reserved_name)
3937-
<< (PVD->getName() == "unknown");
3938-
};
3939-
auto HandleCaptureBy = [&](LifetimeCaptureByAttr *CapturedBy) {
3940-
if (!CapturedBy)
3941-
return;
3942-
const auto &Entities = CapturedBy->getArgIdents();
3943-
for (size_t I = 0; I < Entities.size(); ++I) {
3944-
StringRef Name = Entities[I]->getName();
3945-
auto It = NameIdxMapping.find(Name);
3946-
if (It == NameIdxMapping.end()) {
3947-
auto Loc = CapturedBy->getArgLocs()[I];
3948-
if (!HasImplicitThisParam && Name == "this")
3949-
Diag(Loc, diag::err_capture_by_implicit_this_not_available) << Loc;
3950-
else
3951-
Diag(Loc, diag::err_capture_by_attribute_argument_unknown)
3952-
<< Entities[I] << Loc;
3953-
continue;
3954-
}
3955-
if (Name == "unknown" || Name == "global")
3956-
DisallowReservedParams(Name);
3957-
CapturedBy->setParamIdx(I, It->second);
3958-
}
3959-
};
3960-
for (ParmVarDecl *PVD : FD->parameters())
3961-
HandleCaptureBy(PVD->getAttr<LifetimeCaptureByAttr>());
3962-
if (!HasImplicitThisParam)
3963-
return;
3964-
TypeSourceInfo *TSI = FD->getTypeSourceInfo();
3965-
if (!TSI)
3966-
return;
3967-
AttributedTypeLoc ATL;
3968-
for (TypeLoc TL = TSI->getTypeLoc();
3969-
(ATL = TL.getAsAdjusted<AttributedTypeLoc>());
3970-
TL = ATL.getModifiedLoc()) {
3971-
auto *A = ATL.getAttrAs<LifetimeCaptureByAttr>();
3972-
if (!A)
3973-
continue;
3974-
HandleCaptureBy(const_cast<LifetimeCaptureByAttr *>(A));
3975-
}
3976-
}
3977-
39783870
static bool isFunctionLike(const Type &T) {
39793871
// Check for explicit function types.
39803872
// 'called_once' is only supported in Objective-C and it has
@@ -6752,9 +6644,6 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
67526644
case ParsedAttr::AT_Callback:
67536645
handleCallbackAttr(S, D, AL);
67546646
break;
6755-
case ParsedAttr::AT_LifetimeCaptureBy:
6756-
HandleLifetimeCaptureByAttr(S, D, AL);
6757-
break;
67586647
case ParsedAttr::AT_CalledOnce:
67596648
handleCalledOnceAttr(S, D, AL);
67606649
break;

clang/lib/Sema/SemaType.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8609,15 +8609,6 @@ static void HandleLifetimeBoundAttr(TypeProcessingState &State,
86098609
}
86108610
}
86118611

8612-
static void HandleLifetimeCaptureByAttr(TypeProcessingState &State,
8613-
QualType &CurType, ParsedAttr &PA) {
8614-
if (State.getDeclarator().isDeclarationOfFunction()) {
8615-
auto *Attr = State.getSema().ParseLifetimeCaptureByAttr(PA, "this");
8616-
if (Attr)
8617-
CurType = State.getAttributedType(Attr, CurType, CurType);
8618-
}
8619-
}
8620-
86218612
static void HandleHLSLParamModifierAttr(TypeProcessingState &State,
86228613
QualType &CurType,
86238614
const ParsedAttr &Attr, Sema &S) {
@@ -8779,10 +8770,6 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
87798770
if (TAL == TAL_DeclChunk)
87808771
HandleLifetimeBoundAttr(state, type, attr);
87818772
break;
8782-
case ParsedAttr::AT_LifetimeCaptureBy:
8783-
if (TAL == TAL_DeclChunk)
8784-
HandleLifetimeCaptureByAttr(state, type, attr);
8785-
break;
87868773

87878774
case ParsedAttr::AT_NoDeref: {
87888775
// FIXME: `noderef` currently doesn't work correctly in [[]] syntax.

clang/test/AST/attr-lifetime-capture-by.cpp

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)