42
42
#include " llvm/Support/ErrorHandling.h"
43
43
#include " llvm/Support/TrailingObjects.h"
44
44
45
+ namespace clang {
46
+ class Type ;
47
+ class FunctionType ;
48
+ } // namespace clang
49
+
45
50
namespace llvm {
46
51
struct fltSemantics ;
47
52
} // namespace llvm
@@ -332,11 +337,11 @@ class alignas(1 << TypeAlignInBits) TypeBase {
332
337
Flags : NumFlagBits
333
338
);
334
339
335
- SWIFT_INLINE_BITFIELD_FULL (AnyFunctionType, TypeBase, NumAFTExtInfoBits+16 ,
340
+ SWIFT_INLINE_BITFIELD_FULL (AnyFunctionType, TypeBase, NumAFTExtInfoBits+1 + 16 ,
336
341
// / Extra information which affects how the function is called, like
337
342
// / regparm and the calling convention.
338
- ExtInfo : NumAFTExtInfoBits,
339
-
343
+ ExtInfoBits : NumAFTExtInfoBits,
344
+ HasUncommonInfo : 1 ,
340
345
: NumPadBits,
341
346
NumParams : 16
342
347
);
@@ -357,8 +362,9 @@ class alignas(1 << TypeAlignInBits) TypeBase {
357
362
ID : 32
358
363
);
359
364
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 ,
362
368
CalleeConvention : 3 ,
363
369
HasErrorResult : 1 ,
364
370
CoroutineKind : 2
@@ -2897,30 +2903,59 @@ class AnyFunctionType : public TypeBase {
2897
2903
2898
2904
unsigned Bits; // Naturally sized for speed.
2899
2905
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 ;
2901
2934
2902
- friend class AnyFunctionType ;
2903
-
2904
2935
public:
2905
2936
// 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 ) {
2908
2941
}
2909
2942
2910
2943
// 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 ) {
2913
2947
}
2914
2948
2915
2949
// 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)) {
2924
2959
}
2925
2960
2926
2961
bool isNoEscape () const { return Bits & NoEscapeMask; }
@@ -2980,25 +3015,25 @@ class AnyFunctionType : public TypeBase {
2980
3015
LLVM_NODISCARD
2981
3016
ExtInfo withRepresentation (Representation Rep) const {
2982
3017
return ExtInfo ((Bits & ~RepresentationMask)
2983
- | (unsigned )Rep);
3018
+ | (unsigned )Rep, Other );
2984
3019
}
2985
3020
LLVM_NODISCARD
2986
3021
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);
2991
3024
}
2992
3025
LLVM_NODISCARD
2993
3026
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));
2998
3033
}
2999
3034
3000
- unsigned getFuncAttrKey () const {
3001
- return Bits;
3035
+ std::pair< unsigned , const void *> getFuncAttrKey () const {
3036
+ return std::make_pair ( Bits, Other. ClangFunctionType ) ;
3002
3037
}
3003
3038
3004
3039
// / Put a SIL representation in the ExtInfo.
@@ -3008,7 +3043,7 @@ class AnyFunctionType : public TypeBase {
3008
3043
// / don't need to be parsed, printed, or serialized.
3009
3044
ExtInfo withSILRepresentation (SILFunctionTypeRepresentation Rep) const {
3010
3045
return ExtInfo ((Bits & ~RepresentationMask)
3011
- | (unsigned )Rep);
3046
+ | (unsigned )Rep, Other );
3012
3047
}
3013
3048
3014
3049
SILFunctionTypeRepresentation getSILRepresentation () const {
@@ -3029,11 +3064,13 @@ class AnyFunctionType : public TypeBase {
3029
3064
Type Output, RecursiveTypeProperties properties,
3030
3065
unsigned NumParams, ExtInfo Info)
3031
3066
: TypeBase(Kind, CanTypeContext, properties), Output(Output) {
3032
- Bits.AnyFunctionType .ExtInfo = Info.Bits ;
3067
+ Bits.AnyFunctionType .ExtInfoBits = Info.Bits ;
3068
+ Bits.AnyFunctionType .HasUncommonInfo = false ;
3033
3069
Bits.AnyFunctionType .NumParams = NumParams;
3034
3070
assert (Bits.AnyFunctionType .NumParams == NumParams && " Params dropped!" );
3035
3071
// 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!" );
3037
3074
static_assert (ExtInfo::NumMaskBits == NumAFTExtInfoBits,
3038
3075
" ExtInfo and AnyFunctionTypeBitfields must agree on bit size" );
3039
3076
}
@@ -3071,8 +3108,20 @@ class AnyFunctionType : public TypeBase {
3071
3108
3072
3109
GenericSignature getOptGenericSignature () const ;
3073
3110
3111
+ bool hasClangFunctionType () const {
3112
+ return Bits.AnyFunctionType .HasUncommonInfo ;
3113
+ }
3114
+
3115
+ const clang::Type *getClangFunctionType () const ;
3116
+ const clang::Type *getCanonicalClangFunctionType () const ;
3117
+
3074
3118
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 ());
3076
3125
}
3077
3126
3078
3127
// / Get the representation of the function type.
@@ -3753,7 +3802,7 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
3753
3802
// If bits are added or removed, then TypeBase::SILFunctionTypeBits
3754
3803
// and NumMaskBits must be updated, and they must match.
3755
3804
3756
- // |representation|pseudogeneric| noescape |differentiability|
3805
+ // |representation|pseudogeneric|noescape|differentiability|
3757
3806
// | 0 .. 3 | 4 | 5 | 6 .. 7 |
3758
3807
//
3759
3808
enum : unsigned {
@@ -3767,22 +3816,43 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
3767
3816
3768
3817
unsigned Bits; // Naturally sized for speed.
3769
3818
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) {}
3771
3835
3772
3836
friend class SILFunctionType ;
3773
-
3774
3837
public:
3775
3838
// Constructor with all defaults.
3776
- ExtInfo () : Bits(0 ) { }
3839
+ ExtInfo () : Bits(0 ), Other(Uncommon( nullptr )) { }
3777
3840
3778
3841
// Constructor for polymorphic type.
3779
3842
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 );
3786
3856
}
3787
3857
3788
3858
// / Is this function pseudo-generic? A pseudo-generic function
@@ -3849,23 +3919,21 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
3849
3919
// the following with methods instead of mutating these objects.
3850
3920
ExtInfo withRepresentation (Representation Rep) const {
3851
3921
return ExtInfo ((Bits & ~RepresentationMask)
3852
- | (unsigned )Rep);
3922
+ | (unsigned )Rep, Other );
3853
3923
}
3854
3924
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 );
3859
3929
}
3860
3930
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);
3865
3933
}
3866
3934
3867
- unsigned getFuncAttrKey () const {
3868
- return Bits;
3935
+ std::pair< unsigned , const void *> getFuncAttrKey () const {
3936
+ return std::make_pair ( Bits, Other. ClangFunctionType ) ;
3869
3937
}
3870
3938
3871
3939
bool operator ==(ExtInfo Other) const {
@@ -4176,7 +4244,11 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
4176
4244
return WitnessMethodConformance;
4177
4245
}
4178
4246
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
+ }
4180
4252
4181
4253
// / Returns the language-level calling convention of the function.
4182
4254
Language getLanguage () const {
0 commit comments