41
41
#include " ConstantBuilder.h"
42
42
#include " EnumMetadataVisitor.h"
43
43
#include " FixedTypeInfo.h"
44
+ #include " ForeignClassMetadataVisitor.h"
44
45
#include " GenArchetype.h"
45
46
#include " GenClass.h"
46
47
#include " GenDecl.h"
@@ -296,18 +297,24 @@ llvm::Value *irgen::emitObjCHeapMetadataRef(IRGenFunction &IGF,
296
297
}
297
298
298
299
// / Emit a reference to the type metadata for a foreign type.
299
- static llvm::Value *emitForeignTypeMetadataRef (IRGenFunction &IGF,
300
- CanType type) {
301
- llvm::Value *candidate = IGF.IGM .getAddrOfForeignTypeMetadataCandidate (type);
300
+ static llvm::Value *uniqueForeignTypeMetadataRef (IRGenFunction &IGF,
301
+ llvm::Value *candidate) {
302
302
auto call = IGF.Builder .CreateCall (IGF.IGM .getGetForeignTypeMetadataFn (),
303
- candidate);
303
+ candidate);
304
304
call->addAttribute (llvm::AttributeList::FunctionIndex,
305
305
llvm::Attribute::NoUnwind);
306
306
call->addAttribute (llvm::AttributeList::FunctionIndex,
307
307
llvm::Attribute::ReadNone);
308
308
return call;
309
309
}
310
310
311
+ // / Emit a reference to the type metadata for a foreign type.
312
+ static llvm::Value *emitForeignTypeMetadataRef (IRGenFunction &IGF,
313
+ CanType type) {
314
+ llvm::Value *candidate = IGF.IGM .getAddrOfForeignTypeMetadataCandidate (type);
315
+ return uniqueForeignTypeMetadataRef (IGF, candidate);
316
+ }
317
+
311
318
// / Returns a metadata reference for a nominal type.
312
319
// /
313
320
// / This is only valid in a couple of special cases:
@@ -2189,11 +2196,13 @@ namespace {
2189
2196
// GenericParameterDescriptorFlags Flags;
2190
2197
GenericParameterDescriptorFlags flags;
2191
2198
if (auto *cd = dyn_cast<ClassDecl>(ntd)) {
2192
- auto &layout = IGM.getMetadataLayout (cd);
2193
- if (layout.getVTableSize () > 0 )
2194
- flags = flags.withHasVTable (true );
2195
- if (layout.hasResilientSuperclass ())
2196
- flags = flags.withHasResilientSuperclass (true );
2199
+ if (!cd->isForeign ()) {
2200
+ auto &layout = IGM.getClassMetadataLayout (cd);
2201
+ if (layout.getVTableSize () > 0 )
2202
+ flags = flags.withHasVTable (true );
2203
+ if (layout.hasResilientSuperclass ())
2204
+ flags = flags.withHasResilientSuperclass (true );
2205
+ }
2197
2206
}
2198
2207
2199
2208
// Calculate the number of generic parameters at each nesting depth.
@@ -2428,7 +2437,13 @@ namespace {
2428
2437
ClassDecl *c)
2429
2438
: super(IGM), Target(c)
2430
2439
{
2431
- auto &layout = IGM.getMetadataLayout (Target);
2440
+ if (Target->isForeign ()) {
2441
+ VTable = nullptr ;
2442
+ VTableSize = 0 ;
2443
+ return ;
2444
+ }
2445
+
2446
+ auto &layout = IGM.getClassMetadataLayout (Target);
2432
2447
2433
2448
VTable = IGM.getSILModule ().lookUpVTable (Target);
2434
2449
VTableSize = layout.getVTableSize ();
@@ -2834,7 +2849,7 @@ namespace {
2834
2849
// fill indexes are word-indexed.
2835
2850
auto *metadataWords = IGF.Builder .CreateBitCast (metadataValue, IGM.Int8PtrPtrTy );
2836
2851
2837
- auto genericReqtOffset = IGM.getMetadataLayout (Target)
2852
+ auto genericReqtOffset = IGM.getNominalMetadataLayout (Target)
2838
2853
.getGenericRequirementsOffset (IGF);
2839
2854
2840
2855
for (auto &fillOp : FillOps) {
@@ -3145,7 +3160,7 @@ namespace {
3145
3160
auto fn = entry.Method ;
3146
3161
3147
3162
auto *classDecl = cast<ClassDecl>(fn.getDecl ()->getDeclContext ());
3148
- auto &layout = IGM.getMetadataLayout (classDecl);
3163
+ auto &layout = IGM.getClassMetadataLayout (classDecl);
3149
3164
3150
3165
auto offset = layout.getMethodInfo (IGF, fn).getOffset ();
3151
3166
@@ -3493,7 +3508,7 @@ namespace {
3493
3508
if (!HasResilientSuperclass)
3494
3509
return ;
3495
3510
3496
- auto &layout = IGM.getMetadataLayout (Target);
3511
+ auto &layout = IGM.getClassMetadataLayout (Target);
3497
3512
3498
3513
// Load the size of the superclass metadata.
3499
3514
Address metadataAsBytes (
@@ -3747,7 +3762,7 @@ namespace {
3747
3762
if (doesClassMetadataRequireDynamicInitialization (IGM, Target)) {
3748
3763
auto templateSize = IGM.getSize (Size (B.getNextOffsetFromGlobal ()));
3749
3764
auto numImmediateMembers = IGM.getSize (
3750
- Size (IGM.getMetadataLayout (Target).getNumImmediateMembers ()));
3765
+ Size (IGM.getClassMetadataLayout (Target).getNumImmediateMembers ()));
3751
3766
metadata = IGF.Builder .CreateCall (IGF.IGM .getRelocateClassMetadataFn (),
3752
3767
{metadata, templateSize,
3753
3768
numImmediateMembers});
@@ -3838,7 +3853,7 @@ namespace {
3838
3853
}
3839
3854
3840
3855
auto numImmediateMembers =
3841
- IGM.getSize (Size (IGM.getMetadataLayout (Target).getNumImmediateMembers ()));
3856
+ IGM.getSize (Size (IGM.getClassMetadataLayout (Target).getNumImmediateMembers ()));
3842
3857
3843
3858
return IGF.Builder .CreateCall (IGM.getAllocateGenericClassMetadataFn (),
3844
3859
{metadataPattern, arguments, superMetadata,
@@ -4230,7 +4245,7 @@ std::pair<llvm::Value *, llvm::Value *>
4230
4245
irgen::emitClassResilientInstanceSizeAndAlignMask (IRGenFunction &IGF,
4231
4246
ClassDecl *theClass,
4232
4247
llvm::Value *metadata) {
4233
- auto &layout = IGF.IGM .getMetadataLayout (theClass);
4248
+ auto &layout = IGF.IGM .getClassMetadataLayout (theClass);
4234
4249
4235
4250
Address metadataAsBytes (IGF.Builder .CreateBitCast (metadata, IGF.IGM .Int8PtrTy ),
4236
4251
IGF.IGM .getPointerAlignment ());
@@ -4487,7 +4502,7 @@ FunctionPointer irgen::emitVirtualMethodValue(IRGenFunction &IGF,
4487
4502
auto declaringClass = cast<ClassDecl>(overridden.getDecl ()->getDeclContext ());
4488
4503
4489
4504
auto methodInfo =
4490
- IGF.IGM .getMetadataLayout (declaringClass).getMethodInfo (IGF, overridden);
4505
+ IGF.IGM .getClassMetadataLayout (declaringClass).getMethodInfo (IGF, overridden);
4491
4506
auto offset = methodInfo.getOffset ();
4492
4507
4493
4508
auto slot = IGF.emitAddressAtOffset (metadata, offset,
@@ -4887,36 +4902,6 @@ llvm::Value *IRGenFunction::emitObjCSelectorRefLoad(StringRef selector) {
4887
4902
// ===----------------------------------------------------------------------===//
4888
4903
4889
4904
namespace {
4890
- // / A CRTP layout class for foreign class metadata.
4891
- template <class Impl >
4892
- class ForeignClassMetadataVisitor
4893
- : public NominalMetadataVisitor<Impl> {
4894
- using super = NominalMetadataVisitor<Impl>;
4895
- protected:
4896
- ClassDecl *Target;
4897
- using super::asImpl;
4898
- public:
4899
- ForeignClassMetadataVisitor (IRGenModule &IGM, ClassDecl *target)
4900
- : super(IGM), Target(target) {}
4901
-
4902
- void layout () {
4903
- super::layout ();
4904
- asImpl ().addSuperClass ();
4905
- asImpl ().addReservedWord ();
4906
- asImpl ().addReservedWord ();
4907
- asImpl ().addReservedWord ();
4908
- }
4909
-
4910
- bool requiresInitializationFunction () {
4911
- // TODO: superclasses?
4912
- return false ;
4913
- }
4914
-
4915
- CanType getTargetType () const {
4916
- return Target->getDeclaredType ()->getCanonicalType ();
4917
- }
4918
- };
4919
-
4920
4905
// / An adapter that turns a metadata layout class into a foreign metadata
4921
4906
// / layout class.
4922
4907
// /
@@ -5033,8 +5018,23 @@ namespace {
5033
5018
: ForeignMetadataBuilderBase(IGM, target, B) {}
5034
5019
5035
5020
void emitInitialization (IRGenFunction &IGF, llvm::Value *metadata) {
5036
- // TODO: superclasses?
5037
- llvm_unreachable (" no supported forms of initialization" );
5021
+ // Dig out the address of the superclass field.
5022
+ auto &layout = IGF.IGM .getForeignMetadataLayout (Target);
5023
+ Address metadataWords (IGF.Builder .CreateBitCast (metadata,
5024
+ IGM.Int8PtrPtrTy ),
5025
+ IGM.getPointerAlignment ());
5026
+ auto superclassField =
5027
+ createPointerSizedGEP (IGF, metadataWords,
5028
+ layout.getSuperClassOffset ().getStaticOffset ());
5029
+ superclassField =
5030
+ IGF.Builder .CreateBitCast (
5031
+ superclassField,
5032
+ llvm::PointerType::get (IGM.TypeMetadataPtrTy , 0 ));
5033
+
5034
+ // Unique the superclass field and write it back.
5035
+ auto superclass = IGF.Builder .CreateLoad (superclassField);
5036
+ auto uniquedSuperclass = uniqueForeignTypeMetadataRef (IGF, superclass);
5037
+ IGF.Builder .CreateStore (uniquedSuperclass, superclassField);
5038
5038
}
5039
5039
5040
5040
// Visitor methods.
@@ -5053,9 +5053,26 @@ namespace {
5053
5053
B.addInt (IGM.MetadataKindTy , (unsigned ) MetadataKind::ForeignClass);
5054
5054
}
5055
5055
5056
+ void addNominalTypeDescriptor () {
5057
+ auto descriptor = ClassNominalTypeDescriptorBuilder (this ->IGM , Target).emit ();
5058
+ B.add (descriptor);
5059
+ }
5060
+
5061
+ void noteStartOfSuperClass () { }
5062
+
5056
5063
void addSuperClass () {
5057
- // TODO: superclasses
5058
- B.addNullPointer (IGM.TypeMetadataPtrTy );
5064
+ auto superclassDecl = Target->getSuperclassDecl ();
5065
+ if (!superclassDecl || !superclassDecl->isForeign ()) {
5066
+ B.addNullPointer (IGM.TypeMetadataPtrTy );
5067
+ return ;
5068
+ }
5069
+
5070
+ auto superclassType =
5071
+ superclassDecl->swift ::TypeDecl::getDeclaredInterfaceType ()
5072
+ ->getCanonicalType ();
5073
+ auto superclass =
5074
+ IGM.getAddrOfForeignTypeMetadataCandidate (superclassType);
5075
+ B.add (superclass);
5059
5076
}
5060
5077
5061
5078
void addReservedWord () {
0 commit comments