18
18
#include " swift/ABI/TypeIdentity.h"
19
19
#include " swift/AST/ASTContext.h"
20
20
#include " swift/AST/ASTMangler.h"
21
+ #include " swift/AST/Attr.h"
21
22
#include " swift/AST/CanTypeVisitor.h"
22
23
#include " swift/AST/Decl.h"
23
- #include " swift/AST/Attr .h"
24
+ #include " swift/AST/GenericEnvironment .h"
24
25
#include " swift/AST/IRGenOptions.h"
25
26
#include " swift/AST/PrettyStackTrace.h"
26
27
#include " swift/AST/SubstitutionMap.h"
31
32
#include " swift/SIL/SILModule.h"
32
33
#include " swift/SIL/TypeLowering.h"
33
34
#include " swift/Strings.h"
35
+ #include " clang/AST/Decl.h"
36
+ #include " clang/AST/DeclObjC.h"
34
37
#include " llvm/ADT/SmallString.h"
35
38
#include " llvm/IR/DerivedTypes.h"
36
39
#include " llvm/IR/Function.h"
37
40
#include " llvm/IR/GlobalVariable.h"
38
41
#include " llvm/IR/Module.h"
39
- #include " clang/AST/Decl.h"
40
- #include " clang/AST/DeclObjC.h"
41
42
42
43
#include " Address.h"
43
44
#include " Callee.h"
@@ -3474,23 +3475,31 @@ namespace {
3474
3475
return descriptor;
3475
3476
}
3476
3477
3478
+ llvm::Constant *getNominalTypeDescriptor () {
3479
+ return emitNominalTypeDescriptor ();
3480
+ }
3481
+
3477
3482
void addNominalTypeDescriptor () {
3478
- B.add (emitNominalTypeDescriptor ());
3483
+ B.add (asImpl (). getNominalTypeDescriptor ());
3479
3484
}
3480
3485
3481
3486
ConstantReference emitValueWitnessTable (bool relativeReference) {
3482
3487
auto type = this ->Target ->getDeclaredType ()->getCanonicalType ();
3483
3488
return irgen::emitValueWitnessTable (IGM, type, false , relativeReference);
3484
3489
}
3485
3490
3491
+ ConstantReference getValueWitnessTable (bool relativeReference) {
3492
+ return emitValueWitnessTable (relativeReference);
3493
+ }
3494
+
3486
3495
void addValueWitnessTable () {
3487
- B.add (emitValueWitnessTable (false ).getValue ());
3496
+ B.add (asImpl (). getValueWitnessTable (false ).getValue ());
3488
3497
}
3489
3498
3490
3499
void addFieldOffset (VarDecl *var) {
3491
3500
assert (var->hasStorage () &&
3492
3501
" storing field offset for computed property?!" );
3493
- SILType structType = getLoweredType ();
3502
+ SILType structType = asImpl (). getLoweredType ();
3494
3503
3495
3504
llvm::Constant *offset =
3496
3505
emitPhysicalStructMemberFixedOffset (IGM, structType, var);
@@ -3515,6 +3524,22 @@ namespace {
3515
3524
void addGenericWitnessTable (GenericRequirement requirement) {
3516
3525
llvm_unreachable (" Concrete type metadata cannot have generic requirements" );
3517
3526
}
3527
+
3528
+ bool hasTrailingFlags () {
3529
+ return IGM.shouldPrespecializeGenericMetadata ();
3530
+ }
3531
+
3532
+ void addTrailingFlags () {
3533
+ auto flags = asImpl ().getTrailingFlags ();
3534
+
3535
+ B.addInt (IGM.Int64Ty , flags.getOpaqueValue ());
3536
+ }
3537
+
3538
+ MetadataTrailingFlags getTrailingFlags () {
3539
+ MetadataTrailingFlags flags;
3540
+
3541
+ return flags;
3542
+ }
3518
3543
};
3519
3544
3520
3545
class StructMetadataBuilder :
@@ -3587,6 +3612,16 @@ namespace {
3587
3612
return StructContextDescriptorBuilder (IGM, Target, RequireMetadata).emit ();
3588
3613
}
3589
3614
3615
+ GenericMetadataPatternFlags getPatternFlags () {
3616
+ auto flags = super::getPatternFlags ();
3617
+
3618
+ if (IGM.shouldPrespecializeGenericMetadata ()) {
3619
+ flags.setHasTrailingFlags (true );
3620
+ }
3621
+
3622
+ return flags;
3623
+ }
3624
+
3590
3625
ConstantReference emitValueWitnessTable (bool relativeReference) {
3591
3626
assert (relativeReference && " should only relative reference" );
3592
3627
return getValueWitnessTableForGenericValueType (IGM, Target,
@@ -3646,10 +3681,96 @@ namespace {
3646
3681
vectorSize };
3647
3682
}
3648
3683
3684
+ void addTrailingFlags () { this ->B .addInt (IGM.Int64Ty , 0 ); }
3685
+
3649
3686
bool hasCompletionFunction () {
3650
3687
return !isa<FixedTypeInfo>(IGM.getTypeInfo (getLoweredType ()));
3651
3688
}
3652
3689
};
3690
+
3691
+ class SpecializedGenericStructMetadataBuilder
3692
+ : public StructMetadataBuilderBase<
3693
+ SpecializedGenericStructMetadataBuilder> {
3694
+ using super =
3695
+ StructMetadataBuilderBase<SpecializedGenericStructMetadataBuilder>;
3696
+ CanType type;
3697
+ bool HasUnfilledFieldOffset = false ;
3698
+
3699
+ protected:
3700
+ using super::asImpl;
3701
+ using super::getLoweredType;
3702
+ using super::IGM;
3703
+ using super::Target;
3704
+
3705
+ public:
3706
+ SpecializedGenericStructMetadataBuilder (IRGenModule &IGM, CanType type,
3707
+ StructDecl &decl,
3708
+ ConstantStructBuilder &B)
3709
+ : super(IGM, &decl, B), type(type) {}
3710
+
3711
+ void noteStartOfTypeSpecificMembers () {}
3712
+
3713
+ llvm::Constant *getNominalTypeDescriptor () {
3714
+ return IGM.getAddrOfTypeContextDescriptor (Target, RequireMetadata);
3715
+ }
3716
+
3717
+ SILType getLoweredType () { return SILType::getPrimitiveObjectType (type); }
3718
+
3719
+ ConstantReference getValueWitnessTable (bool relativeReference) {
3720
+ auto type = this ->Target ->getDeclaredType ()->getCanonicalType ();
3721
+ return ConstantReference (IGM.getAddrOfEffectiveValueWitnessTable (type),
3722
+ irgen::ConstantReference::Direct);
3723
+ }
3724
+
3725
+ void addGenericArgument (GenericRequirement requirement) {
3726
+ auto t = requirement.TypeParameter .subst (genericSubstitutions ());
3727
+ ConstantReference ref = IGM.getAddrOfTypeMetadata (
3728
+ CanType (t), SymbolReferenceKind::Relative_Direct);
3729
+ B.add (ref.getDirectValue ());
3730
+ }
3731
+
3732
+ void addGenericWitnessTable (GenericRequirement requirement) {
3733
+ auto conformance = genericSubstitutions ().lookupConformance (
3734
+ requirement.TypeParameter ->getCanonicalType (), requirement.Protocol );
3735
+ ProtocolConformance *concreteConformance = conformance.getConcrete ();
3736
+
3737
+ llvm::Constant *addr;
3738
+
3739
+ Type argument = requirement.TypeParameter .subst (genericSubstitutions ());
3740
+ auto argumentNominal = argument->getAnyNominal ();
3741
+ if (argumentNominal && argumentNominal->isGenericContext ()) {
3742
+ // TODO: Statically specialize the witness table pattern for t's
3743
+ // conformance.
3744
+ llvm_unreachable (" Statically specializing metadata at generic types is "
3745
+ " not supported." );
3746
+ } else {
3747
+ RootProtocolConformance *rootConformance =
3748
+ concreteConformance->getRootConformance ();
3749
+ addr = IGM.getAddrOfWitnessTable (rootConformance);
3750
+ }
3751
+
3752
+ B.add (addr);
3753
+ }
3754
+
3755
+ SubstitutionMap genericSubstitutions () {
3756
+ return type->getContextSubstitutionMap (IGM.getSwiftModule (),
3757
+ type->getAnyNominal ());
3758
+ }
3759
+
3760
+ MetadataTrailingFlags getTrailingFlags () {
3761
+ MetadataTrailingFlags flags = super::getTrailingFlags ();
3762
+
3763
+ flags.setIsStaticSpecialization (true );
3764
+ flags.setIsCanonicalStaticSpecialization (true );
3765
+
3766
+ return flags;
3767
+ }
3768
+
3769
+ void flagUnfilledFieldOffset () { HasUnfilledFieldOffset = true ; }
3770
+
3771
+ bool canBeConstant () { return !HasUnfilledFieldOffset; }
3772
+ };
3773
+
3653
3774
} // end anonymous namespace
3654
3775
3655
3776
// / Emit the type metadata or metadata template for a struct.
@@ -3683,9 +3804,26 @@ void irgen::emitStructMetadata(IRGenModule &IGM, StructDecl *structDecl) {
3683
3804
init.finishAndCreateFuture ());
3684
3805
}
3685
3806
3686
- // / Emit the type metadata or metadata template for a struct.
3687
3807
void irgen::emitSpecializedGenericStructMetadata (IRGenModule &IGM,
3688
- CanType type) {}
3808
+ CanType type) {
3809
+ Type ty = type.getPointer ();
3810
+ auto &context = type->getNominalOrBoundGenericNominal ()->getASTContext ();
3811
+ PrettyStackTraceType stackTraceRAII (
3812
+ context, " emitting prespecialized metadata for" , ty);
3813
+ ConstantInitBuilder initBuilder (IGM);
3814
+ auto init = initBuilder.beginStruct ();
3815
+ init.setPacked (true );
3816
+
3817
+ bool isPattern = false ;
3818
+
3819
+ auto &decl = *type.getStructOrBoundGenericStruct ();
3820
+ SpecializedGenericStructMetadataBuilder builder (IGM, type, decl, init);
3821
+ builder.layout ();
3822
+
3823
+ bool canBeConstant = builder.canBeConstant ();
3824
+ IGM.defineTypeMetadata (type, isPattern, canBeConstant,
3825
+ init.finishAndCreateFuture ());
3826
+ }
3689
3827
3690
3828
// Enums
3691
3829
0 commit comments