|
55 | 55 | #include "swift/Strings.h"
|
56 | 56 | #include "clang/AST/DeclTemplate.h"
|
57 | 57 | #include "clang/Frontend/CompilerInstance.h"
|
| 58 | +#include "clang/Index/USRGeneration.h" |
58 | 59 | #include "clang/Serialization/ASTReader.h"
|
59 | 60 | #include "llvm/ADT/SmallSet.h"
|
60 | 61 | #include "llvm/ADT/SmallString.h"
|
@@ -2116,8 +2117,25 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
|
2116 | 2117 |
|
2117 | 2118 | bool isProtocolExt = DC->getParent()->getExtendedProtocolDecl();
|
2118 | 2119 |
|
| 2120 | + Identifier name = generic->getName(); |
| 2121 | + if (generic->hasClangNode()) { |
| 2122 | + if (auto *ctsd = dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(generic->getClangDecl())) { |
| 2123 | + auto it = name.str().find("<"); |
| 2124 | + if (it != StringRef::npos) { |
| 2125 | + // Serialize a C++ class template specialization name as original |
| 2126 | + // class template name, and use its USR as the discriminator, that |
| 2127 | + // will let Swift find the correct specialization when this cross |
| 2128 | + // reference is deserialized. |
| 2129 | + name = getASTContext().getIdentifier(name.str().substr(0, it)); |
| 2130 | + assert(discriminator.empty()); |
| 2131 | + llvm::SmallString<128> buffer; |
| 2132 | + clang::index::generateUSRForDecl(ctsd, buffer); |
| 2133 | + discriminator = getASTContext().getIdentifier(buffer.str()); |
| 2134 | + } |
| 2135 | + } |
| 2136 | + } |
2119 | 2137 | XRefTypePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
2120 |
| - addDeclBaseNameRef(generic->getName()), |
| 2138 | + addDeclBaseNameRef(name), |
2121 | 2139 | addDeclBaseNameRef(discriminator),
|
2122 | 2140 | isProtocolExt,
|
2123 | 2141 | generic->hasClangNode());
|
@@ -2290,8 +2308,26 @@ void Serializer::writeCrossReference(const Decl *D) {
|
2290 | 2308 | discriminator = containingFile->getDiscriminatorForPrivateDecl(type);
|
2291 | 2309 | }
|
2292 | 2310 |
|
| 2311 | + Identifier name = type->getName(); |
| 2312 | + if (type->hasClangNode()) { |
| 2313 | + if (auto *ctsd = dyn_cast_or_null<clang::ClassTemplateSpecializationDecl>(type->getClangDecl())) { |
| 2314 | + auto it = name.str().find("<"); |
| 2315 | + if (it != StringRef::npos) { |
| 2316 | + // Serialize a C++ class template specialization name as original |
| 2317 | + // class template name, and use its USR as the discriminator, that |
| 2318 | + // will let Swift find the correct specialization when this cross |
| 2319 | + // reference is deserialized. |
| 2320 | + name = getASTContext().getIdentifier(name.str().substr(0, it)); |
| 2321 | + assert(discriminator.empty()); |
| 2322 | + llvm::SmallString<128> buffer; |
| 2323 | + clang::index::generateUSRForDecl(ctsd, buffer); |
| 2324 | + discriminator = getASTContext().getIdentifier(buffer.str()); |
| 2325 | + } |
| 2326 | + } |
| 2327 | + } |
| 2328 | + |
2293 | 2329 | XRefTypePathPieceLayout::emitRecord(Out, ScratchRecord, abbrCode,
|
2294 |
| - addDeclBaseNameRef(type->getName()), |
| 2330 | + addDeclBaseNameRef(name), |
2295 | 2331 | addDeclBaseNameRef(discriminator),
|
2296 | 2332 | isProtocolExt, D->hasClangNode());
|
2297 | 2333 | return;
|
|
0 commit comments