Skip to content

Commit 8021795

Browse files
[AST] Setup AST and SIL to accomodate Clang function types.
We still don't store compute or store the type anywhere; we will do so in later commits.
1 parent a4faab4 commit 8021795

File tree

14 files changed

+236
-113
lines changed

14 files changed

+236
-113
lines changed

include/swift/AST/Types.h

Lines changed: 129 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
4242
#include "llvm/Support/ErrorHandling.h"
4343
#include "llvm/Support/TrailingObjects.h"
4444

45+
namespace clang {
46+
class Type;
47+
class FunctionType;
48+
} // namespace clang
49+
4550
namespace llvm {
4651
struct fltSemantics;
4752
} // namespace llvm
@@ -332,11 +337,11 @@ class alignas(1 << TypeAlignInBits) TypeBase {
332337
Flags : NumFlagBits
333338
);
334339

335-
SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+16,
340+
SWIFT_INLINE_BITFIELD_FULL(AnyFunctionType, TypeBase, NumAFTExtInfoBits+1+16,
336341
/// Extra information which affects how the function is called, like
337342
/// regparm and the calling convention.
338-
ExtInfo : NumAFTExtInfoBits,
339-
343+
ExtInfoBits : NumAFTExtInfoBits,
344+
HasUncommonInfo : 1,
340345
: NumPadBits,
341346
NumParams : 16
342347
);
@@ -357,8 +362,9 @@ class alignas(1 << TypeAlignInBits) TypeBase {
357362
ID : 32
358363
);
359364

