It's in the body of emitValueWitnessTable
, after the early-exit logic to try to use a known value witness table:
ConstantInitBuilder builder(IGM);
auto witnesses = builder.beginArray(IGM.Int8PtrTy);
bool canBeConstant = false;
addValueWitnessesForAbstractType(IGM, witnesses, abstractType, canBeConstant);
// If this is just an instantiation pattern, we should never be modifying
// it in-place.
if (isPattern) canBeConstant = true;
auto addr = IGM.getAddrOfValueWitnessTable(abstractType,
witnesses.finishAndCreateFuture());
auto global = cast<llvm::GlobalVariable>(addr);
global->setConstant(canBeConstant);
return llvm::ConstantExpr::getBitCast(global, IGM.WitnessTablePtrTy);
This part may need to be factored out into an emitValueWitnessTableDefinition
function, that could be reused to lazily define ODR value witness table definitions for known layouts.