|
76 | 76 | #include "StructLayout.h" |
77 | 77 | #include "StructMetadataVisitor.h" |
78 | 78 | #include "TupleMetadataVisitor.h" |
| 79 | +#include "FunctionMetadataVisitor.h" |
79 | 80 |
|
80 | 81 | #include "GenMeta.h" |
81 | 82 |
|
@@ -5615,6 +5616,8 @@ void irgen::emitLazySpecializedValueMetadata(IRGenModule &IGM, |
5615 | 5616 |
|
5616 | 5617 | if (isa<TupleType>(valueTy)) { |
5617 | 5618 | emitLazyTupleMetadata(IGM, valueTy); |
| 5619 | + } else if (isa<FunctionType>(valueTy)) { |
| 5620 | + emitLazyFunctionMetadata(IGM, valueTy); |
5618 | 5621 | } else if (valueTy->getStructOrBoundGenericStruct()) { |
5619 | 5622 | emitSpecializedGenericStructMetadata(IGM, valueTy, |
5620 | 5623 | *valueTy.getStructOrBoundGenericStruct()); |
@@ -6327,6 +6330,66 @@ void irgen::emitLazyTupleMetadata(IRGenModule &IGM, CanType tupleTy) { |
6327 | 6330 | IGM.defineTypeMetadata(tupleTy, isPattern, canBeConstant, |
6328 | 6331 | init.finishAndCreateFuture()); |
6329 | 6332 | } |
| 6333 | + |
| 6334 | +// Functions (only used in embedded existentials mode) |
| 6335 | +// |
| 6336 | +namespace { |
| 6337 | +class FunctionMetadataBuilder : public FunctionMetadataVisitor<FunctionMetadataBuilder> { |
| 6338 | + using super = FunctionMetadataVisitor<FunctionMetadataBuilder>; |
| 6339 | + |
| 6340 | + ConstantStructBuilder &B; |
| 6341 | + |
| 6342 | +protected: |
| 6343 | + |
| 6344 | + using super::asImpl; |
| 6345 | + using super::IGM; |
| 6346 | + using super::Target; |
| 6347 | + |
| 6348 | +public: |
| 6349 | + FunctionMetadataBuilder(IRGenModule &IGM, CanType funTy, ConstantStructBuilder &B) : |
| 6350 | + super(IGM, cast<FunctionType>(funTy)), B(B) {} |
| 6351 | + |
| 6352 | + ConstantReference emitValueWitnessTable(bool relativeReference) { |
| 6353 | + return irgen::emitValueWitnessTable(IGM, Target->getCanonicalType(), |
| 6354 | + false, relativeReference); |
| 6355 | + } |
| 6356 | + |
| 6357 | + void addMetadataFlags() { |
| 6358 | + B.addInt(IGM.MetadataKindTy, unsigned(MetadataKind::Function)); |
| 6359 | + } |
| 6360 | + |
| 6361 | + void addValueWitnessTable() { |
| 6362 | + auto vwtPointer = emitValueWitnessTable(false).getValue(); |
| 6363 | + B.addSignedPointer(vwtPointer, |
| 6364 | + IGM.getOptions().PointerAuth.ValueWitnessTable, |
| 6365 | + PointerAuthEntity()); |
| 6366 | + } |
| 6367 | +}; |
| 6368 | +} // end anonymous namespace |
| 6369 | + |
| 6370 | +void irgen::emitLazyFunctionMetadata(IRGenModule &IGM, CanType funTy) { |
| 6371 | + assert(IGM.Context.LangOpts.hasFeature(Feature::EmbeddedExistentials)); |
| 6372 | + assert(isa<FunctionType>(funTy)); |
| 6373 | + |
| 6374 | + Type ty = funTy.getPointer(); |
| 6375 | + auto &context = ty->getASTContext(); |
| 6376 | + PrettyStackTraceType stackTraceRAII( |
| 6377 | + context, "emitting prespecialized metadata for", ty); |
| 6378 | + |
| 6379 | + ConstantInitBuilder initBuilder(IGM); |
| 6380 | + auto init = initBuilder.beginStruct(); |
| 6381 | + init.setPacked(true); |
| 6382 | + |
| 6383 | + bool isPattern = false; |
| 6384 | + bool canBeConstant = true; |
| 6385 | + |
| 6386 | + FunctionMetadataBuilder builder(IGM, funTy, init); |
| 6387 | + builder.embeddedLayout(); |
| 6388 | + |
| 6389 | + IGM.defineTypeMetadata(funTy, isPattern, canBeConstant, |
| 6390 | + init.finishAndCreateFuture()); |
| 6391 | + |
| 6392 | +} |
6330 | 6393 | // Enums |
6331 | 6394 |
|
6332 | 6395 | static std::optional<Size> |
|
0 commit comments