Repository: shader-slang/slang
File: source/slang/slang-lower-to-ir.cpp (C++)

Code before:
    return emitDeclRef(context, declRef.getDecl(), declRef.declRefBase, type);
}

static void lowerFrontEndEntryPointToIR(
    IRGenContext* context,
    EntryPoint* entryPoint,
    String moduleName)
{
    // TODO: We should emit an entry point as a dedicated IR function
    // (distinct from the IR function used if it were called normally),
    // with a mangled name based on the original function name plus
    // the stage for which it is being compiled as an entry point (so
    // that entry points for distinct stages always have distinct names).
    //
    // For now we just have an (implicit) constraint that a given
    // function should only be used as an entry point for one stage,
    // and any such function should *not* be used as an ordinary function.

    auto entryPointFuncDecl = entryPoint->getFuncDecl();

    if (!entryPointFuncDecl->findModifier<EntryPointAttribute>())
    {
        // If the entry point doesn't have an explicit `[shader("...")]` attribute,
        // then we make sure to add one here, so the lowering logic knows it is an
        // entry point.
        auto entryPointAttr = context->astBuilder->create<EntryPointAttribute>();
        entryPointAttr->capabilitySet = entryPoint->getProfile().getCapabilityName();
        addModifier(entryPointFuncDecl, entryPointAttr);
    }

    auto builder = context->irBuilder;
    builder->setInsertInto(builder->getModule()->getModuleInst());

    auto loweredEntryPointFunc = getSimpleVal(context, ensureDecl(context, entryPointFuncDecl));

    // Attach a marker decoration so that we recognize
    // this as an entry point.
    //
    IRInst* instToDecorate = loweredEntryPointFunc;
    if (auto irGeneric = as<IRGeneric>(instToDecorate))
    {
        instToDecorate = findGenericReturnVal(irGeneric);
    }

    // If the entry-point decorations has already been created (because the user
    // specified duplicate entries in the entry point list), we can stop now.
    if (instToDecorate->findDecoration<IREntryPointDecoration>())
        return;

    {


Review comment (suggestion):
I think this branch is still needed, because we could still have interface members that does not represent a requirement. For example, 
```
interface Foo { struct P { int x; }; }
```

simply defines `Foo::P` as an ordinary type.

Our language does not allow user code that does this, but there could be some synthesis logic that adds ordinary members to an interface like this.

Code after:
            // decl-ref as a lookup of the corresponding member in a witness
            // table.
            //
            // The witness table itself is referenced by the this-type
            // substitution, so we can just lower that.
            //
            // Note: unlike the case for generics above, in the interface-lookup
            // case, we don't end up caring about any further outer substitutions.
            // That is because even if we are naming `ISomething<Foo>.doIt()`,
            // a method inside a generic interface, we don't actually care
            // about the substitution of `Foo` for the parameter `T` of
            // `ISomething<T>`. That is because we really care about the
            // witness table for the concrete type that conforms to `ISomething<Foo>`.
            //
            auto irWitnessTable = lowerSimpleVal(context, thisTypeSubst->getWitness());
            SLANG_RELEASE_ASSERT(irWitnessTable);

            if (isAbstractWitnessTable(irWitnessTable))
            {
                // Copy ThisTypeWitness locally if necessary
                irWitnessTable = maybeCloneThisTypeWitness(
                    context,
                    irWitnessTable,
                    thisTypeSubst->getLookupSource());
            }

            auto irRequirementKey = getInterfaceRequirementKey(context, decl);
            auto irLookupWitness = context->irBuilder->emitLookupInterfaceMethodInst(
                type,
                irWitnessTable,
                irRequirementKey);
            return LoweredValInfo::simple(irLookupWitness);
        }
        else
        {
            // This case is a reference to a member declaration of the interface
            // (or added by an extension of the interface) that does *not*
            // represent a requirement of the interface.
            //
            // Our policy is that concrete methods/members on an interface type
            // are lowered as generics, where the generic parameter represents
            // the `ThisType`.
            //
            auto genericVal = emitDeclRef(
                context,
                decl,
                thisTypeSubst->getBase(),
                context->irBuilder->getGenericKind());
            auto irGenericVal = getSimpleVal(context, genericVal);

            // In order to reference the member for a particular type, we