@@ -8244,14 +8244,17 @@ bool importer::hasSameUnderlyingType(const clang::Type *a,
8244
8244
8245
8245
SourceFile &ClangImporter::Implementation::getClangSwiftAttrSourceFile (
8246
8246
ModuleDecl &module ,
8247
- StringRef attributeText
8247
+ StringRef attributeText,
8248
+ bool cached
8248
8249
) {
8249
- auto &sourceFiles = ClangSwiftAttrSourceFiles[attributeText];
8250
+ if (cached) {
8251
+ auto &sourceFiles = ClangSwiftAttrSourceFiles[attributeText];
8250
8252
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
+ }
8255
8258
}
8256
8259
8257
8260
// Create a new buffer with a copy of the attribute text,
@@ -8273,7 +8276,11 @@ SourceFile &ClangImporter::Implementation::getClangSwiftAttrSourceFile(
8273
8276
// Create the source file.
8274
8277
auto sourceFile = new (SwiftContext)
8275
8278
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
+ }
8277
8284
8278
8285
return *sourceFile;
8279
8286
}
@@ -8450,17 +8457,52 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) {
8450
8457
continue ;
8451
8458
}
8452
8459
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
+ }
8457
8493
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 ;
8464
8506
}
8465
8507
}
8466
8508
0 commit comments