Skip to content

Commit b2b7d46

Browse files
authored
Merge pull request #76600 from DougGregor/mangled-names-in-swiftinterface
Option to emit mangled names for public symbols into the .swiftinterface
2 parents 9569eaf + 0aff85c commit b2b7d46

File tree

9 files changed

+107
-27
lines changed

9 files changed

+107
-27
lines changed

include/swift/AST/ASTMangler.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,6 @@ class ASTMangler : public Mangler {
217217
bool isStatic,
218218
SymbolKind SKind);
219219

220-
std::string mangleGlobalGetterEntity(const ValueDecl *decl,
221-
SymbolKind SKind = SymbolKind::Default);
222-
223220
std::string mangleDefaultArgumentEntity(const DeclContext *func,
224221
unsigned index,
225222
SymbolKind SKind = SymbolKind::Default);

include/swift/AST/PrintOptions.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,10 @@ struct PrintOptions {
520520
/// with types sharing a name with a module.
521521
bool AliasModuleNames = false;
522522

523+
/// Print some ABI details for public symbols as comments that can be
524+
/// parsed by another tool.
525+
bool PrintABIComments = false;
526+
523527
/// Name of the modules that have been aliased in AliasModuleNames mode.
524528
/// Ideally we would use something other than a string to identify a module,
525529
/// but since one alias can apply to more than one module, strings happen
@@ -707,7 +711,8 @@ struct PrintOptions {
707711
bool useExportedModuleNames,
708712
bool aliasModuleNames,
709713
llvm::SmallSet<StringRef, 4>
710-
*aliasModuleNamesTargets
714+
*aliasModuleNamesTargets,
715+
bool abiComments
711716
);
712717

713718
/// Retrieve the set of options suitable for "Generated Interfaces", which

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ struct ModuleInterfaceOptions {
4242
/// [TODO: Clang-type-plumbing] This check should go away.
4343
bool PrintFullConvention = false;
4444

45+
/// Print some ABI details for public symbols as comments that can be
46+
/// parsed by another tool.
47+
bool ABIComments = false;
48+
4549
struct InterfaceFlags {
4650
/// Copy of all the command-line flags passed at .swiftinterface
4751
/// generation time, re-applied to CompilerInvocation when reading

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,9 @@ def disable_alias_module_names_in_module_interface :
10491049
Flag<["-"], "disable-alias-module-names-in-module-interface">,
10501050
HelpText<"When emitting a module interface, disable disambiguating modules "
10511051
"using distinct alias names">;
1052+
def abi_comments_in_module_interface :
1053+
Flag<["-"], "abi-comments-in-module-interface">,
1054+
HelpText<"When emitting a module interface, emit comments with ABI details">;
10521055

10531056
def experimental_spi_imports :
10541057
Flag<["-"], "experimental-spi-imports">,

lib/AST/ASTMangler.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -171,17 +171,6 @@ std::string ASTMangler::mangleAccessorEntity(AccessorKind kind,
171171
return finalize();
172172
}
173173

174-
std::string ASTMangler::mangleGlobalGetterEntity(const ValueDecl *decl,
175-
SymbolKind SKind) {
176-
assert(isa<VarDecl>(decl) && "Only variables can have global getters");
177-
llvm::SaveAndRestore X(AllowInverses, inversesAllowed(decl));
178-
beginMangling();
179-
BaseEntitySignature base(decl);
180-
appendEntity(decl, base, "vG", /*isStatic*/false);
181-
appendSymbolKind(SKind);
182-
return finalize();
183-
}
184-
185174
std::string ASTMangler::mangleDefaultArgumentEntity(const DeclContext *func,
186175
unsigned index,
187176
SymbolKind SKind) {

lib/AST/ASTPrinter.cpp

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
207207
bool useExportedModuleNames,
208208
bool aliasModuleNames,
209209
llvm::SmallSet<StringRef, 4>
210-
*aliasModuleNamesTargets
211-
) {
210+
*aliasModuleNamesTargets,
211+
bool abiComments) {
212212
PrintOptions result;
213213
result.IsForSwiftInterface = true;
214214
result.PrintLongAttrsOnSeparateLines = true;
@@ -230,6 +230,7 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
230230
result.PreferTypeRepr = preferTypeRepr;
231231
result.AliasModuleNames = aliasModuleNames;
232232
result.AliasModuleNamesTargets = aliasModuleNamesTargets;
233+
result.PrintABIComments = abiComments;
233234
if (printFullConvention)
234235
result.PrintFunctionRepresentationAttrs =
235236
PrintOptions::FunctionRepresentationMode::Full;
@@ -770,19 +771,28 @@ class PrintAST : public ASTVisitor<PrintAST> {
770771
printRawComment(RC);
771772
}
772773

774+
/// If we should print a mangled name for this declaration, return that
775+
/// mangled name.
776+
std::optional<std::string> mangledNameToPrint(const Decl *D);
777+
773778
void printDocumentationComment(const Decl *D) {
774-
if (!Options.PrintDocumentationComments)
775-
return;
779+
if (Options.PrintDocumentationComments) {
780+
// Try to print a comment from Clang.
781+
auto MaybeClangNode = D->getClangNode();
782+
if (MaybeClangNode) {
783+
if (auto *CD = MaybeClangNode.getAsDecl())
784+
printClangDocumentationComment(CD);
785+
return;
786+
}
776787

777-
// Try to print a comment from Clang.
778-
auto MaybeClangNode = D->getClangNode();
779-
if (MaybeClangNode) {
780-
if (auto *CD = MaybeClangNode.getAsDecl())
781-
printClangDocumentationComment(CD);
782-
return;
788+
printSwiftDocumentationComment(D);
783789
}
784790

785-
printSwiftDocumentationComment(D);
791+
if (auto mangledName = mangledNameToPrint(D)) {
792+
indent();
793+
Printer << "// MANGLED NAME: " << *mangledName;
794+
Printer.printNewline();
795+
}
786796
}
787797

788798
void printStaticKeyword(StaticSpellingKind StaticSpelling) {
@@ -3061,6 +3071,60 @@ void PrintAST::printExtension(ExtensionDecl *decl) {
30613071
}
30623072
}
30633073

3074+
std::optional<std::string> PrintAST::mangledNameToPrint(const Decl *D) {
3075+
using ASTMangler = Mangle::ASTMangler;
3076+
3077+
if (!Options.PrintABIComments)
3078+
return std::nullopt;
3079+
3080+
auto valueDecl = dyn_cast<ValueDecl>(D);
3081+
if (!valueDecl)
3082+
return std::nullopt;
3083+
3084+
// Anything with an access level less than "package" isn't meant to be
3085+
// referenced from source code outside the module.
3086+
if (valueDecl->getEffectiveAccess() < AccessLevel::Package)
3087+
return std::nullopt;
3088+
3089+
// For functions, mangle the entity directly.
3090+
if (auto func = dyn_cast<FuncDecl>(D)) {
3091+
ASTMangler mangler;
3092+
return mangler.mangleEntity(func);
3093+
}
3094+
3095+
// For initializers, mangle the allocating initializer.
3096+
if (auto init = dyn_cast<ConstructorDecl>(D)) {
3097+
ASTMangler mangler;
3098+
return mangler.mangleConstructorEntity(init, /*isAllocating=*/true);
3099+
}
3100+
3101+
// For global and static variables, mangle the entity directly.
3102+
if (auto var = dyn_cast<VarDecl>(D)) {
3103+
if (!var->isInstanceMember()) {
3104+
ASTMangler mangler;
3105+
return mangler.mangleEntity(var);
3106+
}
3107+
}
3108+
3109+
// For subscripts, mangle the entity directly.
3110+
if (auto subscript = dyn_cast<SubscriptDecl>(D)) {
3111+
ASTMangler mangler;
3112+
return mangler.mangleEntity(subscript);
3113+
}
3114+
3115+
// For nominal types, mangle the type metadata accessor.
3116+
if (auto nominal = dyn_cast<NominalTypeDecl>(D)) {
3117+
if (!isa<ProtocolDecl>(nominal) && !nominal->getGenericSignature()) {
3118+
ASTMangler mangler;
3119+
std::string name = mangler.mangleNominalType(nominal);
3120+
name += "Ma";
3121+
return name;
3122+
}
3123+
}
3124+
3125+
return std::nullopt;
3126+
}
3127+
30643128
static void suppressingFeatureIsolatedAny(PrintOptions &options,
30653129
llvm::function_ref<void()> action) {
30663130
llvm::SaveAndRestore<bool> scope(options.SuppressIsolatedAny, true);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ static void ParseModuleInterfaceArgs(ModuleInterfaceOptions &Opts,
525525
Args.hasArg(OPT_debug_emit_invalid_swiftinterface_syntax);
526526
Opts.PrintMissingImports =
527527
!Args.hasArg(OPT_disable_print_missing_imports_in_module_interface);
528+
Opts.ABIComments = Args.hasArg(OPT_abi_comments_in_module_interface);
528529

529530
if (const Arg *A = Args.getLastArg(OPT_library_level)) {
530531
StringRef contents = A->getValue();

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,7 @@ bool swift::emitSwiftInterface(raw_ostream &out,
914914
M, Opts.PreserveTypesAsWritten, Opts.PrintFullConvention,
915915
Opts.InterfaceContentMode,
916916
useExportedModuleNames,
917-
Opts.AliasModuleNames, &aliasModuleNamesTargets);
917+
Opts.AliasModuleNames, &aliasModuleNamesTargets, Opts.ABIComments);
918918
InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;
919919

920920
SmallVector<Decl *, 16> topLevelDecls;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend -typecheck -emit-module-interface-path %t/ABIComments.swiftinterface -module-name ABIComments -abi-comments-in-module-interface %s
4+
5+
// RUN: %FileCheck %s < %t/ABIComments.swiftinterface
6+
7+
// CHECK: // MANGLED NAME: $s11ABIComments11intToStringySSSiF
8+
// CHECK-NEXT: public func intToString(_ value: Swift.Int) -> Swift.String
9+
public func intToString(_ value: Int) -> String { "\(value)" }
10+
11+
// CHECK: // MANGLED NAME: $s11ABIComments8MyStructVMa
12+
// CHECK-NEXT: public struct MyStruct {
13+
public struct MyStruct {
14+
// CHECK: // MANGLED NAME: $s11ABIComments8MyStructV6methodSiyF
15+
// CHECK-NEXT: public func method() -> Swift.Int
16+
public func method() -> Int { 5 }
17+
}

0 commit comments

Comments
 (0)