//===----------------------------------------------------------------------===//
//
/// \file
-/// Defines the clang::IdentifierInfo, clang::IdentifierTable, and
-/// clang::Selector interfaces.
+/// Defines helper utilities for supporting the HLSL runtime environment.
//
//===----------------------------------------------------------------------===//
#ifndef CLANG_BASIC_HLSLRUNTIME_H
#define CLANG_BASIC_HLSLRUNTIME_H
+#include "clang/Basic/LangOptions.h"
#include <cstdint>
namespace clang {
NumClasses
};
+constexpr ShaderStage
+getStageFromEnvironment(const llvm::Triple::EnvironmentType &E) {
+ uint32_t Pipeline =
+ static_cast<uint32_t>(E) - static_cast<uint32_t>(llvm::Triple::Pixel);
+
+ if (Pipeline > (uint32_t)ShaderStage::Invalid)
+ return ShaderStage::Invalid;
+ return static_cast<ShaderStage>(Pipeline);
+}
+
+#define ENUM_COMPARE_ASSERT(Value) \
+ static_assert( \
+ getStageFromEnvironment(llvm::Triple::Value) == ShaderStage::Value, \
+ "Mismatch between llvm::Triple and clang::ShaderStage for " #Value);
+
+ENUM_COMPARE_ASSERT(Pixel)
+ENUM_COMPARE_ASSERT(Vertex)
+ENUM_COMPARE_ASSERT(Geometry)
+ENUM_COMPARE_ASSERT(Hull)
+ENUM_COMPARE_ASSERT(Domain)
+ENUM_COMPARE_ASSERT(Compute)
+ENUM_COMPARE_ASSERT(Library)
+ENUM_COMPARE_ASSERT(RayGeneration)
+ENUM_COMPARE_ASSERT(Intersection)
+ENUM_COMPARE_ASSERT(AnyHit)
+ENUM_COMPARE_ASSERT(ClosestHit)
+ENUM_COMPARE_ASSERT(Miss)
+ENUM_COMPARE_ASSERT(Callable)
+ENUM_COMPARE_ASSERT(Mesh)
+ENUM_COMPARE_ASSERT(Amplification)
+
+static_assert(getStageFromEnvironment(llvm::Triple::UnknownEnvironment) ==
+ ShaderStage::Invalid,
+ "Mismatch between llvm::Triple and "
+ "clang::ShaderStage for Invalid");
+static_assert(getStageFromEnvironment(llvm::Triple::MSVC) ==
+ ShaderStage::Invalid,
+ "Mismatch between llvm::Triple and "
+ "clang::ShaderStage for Invalid");
+
} // namespace hlsl
} // namespace clang
enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable };
/// Shader programs run in specific pipeline stages.
+/// The order of these values matters, and must be kept in sync with the
+/// Triple Environment enum in llvm::Triple. The ordering is enforced in
+/// static_asserts in Triple.cpp and in clang/Basic/HLSLRuntime.h.
enum class ShaderStage {
Pixel = 0,
Vertex,
//===----------------------------------------------------------------------===//
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/HLSLRuntime.h"
#include "clang/Basic/MacroBuilder.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SyncScope.h"
Builder.defineMacro("__SHADER_STAGE_LIBRARY",
Twine((uint32_t)ShaderStage::Library));
// The current shader stage itself
- uint32_t StageInteger = (uint32_t)TI.getTriple().getEnvironment() -
- (uint32_t)llvm::Triple::Pixel;
+ uint32_t StageInteger = static_cast<uint32_t>(
+ hlsl::getStageFromEnvironment(TI.getTriple().getEnvironment()));
Builder.defineMacro("__SHADER_TARGET_STAGE", Twine(StageInteger));
// Add target versions
#include "clang/AST/Randstruct.h"
#include "clang/AST/StmtCXX.h"
#include "clang/Basic/Builtins.h"
+#include "clang/Basic/HLSLRuntime.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
S->getDepth() == 0) {
CheckHLSLEntryPoint(NewFD);
if (!NewFD->isInvalidDecl()) {
- auto TripleShaderType = TargetInfo.getTriple().getEnvironment();
+ auto Env = TargetInfo.getTriple().getEnvironment();
AttributeCommonInfo AL(NewFD->getBeginLoc());
- HLSLShaderAttr::ShaderType ShaderType = (HLSLShaderAttr::ShaderType)(
- TripleShaderType - (uint32_t)llvm::Triple::Pixel);
+ HLSLShaderAttr::ShaderType ShaderType =
+ static_cast<HLSLShaderAttr::ShaderType>(
+ hlsl::getStageFromEnvironment(Env));
// To share code with HLSLShaderAttr, add HLSLShaderAttr to entry
// function.
if (HLSLShaderAttr *Attr = mergeHLSLShaderAttr(NewFD, AL, ShaderType))
#include "clang/AST/Type.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/DarwinSDKInfo.h"
+#include "clang/Basic/HLSLRuntime.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
static void handleHLSLNumThreadsAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
using llvm::Triple;
Triple Target = S.Context.getTargetInfo().getTriple();
+ auto Env = S.Context.getTargetInfo().getTriple().getEnvironment();
if (!llvm::is_contained({Triple::Compute, Triple::Mesh, Triple::Amplification,
Triple::Library},
- Target.getEnvironment())) {
+ Env)) {
uint32_t Pipeline =
- (uint32_t)S.Context.getTargetInfo().getTriple().getEnvironment() -
- (uint32_t)llvm::Triple::Pixel;
+ static_cast<uint32_t>(hlsl::getStageFromEnvironment(Env));
S.Diag(AL.getLoc(), diag::err_hlsl_attr_unsupported_in_stage)
<< AL << Pipeline << "Compute, Amplification, Mesh or Library";
return;
static void handleHLSLSVGroupIndexAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
using llvm::Triple;
- Triple Target = S.Context.getTargetInfo().getTriple();
- if (Target.getEnvironment() != Triple::Compute &&
- Target.getEnvironment() != Triple::Library) {
+ auto Env = S.Context.getTargetInfo().getTriple().getEnvironment();
+ if (Env != Triple::Compute && Env != Triple::Library) {
// FIXME: it is OK for a compute shader entry and pixel shader entry live in
// same HLSL file. Issue https://github.com/llvm/llvm-project/issues/57880.
- uint32_t Pipeline =
- (uint32_t)S.Context.getTargetInfo().getTriple().getEnvironment() -
- (uint32_t)llvm::Triple::Pixel;
+ ShaderStage Pipeline = hlsl::getStageFromEnvironment(Env);
S.Diag(AL.getLoc(), diag::err_hlsl_attr_unsupported_in_stage)
- << AL << Pipeline << "Compute";
+ << AL << (uint32_t)Pipeline << "Compute";
return;
}
MacABI, // Mac Catalyst variant of Apple's iOS deployment target.
// Shader Stages
+ // The order of these values matters, and must be kept in sync with the
+ // language options enum in Clang. The ordering is enforced in
+ // static_asserts in Triple.cpp and in Clang.
Pixel,
Vertex,
Geometry,