@@ -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,49 @@ 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 (auto customAttr = dyn_cast<CustomAttr>(attr)) {
8480+ if (customAttr->getArgs () != nullptr ) {
8481+ hasNonclonableAttribute = true ;
8482+ break ;
8483+ }
8484+ }
8485+ }
8486+ }
84578487
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));
8488+ if (hasNonclonableAttribute) {
8489+ cached = false ;
8490+ continue ;
8491+ }
8492+ }
8493+
8494+ // Collect the attributes from the synthesized top-level declaration in
8495+ // the source file.
8496+ for (auto decl : topLevelDecls) {
8497+ for (auto attr : decl->getAttrs ()) {
8498+ MappedDecl->getAttrs ().add (attr->clone (SwiftContext));
8499+ }
8500+ }
8501+
8502+ break ;
84648503 }
84658504 }
84668505
0 commit comments