360-
SWIFT_INLINE_BITFIELD(SILFunctionType, TypeBase, NumSILExtInfoBits+3+1+2,
361-
ExtInfo : NumSILExtInfoBits,
365+
SWIFT_INLINE_BITFIELD(SILFunctionType, TypeBase, NumSILExtInfoBits+1+3+1+2,
366+
ExtInfoBits : NumSILExtInfoBits,
367+
HasUncommonInfo : 1,
362368
CalleeConvention : 3,
363369
HasErrorResult : 1,
364370
CoroutineKind : 2
@@ -2897,30 +2903,59 @@ class AnyFunctionType : public TypeBase {
28972903

28982904
unsigned Bits; // Naturally sized for speed.
28992905

2900-
ExtInfo(unsigned Bits) : Bits(Bits) {}
2906+
public:
2907+
class Uncommon {
2908+
friend ExtInfo;
2909+
friend class AnyFunctionType;
2910+
friend class FunctionType;
2911+
// We preserve a full clang::Type *, not a clang::FunctionType *, so
2912+
// we can keep sugar in case we need to present an error to the user.
2913+
const clang::Type *ClangFunctionType;
2914+
2915+
bool empty() const { return !ClangFunctionType; }
2916+
Uncommon(const clang::Type *type) : ClangFunctionType(type) {}
2917+
};
2918+
2919+
private:
2920+
Uncommon Other;
2921+
2922+
static void assertIsFunctionType(const clang::Type *);
2923+
2924+
ExtInfo(unsigned Bits, Uncommon Other) : Bits(Bits), Other(Other) {
2925+
// TODO: [store-sil-clang-function-type] Once we start serializing
2926+
// the Clang type, we should also assert that the pointer is non-null.
2927+
auto Rep = Representation(Bits & RepresentationMask);
2928+
if ((Rep == Representation::CFunctionPointer) && Other.ClangFunctionType)
2929+
assertIsFunctionType(Other.ClangFunctionType);
2930+
}
2931+
2932+
friend AnyFunctionType;
2933+
friend class FunctionType;
29012934

2902-
friend class AnyFunctionType;
2903-
29042935
public:
29052936
// Constructor with all defaults.
2906-
ExtInfo() : Bits(0) {
2907-
assert(getRepresentation() == Representation::Swift);
2937+
ExtInfo()
2938+
: ExtInfo(Representation::Swift, false, false,
2939+
DifferentiabilityKind::NonDifferentiable,
2940+
nullptr) {
29082941
}
29092942

29102943
// Constructor for polymorphic type.
2911-
ExtInfo(Representation Rep, bool Throws) {
2912-
Bits = ((unsigned) Rep) | (Throws ? ThrowsMask : 0);
2944+
ExtInfo(Representation Rep, bool Throws)
2945+
: ExtInfo(Rep, false, Throws, DifferentiabilityKind::NonDifferentiable,
2946+
nullptr) {
29132947
}
29142948

29152949
// Constructor with no defaults.
2916-
ExtInfo(Representation Rep,
2917-
bool IsNoEscape,
2918-
bool Throws,
2919-
DifferentiabilityKind DiffKind)
2920-
: ExtInfo(Rep, Throws) {
2921-
Bits |= (IsNoEscape ? NoEscapeMask : 0);
2922-
Bits |= ((unsigned)DiffKind << DifferentiabilityMaskOffset) &
2923-
DifferentiabilityMask;
2950+
ExtInfo(Representation Rep, bool IsNoEscape, bool Throws,
2951+
DifferentiabilityKind DiffKind,
2952+
const clang::Type *type)
2953+
: ExtInfo(((unsigned) Rep)
2954+
| (IsNoEscape ? NoEscapeMask : 0)
2955+
| (Throws ? ThrowsMask : 0)
2956+
| (((unsigned)DiffKind << DifferentiabilityMaskOffset)
2957+
& DifferentiabilityMask),
2958+
Uncommon(type)) {
29242959
}
29252960

29262961
bool isNoEscape() const { return Bits & NoEscapeMask; }
@@ -2980,25 +3015,25 @@ class AnyFunctionType : public TypeBase {
29803015
LLVM_NODISCARD
29813016
ExtInfo withRepresentation(Representation Rep) const {
29823017
return ExtInfo((Bits & ~RepresentationMask)
2983-
| (unsigned)Rep);
3018+
| (unsigned)Rep, Other);
29843019
}
29853020
LLVM_NODISCARD
29863021
ExtInfo withNoEscape(bool NoEscape = true) const {
2987-
if (NoEscape)
2988-
return ExtInfo(Bits | NoEscapeMask);
2989-
else
2990-
return ExtInfo(Bits & ~NoEscapeMask);
3022+
return ExtInfo(NoEscape ? (Bits | NoEscapeMask) : (Bits & ~NoEscapeMask),
3023+
Other);
29913024
}
29923025
LLVM_NODISCARD
29933026
ExtInfo withThrows(bool Throws = true) const {
2994-
if (Throws)
2995-
return ExtInfo(Bits | ThrowsMask);
2996-
else
2997-
return ExtInfo(Bits & ~ThrowsMask);
3027+
return ExtInfo(Throws ? (Bits | ThrowsMask) : (Bits & ~ThrowsMask),
3028+
Other);
3029+
}
3030+
LLVM_NODISCARD
3031+
ExtInfo withClangFunctionType(const clang::Type *type) const {
3032+
return ExtInfo(Bits, Uncommon(type));
29983033
}
29993034

3000-
unsigned getFuncAttrKey() const {
3001-
return Bits;
3035+
std::pair<unsigned, const void *> getFuncAttrKey() const {
3036+
return std::make_pair(Bits, Other.ClangFunctionType);
30023037
}
30033038

30043039
/// Put a SIL representation in the ExtInfo.
@@ -3008,7 +3043,7 @@ class AnyFunctionType : public TypeBase {
30083043
/// don't need to be parsed, printed, or serialized.
30093044
ExtInfo withSILRepresentation(SILFunctionTypeRepresentation Rep) const {
30103045
return ExtInfo((Bits & ~RepresentationMask)
3011-
| (unsigned)Rep);
3046+
| (unsigned)Rep, Other);
30123047
}
30133048

30143049
SILFunctionTypeRepresentation getSILRepresentation() const {
@@ -3029,11 +3064,13 @@ class AnyFunctionType : public TypeBase {
30293064
Type Output, RecursiveTypeProperties properties,
30303065
unsigned NumParams, ExtInfo Info)
30313066
: TypeBase(Kind, CanTypeContext, properties), Output(Output) {
3032-
Bits.AnyFunctionType.ExtInfo = Info.Bits;
3067+
Bits.AnyFunctionType.ExtInfoBits = Info.Bits;
3068+
Bits.AnyFunctionType.HasUncommonInfo = false;
30333069
Bits.AnyFunctionType.NumParams = NumParams;
30343070
assert(Bits.AnyFunctionType.NumParams == NumParams && "Params dropped!");
30353071
// The use of both assert() and static_assert() is intentional.
3036-
assert(Bits.AnyFunctionType.ExtInfo == Info.Bits && "Bits were dropped!");
3072+
assert(Bits.AnyFunctionType.ExtInfoBits == Info.Bits
3073+
&& "Bits were dropped!");
30373074
static_assert(ExtInfo::NumMaskBits == NumAFTExtInfoBits,
30383075
"ExtInfo and AnyFunctionTypeBitfields must agree on bit size");
30393076
}
@@ -3071,8 +3108,20 @@ class AnyFunctionType : public TypeBase {
30713108

30723109
GenericSignature getOptGenericSignature() const;
30733110

3111+
bool hasClangFunctionType() const {
3112+
return Bits.AnyFunctionType.HasUncommonInfo;
3113+
}
3114+
3115+
const clang::Type *getClangFunctionType() const;
3116+
const clang::Type *getCanonicalClangFunctionType() const;
3117+
30743118
ExtInfo getExtInfo() const {
3075-
return ExtInfo(Bits.AnyFunctionType.ExtInfo);
3119+
return ExtInfo(Bits.AnyFunctionType.ExtInfoBits, getClangFunctionType());
3120+
}
3121+
3122+
ExtInfo getCanonicalExtInfo() const {
3123+
return ExtInfo(Bits.AnyFunctionType.ExtInfoBits,
3124+
getCanonicalClangFunctionType());
30763125
}
30773126

30783127
/// Get the representation of the function type.
@@ -3753,7 +3802,7 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
37533802
// If bits are added or removed, then TypeBase::SILFunctionTypeBits
37543803
// and NumMaskBits must be updated, and they must match.
37553804

3756-
// |representation|pseudogeneric| noescape |differentiability|
3805+
// |representation|pseudogeneric|noescape|differentiability|
37573806
// | 0 .. 3 | 4 | 5 | 6 .. 7 |
37583807
//
37593808
enum : unsigned {
@@ -3767,22 +3816,43 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
37673816

37683817
unsigned Bits; // Naturally sized for speed.
37693818

3770-
ExtInfo(unsigned Bits) : Bits(Bits) {}
3819+
class Uncommon {
3820+
friend ExtInfo;
3821+
friend class SILFunctionType;
3822+
3823+
// Invariant: The FunctionType is canonical.
3824+
// We store a clang::FunctionType * instead of a clang::CanQualType to
3825+
// avoid depending on the Clang AST in this header.
3826+
const clang::FunctionType *ClangFunctionType;
3827+
3828+
bool empty() const { return !ClangFunctionType; }
3829+
Uncommon(const clang::FunctionType *type) : ClangFunctionType(type) {}
3830+
};
3831+
3832+
Uncommon Other;
3833+
3834+
ExtInfo(unsigned Bits, Uncommon Other) : Bits(Bits), Other(Other) {}
37713835

37723836
friend class SILFunctionType;
3773-
37743837
public:
37753838
// Constructor with all defaults.
3776-
ExtInfo() : Bits(0) { }
3839+
ExtInfo() : Bits(0), Other(Uncommon(nullptr)) { }
37773840

37783841
// Constructor for polymorphic type.
37793842
ExtInfo(Representation rep, bool isPseudogeneric, bool isNoEscape,
3780-
DifferentiabilityKind diffKind) {
3781-
Bits = ((unsigned) rep) |
3782-
(isPseudogeneric ? PseudogenericMask : 0) |
3783-
(isNoEscape ? NoEscapeMask : 0) |
3784-
(((unsigned)diffKind << DifferentiabilityMaskOffset) &
3785-
DifferentiabilityMask);
3843+
DifferentiabilityKind diffKind,
3844+
const clang::FunctionType *type)
3845+
: ExtInfo(((unsigned) rep)
3846+
| (isPseudogeneric ? PseudogenericMask : 0)
3847+
| (isNoEscape ? NoEscapeMask : 0)
3848+
| (((unsigned)diffKind << DifferentiabilityMaskOffset)
3849+
& DifferentiabilityMask),
3850+
Uncommon(type)) {
3851+
}
3852+
3853+
static ExtInfo getThin() {
3854+
return ExtInfo(Representation::Thin, false, false,
3855+
DifferentiabilityKind::NonDifferentiable, nullptr);
37863856
}
37873857

37883858
/// Is this function pseudo-generic? A pseudo-generic function
@@ -3849,23 +3919,21 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
38493919
// the following with methods instead of mutating these objects.
38503920
ExtInfo withRepresentation(Representation Rep) const {
38513921
return ExtInfo((Bits & ~RepresentationMask)
3852-
| (unsigned)Rep);
3922+
| (unsigned)Rep, Other);
38533923
}
38543924
ExtInfo withIsPseudogeneric(bool isPseudogeneric = true) const {
3855-
if (isPseudogeneric)
3856-
return ExtInfo(Bits | PseudogenericMask);
3857-
else
3858-
return ExtInfo(Bits & ~PseudogenericMask);
3925+
return ExtInfo(isPseudogeneric
3926+
? (Bits | PseudogenericMask)
3927+
: (Bits & ~PseudogenericMask),
3928+
Other);
38593929
}
38603930
ExtInfo withNoEscape(bool NoEscape = true) const {
3861-
if (NoEscape)
3862-
return ExtInfo(Bits | NoEscapeMask);
3863-
else
3864-
return ExtInfo(Bits & ~NoEscapeMask);
3931+
return ExtInfo(NoEscape ? (Bits | NoEscapeMask) : (Bits & ~NoEscapeMask),
3932+
Other);
38653933
}
38663934

3867-
unsigned getFuncAttrKey() const {
3868-
return Bits;
3935+
std::pair<unsigned, const void *> getFuncAttrKey() const {
3936+
return std::make_pair(Bits, Other.ClangFunctionType);
38693937
}
38703938

38713939
bool operator==(ExtInfo Other) const {
@@ -4176,7 +4244,11 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
41764244
return WitnessMethodConformance;
41774245
}
41784246

4179-
ExtInfo getExtInfo() const { return ExtInfo(Bits.SILFunctionType.ExtInfo); }
4247+
const clang::FunctionType *getClangFunctionType() const;
4248+
4249+
ExtInfo getExtInfo() const {
4250+
return ExtInfo(Bits.SILFunctionType.ExtInfoBits, getClangFunctionType());
4251+
}
41804252

41814253
/// Returns the language-level calling convention of the function.
41824254
Language getLanguage() const {

lib/AST/ASTContext.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2975,7 +2975,9 @@ void FunctionType::Profile(llvm::FoldingSetNodeID &ID,
29752975
ExtInfo info) {
29762976
profileParams(ID, params);
29772977
ID.AddPointer(result.getPointer());
2978-
ID.AddInteger(info.getFuncAttrKey());
2978+
auto infoKey = info.getFuncAttrKey();
2979+
ID.AddInteger(infoKey.first);
2980+
ID.AddPointer(infoKey.second);
29792981
}
29802982

29812983
FunctionType *FunctionType::get(ArrayRef<AnyFunctionType::Param> params,
@@ -3026,7 +3028,9 @@ void GenericFunctionType::Profile(llvm::FoldingSetNodeID &ID,
30263028
ID.AddPointer(sig.getPointer());
30273029
profileParams(ID, params);
30283030
ID.AddPointer(result.getPointer());
3029-
ID.AddInteger(info.getFuncAttrKey());
3031+
auto infoKey = info.getFuncAttrKey();
3032+
ID.AddInteger(infoKey.first);
3033+
ID.AddPointer(infoKey.second);
30303034
}
30313035

30323036
GenericFunctionType *GenericFunctionType::get(GenericSignature sig,
@@ -3121,7 +3125,9 @@ void SILFunctionType::Profile(
31213125
bool isGenericSignatureImplied,
31223126
SubstitutionMap substitutions) {
31233127
id.AddPointer(genericParams.getPointer());
3124-
id.AddInteger(info.getFuncAttrKey());
3128+
auto infoKey = info.getFuncAttrKey();
3129+
id.AddInteger(infoKey.first);
3130+
id.AddPointer(infoKey.second);
31253131
id.AddInteger(unsigned(coroutineKind));
31263132
id.AddInteger(unsigned(calleeConvention));
31273133
id.AddInteger(params.size());
@@ -3165,9 +3171,10 @@ SILFunctionType::SILFunctionType(
31653171
Substitutions(substitutions) {
31663172

31673173
Bits.SILFunctionType.HasErrorResult = errorResult.hasValue();
3168-
Bits.SILFunctionType.ExtInfo = ext.Bits;
3174+
Bits.SILFunctionType.ExtInfoBits = ext.Bits;
3175+
Bits.SILFunctionType.HasUncommonInfo = false;
31693176
// The use of both assert() and static_assert() below is intentional.
3170-
assert(Bits.SILFunctionType.ExtInfo == ext.Bits && "Bits were dropped!");
3177+
assert(Bits.SILFunctionType.ExtInfoBits == ext.Bits && "Bits were dropped!");
31713178
static_assert(ExtInfo::NumMaskBits == NumSILExtInfoBits,
31723179
"ExtInfo and SILFunctionTypeBitfields must agree on bit size");
31733180
Bits.SILFunctionType.CoroutineKind = unsigned(coroutineKind);

lib/AST/ASTDemangler.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,11 @@ Type ASTBuilder::createImplFunctionType(
479479
break;
480480
}
481481

482+
// TODO: [store-sil-clang-function-type]
482483
auto einfo = SILFunctionType::ExtInfo(
483484
representation, flags.isPseudogeneric(), !flags.isEscaping(),
484-
DifferentiabilityKind::NonDifferentiable);
485+
DifferentiabilityKind::NonDifferentiable,
486+
/*clangFunctionType*/ nullptr);
485487

486488
llvm::SmallVector<SILParameterInfo, 8> funcParams;
487489
llvm::SmallVector<SILYieldInfo, 8> funcYields;

lib/AST/ASTDumper.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "swift/Basic/Defer.h"
2828
#include "swift/Basic/QuotedString.h"
2929
#include "swift/Basic/STLExtras.h"
30+
#include "clang/AST/Type.h"
3031
#include "llvm/ADT/APFloat.h"
3132
#include "llvm/ADT/Optional.h"
3233
#include "llvm/ADT/SmallString.h"

0 commit comments

Comments
 (0)