mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Printer] Conditionally print Clang types in emitted SIL.
Hopefully, this helps us debug Clang type mismatches better.
This commit is contained in:
@@ -564,7 +564,7 @@ struct PrintOptions {
|
||||
static PrintOptions printDocInterface();
|
||||
|
||||
/// Retrieve the set of options suitable for printing SIL functions.
|
||||
static PrintOptions printSIL() {
|
||||
static PrintOptions printSIL(bool printFullConvention = false) {
|
||||
PrintOptions result;
|
||||
result.PrintLongAttrsOnSeparateLines = true;
|
||||
result.PrintStorageRepresentationAttrs = true;
|
||||
@@ -575,6 +575,9 @@ struct PrintOptions {
|
||||
result.PrintIfConfig = false;
|
||||
result.OpaqueReturnTypePrinting =
|
||||
OpaqueReturnTypePrintingMode::StableReference;
|
||||
if (printFullConvention)
|
||||
result.PrintFunctionRepresentationAttrs =
|
||||
PrintOptions::FunctionRepresentationMode::Full;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,9 @@ public:
|
||||
/// variables by name when we print it out. This eases diffing of SIL files.
|
||||
bool EmitSortedSIL = false;
|
||||
|
||||
/// See \ref FrontendOptions.PrintFullConvention
|
||||
bool PrintFullConvention = false;
|
||||
|
||||
/// Whether to stop the optimization pipeline after serializing SIL.
|
||||
bool StopOptimizationAfterSerialization = false;
|
||||
|
||||
|
||||
@@ -253,6 +253,9 @@ public:
|
||||
/// See the \ref SILOptions.EmitSortedSIL flag.
|
||||
bool EmitSortedSIL = false;
|
||||
|
||||
/// Should we emit the cType when printing @convention(c) or no?
|
||||
bool PrintFullConvention = false;
|
||||
|
||||
/// Indicates whether the dependency tracker should track system
|
||||
/// dependencies as well.
|
||||
bool TrackSystemDeps = false;
|
||||
|
||||
@@ -31,8 +31,8 @@ struct ModuleInterfaceOptions {
|
||||
/// interface, or should we fully-qualify them?
|
||||
bool PreserveTypesAsWritten = false;
|
||||
|
||||
/// Should we emit the cType when printing @convention(c) or no?
|
||||
/// FIXME: [clang-function-type-serialization] This check should go away.
|
||||
/// See \ref FrontendOptions.PrintFullConvention.
|
||||
/// FIXME: [clang-function-type-serialization] This flag should go away.
|
||||
bool PrintFullConvention = false;
|
||||
|
||||
/// Copy of all the command-line flags passed at .swiftinterface
|
||||
|
||||
@@ -608,10 +608,12 @@ def module_interface_preserve_types_as_written :
|
||||
HelpText<"When emitting a module interface, preserve types as they were "
|
||||
"written in the source">;
|
||||
|
||||
// FIXME: [clang-function-type-serialization] Make this a SIL-only option once we
|
||||
// start unconditionally emitting non-canonical Clang types in swiftinterfaces.
|
||||
def experimental_print_full_convention :
|
||||
Flag<["-"], "experimental-print-full-convention">,
|
||||
HelpText<"When emitting a module interface, emit additional @convention "
|
||||
"arguments, regardless of whether they were written in the source">;
|
||||
HelpText<"When emitting a module interface or SIL, emit additional @convention"
|
||||
" arguments, regardless of whether they were written in the source">;
|
||||
|
||||
def prebuilt_module_cache_path :
|
||||
Separate<["-"], "prebuilt-module-cache-path">,
|
||||
|
||||
@@ -647,10 +647,11 @@ public:
|
||||
/// \param ShouldSort If set to true sorts functions, vtables, sil global
|
||||
/// variables, and witness tables by name to ease diffing.
|
||||
/// \param PrintASTDecls If set to true print AST decls.
|
||||
void print(raw_ostream &OS, bool Verbose = false,
|
||||
ModuleDecl *M = nullptr, bool ShouldSort = false,
|
||||
void print(raw_ostream &OS,
|
||||
ModuleDecl *M = nullptr,
|
||||
const SILOptions &Opts = SILOptions(),
|
||||
bool PrintASTDecls = true) const {
|
||||
SILPrintContext PrintCtx(OS, Verbose, ShouldSort);
|
||||
SILPrintContext PrintCtx(OS, Opts);
|
||||
print(PrintCtx, M, PrintASTDecls);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifndef SWIFT_SIL_PRINTCONTEXT_H
|
||||
#define SWIFT_SIL_PRINTCONTEXT_H
|
||||
|
||||
#include "swift/AST/SILOptions.h"
|
||||
#include "swift/SIL/SILDebugScope.h"
|
||||
#include "swift/SIL/SILValue.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
@@ -65,6 +66,9 @@ protected:
|
||||
/// Print debug locations and scopes.
|
||||
bool DebugInfo;
|
||||
|
||||
/// See \ref FrontendOptions.PrintFullConvention.
|
||||
bool PrintFullConvention;
|
||||
|
||||
public:
|
||||
/// Constructor with default values for options.
|
||||
///
|
||||
@@ -72,6 +76,11 @@ public:
|
||||
SILPrintContext(llvm::raw_ostream &OS, bool Verbose = false,
|
||||
bool SortedSIL = false);
|
||||
|
||||
/// Constructor based on SILOptions.
|
||||
///
|
||||
/// DebugInfo will be set according to the -sil-print-debuginfo option.
|
||||
SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts);
|
||||
|
||||
SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
|
||||
bool SortedSIL, bool DebugInfo);
|
||||
|
||||
@@ -94,6 +103,9 @@ public:
|
||||
/// Returns true if debug locations and scopes should be printed.
|
||||
bool printDebugInfo() const { return DebugInfo; }
|
||||
|
||||
/// Returns true if the entire @convention(c, cType: ..) should be printed.
|
||||
bool printFullConvention() const { return PrintFullConvention; }
|
||||
|
||||
SILPrintContext::ID getID(const SILBasicBlock *Block);
|
||||
|
||||
SILPrintContext::ID getID(const SILNode *node);
|
||||
|
||||
@@ -581,7 +581,8 @@ public:
|
||||
|
||||
std::string getAsString() const;
|
||||
void dump() const;
|
||||
void print(raw_ostream &OS) const;
|
||||
void print(raw_ostream &OS,
|
||||
const PrintOptions &PO = PrintOptions::printSIL()) const;
|
||||
};
|
||||
|
||||
// Statically prevent SILTypes from being directly cast to a type
|
||||
|
||||
@@ -68,6 +68,8 @@ bool ArgsToFrontendOptionsConverter::convert(
|
||||
|
||||
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
|
||||
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
|
||||
Opts.PrintFullConvention |=
|
||||
Args.hasArg(OPT_experimental_print_full_convention);
|
||||
|
||||
Opts.EnableTesting |= Args.hasArg(OPT_enable_testing);
|
||||
Opts.EnablePrivateImports |= Args.hasArg(OPT_enable_private_imports);
|
||||
|
||||
@@ -942,6 +942,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
|
||||
Opts.DebugSerialization |= Args.hasArg(OPT_sil_debug_serialization);
|
||||
Opts.EmitVerboseSIL |= Args.hasArg(OPT_emit_verbose_sil);
|
||||
Opts.EmitSortedSIL |= Args.hasArg(OPT_emit_sorted_sil);
|
||||
Opts.PrintFullConvention |=
|
||||
Args.hasArg(OPT_experimental_print_full_convention);
|
||||
Opts.PrintInstCounts |= Args.hasArg(OPT_print_inst_counts);
|
||||
if (const Arg *A = Args.getLastArg(OPT_external_pass_pipeline_filename))
|
||||
Opts.ExternalPassPipelineFilename = A->getValue();
|
||||
|
||||
@@ -499,20 +499,19 @@ static bool emitSyntax(SourceFile *SF, StringRef OutputFilename) {
|
||||
}
|
||||
|
||||
/// Writes SIL out to the given file.
|
||||
static bool writeSIL(SILModule &SM, ModuleDecl *M, bool EmitVerboseSIL,
|
||||
StringRef OutputFilename, bool SortSIL) {
|
||||
static bool writeSIL(SILModule &SM, ModuleDecl *M, const SILOptions &Opts,
|
||||
StringRef OutputFilename) {
|
||||
auto OS = getFileOutputStream(OutputFilename, M->getASTContext());
|
||||
if (!OS) return true;
|
||||
SM.print(*OS, EmitVerboseSIL, M, SortSIL);
|
||||
SM.print(*OS, M, Opts);
|
||||
|
||||
return M->getASTContext().hadError();
|
||||
}
|
||||
|
||||
static bool writeSIL(SILModule &SM, const PrimarySpecificPaths &PSPs,
|
||||
const CompilerInstance &Instance,
|
||||
const SILOptions &opts) {
|
||||
return writeSIL(SM, Instance.getMainModule(), opts.EmitVerboseSIL,
|
||||
PSPs.OutputFilename, opts.EmitSortedSIL);
|
||||
const SILOptions &Opts) {
|
||||
return writeSIL(SM, Instance.getMainModule(), Opts, PSPs.OutputFilename);
|
||||
}
|
||||
|
||||
/// Prints the Objective-C "generated header" interface for \p M to \p
|
||||
|
||||
@@ -419,12 +419,11 @@ static void printSILTypeColorAndSigil(raw_ostream &OS, SILType t) {
|
||||
::print(OS, t.getCategory());
|
||||
}
|
||||
|
||||
void SILType::print(raw_ostream &OS) const {
|
||||
void SILType::print(raw_ostream &OS, const PrintOptions &PO) const {
|
||||
printSILTypeColorAndSigil(OS, *this);
|
||||
|
||||
// Print other types as their Swift representation.
|
||||
PrintOptions SubPrinter = PrintOptions::printSIL();
|
||||
getASTType().print(OS, SubPrinter);
|
||||
getASTType().print(OS, PO);
|
||||
}
|
||||
|
||||
void SILType::dump() const {
|
||||
@@ -493,7 +492,8 @@ public:
|
||||
SILPrintContext &PrintCtx,
|
||||
llvm::DenseMap<CanType, Identifier> *AlternativeTypeNames = nullptr)
|
||||
: Ctx(PrintCtx),
|
||||
PrintState{{PrintCtx.OS()}, PrintOptions::printSIL()},
|
||||
PrintState{{PrintCtx.OS()},
|
||||
PrintOptions::printSIL(PrintCtx.printFullConvention())},
|
||||
LastBufferID(0) {
|
||||
PrintState.ASTOptions.AlternativeTypeNames = AlternativeTypeNames;
|
||||
PrintState.ASTOptions.PrintForSIL = true;
|
||||
@@ -2449,7 +2449,8 @@ void SILFunction::print(SILPrintContext &PrintCtx) const {
|
||||
}
|
||||
|
||||
{
|
||||
PrintOptions withGenericEnvironment = PrintOptions::printSIL();
|
||||
PrintOptions withGenericEnvironment =
|
||||
PrintOptions::printSIL(PrintCtx.printFullConvention());
|
||||
withGenericEnvironment.GenericEnv = env;
|
||||
withGenericEnvironment.AlternativeTypeNames =
|
||||
Aliases.empty() ? nullptr : &Aliases;
|
||||
@@ -2732,7 +2733,8 @@ void SILModule::print(SILPrintContext &PrintCtx, ModuleDecl *M,
|
||||
// Print the declarations and types from the associated context (origin module or
|
||||
// current file).
|
||||
if (M && PrintASTDecls) {
|
||||
PrintOptions Options = PrintOptions::printSIL();
|
||||
PrintOptions Options =
|
||||
PrintOptions::printSIL(PrintCtx.printFullConvention());
|
||||
Options.TypeDefinitions = true;
|
||||
Options.VarInitializers = true;
|
||||
// FIXME: ExplodePatternBindingDecls is incompatible with VarInitializers!
|
||||
@@ -3116,6 +3118,11 @@ SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
|
||||
OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
|
||||
DebugInfo(SILPrintDebugInfo) { }
|
||||
|
||||
SILPrintContext::SILPrintContext(llvm::raw_ostream &OS,
|
||||
const SILOptions &Opts) :
|
||||
OutStream(OS), Verbose(Opts.EmitVerboseSIL), SortedSIL(Opts.EmitSortedSIL),
|
||||
DebugInfo(SILPrintDebugInfo), PrintFullConvention(Opts.PrintFullConvention) {}
|
||||
|
||||
SILPrintContext::SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
|
||||
bool SortedSIL, bool DebugInfo) :
|
||||
OutStream(OS), Verbose(Verbose), SortedSIL(SortedSIL),
|
||||
|
||||
8
test/SIL/clang-function-types.swift
Normal file
8
test/SIL/clang-function-types.swift
Normal file
@@ -0,0 +1,8 @@
|
||||
// RUN: %target-swift-frontend %s -emit-sil -swift-version 5 -use-clang-function-types -experimental-print-full-convention -o - | %FileCheck %s
|
||||
|
||||
public func f(g: @convention(c) () -> ()) { g() }
|
||||
|
||||
// CHECK: sil @$s4main1f1gyyyXC_tF : $@convention(thin) (@convention(c, cType: "void (*)(void)") @noescape () -> ()) -> () {
|
||||
// CHECK: bb0(%0 : $@convention(c, cType: "void (*)(void)") @noescape () -> ()):
|
||||
// CHECK: debug_value %0 : $@convention(c, cType: "void (*)(void)") @noescape () -> (), let, name "g", argno 1 // id: %1
|
||||
// CHECK: %2 = apply %0() : $@convention(c, cType: "void (*)(void)") @noescape () -> ()
|
||||
@@ -101,10 +101,10 @@ static llvm::cl::opt<std::string> Triple("target",
|
||||
llvm::cl::desc("target triple"));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
EnableSILSortOutput("emit-sorted-sil", llvm::cl::Hidden,
|
||||
llvm::cl::init(false),
|
||||
llvm::cl::desc("Sort Functions, VTables, Globals, "
|
||||
"WitnessTables by name to ease diffing."));
|
||||
EmitSortedSIL("emit-sorted-sil", llvm::cl::Hidden,
|
||||
llvm::cl::init(false),
|
||||
llvm::cl::desc("Sort Functions, VTables, Globals, "
|
||||
"WitnessTables by name to ease diffing."));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden,
|
||||
@@ -250,6 +250,10 @@ int main(int argc, char **argv) {
|
||||
Invocation.getLangOptions().EnableAccessControl = false;
|
||||
Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false;
|
||||
|
||||
SILOptions &Opts = Invocation.getSILOptions();
|
||||
Opts.EmitVerboseSIL = EmitVerboseSIL;
|
||||
Opts.EmitSortedSIL = EmitSortedSIL;
|
||||
|
||||
serialization::ExtendedValidationInfo extendedInfo;
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
|
||||
Invocation.setUpInputForSILTool(InputFilename, ModuleName,
|
||||
@@ -356,8 +360,8 @@ int main(int argc, char **argv) {
|
||||
OutputFilename.size() ? StringRef(OutputFilename) : "-";
|
||||
|
||||
if (OutputFile == "-") {
|
||||
CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(),
|
||||
EnableSILSortOutput, !DisableASTDump);
|
||||
CI.getSILModule()->print(llvm::outs(), CI.getMainModule(),
|
||||
Invocation.getSILOptions(), !DisableASTDump);
|
||||
} else {
|
||||
std::error_code EC;
|
||||
llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None);
|
||||
@@ -366,8 +370,8 @@ int main(int argc, char **argv) {
|
||||
<< '\n';
|
||||
return 1;
|
||||
}
|
||||
CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(),
|
||||
EnableSILSortOutput, !DisableASTDump);
|
||||
CI.getSILModule()->print(OS, CI.getMainModule(),
|
||||
Invocation.getSILOptions(), !DisableASTDump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,10 +196,10 @@ static llvm::cl::opt<std::string>
|
||||
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
EnableSILSortOutput("emit-sorted-sil", llvm::cl::Hidden,
|
||||
llvm::cl::init(false),
|
||||
llvm::cl::desc("Sort Functions, VTables, Globals, "
|
||||
"WitnessTables by name to ease diffing."));
|
||||
EmitSortedSIL("emit-sorted-sil", llvm::cl::Hidden,
|
||||
llvm::cl::init(false),
|
||||
llvm::cl::desc("Sort Functions, VTables, Globals, "
|
||||
"WitnessTables by name to ease diffing."));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
DisableASTDump("sil-disable-ast-dump", llvm::cl::Hidden,
|
||||
@@ -375,6 +375,8 @@ int main(int argc, char **argv) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SILOpts.EmitVerboseSIL |= EmitVerboseSIL;
|
||||
SILOpts.EmitSortedSIL |= EmitSortedSIL;
|
||||
|
||||
serialization::ExtendedValidationInfo extendedInfo;
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr =
|
||||
@@ -481,8 +483,8 @@ int main(int argc, char **argv) {
|
||||
StringRef(OutputFilename) : "-";
|
||||
|
||||
if (OutputFile == "-") {
|
||||
CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(),
|
||||
EnableSILSortOutput, !DisableASTDump);
|
||||
CI.getSILModule()->print(llvm::outs(), CI.getMainModule(),
|
||||
Invocation.getSILOptions(), !DisableASTDump);
|
||||
} else {
|
||||
std::error_code EC;
|
||||
llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None);
|
||||
@@ -491,8 +493,8 @@ int main(int argc, char **argv) {
|
||||
<< EC.message() << '\n';
|
||||
return 1;
|
||||
}
|
||||
CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(),
|
||||
EnableSILSortOutput, !DisableASTDump);
|
||||
CI.getSILModule()->print(OS, CI.getMainModule(),
|
||||
Invocation.getSILOptions(), !DisableASTDump);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user