================ @@ -3867,6 +3868,112 @@ 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; + } + SmallVector<IdentifierInfo *> ParamIdents; + SmallVector<SourceLocation> ParamLocs; + for (unsigned I = 0; I < AL.getNumArgs(); ++I) { + if (AL.isArgExpr(I)) { + Expr *E = AL.getArgAsExpr(I); + Diag(E->getExprLoc(), diag::err_capture_by_attribute_argument_unknown) + << E << E->getExprLoc(); + 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; + continue; + } + ParamIdents.push_back(IdLoc->Ident); + ParamLocs.push_back(IdLoc->Loc); + } + SmallVector<int> FakeParamIndices(ParamIdents.size(), + LifetimeCaptureByAttr::INVALID); + LifetimeCaptureByAttr *CapturedBy = ::new (Context) LifetimeCaptureByAttr( + Context, AL, FakeParamIndices.data(), FakeParamIndices.size()); + CapturedBy->setArgs(std::move(ParamIdents), std::move(ParamLocs)); + return CapturedBy; +} + +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) + D->addAttr(CaptureByAttr); +} + +void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) { + bool HasImplicitThisParam = isInstanceMethod(FD); + SmallVector<LifetimeCaptureByAttr *, 1> Attrs; + for (ParmVarDecl *PVD : FD->parameters()) + if (auto *A = PVD->getAttr<LifetimeCaptureByAttr>()) + Attrs.push_back(A); + if (HasImplicitThisParam) { + TypeSourceInfo *TSI = FD->getTypeSourceInfo(); + if (!TSI) + return; + AttributedTypeLoc ATL; + for (TypeLoc TL = TSI->getTypeLoc(); + (ATL = TL.getAsAdjusted<AttributedTypeLoc>()); + TL = ATL.getModifiedLoc()) { + if (auto *A = ATL.getAttrAs<LifetimeCaptureByAttr>()) + Attrs.push_back(const_cast<LifetimeCaptureByAttr *>(A)); + } + } + if (Attrs.empty()) + return; + llvm::StringMap<int> NameIdxMapping; + NameIdxMapping["global"] = LifetimeCaptureByAttr::GLOBAL; + NameIdxMapping["unknown"] = LifetimeCaptureByAttr::UNKNOWN; ---------------- hokein wrote:
we can inline these two `key-value`s in the `NameIdxMapping` initialization, this can save some lookup cost. ``` llvm::StringMap<int> NameIdxMapping = {{"global", LifetimeCaptureByAttr::GLOBAL}, ...} ``` https://github.com/llvm/llvm-project/pull/115823 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits