@@ -8016,27 +8016,38 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
8016
8016
irSatisfyingWitnessTable = subBuilder->createWitnessTable(
8017
8017
irWitnessTableBaseType,
8018
8018
irWitnessTable->getConcreteType());
8019
- auto mangledName = getMangledNameForConformanceWitness(
8020
- subContext->astBuilder,
8021
- astReqWitnessTable->witnessedType,
8022
- astReqWitnessTable->baseType);
8023
- subBuilder->addExportDecoration(
8024
- irSatisfyingWitnessTable,
8025
- mangledName.getUnownedSlice());
8026
- if (isExportedType(astReqWitnessTable->witnessedType))
8019
+
8020
+ // TODO: When WitnessTable became HOISTABLE, we needed a way to avoid
8021
+ // adding the same decorations and childrens redundantly.
8022
+ // There isn't an easy way to tell if the returned WitnessTable is a
8023
+ // brand new or a found one from the existing pool.
8024
+ // The code below assumes that when there are any decoration or child,
8025
+ // it is a pre-existed one.
8026
+ //
8027
+ if (irSatisfyingWitnessTable->getFirstDecorationOrChild() == nullptr)
8027
8028
{
8028
- subBuilder->addHLSLExportDecoration(irSatisfyingWitnessTable);
8029
- subBuilder->addKeepAliveDecoration(irSatisfyingWitnessTable);
8030
- }
8029
+ auto mangledName = getMangledNameForConformanceWitness(
8030
+ subContext->astBuilder,
8031
+ astReqWitnessTable->witnessedType,
8032
+ astReqWitnessTable->baseType);
8033
+ subBuilder->addExportDecoration(
8034
+ irSatisfyingWitnessTable,
8035
+ mangledName.getUnownedSlice());
8036
+ if (isExportedType(astReqWitnessTable->witnessedType))
8037
+ {
8038
+ subBuilder->addHLSLExportDecoration(irSatisfyingWitnessTable);
8039
+ subBuilder->addKeepAliveDecoration(irSatisfyingWitnessTable);
8040
+ }
8031
8041
8032
- // Recursively lower the sub-table.
8033
- lowerWitnessTable(
8034
- subContext,
8035
- astReqWitnessTable,
8036
- irSatisfyingWitnessTable,
8037
- mapASTToIRWitnessTable);
8042
+ // Recursively lower the sub-table.
8043
+ lowerWitnessTable(
8044
+ subContext,
8045
+ astReqWitnessTable,
8046
+ irSatisfyingWitnessTable,
8047
+ mapASTToIRWitnessTable);
8038
8048
8039
- irSatisfyingWitnessTable->moveToEnd();
8049
+ irSatisfyingWitnessTable->moveToEnd();
8050
+ }
8040
8051
}
8041
8052
irSatisfyingVal = irSatisfyingWitnessTable;
8042
8053
}
@@ -8145,58 +8156,74 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
8145
8156
//
8146
8157
auto irWitnessTableBaseType = lowerType(subContext, superType);
8147
8158
8148
- // Create the IR-level witness table
8149
- auto irWitnessTable = subBuilder->createWitnessTable(irWitnessTableBaseType, nullptr);
8150
-
8151
- // Register the value now, rather than later, to avoid any possible infinite recursion.
8159
+ // Register a dummy value to avoid infinite recursions.
8160
+ // Without this, the call to lowerType() can get into an infinite recursion.
8161
+ //
8152
8162
context->setGlobalValue(
8153
8163
inheritanceDecl,
8154
- LoweredValInfo::simple(findOuterMostGeneric(irWitnessTable )));
8164
+ LoweredValInfo::simple(findOuterMostGeneric(subBuilder->getInsertLoc().getParent() )));
8155
8165
8156
8166
auto irSubType = lowerType(subContext, subType);
8157
- irWitnessTable->setConcreteType(irSubType);
8158
8167
8159
- // TODO(JS):
8160
- // Should the mangled name take part in obfuscation if enabled?
8168
+ // Create the IR-level witness table
8169
+ auto irWitnessTable = subBuilder->createWitnessTable(irWitnessTableBaseType, irSubType);
8170
+
8171
+ // TODO: When WitnessTable became HOISTABLE, we needed a way to avoid
8172
+ // adding the same decorations and childrens redundantly.
8173
+ // There isn't an easy way to tell if the returned WitnessTable is a
8174
+ // brand new or a found one from the existing pool.
8175
+ // The code below assumes that when there are any decoration or child,
8176
+ // it is a pre-existed one.
8177
+ //
8178
+ if (irWitnessTable->getFirstDecorationOrChild() == nullptr)
8179
+ {
8180
+ // Override with the correct witness-table
8181
+ context->setGlobalValue(
8182
+ inheritanceDecl,
8183
+ LoweredValInfo::simple(findOuterMostGeneric(irWitnessTable)));
8161
8184
8162
- addLinkageDecoration(
8163
- context,
8164
- irWitnessTable,
8165
- inheritanceDecl,
8166
- mangledName.getUnownedSlice());
8185
+ // TODO(JS):
8186
+ // Should the mangled name take part in obfuscation if enabled?
8167
8187
8168
- // If the witness table is for a COM interface, always keep it alive.
8169
- if (irWitnessTableBaseType->findDecoration<IRComInterfaceDecoration>())
8170
- {
8171
- subBuilder->addHLSLExportDecoration(irWitnessTable);
8172
- }
8188
+ addLinkageDecoration(
8189
+ context,
8190
+ irWitnessTable,
8191
+ inheritanceDecl,
8192
+ mangledName.getUnownedSlice());
8173
8193
8174
- for (auto mod : parentDecl->modifiers)
8175
- {
8176
- if (as<HLSLExportModifier>(mod))
8194
+ // If the witness table is for a COM interface, always keep it alive.
8195
+ if (irWitnessTableBaseType->findDecoration<IRComInterfaceDecoration>())
8177
8196
{
8178
8197
subBuilder->addHLSLExportDecoration(irWitnessTable);
8179
- subBuilder->addKeepAliveDecoration(irWitnessTable);
8180
8198
}
8181
- else if (as<AutoDiffBuiltinAttribute>(mod))
8199
+
8200
+ for (auto mod : parentDecl->modifiers)
8182
8201
{
8183
- subBuilder->addAutoDiffBuiltinDecoration(irWitnessTable);
8202
+ if (as<HLSLExportModifier>(mod))
8203
+ {
8204
+ subBuilder->addHLSLExportDecoration(irWitnessTable);
8205
+ subBuilder->addKeepAliveDecoration(irWitnessTable);
8206
+ }
8207
+ else if (as<AutoDiffBuiltinAttribute>(mod))
8208
+ {
8209
+ subBuilder->addAutoDiffBuiltinDecoration(irWitnessTable);
8210
+ }
8184
8211
}
8185
- }
8186
8212
8187
- // Make sure that all the entries in the witness table have been filled in,
8188
- // including any cases where there are sub-witness-tables for conformances
8189
- bool isExplicitExtern = false;
8190
- if (!isImportedDecl(context, parentDecl, isExplicitExtern))
8191
- {
8192
- Dictionary<WitnessTable*, IRWitnessTable*> mapASTToIRWitnessTable;
8193
- lowerWitnessTable(
8194
- subContext,
8195
- inheritanceDecl->witnessTable,
8196
- irWitnessTable,
8197
- mapASTToIRWitnessTable);
8213
+ // Make sure that all the entries in the witness table have been filled in,
8214
+ // including any cases where there are sub-witness-tables for conformances
8215
+ bool isExplicitExtern = false;
8216
+ if (!isImportedDecl(context, parentDecl, isExplicitExtern))
8217
+ {
8218
+ Dictionary<WitnessTable*, IRWitnessTable*> mapASTToIRWitnessTable;
8219
+ lowerWitnessTable(
8220
+ subContext,
8221
+ inheritanceDecl->witnessTable,
8222
+ irWitnessTable,
8223
+ mapASTToIRWitnessTable);
8224
+ }
8225
+ irWitnessTable->moveToEnd();
8198
8226
}
8199
- irWitnessTable->moveToEnd();
8200
8227
8201
8228
return LoweredValInfo::simple(
8202
8229
finishOuterGenerics(subBuilder, irWitnessTable, outerGeneric));
0 commit comments