You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[202x][0009] Implement hlsl namespace for intrinsic functions - #9006
This PR has significantly grown in complexity during development. Initially it just put declarations into the namespace and did some minor fixes to name lookup. As the test cases developed that proved insufficient because of how the names of functions are lazily added to the AST (which is critical for DXC's compile-time performance).
The full change has a more invasive connection into name lookup, and leverages another part of the ExternalSemaSource.
The first change is marking our namespaces with the ExternallyVisibleStorage, which is a flag on the DeclContext to mark that it has "some external storage" (think serialized AST file, or our code that injects AST nodes) that contains declarations which should be visible in the context. This is similar to the ExternalLexicalStorage flag which we already use, but it extends from just lexical declarations to visible declarations.
When name lookup inspects a declaration context there is a callback, FindExternalVisibleDeclsByName, which gets called if the DeclContext has externally stored visible declarations. This provides a hook to insert visible names during name lookup. This complements our existing name lookup hook in LookupUnqualified by also supporting qualified name lookup, and triggering earlier in the lookup process.
In FindExternalVisibleDeclsByName, if the specified name is an intrinsic we insert a function declaration that serves as a marker for the builtin intrinsic. This function declaration takes no arguments, returns void, and has an attribute applied to mark it as an intrinsic marker. This gives us a declaration to slide into normal name lookup, but also avoids us needing to add all the overloads.
When name lookup returns such a declaration we then know that we have an intrinsic function and we can perform the same overload resolution against it that we would have previously.
The one outstanding bit of work is to move the HLSL resource objects and raytracing objects into the hlsl namespace.
Update the test command to check for implicit 'hlsl' namespace.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Intrinsic lookup and constant-folding regressions remain unresolved.
No open issues 🎉
3 previously missed issues
In code that hasn't changed since last review
Preserve namespace visibility for dependent HLSL intrinsic calls
tools/clang/lib/Sema/SemaHLSL.cpp:5576
Dependent unqualified intrinsic calls lose access to hlsl during template instantiation. For example, template<typename T> T f(T x) { using namespace hlsl; return sin(x); } cannot resolve sin when first instantiated with float: TreeTransform::RebuildCallExpr passes a null Scope, leaving SearchHlslViaUsing false. A translation-unit using-directive has the same problem. Preserve definition-time namespace visibility for dependent calls, including block-scoped directives, and add regression tests for both scopes.
Restore constant folding for HLSL namespace intrinsics
tools/clang/lib/Sema/SemaHLSL.cpp:5682
Making m_hlslNSDecl non-null drops the existing constant-folding path for core intrinsics. AddHLSLIntrinsicFunction attaches HLSLBuiltinCallAttr only when NS is null, while CGExpr.cpp:3649 requires that attribute to reach TryEvalIntrinsic. Thus constant calls such as hlsl::sin(1.0f) bypass codegen-time folding. After creating an intrinsic declaration, attach the attribute when m_hlslNSDecl && T.NS == m_hlslNSDecl, preserving existing dx/vk handling, and add a constant-argument codegen regression.
Support HLSL intrinsics in using-declarations
tools/clang/lib/Sema/SemaHLSL.cpp:5689
In a fresh HLSL 202x translation unit, using hlsl::sin; fails with “no member named 'sin'”. Intrinsic declarations are synthesized by AddOverloadedCallCandidates, but BuildUsingDeclaration performs ordinary qualified lookup; marking external lexical storage does not expose those names. Support intrinsic-name lookup for using-declarations while preserving lazy overload generation, and add a regression that imports and calls an intrinsic before any qualified call.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
The changes span lazy name lookup, template instantiation, and overload resolution, requiring compiler-domain human review supported by regression results.
Chris B (llvm-beanz)
changed the title
[202x][0009] Implement hlsl namespace
[202x][0009] Implement hlsl namespace for intrinsic functions
Oct 22, 2026
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Human assessment is needed because an intrinsic-overload edge case leaves no candidates for an argument-count mismatch, producing a misleading missing-member diagnostic.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Interacting changes to core lookup, ADL, and template overload resolution require compiler-maintainer review and cross-version DXIL/SPIR-V regression validation beyond this source-only review.
No open issues 🎉
Review effort: Balanced
This branch has not been deployed
No deployments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR implements the
hlslnamespace and moves all built-in functions into thehlslnamespace.This feature was adopted by TC57 in proposal 0009: https://hlsl-tc57.github.io/tc57/proposal/0009/
This PR has significantly grown in complexity during development. Initially it just put declarations into the namespace and did some minor fixes to name lookup. As the test cases developed that proved insufficient because of how the names of functions are lazily added to the AST (which is critical for DXC's compile-time performance).
The full change has a more invasive connection into name lookup, and leverages another part of the
ExternalSemaSource.The first change is marking our namespaces with the
ExternallyVisibleStorage, which is a flag on theDeclContextto mark that it has "some external storage" (think serialized AST file, or our code that injects AST nodes) that contains declarations which should be visible in the context. This is similar to theExternalLexicalStorageflag which we already use, but it extends from just lexical declarations to visible declarations.When name lookup inspects a declaration context there is a callback,
FindExternalVisibleDeclsByName, which gets called if theDeclContexthas externally stored visible declarations. This provides a hook to insert visible names during name lookup. This complements our existing name lookup hook inLookupUnqualifiedby also supporting qualified name lookup, and triggering earlier in the lookup process.In
FindExternalVisibleDeclsByName, if the specified name is an intrinsic we insert a function declaration that serves as a marker for the builtin intrinsic. This function declaration takes no arguments, returns void, and has an attribute applied to mark it as an intrinsic marker. This gives us a declaration to slide into normal name lookup, but also avoids us needing to add all the overloads.When name lookup returns such a declaration we then know that we have an intrinsic function and we can perform the same overload resolution against it that we would have previously.
The one outstanding bit of work is to move the HLSL resource objects and raytracing objects into the
hlslnamespace.Partial implementation of #8918