Skip to content

Commit 983399c

Browse files
[Printer] Conditionally print Clang types in emitted SIL.
1 parent 5e9bf1f commit 983399c

File tree

16 files changed

+93
-59
lines changed

16 files changed

+93
-59
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ struct PrintOptions {
594594
static PrintOptions printDocInterface();
595595

596596
/// Retrieve the set of options suitable for printing SIL functions.
597-
static PrintOptions printSIL() {
597+
static PrintOptions printSIL(bool printFullConvention = false) {
598598
PrintOptions result;
599599
result.PrintLongAttrsOnSeparateLines = true;
600600
result.PrintStorageRepresentationAttrs = true;
@@ -605,6 +605,9 @@ struct PrintOptions {
605605
result.PrintIfConfig = false;
606606
result.OpaqueReturnTypePrinting =
607607
OpaqueReturnTypePrintingMode::StableReference;
608+
if (printFullConvention)
609+
result.PrintFunctionRepresentationAttrs =
610+
PrintOptions::FunctionRepresentationMode::Full;
608611
return result;
609612
}
610613

include/swift/AST/SILOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ class SILOptions {
7878
/// variables by name when we print it out. This eases diffing of SIL files.
7979
bool EmitSortedSIL = false;
8080

81+
/// See \ref FrontendOptions.PrintFullConvention
82+
bool PrintFullConvention = false;
83+
8184
/// Whether to stop the optimization pipeline after serializing SIL.
8285
bool StopOptimizationAfterSerialization = false;
8386

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ class FrontendOptions {
239239
/// output path is configured.
240240
Optional<IntermoduleDepTrackingMode> IntermoduleDependencyTracking;
241241

242+
/// Should we emit the cType when printing @convention(c) or no?
243+
bool PrintFullConvention = false;
244+
242245
/// Should we serialize the hashes of dependencies (vs. the modification
243246
/// times) when compiling a module interface?
244247
bool SerializeModuleInterfaceDependencyHashes = false;

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ struct ModuleInterfaceOptions {
3232
/// interface, or should we fully-qualify them?
3333
bool PreserveTypesAsWritten = false;
3434

35-
/// Should we emit the cType when printing @convention(c) or no?
35+
/// See \ref FrontendOptions.PrintFullConvention.
3636
/// [TODO: Clang-type-plumbing] This check should go away.
3737
bool PrintFullConvention = false;
3838

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,12 @@ def experimental_spi_imports :
659659
Flag<["-"], "experimental-spi-imports">,
660660
HelpText<"Enable experimental support for SPI imports">;
661661

662+
// [FIXME: Clang-type-plumbing] Make this a SIL-only option once we start
663+
// unconditionally emitting non-canonical Clang types in swiftinterfaces.
662664
def experimental_print_full_convention :
663665
Flag<["-"], "experimental-print-full-convention">,
664-
HelpText<"When emitting a module interface, emit additional @convention "
665-
"arguments, regardless of whether they were written in the source">;
666+
HelpText<"When emitting a module interface or SIL, emit additional @convention"
667+
" arguments, regardless of whether they were written in the source">;
666668

667669
def experimental_one_way_closure_params :
668670
Flag<["-"], "experimental-one-way-closure-params">,

include/swift/SIL/SILModule.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -671,8 +671,7 @@ class SILModule {
671671
/// \param Opts The SIL options, used to determine printing verbosity and
672672
/// and sorting.
673673
/// \param PrintASTDecls If set to true print AST decls.
674-
void print(raw_ostream& OS,
675-
ModuleDecl *M = nullptr,
674+
void print(raw_ostream &OS, ModuleDecl *M = nullptr,
676675
const SILOptions &Opts = SILOptions(),
677676
bool PrintASTDecls = true) const {
678677
SILPrintContext PrintCtx(OS, Opts);

include/swift/SIL/SILPrintContext.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,23 @@ class SILPrintContext {
6666
/// Print debug locations and scopes.
6767
bool DebugInfo;
6868

69+
/// See \ref FrontendOptions.PrintFullConvention.
70+
bool PrintFullConvention;
71+
6972
public:
7073
/// Constructor with default values for options.
7174
///
7275
/// DebugInfo will be set according to the -sil-print-debuginfo option.
7376
SILPrintContext(llvm::raw_ostream &OS, bool Verbose = false,
74-
bool SortedSIL = false);
77+
bool SortedSIL = false, bool PrintFullConvention = false);
7578

7679
/// Constructor based on SILOptions.
7780
///
7881
/// DebugInfo will be set according to the -sil-print-debuginfo option.
7982
SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts);
8083

81-
SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
82-
bool SortedSIL, bool DebugInfo);
84+
SILPrintContext(llvm::raw_ostream &OS, bool Verbose, bool SortedSIL,
85+
bool DebugInfo, bool PrintFullConvention);
8386

8487
virtual ~SILPrintContext();
8588

@@ -100,6 +103,9 @@ class SILPrintContext {
100103
/// Returns true if debug locations and scopes should be printed.
101104
bool printDebugInfo() const { return DebugInfo; }
102105

106+
/// Returns true if the entire @convention(c, cType: ..) should be printed.
107+
bool printFullConvention() const { return PrintFullConvention; }
108+
103109
SILPrintContext::ID getID(const SILBasicBlock *Block);
104110

105111
SILPrintContext::ID getID(const SILNode *node);

include/swift/SIL/SILType.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -611,7 +611,8 @@ class SILType {
611611

612612
std::string getAsString() const;
613613
void dump() const;
614-
void print(raw_ostream &OS) const;
614+
void print(raw_ostream &OS,
615+
const PrintOptions &PO = PrintOptions::printSIL()) const;
615616
};
616617

617618
// Statically prevent SILTypes from being directly cast to a type

lib/AST/ASTPrinter.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4053,8 +4053,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
40534053
info.getSILRepresentation() == SILFunctionType::Representation::Thick)
40544054
return;
40554055

4056-
bool printNameOnly = Options.PrintFunctionRepresentationAttrs ==
4057-
PrintOptions::FunctionRepresentationMode::NameOnly;
4056+
bool printClangType = Options.PrintFunctionRepresentationAttrs ==
4057+
PrintOptions::FunctionRepresentationMode::Full;
40584058
Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);
40594059
Printer.printAttrName("@convention");
40604060
Printer << "(";
@@ -4067,13 +4067,13 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
40674067
break;
40684068
case SILFunctionType::Representation::Block:
40694069
Printer << "block";
4070+
if (printClangType && !info.getClangTypeInfo().empty())
4071+
printCType(Ctx, Printer, info);
40704072
break;
40714073
case SILFunctionType::Representation::CFunctionPointer:
40724074
Printer << "c";
4073-
// [TODO: Clang-type-plumbing] Remove the second check.
4074-
if (printNameOnly || info.getClangTypeInfo().empty())
4075-
break;
4076-
printCType(Ctx, Printer, info);
4075+
if (printClangType && !info.getClangTypeInfo().empty())
4076+
printCType(Ctx, Printer, info);
40774077
break;
40784078
case SILFunctionType::Representation::Method:
40794079
Printer << "method";
@@ -4120,8 +4120,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41204120
info.getRepresentation() == SILFunctionType::Representation::Thick)
41214121
break;
41224122

4123-
bool printNameOnly = Options.PrintFunctionRepresentationAttrs ==
4124-
PrintOptions::FunctionRepresentationMode::NameOnly;
4123+
bool printClangType = Options.PrintFunctionRepresentationAttrs ==
4124+
PrintOptions::FunctionRepresentationMode::Full;
41254125
Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);
41264126
Printer.printAttrName("@convention");
41274127
Printer << "(";
@@ -4133,13 +4133,13 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
41334133
break;
41344134
case SILFunctionType::Representation::Block:
41354135
Printer << "block";
4136+
if (printClangType)
4137+
printCType(Ctx, Printer, info);
41364138
break;
41374139
case SILFunctionType::Representation::CFunctionPointer:
41384140
Printer << "c";
4139-
// [TODO: Clang-type-plumbing] Remove the second check.
4140-
if (printNameOnly || info.getClangTypeInfo().empty())
4141-
break;
4142-
printCType(Ctx, Printer, info);
4141+
if (printClangType)
4142+
printCType(Ctx, Printer, info);
41434143
break;
41444144
case SILFunctionType::Representation::Method:
41454145
Printer << "method";

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ bool ArgsToFrontendOptionsConverter::convert(
7171

7272
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
7373
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
74+
Opts.PrintFullConvention |=
75+
Args.hasArg(OPT_experimental_print_full_convention);
7476

7577
Opts.EnableTesting |= Args.hasArg(OPT_enable_testing);
7678
Opts.EnablePrivateImports |= Args.hasArg(OPT_enable_private_imports);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
11621162
Opts.DebugSerialization |= Args.hasArg(OPT_sil_debug_serialization);
11631163
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
11641164
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
1165+
Opts.PrintFullConvention |=
1166+
Args.hasArg(OPT_experimental_print_full_convention);
11651167
Opts.PrintInstCounts |= Args.hasArg(OPT_print_inst_counts);
11661168
if (const Arg *A = Args.getLastArg(OPT_external_pass_pipeline_filename))
11671169
Opts.ExternalPassPipelineFilename = A->getValue();

lib/SIL/IR/SILPrinter.cpp

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -440,13 +440,12 @@ static void printSILTypeColorAndSigil(raw_ostream &OS, SILType t) {
440440
// Potentially add a leading sigil for the value category.
441441
::print(OS, t.getCategory());
442442
}
443-
444-
void SILType::print(raw_ostream &OS) const {
443+
444+
void SILType::print(raw_ostream &OS, const PrintOptions &PO) const {
445445
printSILTypeColorAndSigil(OS, *this);
446446

447447
// Print other types as their Swift representation.
448-
PrintOptions SubPrinter = PrintOptions::printSIL();
449-
getASTType().print(OS, SubPrinter);
448+
getASTType().print(OS, PO);
450449
}
451450

452451
void SILType::dump() const {
@@ -459,7 +458,8 @@ void SILType::dump() const {
459458
/// result in `sugaredTypeNames`.
460459
static void printSILFunctionNameAndType(
461460
llvm::raw_ostream &OS, const SILFunction *function,
462-
llvm::DenseMap<CanType, Identifier> &sugaredTypeNames) {
461+
llvm::DenseMap<CanType, Identifier> &sugaredTypeNames,
462+
bool printFullConvention = false) {
463463
function->printName(OS);
464464
OS << " : $";
465465
auto *genEnv = function->getGenericEnvironment();
@@ -496,7 +496,7 @@ static void printSILFunctionNameAndType(
496496
sugaredTypeNames[archetypeTy->getCanonicalType()] = name;
497497
}
498498
}
499-
auto printOptions = PrintOptions::printSIL();
499+
auto printOptions = PrintOptions::printSIL(printFullConvention);
500500
printOptions.GenericSig = genSig;
501501
printOptions.AlternativeTypeNames =
502502
sugaredTypeNames.empty() ? nullptr : &sugaredTypeNames;
@@ -570,8 +570,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
570570
SILPrinter(
571571
SILPrintContext &PrintCtx,
572572
llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr)
573-
: Ctx(PrintCtx),
574-
PrintState{{PrintCtx.OS()}, PrintOptions::printSIL()},
573+
: Ctx(PrintCtx), PrintState{{PrintCtx.OS()},
574+
PrintOptions::printSIL(
575+
PrintCtx.printFullConvention())},
575576
LastBufferID(0) {
576577
PrintState.ASTOptions.AlternativeTypeNames = AlternativeTypeNames;
577578
PrintState.ASTOptions.PrintForSIL = true;
@@ -2684,7 +2685,8 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
26842685
OS << "[ossa] ";
26852686

26862687
llvm::DenseMap<CanType, Identifier> sugaredTypeNames;
2687-
printSILFunctionNameAndType(OS, this, sugaredTypeNames);
2688+
printSILFunctionNameAndType(OS, this, sugaredTypeNames,
2689+
PrintCtx.printFullConvention());
26882690

26892691
if (!isExternalDeclaration()) {
26902692
if (auto eCount = getEntryCount()) {
@@ -2702,9 +2704,7 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
27022704

27032705
/// Pretty-print the SILFunction's name using SIL syntax,
27042706
/// '@function_mangled_name'.
2705-
void SILFunction::printName(raw_ostream &OS) const {
2706-
OS << "@" << Name;
2707-
}
2707+
void SILFunction::printName(raw_ostream &OS) const { OS << "@" << Name; }
27082708

27092709
/// Pretty-print a global variable to the designated stream.
27102710
void SILGlobalVariable::print(llvm::raw_ostream &OS, bool Verbose) const {
@@ -2971,8 +2971,8 @@ static void printFileIDMap(SILPrintContext &Ctx, const FileIDMap map) {
29712971
}
29722972

29732973
void SILProperty::print(SILPrintContext &Ctx) const {
2974-
PrintOptions Options = PrintOptions::printSIL();
2975-
2974+
PrintOptions Options = PrintOptions::printSIL(Ctx.printFullConvention());
2975+
29762976
auto &OS = Ctx.OS();
29772977
OS << "sil_property ";
29782978
if (isSerialized())
@@ -3495,19 +3495,20 @@ void SILSpecializeAttr::print(llvm::raw_ostream &OS) const {
34953495
//===----------------------------------------------------------------------===//
34963496

34973497
SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
3498-
bool SortedSIL) :
3499-
OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
3500-
DebugInfo(SILPrintDebugInfo) { }
3498+
bool SortedSIL, bool PrintFullConvention)
3499+
: OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
3500+
DebugInfo(SILPrintDebugInfo), PrintFullConvention(PrintFullConvention) {}
35013501

3502-
SILPrintContext::SILPrintContext(llvm::raw_ostream &OS,
3503-
const SILOptions &Opts) :
3504-
OutStream(OS), Verbose(Opts.EmitVerboseSIL), SortedSIL(Opts.EmitSortedSIL),
3505-
DebugInfo(SILPrintDebugInfo) {}
3502+
SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts)
3503+
: OutStream(OS), Verbose(Opts.EmitVerboseSIL),
3504+
SortedSIL(Opts.EmitSortedSIL), DebugInfo(SILPrintDebugInfo),
3505+
PrintFullConvention(Opts.PrintFullConvention) {}
35063506

35073507
SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
3508-
bool SortedSIL, bool DebugInfo) :
3509-
OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
3510-
DebugInfo(DebugInfo) { }
3508+
bool SortedSIL, bool DebugInfo,
3509+
bool PrintFullConvention)
3510+
: OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
3511+
DebugInfo(DebugInfo), PrintFullConvention(PrintFullConvention) {}
35113512

35123513
void SILPrintContext::setContext(const void *FunctionOrBlock) {
35133514
if (FunctionOrBlock != ContextFunctionOrBlock) {

test/SIL/clang-function-types.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend %s -emit-sil -swift-version 5 -use-clang-function-types -experimental-print-full-convention -o - | %FileCheck %s
2+
3+
public func f(g: @convention(c) () -> ()) { g() }
4+
5+
// CHECK: sil @$s4main1f1gyyyXC_tF : $@convention(thin) (@convention(c, cType: "void (*)(void)") @noescape () -> ()) -> () {
6+
// CHECK: bb0(%0 : $@convention(c, cType: "void (*)(void)") @noescape () -> ()):
7+
// CHECK: debug_value %0 : $@convention(c, cType: "void (*)(void)") @noescape () -> (), let, name "g", argno 1 // id: %1
8+
// CHECK: %2 = apply %0() : $@convention(c, cType: "void (*)(void)") @noescape () -> ()

test/Serialization/clang-function-types.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import def_clang_function_types
1111
// CHECK-LABEL: sil hidden @$s4main5test1yyF
1212
func test1() {
1313
// FIXME: this mangling will have to change
14-
// CHECK: global_addr @$s24def_clang_function_types11has_fp_types13OpaquePointerVSgyXCSgvp : $*Optional<@convention(c) () -> Optional<OpaquePointer>>
14+
// CHECK: global_addr @$s24def_clang_function_types11has_fp_types13OpaquePointerVSgyXCSgvp : $*Optional<@convention(c, cType: "struct ForwardInTypedefForFP *(*)(void)") () -> Optional<OpaquePointer>>
1515
let fp = has_fp_type
1616
_ = fp?()
1717
}
@@ -24,7 +24,7 @@ func test2() {
2424
// CHECK-LABEL: } // end sil function '$s4main5test2yyF'
2525

2626
// CHECK-LABEL: sil public_external [canonical] @$s24def_clang_function_types17use_fp_internallyyyF
27-
// CHECK: enum $Optional<@convention(c) () -> Optional<OpaquePointer>>, #Optional.none!enumelt
27+
// CHECK: enum $Optional<@convention(c, cType: "struct ForwardInTypedefForFP2 *(*)(void)") () -> Optional<OpaquePointer>>, #Optional.none!enumelt
2828
// CHECK: [[FN:%.*]] = function_ref @$s24def_clang_function_types9use_inout3argyxz_tlF : $@convention(thin) <τ_0_0> (@inout τ_0_0) -> ()
29-
// CHECK: apply [[FN]]<(@convention(c) () -> OpaquePointer?)?>
29+
// CHECK: apply [[FN]]<(@convention(c, cType: "OpaqueTypedefForFP2 (*)(void)") () -> OpaquePointer?)?>
3030
// CHECK-LABEL: } // end sil function '$s24def_clang_function_types17use_fp_internallyyyF'

tools/sil-func-extractor/SILFunctionExtractor.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,9 @@ static llvm::cl::opt<std::string> Triple("target",
101101
llvm::cl::desc("target triple"));
102102

103103
static llvm::cl::opt<bool>
104-
EnableSILSortOutput("emit-sorted-sil", llvm::cl::Hidden,
105-
llvm::cl::init(false),
106-
llvm::cl::desc("Sort Functions, VTables, Globals, "
107-
"WitnessTables by name to ease diffing."));
104+
EmitSortedSIL("emit-sorted-sil", llvm::cl::Hidden, llvm::cl::init(false),
105+
llvm::cl::desc("Sort Functions, VTables, Globals, "
106+
"WitnessTables by name to ease diffing."));
108107

109108
static llvm::cl::opt<bool>
110109
DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden,
@@ -245,6 +244,10 @@ int main(int argc, char **argv) {
245244
Invocation.getLangOptions().EnableAccessControl = false;
246245
Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
247246

247+
SILOptions &Opts = Invocation.getSILOptions();
248+
Opts.EmitVerboseSIL = EmitVerboseSIL;
249+
Opts.EmitSortedSIL = EmitSortedSIL;
250+
248251
serialization::ExtendedValidationInfo extendedInfo;
249252
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
250253
Invocation.setUpInputForSILTool(InputFilename, ModuleName,
@@ -340,7 +343,7 @@ int main(int argc, char **argv) {
340343

341344
auto SILOpts = SILOptions();
342345
SILOpts.EmitVerboseSIL = EmitVerboseSIL;
343-
SILOpts.EmitSortedSIL = EnableSILSortOutput;
346+
SILOpts.EmitSortedSIL = EmitSortedSIL;
344347

345348
if (OutputFile == "-") {
346349
SILMod->print(llvm::outs(), CI.getMainModule(), SILOpts, !DisableASTDump);

0 commit comments

Comments
 (0)