@@ -5267,7 +5267,7 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
5267
5267
return result;
5268
5268
}
5269
5269
5270
- static const llvm::StringMap<std::vector<int >> STLConditionalEscapableParams {
5270
+ static const llvm::StringMap<std::vector<int >> STLConditionalParams {
5271
5271
{" basic_string" , {0 }},
5272
5272
{" vector" , {0 }},
5273
5273
{" array" , {0 }},
@@ -5343,10 +5343,10 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
5343
5343
return CxxEscapability::Escapable;
5344
5344
auto injectedStlAnnotation =
5345
5345
recordDecl->isInStdNamespace ()
5346
- ? STLConditionalEscapableParams .find (recordDecl->getName ())
5347
- : STLConditionalEscapableParams .end ();
5346
+ ? STLConditionalParams .find (recordDecl->getName ())
5347
+ : STLConditionalParams .end ();
5348
5348
bool hasInjectedSTLAnnotation =
5349
- injectedStlAnnotation != STLConditionalEscapableParams .end ();
5349
+ injectedStlAnnotation != STLConditionalParams .end ();
5350
5350
auto conditionalParams = getConditionalEscapableAttrParams (recordDecl);
5351
5351
if (!conditionalParams.empty () || hasInjectedSTLAnnotation) {
5352
5352
auto specDecl = cast<clang::ClassTemplateSpecializationDecl>(recordDecl);
@@ -8299,6 +8299,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
8299
8299
CxxValueSemanticsDescriptor desc) const {
8300
8300
8301
8301
const auto *type = desc.type ;
8302
+ auto *importerImpl = desc.importerImpl ;
8302
8303
8303
8304
auto desugared = type->getUnqualifiedDesugaredType ();
8304
8305
const auto *recordType = desugared->getAs <clang::RecordType>();
@@ -8310,7 +8311,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
8310
8311
// When a reference type is copied, the pointer’s value is copied rather than
8311
8312
// the object’s storage. This means reference types can be imported as
8312
8313
// copyable to Swift, even when they are non-copyable in C++.
8313
- if (recordHasReferenceSemantics (recordDecl, desc. importerImpl ))
8314
+ if (recordHasReferenceSemantics (recordDecl, importerImpl))
8314
8315
return CxxValueSemanticsKind::Copyable;
8315
8316
8316
8317
if (recordDecl->isInStdNamespace ()) {
@@ -8319,10 +8320,40 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
8319
8320
if (recordDecl->getIdentifier () &&
8320
8321
recordDecl->getName () == " _Optional_construct_base" )
8321
8322
return CxxValueSemanticsKind::Copyable;
8323
+
8324
+ auto injectedStlAnnotation =
8325
+ STLConditionalParams.find (recordDecl->getName ());
8326
+
8327
+ if (injectedStlAnnotation != STLConditionalParams.end ()) {
8328
+ auto specDecl = cast<clang::ClassTemplateSpecializationDecl>(recordDecl);
8329
+ auto &argList = specDecl->getTemplateArgs ();
8330
+ for (auto argToCheck : injectedStlAnnotation->second ) {
8331
+ auto arg = argList[argToCheck];
8332
+ llvm::SmallVector<clang::TemplateArgument, 1 > nonPackArgs;
8333
+ if (arg.getKind () == clang::TemplateArgument::Pack) {
8334
+ auto pack = arg.getPackAsArray ();
8335
+ nonPackArgs.assign (pack.begin (), pack.end ());
8336
+ } else
8337
+ nonPackArgs.push_back (arg);
8338
+ for (auto nonPackArg : nonPackArgs) {
8339
+
8340
+ auto argValueSemantics = evaluateOrDefault (
8341
+ evaluator,
8342
+ CxxValueSemantics (
8343
+ {nonPackArg.getAsType ()->getUnqualifiedDesugaredType (),
8344
+ desc.importerImpl }),
8345
+ {});
8346
+ if (argValueSemantics != CxxValueSemanticsKind::Copyable)
8347
+ return argValueSemantics;
8348
+ }
8349
+ }
8350
+
8351
+ return CxxValueSemanticsKind::Copyable;
8352
+ }
8322
8353
}
8323
8354
8324
8355
const auto cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(recordDecl);
8325
- if (!cxxRecordDecl) {
8356
+ if (!cxxRecordDecl || !cxxRecordDecl-> isCompleteDefinition () ) {
8326
8357
if (hasNonCopyableAttr (recordDecl))
8327
8358
return CxxValueSemanticsKind::MoveOnly;
8328
8359
return CxxValueSemanticsKind::Copyable;
0 commit comments