diff options
| author | Yong He <yonghe@outlook.com> | 2025-06-04 13:05:58 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-04 13:05:58 -0700 |
| commit | 812e478989e27983b8dea7ab11964de751654ba2 (patch) | |
| tree | e6db6def9c7896ee48c5fe42926856644e81c0e6 /source/slang/slang-check-shader.cpp | |
| parent | b9dc21d362f65f22bc707bede733a9537b80460a (diff) | |
Make interface types non c-style in Slang2026. (#7260)
* Make interface types non c-style.
* Make Optional<T> work with autodiff and existential types.
* Fix.
* patch behind slang 2026.
* Fix warnings.
* cleanup.
* Fix tests.
* Fix.
* Fix com interface lowering.
* Add comment to test.
* regenerate command line reference
* Add test for passing `none` to autodiff function.
* Fix recording of `getDynamicObjectRTTIBytes`.
* Fix nested Optional types.
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-check-shader.cpp')
| -rw-r--r-- | source/slang/slang-check-shader.cpp | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/source/slang/slang-check-shader.cpp b/source/slang/slang-check-shader.cpp index 6a713f412..a57e01a88 100644 --- a/source/slang/slang-check-shader.cpp +++ b/source/slang/slang-check-shader.cpp @@ -915,6 +915,51 @@ RefPtr<ComponentType> fillRequirements(ComponentType* inComponentType) return componentType; } +bool parseTypeConformanceArgString( + UnownedStringSlice optionString, + UnownedStringSlice& outTypeName, + UnownedStringSlice& outInterfaceName, + Index& outSequentialId) +{ + // The expected format for the type conformance argument is: + // `TypeName:InterfaceName[=SequentialId]` + // + // Where `TypeName` is the name of a concrete type, `InterfaceName` + // is the name of an interface type, and `SequentialId` is an optional + // integer that specifies a sequential ID for the conformance. + // + // If the string does not match this format, we will return false. + + outTypeName = UnownedStringSlice(); + outInterfaceName = UnownedStringSlice(); + outSequentialId = -1; + auto colonPos = optionString.indexOf(':'); + if (colonPos < 0) + { + // If there is no colon, then the string is invalid. + return false; + } + outTypeName = optionString.head(colonPos); + auto interfaceNameStart = colonPos + 1; + auto equalsPos = optionString.indexOf('='); + if (equalsPos < interfaceNameStart) + { + // If there is no equals sign, then the interface name goes to the end of the string. + outInterfaceName = optionString.tail(interfaceNameStart); + } + else + { + // If there is an equals sign, then the interface name goes up to that point. + outInterfaceName = + optionString.subString(interfaceNameStart, equalsPos - interfaceNameStart); + // The sequential ID is the part after the equals sign. + auto sequentialIdString = optionString.tail(equalsPos + 1); + if (SLANG_FAILED(StringUtil::parseInt(sequentialIdString, outSequentialId))) + return false; + } + return true; +} + /// Create a component type to represent the "global scope" of a compile request. /// /// This component type will include all the modules and their global @@ -965,6 +1010,85 @@ RefPtr<ComponentType> createUnspecializedGlobalComponentType(FrontEndCompileRequ CompositeComponentType::create(linkage, translationUnitComponentTypes); } + List<RefPtr<ComponentType>> conformanceComponents; + + // Find and include all type conformances specified through compiler options. + for (auto conformances : + compileRequest->optionSet.getArray(CompilerOptionName::TypeConformance)) + { + auto stringValue = conformances.stringValue.getUnownedSlice(); + UnownedStringSlice typeName, interfaceName; + Index sequentialId = -1; + if (!parseTypeConformanceArgString(stringValue, typeName, interfaceName, sequentialId)) + { + compileRequest->getSink()->diagnose( + SourceLoc(), + Diagnostics::invalidTypeConformanceOptionString, + stringValue); + continue; + } + auto concreteType = globalComponentType->getTypeFromString( + String(typeName).getBuffer(), + compileRequest->getSink()); + if (!concreteType) + { + compileRequest->getSink()->diagnose( + SourceLoc(), + Diagnostics::invalidTypeConformanceOptionNoType, + stringValue, + typeName); + continue; + } + auto interfaceType = globalComponentType->getTypeFromString( + String(interfaceName).getBuffer(), + compileRequest->getSink()); + if (!interfaceType) + { + compileRequest->getSink()->diagnose( + SourceLoc(), + Diagnostics::invalidTypeConformanceOptionNoType, + stringValue, + interfaceName); + continue; + } + ComPtr<slang::ITypeConformance> conformanceComponent; + ComPtr<ISlangBlob> diagnostics; + compileRequest->getLinkage()->createTypeConformanceComponentType( + (slang::TypeReflection*)concreteType, + (slang::TypeReflection*)interfaceType, + conformanceComponent.writeRef(), + sequentialId, + diagnostics.writeRef()); + if (!conformanceComponent) + { + // If we failed to create the conformance component, then + // we should report the diagnostics that were generated. + // + compileRequest->getSink()->diagnose( + SourceLoc(), + Diagnostics::cannotCreateTypeConformance, + stringValue); + if (diagnostics) + { + compileRequest->getSink()->diagnoseRaw( + Severity::Error, + UnownedStringSlice((char*)diagnostics->getBufferPointer())); + } + continue; + } + conformanceComponents.add(static_cast<TypeConformance*>(conformanceComponent.get())); + } + + if (conformanceComponents.getCount() > 0) + { + // If we found any type conformances, then we will + // create a composite component type that includes + // the global component type and the conformance components. + // + conformanceComponents.add(globalComponentType); + globalComponentType = CompositeComponentType::create(linkage, conformanceComponents); + } + return fillRequirements(globalComponentType); } |
