@@ -8244,14 +8244,17 @@ bool importer::hasSameUnderlyingType(const clang::Type *a,
82448244
82458245SourceFile &ClangImporter::Implementation::getClangSwiftAttrSourceFile (
82468246 ModuleDecl &module ,
8247- StringRef attributeText
8247+ StringRef attributeText,
8248+ bool cached
82488249) {
8249- auto &sourceFiles = ClangSwiftAttrSourceFiles[attributeText];
8250+ if (cached) {
8251+ auto &sourceFiles = ClangSwiftAttrSourceFiles[attributeText];
82508252
8251- // Check whether we've already created a source file.
8252- for (auto sourceFile : sourceFiles) {
8253- if (sourceFile->getParentModule () == &module )
8254- return *sourceFile;
8253+ // Check whether we've already created a source file.
8254+ for (auto sourceFile : sourceFiles) {
8255+ if (sourceFile->getParentModule () == &module )
8256+ return *sourceFile;
8257+ }
82558258 }
82568259
82578260 // Create a new buffer with a copy of the attribute text,
@@ -8273,7 +8276,11 @@ SourceFile &ClangImporter::Implementation::getClangSwiftAttrSourceFile(
82738276 // Create the source file.
82748277 auto sourceFile = new (SwiftContext)
82758278 SourceFile (module , SourceFileKind::Library, bufferID);
8276- sourceFiles.push_back (sourceFile);
8279+
8280+ if (cached) {
8281+ auto &sourceFiles = ClangSwiftAttrSourceFiles[attributeText];
8282+ sourceFiles.push_back (sourceFile);
8283+ }
82778284
82788285 return *sourceFile;
82798286}
@@ -8450,17 +8457,52 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
84508457 continue ;
84518458 }
84528459
8453- // Dig out a source file we can use for parsing.
8454- auto &sourceFile = getClangSwiftAttrSourceFile (
8455- *MappedDecl->getDeclContext ()->getParentModule (),
8456- swiftAttr->getAttribute ());
8460+ bool cached = true ;
8461+ while (true ) {
8462+ // Dig out a source file we can use for parsing.
8463+ auto &sourceFile = getClangSwiftAttrSourceFile (
8464+ *MappedDecl->getDeclContext ()->getParentModule (),
8465+ swiftAttr->getAttribute (),
8466+ cached);
8467+
8468+ auto topLevelDecls = sourceFile.getTopLevelDecls ();
8469+
8470+ // If we're using the cached version, check whether we can correctly
8471+ // clone the attribute.
8472+ if (cached) {
8473+ bool hasNonclonableAttribute = false ;
8474+ for (auto decl : topLevelDecls) {
8475+ if (hasNonclonableAttribute)
8476+ break ;
8477+
8478+ for (auto attr : decl->getAttrs ()) {
8479+ if (!attr->canClone ()) {
8480+ hasNonclonableAttribute = true ;
8481+ break ;
8482+ }
8483+ }
8484+ }
8485+
8486+ // We cannot clone one of the attributes. Go back and build a new
8487+ // source file without caching it.
8488+ if (hasNonclonableAttribute) {
8489+ cached = false ;
8490+ continue ;
8491+ }
8492+ }
84578493
8458- // Collect the attributes from the synthesized top-level declaration in
8459- // the source file.
8460- auto topLevelDecls = sourceFile.getTopLevelDecls ();
8461- for (auto decl : topLevelDecls) {
8462- for (auto attr : decl->getAttrs ())
8463- MappedDecl->getAttrs ().add (attr->clone (SwiftContext));
8494+ // Collect the attributes from the synthesized top-level declaration in
8495+ // the source file. If we're using a cached copy, clone the attribute.
8496+ for (auto decl : topLevelDecls) {
8497+ SmallVector<DeclAttribute *, 2 > attrs (decl->getAttrs ().begin (),
8498+ decl->getAttrs ().end ());
8499+ for (auto attr : attrs) {
8500+ MappedDecl->getAttrs ().add (cached ? attr->clone (SwiftContext)
8501+ : attr);
8502+ }
8503+ }
8504+
8505+ break ;
84648506 }
84658507 }
84668508
0 commit comments