@@ -4097,7 +4097,8 @@ namespace {
4097
4097
func->setSelfIndex (selfIdx.value ());
4098
4098
if (Impl.SwiftContext .LangOpts .hasFeature (
4099
4099
Feature::AddressableParameters))
4100
- func->getImplicitSelfDecl ()->setAddressable ();
4100
+ func->getAttrs ().add (new (Impl.SwiftContext )
4101
+ AddressableSelfAttr (true ));
4101
4102
} else {
4102
4103
func->setStatic ();
4103
4104
func->setImportAsStaticMember ();
@@ -4145,6 +4146,34 @@ namespace {
4145
4146
return false ;
4146
4147
}
4147
4148
4149
+ // Inject lifetime annotations selectively for some STL types so we can use
4150
+ // unsafeAddress to avoid copies.
4151
+ bool inferSelfDependence (const clang::FunctionDecl *decl,
4152
+ AbstractFunctionDecl *result, size_t returnIdx) {
4153
+ const auto *method = dyn_cast<clang::CXXMethodDecl>(decl);
4154
+ if (!method)
4155
+ return false ;
4156
+ const auto *enclosing = method->getParent ();
4157
+ if (enclosing->isInStdNamespace () &&
4158
+ (enclosing->getName () == " unique_ptr" ||
4159
+ enclosing->getName () == " shared_ptr" ) &&
4160
+ method->isOverloadedOperator () &&
4161
+ method->getOverloadedOperator () == clang::OO_Star) {
4162
+ SmallVector<LifetimeDependenceInfo, 1 > lifetimeDependencies;
4163
+ SmallBitVector dependenciesOfRet (returnIdx);
4164
+ dependenciesOfRet[result->getSelfIndex ()] = true ;
4165
+ lifetimeDependencies.push_back (LifetimeDependenceInfo (
4166
+ nullptr , IndexSubset::get (Impl.SwiftContext , dependenciesOfRet),
4167
+ returnIdx,
4168
+ /* isImmortal*/ false ));
4169
+ Impl.SwiftContext .evaluator .cacheOutput (
4170
+ LifetimeDependenceInfoRequest{result},
4171
+ Impl.SwiftContext .AllocateCopy (lifetimeDependencies));
4172
+ return true ;
4173
+ }
4174
+ return false ;
4175
+ }
4176
+
4148
4177
void addLifetimeDependencies (const clang::FunctionDecl *decl,
4149
4178
AbstractFunctionDecl *result) {
4150
4179
if (decl->getTemplatedKind () == clang::FunctionDecl::TK_FunctionTemplate)
@@ -4163,10 +4192,19 @@ namespace {
4163
4192
CxxEscapability::Unknown) != CxxEscapability::NonEscapable;
4164
4193
};
4165
4194
4195
+ auto swiftParams = result->getParameters ();
4196
+ bool hasSelf =
4197
+ result->hasImplicitSelfDecl () && !isa<ConstructorDecl>(result);
4198
+ auto returnIdx = swiftParams->size () + hasSelf;
4199
+
4200
+ if (inferSelfDependence (decl, result, returnIdx))
4201
+ return ;
4202
+
4166
4203
// FIXME: this uses '0' as the result index. That only works for
4167
4204
// standalone functions with no parameters.
4168
4205
// See markReturnsUnsafeNonescapable() for a general approach.
4169
4206
auto &ASTContext = result->getASTContext ();
4207
+
4170
4208
SmallVector<LifetimeDependenceInfo, 1 > lifetimeDependencies;
4171
4209
LifetimeDependenceInfo immortalLifetime (nullptr , nullptr , 0 ,
4172
4210
/* isImmortal*/ true );
@@ -4189,10 +4227,7 @@ namespace {
4189
4227
}
4190
4228
};
4191
4229
4192
- auto swiftParams = result->getParameters ();
4193
- bool hasSelf =
4194
- result->hasImplicitSelfDecl () && !isa<ConstructorDecl>(result);
4195
- const auto dependencyVecSize = swiftParams->size () + hasSelf;
4230
+ const auto dependencyVecSize = returnIdx;
4196
4231
SmallBitVector inheritLifetimeParamIndicesForReturn (dependencyVecSize);
4197
4232
SmallBitVector scopedLifetimeParamIndicesForReturn (dependencyVecSize);
4198
4233
SmallBitVector paramHasAnnotation (dependencyVecSize);
@@ -4271,7 +4306,7 @@ namespace {
4271
4306
? IndexSubset::get (Impl.SwiftContext ,
4272
4307
scopedLifetimeParamIndicesForReturn)
4273
4308
: nullptr ,
4274
- swiftParams-> size () + hasSelf ,
4309
+ returnIdx ,
4275
4310
/* isImmortal*/ false ));
4276
4311
else if (auto *ctordecl = dyn_cast<clang::CXXConstructorDecl>(decl)) {
4277
4312
// Assume default constructed view types have no dependencies.
0 commit comments