Skip to content

Commit 4c5e22f

Browse files
authored
Merge pull request #39010 from nkcsgexi/diff-demangled
ABIChecker: diagnose mangled name changes
2 parents bcbe8e7 + d7f5dc4 commit 4c5e22f

File tree

7 files changed

+59
-0
lines changed

7 files changed

+59
-0
lines changed

include/swift/AST/DiagnosticsModuleDiffer.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ ERROR(not_inheriting_convenience_inits,APIDigesterBreakage,"%0 no longer inherit
8888

8989
ERROR(enum_case_added,APIDigesterBreakage,"%0 has been added as a new enum case", (StringRef))
9090

91+
ERROR(demangled_name_changed,APIDigesterBreakage,"%0 has mangled name changing from '%1' to '%2'", (StringRef, StringRef, StringRef))
92+
9193
WARNING(cannot_read_allowlist,none,"cannot read breakage allowlist at '%0'", (StringRef))
9294

9395
#define UNDEFINE_DIAGNOSTIC_MACROS

include/swift/AST/USRGeneration.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ bool printExtensionUSR(const ExtensionDecl *ED, raw_ostream &OS);
6161
/// \returns true if it failed, false on success.
6262
bool printDeclUSR(const Decl *D, raw_ostream &OS);
6363

64+
/// Demangle a mangle-name-based USR to a human readable name.
65+
std::string demangleUSR(StringRef mangled);
66+
6467
} // namespace ide
6568
} // namespace swift
6669

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,8 @@ static bool isSDKNodeEqual(SDKContext &Ctx, const SDKNode &L, const SDKNode &R)
944944
if (Left->getFixedBinaryOrder() != Right->getFixedBinaryOrder())
945945
return false;
946946
}
947+
if (Left->getUsr() != Right->getUsr())
948+
return false;
947949
LLVM_FALLTHROUGH;
948950
}
949951
case SDKNodeKind::Conformance:
@@ -2551,6 +2553,13 @@ void swift::ide::api::SDKNodeDecl::diagnose(SDKNode *Right) {
25512553
emitDiag(Loc, diag::decl_reorder, getFixedBinaryOrder(),
25522554
RD->getFixedBinaryOrder());
25532555
}
2556+
if (getUsr() != RD->getUsr()) {
2557+
auto left = demangleUSR(getUsr());
2558+
auto right = demangleUSR(RD->getUsr());
2559+
if (left != right) {
2560+
emitDiag(Loc, diag::demangled_name_changed, left, right);
2561+
}
2562+
}
25542563
}
25552564
}
25562565

