@@ -5267,7 +5267,7 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
52675267 return result;
52685268}
52695269
5270- static const llvm::StringMap<std::vector<int >> STLConditionalEscapableParams {
5270+ static const llvm::StringMap<std::vector<int >> STLConditionalParams {
52715271 {" basic_string" , {0 }},
52725272 {" vector" , {0 }},
52735273 {" array" , {0 }},
@@ -5343,10 +5343,10 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
53435343 return CxxEscapability::Escapable;
53445344 auto injectedStlAnnotation =
53455345 recordDecl->isInStdNamespace ()
5346- ? STLConditionalEscapableParams .find (recordDecl->getName ())
5347- : STLConditionalEscapableParams .end ();
5346+ ? STLConditionalParams .find (recordDecl->getName ())
5347+ : STLConditionalParams .end ();
53485348 bool hasInjectedSTLAnnotation =
5349- injectedStlAnnotation != STLConditionalEscapableParams .end ();
5349+ injectedStlAnnotation != STLConditionalParams .end ();
53505350 auto conditionalParams = getConditionalEscapableAttrParams (recordDecl);
53515351 if (!conditionalParams.empty () || hasInjectedSTLAnnotation) {
53525352 auto specDecl = cast<clang::ClassTemplateSpecializationDecl>(recordDecl);
@@ -8299,6 +8299,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
82998299 CxxValueSemanticsDescriptor desc) const {
83008300
83018301 const auto *type = desc.type ;
8302+ auto *importerImpl = desc.importerImpl ;
83028303
83038304 auto desugared = type->getUnqualifiedDesugaredType ();
83048305 const auto *recordType = desugared->getAs <clang::RecordType>();
@@ -8310,7 +8311,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
83108311 // When a reference type is copied, the pointer’s value is copied rather than
83118312 // the object’s storage. This means reference types can be imported as
83128313 // copyable to Swift, even when they are non-copyable in C++.
8313- if (recordHasReferenceSemantics (recordDecl, desc. importerImpl ))
8314+ if (recordHasReferenceSemantics (recordDecl, importerImpl))
83148315 return CxxValueSemanticsKind::Copyable;
83158316
83168317 if (recordDecl->isInStdNamespace ()) {
@@ -8319,10 +8320,40 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
83198320 if (recordDecl->getIdentifier () &&
83208321 recordDecl->getName () == " _Optional_construct_base" )
83218322 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+ }
83228353 }
83238354
83248355 const auto cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(recordDecl);
8325- if (!cxxRecordDecl) {
8356+ if (!cxxRecordDecl || !cxxRecordDecl-> isCompleteDefinition () ) {
83268357 if (hasNonCopyableAttr (recordDecl))
83278358 return CxxValueSemanticsKind::MoveOnly;
83288359 return CxxValueSemanticsKind::Copyable;
0 commit comments