@@ -5195,7 +5195,7 @@ TinyPtrVector<ValueDecl *> CXXNamespaceMemberLookup::evaluate(
51955195 return result;
51965196}
51975197
5198- static const llvm::StringMap<std::vector<int >> STLConditionalEscapableParams {
5198+ static const llvm::StringMap<std::vector<int >> STLConditionalParams {
51995199 {" basic_string" , {0 }},
52005200 {" vector" , {0 }},
52015201 {" array" , {0 }},
@@ -5271,10 +5271,10 @@ ClangTypeEscapability::evaluate(Evaluator &evaluator,
52715271 return CxxEscapability::Escapable;
52725272 auto injectedStlAnnotation =
52735273 recordDecl->isInStdNamespace ()
5274- ? STLConditionalEscapableParams .find (recordDecl->getName ())
5275- : STLConditionalEscapableParams .end ();
5274+ ? STLConditionalParams .find (recordDecl->getName ())
5275+ : STLConditionalParams .end ();
52765276 bool hasInjectedSTLAnnotation =
5277- injectedStlAnnotation != STLConditionalEscapableParams .end ();
5277+ injectedStlAnnotation != STLConditionalParams .end ();
52785278 auto conditionalParams = getConditionalEscapableAttrParams (recordDecl);
52795279 if (!conditionalParams.empty () || hasInjectedSTLAnnotation) {
52805280 auto specDecl = cast<clang::ClassTemplateSpecializationDecl>(recordDecl);
@@ -8227,6 +8227,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
82278227 CxxValueSemanticsDescriptor desc) const {
82288228
82298229 const auto *type = desc.type ;
8230+ auto *importerImpl = desc.importerImpl ;
82308231
82318232 auto desugared = type->getUnqualifiedDesugaredType ();
82328233 const auto *recordType = desugared->getAs <clang::RecordType>();
@@ -8238,7 +8239,7 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
82388239 // When a reference type is copied, the pointer’s value is copied rather than
82398240 // the object’s storage. This means reference types can be imported as
82408241 // copyable to Swift, even when they are non-copyable in C++.
8241- if (recordHasReferenceSemantics (recordDecl, desc. importerImpl ))
8242+ if (recordHasReferenceSemantics (recordDecl, importerImpl))
82428243 return CxxValueSemanticsKind::Copyable;
82438244
82448245 if (recordDecl->isInStdNamespace ()) {
@@ -8247,10 +8248,40 @@ CxxValueSemantics::evaluate(Evaluator &evaluator,
82478248 if (recordDecl->getIdentifier () &&
82488249 recordDecl->getName () == " _Optional_construct_base" )
82498250 return CxxValueSemanticsKind::Copyable;
8251+
8252+ auto injectedStlAnnotation =
8253+ STLConditionalParams.find (recordDecl->getName ());
8254+
8255+ if (injectedStlAnnotation != STLConditionalParams.end ()) {
8256+ auto specDecl = cast<clang::ClassTemplateSpecializationDecl>(recordDecl);
8257+ auto &argList = specDecl->getTemplateArgs ();
8258+ for (auto argToCheck : injectedStlAnnotation->second ) {
8259+ auto arg = argList[argToCheck];
8260+ llvm::SmallVector<clang::TemplateArgument, 1 > nonPackArgs;
8261+ if (arg.getKind () == clang::TemplateArgument::Pack) {
8262+ auto pack = arg.getPackAsArray ();
8263+ nonPackArgs.assign (pack.begin (), pack.end ());
8264+ } else
8265+ nonPackArgs.push_back (arg);
8266+ for (auto nonPackArg : nonPackArgs) {
8267+
8268+ auto argValueSemantics = evaluateOrDefault (
8269+ evaluator,
8270+ CxxValueSemantics (
8271+ {nonPackArg.getAsType ()->getUnqualifiedDesugaredType (),
8272+ desc.importerImpl }),
8273+ {});
8274+ if (argValueSemantics != CxxValueSemanticsKind::Copyable)
8275+ return argValueSemantics;
8276+ }
8277+ }
8278+
8279+ return CxxValueSemanticsKind::Copyable;
8280+ }
82508281 }
82518282
82528283 const auto cxxRecordDecl = dyn_cast<clang::CXXRecordDecl>(recordDecl);
8253- if (!cxxRecordDecl) {
8284+ if (!cxxRecordDecl || !cxxRecordDecl-> isCompleteDefinition () ) {
82548285 if (hasNonCopyableAttr (recordDecl))
82558286 return CxxValueSemanticsKind::MoveOnly;
82568287 return CxxValueSemanticsKind::Copyable;
0 commit comments