lib/APIDigester/ModuleDiagsConsumer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ static StringRef getCategoryName(uint32_t ID) {
5454
case LocalDiagID::raw_type_change:
5555
return "/* RawRepresentable Changes */";
5656
case LocalDiagID::generic_sig_change:
57+
case LocalDiagID::demangled_name_changed:
5758
return "/* Generic Signature Changes */";
5859
case LocalDiagID::enum_case_added:
5960
case LocalDiagID::decl_added:

lib/AST/USRGeneration.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/SwiftNameTranslation.h"
2020
#include "swift/AST/TypeCheckRequests.h"
2121
#include "swift/AST/USRGeneration.h"
22+
#include "swift/Demangling/Demangler.h"
2223
#include "llvm/ADT/SmallString.h"
2324
#include "llvm/ADT/StringRef.h"
2425
#include "llvm/Support/raw_ostream.h"
@@ -255,6 +256,18 @@ swift::USRGenerationRequest::evaluate(Evaluator &evaluator,
255256
return NewMangler.mangleDeclAsUSR(D, getUSRSpacePrefix());
256257
}
257258

259+
std::string ide::demangleUSR(StringRef mangled) {
260+
if (mangled.startswith(getUSRSpacePrefix())) {
261+
mangled = mangled.substr(getUSRSpacePrefix().size());
262+
}
263+
SmallString<128> buffer;
264+
buffer += "$s";
265+
buffer += mangled;
266+
mangled = buffer.str();
267+
Demangler Dem;
268+
return nodeToString(Dem.demangleSymbol(mangled));
269+
}
270+
258271
std::string
259272
swift::MangleLocalTypeDeclRequest::evaluate(Evaluator &evaluator,
260273
const TypeDecl *D) const {

test/api-digester/Outputs/Cake-abi.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11

22
/* Generic Signature Changes */
3+
cake: Constructor S1.init(_:) has mangled name changing from 'cake.S1.init(Swift.Int) -> cake.S1' to 'cake.S1.init(Swift.Double) -> cake.S1'
4+
cake: Func C1.foo1() has mangled name changing from 'static cake.C1.foo1() -> ()' to 'cake.C1.foo1() -> ()'
5+
cake: Func C1.foo2(_:) has mangled name changing from 'cake.C1.foo2(Swift.Int) -> ()' to 'cake.C1.foo2(() -> ()) -> ()'
36
cake: Func P1.P1Constraint() has generic signature change from <Self where Self : cake.P1, Self : cake.P2> to <Self where Self : cake.P1>
7+
cake: Func P1.P1Constraint() has mangled name changing from '(extension in cake):cake.P1< where A: cake.P2>.P1Constraint() -> ()' to '(extension in cake):cake.P1.P1Constraint() -> ()'
8+
cake: Func S1.foo3() has mangled name changing from 'cake.S1.foo3() -> ()' to 'static cake.S1.foo3() -> ()'
9+
cake: Func S1.foo5(x:y:) has mangled name changing from 'cake.S1.foo5(x: Swift.Int, y: Swift.Int) -> ()' to 'cake.S1.foo5(x: Swift.Int, y: Swift.Int, z: Swift.Int) -> ()'
10+
cake: Func Somestruct2.foo1(_:) has mangled name changing from 'static cake.Somestruct2.foo1(cake.C3) -> ()' to 'static cake.NSSomestruct2.foo1(cake.C1) -> ()'
11+
cake: Func ownershipChange(_:_:) has mangled name changing from 'cake.ownershipChange(inout Swift.Int, __shared Swift.Int) -> ()' to 'cake.ownershipChange(Swift.Int, __owned Swift.Int) -> ()'
12+
cake: Func returnFunctionTypeOwnershipChange() has mangled name changing from 'cake.returnFunctionTypeOwnershipChange() -> (cake.C1) -> ()' to 'cake.returnFunctionTypeOwnershipChange() -> (__owned cake.C1) -> ()'
413
cake: Protocol P3 has generic signature change from <Self : cake.P1, Self : cake.P2> to <Self : cake.P1, Self : cake.P4>
14+
cake: Struct Somestruct2 has mangled name changing from 'cake.Somestruct2' to 'cake.NSSomestruct2'
515

616
/* RawRepresentable Changes */
717

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: echo "public func foo() {}" > %t/Foo.swift
3+
4+
// RUN: echo "public protocol P { associatedtype A }" > %t/Foo-1.swift
5+
// RUN: echo "public extension P { public func f() where A == Int {} }" >> %t/Foo-1.swift
6+
7+
// RUN: echo "public protocol P { associatedtype A }" > %t/Foo-2.swift
8+
// RUN: echo "public extension P where A == Int { public func f() {} }" >> %t/Foo-2.swift
9+
10+
// RUN: %target-swift-frontend -emit-module %t/Foo-1.swift -module-name Foo -emit-module-interface-path %t/Foo1.swiftinterface
11+
// RUN: %target-swift-frontend -emit-module %t/Foo-2.swift -module-name Foo -emit-module-interface-path %t/Foo2.swiftinterface
12+
13+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Foo1.swiftinterface -o %t/Foo1.swiftmodule -module-name Foo -emit-abi-descriptor-path %t/Foo1.json
14+
15+
// RUN: %target-swift-frontend -compile-module-from-interface %t/Foo2.swiftinterface -o %t/Foo2.swiftmodule -module-name Foo -emit-abi-descriptor-path %t/Foo2.json
16+
17+
// RUN: %api-digester -diagnose-sdk -print-module --input-paths %t/Foo1.json -input-paths %t/Foo2.json -abi -o %t/result.txt
18+
19+
// RUN: %FileCheck %s < %t/result.txt
20+
21+
// CHECK: Foo: Func P.f() has mangled name changing from '(extension in Foo):Foo.P.f< where A.A == Swift.Int>() -> ()' to '(extension in Foo):Foo.P< where A.A == Swift.Int>.f() -> ()'

0 commit comments

Comments
 (0)