Skip to content

Commit f6e0db5

Browse files
Merge pull request #29239 from varungandhi-apple/vg-clang-types-in-sil
Propagate Clang types through SIL
2 parents 423adbc + a27c5f0 commit f6e0db5

28 files changed

+380
-135
lines changed

include/swift/AST/ASTContext.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,10 @@ class ASTContext final {
582582
Type getBridgedToObjC(const DeclContext *dc, Type type,
583583
Type *bridgedValueType = nullptr) const;
584584

585+
private:
586+
void initializeClangTypeConverter();
587+
588+
public:
585589
/// Get the Clang type corresponding to a Swift function type.
586590
///
587591
/// \param params The function parameters.
@@ -595,6 +599,15 @@ class ASTContext final {
595599
const FunctionType::ExtInfo incompleteExtInfo,
596600
FunctionTypeRepresentation trueRep);
597601

602+
/// Get the canonical Clang type corresponding to a SIL function type.
603+
///
604+
/// SIL analog of \c ASTContext::getClangFunctionType .
605+
const clang::Type *
606+
getCanonicalClangFunctionType(
607+
ArrayRef<SILParameterInfo> params, Optional<SILResultInfo> result,
608+
const SILFunctionType::ExtInfo incompleteExtInfo,
609+
SILFunctionType::Representation trueRep);
610+
598611
/// Determine whether the given Swift type is representable in a
599612
/// given foreign language.
600613
ForeignRepresentationInfo

include/swift/AST/PrintOptions.h

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

566566
/// Retrieve the set of options suitable for printing SIL functions.
567-
static PrintOptions printSIL() {
567+
static PrintOptions printSIL(bool printFullConvention = false) {
568568
PrintOptions result;
569569
result.PrintLongAttrsOnSeparateLines = true;
570570
result.PrintStorageRepresentationAttrs = true;
@@ -575,6 +575,9 @@ struct PrintOptions {
575575
result.PrintIfConfig = false;
576576
result.OpaqueReturnTypePrinting =
577577
OpaqueReturnTypePrintingMode::StableReference;
578+
if (printFullConvention)
579+
result.PrintFunctionRepresentationAttrs =
580+
PrintOptions::FunctionRepresentationMode::Full;
578581
return result;
579582
}
580583

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/AST/Types.h

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444

4545
namespace clang {
4646
class Type;
47-
class FunctionType;
4847
} // namespace clang
4948

5049
namespace llvm {
@@ -2947,6 +2946,7 @@ class AnyFunctionType : public TypeBase {
29472946
friend ExtInfo;
29482947
friend class AnyFunctionType;
29492948
friend class FunctionType;
2949+
friend class SILUncommonInfo;
29502950
// We preserve a full clang::Type *, not a clang::FunctionType * as:
29512951
// 1. We need to keep sugar in case we need to present an error to the user.
29522952
// 2. The actual type being stored is [ignoring sugar] either a
@@ -2969,7 +2969,7 @@ class AnyFunctionType : public TypeBase {
29692969
static void assertIsFunctionType(const clang::Type *);
29702970

29712971
ExtInfo(unsigned Bits, Uncommon Other) : Bits(Bits), Other(Other) {
2972-
// TODO: [store-sil-clang-function-type] Once we start serializing
2972+
// TODO: [clang-function-type-serialization] Once we start serializing
29732973
// the Clang type, we should also assert that the pointer is non-null.
29742974
auto Rep = Representation(Bits & RepresentationMask);
29752975
if ((Rep == Representation::CFunctionPointer) && Other.ClangFunctionType)
@@ -3917,6 +3917,24 @@ namespace Lowering {
39173917
class TypeConverter;
39183918
};
39193919

3920+
class SILUncommonInfo {
3921+
friend class SILFunctionType;
3922+
3923+
// Invariant: The FunctionType is canonical.
3924+
// We store a clang::FunctionType * instead of a clang::CanQualType to
3925+
// avoid depending on the Clang AST in this header.
3926+
const clang::Type *ClangFunctionType;
3927+
3928+
bool empty() const { return !ClangFunctionType; }
3929+
SILUncommonInfo(const clang::Type *type) : ClangFunctionType(type) {}
3930+
SILUncommonInfo(AnyFunctionType::ExtInfo::Uncommon uncommon);
3931+
3932+
public:
3933+
/// Analog of AnyFunctionType::ExtInfo::Uncommon::printClangFunctionType.
3934+
void printClangFunctionType(ClangModuleLoader *cml,
3935+
llvm::raw_ostream &os) const;
3936+
};
3937+
39203938
/// SILFunctionType - The lowered type of a function value, suitable
39213939
/// for use by SIL.
39223940
///
@@ -3925,7 +3943,8 @@ namespace Lowering {
39253943
/// function parameter and result types.
39263944
class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
39273945
private llvm::TrailingObjects<SILFunctionType, SILParameterInfo,
3928-
SILResultInfo, SILYieldInfo, CanType> {
3946+
SILResultInfo, SILYieldInfo, CanType,
3947+
SILUncommonInfo> {
39293948
friend TrailingObjects;
39303949

39313950
size_t numTrailingObjects(OverloadToken<SILParameterInfo>) const {
@@ -3944,6 +3963,10 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
39443963
return hasResultCache() ? 2 : 0;
39453964
}
39463965

3966+
size_t numTrailingObjects(OverloadToken<SILUncommonInfo>) const {
3967+
return Bits.SILFunctionType.HasUncommonInfo ? 1 : 0;
3968+
}
3969+
39473970
public:
39483971
using Language = SILFunctionLanguage;
39493972
using Representation = SILFunctionTypeRepresentation;
@@ -3968,27 +3991,31 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
39683991

39693992
unsigned Bits; // Naturally sized for speed.
39703993

3971-
class Uncommon {
3972-
friend ExtInfo;
3973-
friend class SILFunctionType;
3974-
3975-
// Invariant: The FunctionType is canonical.
3976-
// We store a clang::FunctionType * instead of a clang::CanQualType to
3977-
// avoid depending on the Clang AST in this header.
3978-
const clang::FunctionType *ClangFunctionType;
3994+
// For symmetry with AnyFunctionType::Uncommon
3995+
using Uncommon = SILUncommonInfo;
39793996

3980-
bool empty() const { return !ClangFunctionType; }
3981-
Uncommon(const clang::FunctionType *type) : ClangFunctionType(type) {}
3997+
Uncommon Other;
39823998

3983-
public:
3984-
/// Analog of AnyFunctionType::ExtInfo::Uncommon::printClangFunctionType.
3985-
void printClangFunctionType(ClangModuleLoader *cml,
3986-
llvm::raw_ostream &os) const;
3987-
};
3999+
static void assertIsFunctionType(const clang::Type *);
39884000

3989-
Uncommon Other;
4001+
ExtInfo(unsigned Bits, Uncommon Other) : Bits(Bits), Other(Other) {
4002+
auto Rep = Representation(Bits & RepresentationMask);
4003+
// TODO: [clang-function-type-serialization] Once we start serializing
4004+
// the Clang type, we should also assert that the pointer is non-null.
4005+
if ((Rep == Representation::CFunctionPointer) && Other.ClangFunctionType)
4006+
assertIsFunctionType(Other.ClangFunctionType);
4007+
}
39904008

3991-
ExtInfo(unsigned Bits, Uncommon Other) : Bits(Bits), Other(Other) {}
4009+
static constexpr unsigned makeBits(Representation rep,
4010+
bool isPseudogeneric,
4011+
bool isNoEscape,
4012+
DifferentiabilityKind diffKind) {
4013+
return ((unsigned) rep)
4014+
| (isPseudogeneric ? PseudogenericMask : 0)
4015+
| (isNoEscape ? NoEscapeMask : 0)
4016+
| (((unsigned)diffKind << DifferentiabilityMaskOffset)
4017+
& DifferentiabilityMask);
4018+
}
39924019

39934020
friend class SILFunctionType;
39944021
public:
@@ -3998,15 +4025,21 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
39984025
// Constructor for polymorphic type.
39994026
ExtInfo(Representation rep, bool isPseudogeneric, bool isNoEscape,
40004027
DifferentiabilityKind diffKind,
4001-
const clang::FunctionType *type)
4002-
: ExtInfo(((unsigned) rep)
4003-
| (isPseudogeneric ? PseudogenericMask : 0)
4004-
| (isNoEscape ? NoEscapeMask : 0)
4005-
| (((unsigned)diffKind << DifferentiabilityMaskOffset)
4006-
& DifferentiabilityMask),
4028+
const clang::Type *type)
4029+
: ExtInfo(makeBits(rep, isPseudogeneric, isNoEscape, diffKind),
40074030
Uncommon(type)) {
40084031
}
40094032

4033+
ExtInfo(AnyFunctionType::ExtInfo info, bool isPseudogeneric)
4034+
: ExtInfo(makeBits(info.getSILRepresentation(),
4035+
isPseudogeneric,
4036+
info.isNoEscape(),
4037+
info.getDifferentiabilityKind()),
4038+
info.getUncommonInfo().hasValue()
4039+
? Uncommon(info.getUncommonInfo().getValue())
4040+
: Uncommon(nullptr)) {
4041+
}
4042+
40104043
static ExtInfo getThin() {
40114044
return ExtInfo(Representation::Thin, false, false,
40124045
DifferentiabilityKind::NonDifferentiable, nullptr);
@@ -4093,6 +4126,9 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
40934126
return ExtInfo(NoEscape ? (Bits | NoEscapeMask) : (Bits & ~NoEscapeMask),
40944127
Other);
40954128
}
4129+
ExtInfo withClangFunctionType(const clang::Type *type) const {
4130+
return ExtInfo(Bits, Uncommon(type));
4131+
}
40964132

40974133
std::pair<unsigned, const void *> getFuncAttrKey() const {
40984134
return std::make_pair(Bits, Other.ClangFunctionType);
@@ -4388,7 +4424,7 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
43884424
return WitnessMethodConformance;
43894425
}
43904426

4391-
const clang::FunctionType *getClangFunctionType() const;
4427+
const clang::Type *getClangFunctionType() const;
43924428

43934429
ExtInfo getExtInfo() const {
43944430
return ExtInfo(Bits.SILFunctionType.ExtInfoBits, getClangFunctionType());

include/swift/Frontend/FrontendOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ class FrontendOptions {
253253
/// See the \ref SILOptions.EmitSortedSIL flag.
254254
bool EmitSortedSIL = false;
255255

256+
/// Should we emit the cType when printing @convention(c) or no?
257+
bool PrintFullConvention = false;
258+
256259
/// Indicates whether the dependency tracker should track system
257260
/// dependencies as well.
258261
bool TrackSystemDeps = false;

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ struct ModuleInterfaceOptions {
3131
/// interface, or should we fully-qualify them?
3232
bool PreserveTypesAsWritten = false;
3333

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

3838
/// Copy of all the command-line flags passed at .swiftinterface

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -608,10 +608,12 @@ def module_interface_preserve_types_as_written :
608608
HelpText<"When emitting a module interface, preserve types as they were "
609609
"written in the source">;
610610

611+
// FIXME: [clang-function-type-serialization] Make this a SIL-only option once we
612+
// start unconditionally emitting non-canonical Clang types in swiftinterfaces.
611613
def experimental_print_full_convention :
612614
Flag<["-"], "experimental-print-full-convention">,
613-
HelpText<"When emitting a module interface, emit additional @convention "
614-
"arguments, regardless of whether they were written in the source">;
615+
HelpText<"When emitting a module interface or SIL, emit additional @convention"
616+
" arguments, regardless of whether they were written in the source">;
615617

616618
def prebuilt_module_cache_path :
617619
Separate<["-"], "prebuilt-module-cache-path">,

include/swift/SIL/SILModule.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -647,10 +647,11 @@ class SILModule {
647647
/// \param ShouldSort If set to true sorts functions, vtables, sil global
648648
/// variables, and witness tables by name to ease diffing.
649649
/// \param PrintASTDecls If set to true print AST decls.
650-
void print(raw_ostream &OS, bool Verbose = false,
651-
ModuleDecl *M = nullptr, bool ShouldSort = false,
650+
void print(raw_ostream &OS,
651+
ModuleDecl *M = nullptr,
652+
const SILOptions &Opts = SILOptions(),
652653
bool PrintASTDecls = true) const {
653-
SILPrintContext PrintCtx(OS, Verbose, ShouldSort);
654+
SILPrintContext PrintCtx(OS, Opts);
654655
print(PrintCtx, M, PrintASTDecls);
655656
}
656657

include/swift/SIL/SILPrintContext.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_SIL_PRINTCONTEXT_H
1414
#define SWIFT_SIL_PRINTCONTEXT_H
1515

16+
#include "swift/AST/SILOptions.h"
1617
#include "swift/SIL/SILDebugScope.h"
1718
#include "swift/SIL/SILValue.h"
1819
#include "llvm/ADT/DenseMap.h"
@@ -65,13 +66,21 @@ class SILPrintContext {
6566
/// Print debug locations and scopes.
6667
bool DebugInfo;
6768

69+
/// See \ref FrontendOptions.PrintFullConvention.
70+
bool PrintFullConvention;
71+
6872
public:
6973
/// Constructor with default values for options.
7074
///
7175
/// DebugInfo will be set according to the -sil-print-debuginfo option.
7276
SILPrintContext(llvm::raw_ostream &OS, bool Verbose = false,
7377
bool SortedSIL = false);
7478

79+
/// Constructor based on SILOptions.
80+
///
81+
/// DebugInfo will be set according to the -sil-print-debuginfo option.
82+
SILPrintContext(llvm::raw_ostream &OS, const SILOptions &Opts);
83+
7584
SILPrintContext(llvm::raw_ostream &OS, bool Verbose,
7685
bool SortedSIL, bool DebugInfo);
7786

@@ -94,6 +103,9 @@ class SILPrintContext {
94103
/// Returns true if debug locations and scopes should be printed.
95104
bool printDebugInfo() const { return DebugInfo; }
96105

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

99111
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
@@ -581,7 +581,8 @@ class SILType {
581581

582582
std::string getAsString() const;
583583
void dump() const;
584-
void print(raw_ostream &OS) const;
584+
void print(raw_ostream &OS,
585+
const PrintOptions &PO = PrintOptions::printSIL()) const;
585586
};
586587

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

0 commit comments

Comments
 (0)