6565#include " llvm/ADT/StringExtras.h"
6666#include " llvm/Demangle/Demangle.h"
6767#include " llvm/IR/Assumptions.h"
68+ #include " llvm/IR/DerivedTypes.h"
6869#include " llvm/MC/MCSectionMachO.h"
6970#include " llvm/Support/Error.h"
7071#include " llvm/Support/MathExtras.h"
@@ -3876,33 +3877,38 @@ LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
38763877 << AL.getRange ();
38773878 return nullptr ;
38783879 }
3879- SmallVector<IdentifierInfo *, 1 > ParamIdents;
3880- SmallVector<SourceLocation, 1 > ParamLocs;
3881- for (unsigned I = 0 ; I < AL.getNumArgs (); ++I) {
3880+ unsigned N = AL.getNumArgs ();
3881+ IdentifierInfo **ParamIdents = new (Context) IdentifierInfo *[N];
3882+ SourceLocation *ParamLocs = new (Context) SourceLocation[N];
3883+ bool IsValid = true ;
3884+ for (unsigned I = 0 ; I < N; ++I) {
38823885 if (AL.isArgExpr (I)) {
38833886 Expr *E = AL.getArgAsExpr (I);
38843887 Diag (E->getExprLoc (), diag::err_capture_by_attribute_argument_unknown)
38853888 << E << E->getExprLoc ();
3889+ IsValid = false ;
38863890 continue ;
38873891 }
38883892 assert (AL.isArgIdent (I));
38893893 IdentifierLoc *IdLoc = AL.getArgAsIdent (I);
38903894 if (IdLoc->Ident ->getName () == ParamName) {
38913895 Diag (IdLoc->Loc , diag::err_capture_by_references_itself) << IdLoc->Loc ;
3896+ IsValid = false ;
38923897 continue ;
38933898 }
3894- ParamIdents. push_back ( IdLoc->Ident ) ;
3895- ParamLocs. push_back ( IdLoc->Loc ) ;
3899+ ParamIdents[I] = IdLoc->Ident ;
3900+ ParamLocs[I] = IdLoc->Loc ;
38963901 }
3897- SmallVector<int , 1 > FakeParamIndices (ParamIdents.size (),
3898- LifetimeCaptureByAttr::INVALID);
3902+ if (!IsValid)
3903+ return nullptr ;
3904+ SmallVector<int > FakeParamIndices (N, LifetimeCaptureByAttr::INVALID);
38993905 LifetimeCaptureByAttr *CapturedBy = ::new (Context) LifetimeCaptureByAttr (
39003906 Context, AL, FakeParamIndices.data (), FakeParamIndices.size ());
3901- CapturedBy->setArgs (std::move ( ParamIdents), std::move ( ParamLocs) );
3907+ CapturedBy->setArgs (ParamIdents, ParamLocs);
39023908 return CapturedBy;
39033909}
39043910
3905- static void HandleLifetimeCaptureByAttr (Sema &S, Decl *D,
3911+ static void handleLifetimeCaptureByAttr (Sema &S, Decl *D,
39063912 const ParsedAttr &AL) {
39073913 // Do not allow multiple attributes.
39083914 if (D->hasAttr <LifetimeCaptureByAttr>()) {
@@ -3919,10 +3925,27 @@ static void HandleLifetimeCaptureByAttr(Sema &S, Decl *D,
39193925
39203926void Sema::LazyProcessLifetimeCaptureByParams (FunctionDecl *FD) {
39213927 bool HasImplicitThisParam = isInstanceMethod (FD);
3922-
3923- llvm::StringMap<int > NameIdxMapping;
3924- NameIdxMapping[" global" ] = LifetimeCaptureByAttr::GLOBAL;
3925- NameIdxMapping[" unknown" ] = LifetimeCaptureByAttr::UNKNOWN;
3928+ SmallVector<LifetimeCaptureByAttr *, 1 > Attrs;
3929+ for (ParmVarDecl *PVD : FD->parameters ())
3930+ if (auto *A = PVD->getAttr <LifetimeCaptureByAttr>())
3931+ Attrs.push_back (A);
3932+ if (HasImplicitThisParam) {
3933+ TypeSourceInfo *TSI = FD->getTypeSourceInfo ();
3934+ if (!TSI)
3935+ return ;
3936+ AttributedTypeLoc ATL;
3937+ for (TypeLoc TL = TSI->getTypeLoc ();
3938+ (ATL = TL.getAsAdjusted <AttributedTypeLoc>());
3939+ TL = ATL.getModifiedLoc ()) {
3940+ if (auto *A = ATL.getAttrAs <LifetimeCaptureByAttr>())
3941+ Attrs.push_back (const_cast <LifetimeCaptureByAttr *>(A));
3942+ }
3943+ }
3944+ if (Attrs.empty ())
3945+ return ;
3946+ llvm::StringMap<int > NameIdxMapping = {
3947+ {" global" , LifetimeCaptureByAttr::GLOBAL},
3948+ {" unknown" , LifetimeCaptureByAttr::UNKNOWN}};
39263949 int Idx = 0 ;
39273950 if (HasImplicitThisParam) {
39283951 NameIdxMapping[" this" ] = 0 ;
@@ -3936,9 +3959,7 @@ void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
39363959 Diag (PVD->getLocation (), diag::err_capture_by_param_uses_reserved_name)
39373960 << (PVD->getName () == " unknown" );
39383961 };
3939- auto HandleCaptureBy = [&](LifetimeCaptureByAttr *CapturedBy) {
3940- if (!CapturedBy)
3941- return ;
3962+ for (auto *CapturedBy : Attrs) {
39423963 const auto &Entities = CapturedBy->getArgIdents ();
39433964 for (size_t I = 0 ; I < Entities.size (); ++I) {
39443965 StringRef Name = Entities[I]->getName ();
@@ -3956,22 +3977,6 @@ void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
39563977 DisallowReservedParams (Name);
39573978 CapturedBy->setParamIdx (I, It->second );
39583979 }
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));
39753980 }
39763981}
39773982
@@ -6753,7 +6758,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
67536758 handleCallbackAttr (S, D, AL);
67546759 break ;
67556760 case ParsedAttr::AT_LifetimeCaptureBy:
6756- HandleLifetimeCaptureByAttr (S, D, AL);
6761+ handleLifetimeCaptureByAttr (S, D, AL);
67576762 break ;
67586763 case ParsedAttr::AT_CalledOnce:
67596764 handleCalledOnceAttr (S, D, AL);
0 commit comments