65
65
#include " llvm/ADT/StringExtras.h"
66
66
#include " llvm/Demangle/Demangle.h"
67
67
#include " llvm/IR/Assumptions.h"
68
+ #include " llvm/IR/DerivedTypes.h"
68
69
#include " llvm/MC/MCSectionMachO.h"
69
70
#include " llvm/Support/Error.h"
70
71
#include " llvm/Support/MathExtras.h"
@@ -3876,33 +3877,38 @@ LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL,
3876
3877
<< AL.getRange ();
3877
3878
return nullptr ;
3878
3879
}
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) {
3882
3885
if (AL.isArgExpr (I)) {
3883
3886
Expr *E = AL.getArgAsExpr (I);
3884
3887
Diag (E->getExprLoc (), diag::err_capture_by_attribute_argument_unknown)
3885
3888
<< E << E->getExprLoc ();
3889
+ IsValid = false ;
3886
3890
continue ;
3887
3891
}
3888
3892
assert (AL.isArgIdent (I));
3889
3893
IdentifierLoc *IdLoc = AL.getArgAsIdent (I);
3890
3894
if (IdLoc->Ident ->getName () == ParamName) {
3891
3895
Diag (IdLoc->Loc , diag::err_capture_by_references_itself) << IdLoc->Loc ;
3896
+ IsValid = false ;
3892
3897
continue ;
3893
3898
}
3894
- ParamIdents. push_back ( IdLoc->Ident ) ;
3895
- ParamLocs. push_back ( IdLoc->Loc ) ;
3899
+ ParamIdents[I] = IdLoc->Ident ;
3900
+ ParamLocs[I] = IdLoc->Loc ;
3896
3901
}
3897
- SmallVector<int , 1 > FakeParamIndices (ParamIdents.size (),
3898
- LifetimeCaptureByAttr::INVALID);
3902
+ if (!IsValid)
3903
+ return nullptr ;
3904
+ SmallVector<int > FakeParamIndices (N, LifetimeCaptureByAttr::INVALID);
3899
3905
LifetimeCaptureByAttr *CapturedBy = ::new (Context) LifetimeCaptureByAttr (
3900
3906
Context, AL, FakeParamIndices.data (), FakeParamIndices.size ());
3901
- CapturedBy->setArgs (std::move ( ParamIdents), std::move ( ParamLocs) );
3907
+ CapturedBy->setArgs (ParamIdents, ParamLocs);
3902
3908
return CapturedBy;
3903
3909
}
3904
3910
3905
- static void HandleLifetimeCaptureByAttr (Sema &S, Decl *D,
3911
+ static void handleLifetimeCaptureByAttr (Sema &S, Decl *D,
3906
3912
const ParsedAttr &AL) {
3907
3913
// Do not allow multiple attributes.
3908
3914
if (D->hasAttr <LifetimeCaptureByAttr>()) {
@@ -3919,10 +3925,27 @@ static void HandleLifetimeCaptureByAttr(Sema &S, Decl *D,
3919
3925
3920
3926
void Sema::LazyProcessLifetimeCaptureByParams (FunctionDecl *FD) {
3921
3927
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}};
3926
3949
int Idx = 0 ;
3927
3950
if (HasImplicitThisParam) {
3928
3951
NameIdxMapping[" this" ] = 0 ;
@@ -3936,9 +3959,7 @@ void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
3936
3959
Diag (PVD->getLocation (), diag::err_capture_by_param_uses_reserved_name)
3937
3960
<< (PVD->getName () == " unknown" );
3938
3961
};
3939
- auto HandleCaptureBy = [&](LifetimeCaptureByAttr *CapturedBy) {
3940
- if (!CapturedBy)
3941
- return ;
3962
+ for (auto *CapturedBy : Attrs) {
3942
3963
const auto &Entities = CapturedBy->getArgIdents ();
3943
3964
for (size_t I = 0 ; I < Entities.size (); ++I) {
3944
3965
StringRef Name = Entities[I]->getName ();
@@ -3956,22 +3977,6 @@ void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) {
3956
3977
DisallowReservedParams (Name);
3957
3978
CapturedBy->setParamIdx (I, It->second );
3958
3979
}
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
3980
}
3976
3981
}
3977
3982
@@ -6753,7 +6758,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
6753
6758
handleCallbackAttr (S, D, AL);
6754
6759
break ;
6755
6760
case ParsedAttr::AT_LifetimeCaptureBy:
6756
- HandleLifetimeCaptureByAttr (S, D, AL);
6761
+ handleLifetimeCaptureByAttr (S, D, AL);
6757
6762
break ;
6758
6763
case ParsedAttr::AT_CalledOnce:
6759
6764
handleCalledOnceAttr (S, D, AL);
0 commit comments