25
25
#include " swift/AST/ConformanceLookup.h"
26
26
#include " swift/AST/Decl.h"
27
27
#include " swift/AST/DiagnosticsClangImporter.h"
28
+ #include " swift/AST/LifetimeDependence.h"
28
29
#include " swift/ClangImporter/ClangImporter.h"
29
30
#include " swift/AST/ExistentialLayout.h"
30
31
#include " swift/AST/Expr.h"
56
57
#include " swift/Strings.h"
57
58
#include " clang/AST/ASTContext.h"
58
59
#include " clang/AST/Attr.h"
60
+ #include " clang/AST/Attrs.inc"
59
61
#include " clang/AST/Decl.h"
60
62
#include " clang/AST/DeclCXX.h"
61
63
#include " clang/AST/DeclObjCCommon.h"
66
68
#include " clang/Sema/Lookup.h"
67
69
68
70
#include " llvm/ADT/STLExtras.h"
71
+ #include " llvm/ADT/SmallBitVector.h"
69
72
#include " llvm/ADT/SmallString.h"
70
73
#include " llvm/ADT/Statistic.h"
71
74
#include " llvm/ADT/StringExtras.h"
@@ -3892,10 +3895,10 @@ namespace {
3892
3895
auto swiftParams = result->getParameters ();
3893
3896
bool hasSelf =
3894
3897
result->hasImplicitSelfDecl () && !isa<ConstructorDecl>(result);
3895
- SmallBitVector inheritLifetimeParamIndicesForReturn ( swiftParams->size () +
3896
- hasSelf );
3897
- SmallBitVector scopedLifetimeParamIndicesForReturn (swiftParams-> size () +
3898
- hasSelf) ;
3898
+ const auto dependencyVecSize = swiftParams->size () + hasSelf;
3899
+ SmallBitVector inheritLifetimeParamIndicesForReturn (dependencyVecSize );
3900
+ SmallBitVector scopedLifetimeParamIndicesForReturn (dependencyVecSize);
3901
+ std::map< unsigned , SmallBitVector> inheritedArgDependences ;
3899
3902
for (auto [idx, param] : llvm::enumerate (decl->parameters ())) {
3900
3903
if (param->hasAttr <clang::LifetimeBoundAttr>()) {
3901
3904
warnForEscapableReturnType ();
@@ -3904,6 +3907,26 @@ namespace {
3904
3907
else
3905
3908
inheritLifetimeParamIndicesForReturn[idx] = true ;
3906
3909
}
3910
+ if (const auto *captureAttr = param->getAttr <clang::LifetimeCaptureByAttr>()) {
3911
+ // FIXME: support scoped inheritance. This is not straightforward as const T& is imported as taking a value
3912
+ // and we assume the address of T would not escape. An annotation in this case contradicts our assumptions.
3913
+ // We should diagnose that, and support this for the non-const case.
3914
+ if (swiftParams->get (idx)->getInterfaceType ()->isEscapable ())
3915
+ continue ;
3916
+ for (auto param : captureAttr->params ()) {
3917
+ // FIXME: Swift assumes no escaping to globals. We should diagnose this.
3918
+ if (param == clang::LifetimeCaptureByAttr::GLOBAL || param == clang::LifetimeCaptureByAttr::UNKNOWN || param == clang::LifetimeCaptureByAttr::INVALID)
3919
+ continue ;
3920
+
3921
+ if (isa<clang::CXXMethodDecl>(decl) && param == clang::LifetimeCaptureByAttr::THIS) {
3922
+ auto [it, inserted] = inheritedArgDependences.try_emplace (result->getSelfIndex (), SmallBitVector (dependencyVecSize));
3923
+ it->second [idx] = true ;
3924
+ } else {
3925
+ auto [it, inserted] = inheritedArgDependences.try_emplace (param, SmallBitVector (dependencyVecSize));
3926
+ it->second [idx] = true ;
3927
+ }
3928
+ }
3929
+ }
3907
3930
}
3908
3931
if (implicitObjectParamIsLifetimeBound (decl)) {
3909
3932
warnForEscapableReturnType ();
@@ -3914,6 +3937,11 @@ namespace {
3914
3937
inheritLifetimeParamIndicesForReturn[idx] = true ;
3915
3938
}
3916
3939
3940
+ for (auto & [idx, inheritedDepVec]: inheritedArgDependences) {
3941
+ lifetimeDependencies.push_back (LifetimeDependenceInfo (inheritedDepVec.any () ? IndexSubset::get (Impl.SwiftContext ,
3942
+ inheritedDepVec): nullptr , nullptr , idx, /* isImmortal=*/ false ));
3943
+ }
3944
+
3917
3945
if (inheritLifetimeParamIndicesForReturn.any () ||
3918
3946
scopedLifetimeParamIndicesForReturn.any ())
3919
3947
lifetimeDependencies.push_back (LifetimeDependenceInfo (
0 commit comments