Skip to content

[HLSL] Default and Relaxed Availability Diagnostics #92704

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 30, 2024
Merged
45 changes: 33 additions & 12 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1060,18 +1060,10 @@ static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
.Case("ShaderModel", "shadermodel")
.Default(Platform);
}
static llvm::StringRef getPrettyEnviromentName(llvm::StringRef Environment) {
return llvm::StringSwitch<llvm::StringRef>(Environment)
.Case("pixel", "pixel shader")
.Case("vertex", "vertex shader")
.Case("geometry", "geometry shader")
.Case("hull", "hull shader")
.Case("domain", "domain shader")
.Case("compute", "compute shader")
.Case("mesh", "mesh shader")
.Case("amplification", "amplification shader")
.Case("library", "shader library")
.Default(Environment);
static llvm::StringRef getPrettyEnviromentName(llvm::Triple::EnvironmentType EnvironmentType) {
if (EnvironmentType >= llvm::Triple::Pixel && EnvironmentType <= llvm::Triple::Amplification)
return llvm::Triple::getEnvironmentTypeName(EnvironmentType);
return "";
}
static llvm::Triple::EnvironmentType getEnvironmentType(llvm::StringRef Environment) {
return llvm::StringSwitch<llvm::Triple::EnvironmentType>(Environment)
Expand All @@ -1081,6 +1073,12 @@ static llvm::Triple::EnvironmentType getEnvironmentType(llvm::StringRef Environm
.Case("hull", llvm::Triple::Hull)
.Case("domain", llvm::Triple::Domain)
.Case("compute", llvm::Triple::Compute)
.Case("raygeneration", llvm::Triple::RayGeneration)
.Case("intersection", llvm::Triple::Intersection)
.Case("anyhit", llvm::Triple::AnyHit)
.Case("closesthit", llvm::Triple::ClosestHit)
.Case("miss", llvm::Triple::Miss)
.Case("callable", llvm::Triple::Callable)
.Case("mesh", llvm::Triple::Mesh)
.Case("amplification", llvm::Triple::Amplification)
.Case("library", llvm::Triple::Library)
Expand Down Expand Up @@ -4476,6 +4474,29 @@ def HLSLShader : InheritableAttr {
"Miss", "Callable", "Mesh", "Amplification"]>
];
let Documentation = [HLSLSV_ShaderTypeAttrDocs];
let AdditionalMembers =
[{
static const unsigned ShaderTypeMaxValue = (unsigned)HLSLShaderAttr::Amplification;

static llvm::Triple::EnvironmentType getTypeAsEnvironment(HLSLShaderAttr::ShaderType ShaderType) {
switch (ShaderType) {
case HLSLShaderAttr::Pixel: return llvm::Triple::Pixel;
case HLSLShaderAttr::Vertex: return llvm::Triple::Vertex;
case HLSLShaderAttr::Geometry: return llvm::Triple::Geometry;
case HLSLShaderAttr::Hull: return llvm::Triple::Hull;
case HLSLShaderAttr::Domain: return llvm::Triple::Domain;
case HLSLShaderAttr::Compute: return llvm::Triple::Compute;
case HLSLShaderAttr::RayGeneration: return llvm::Triple::RayGeneration;
case HLSLShaderAttr::Intersection: return llvm::Triple::Intersection;
case HLSLShaderAttr::AnyHit: return llvm::Triple::AnyHit;
case HLSLShaderAttr::ClosestHit: return llvm::Triple::ClosestHit;
case HLSLShaderAttr::Miss: return llvm::Triple::Miss;
case HLSLShaderAttr::Callable: return llvm::Triple::Callable;
case HLSLShaderAttr::Mesh: return llvm::Triple::Mesh;
case HLSLShaderAttr::Amplification: return llvm::Triple::Amplification;
}
}
}];
}

def HLSLResource : InheritableAttr {
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1513,6 +1513,9 @@ def HLSLMixPackOffset : DiagGroup<"mix-packoffset">;
// Warnings for DXIL validation
def DXILValidation : DiagGroup<"dxil-validation">;

// Warning for HLSL API availability
def HLSLAvailability : DiagGroup<"hlsl-availability">;

// Warnings and notes related to const_var_decl_type attribute checks
def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">;

Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -12218,6 +12218,13 @@ def err_hlsl_param_qualifier_mismatch :
def warn_hlsl_impcast_vector_truncation : Warning<
"implicit conversion truncates vector: %0 to %1">, InGroup<Conversion>;

def warn_hlsl_availability : Warning<
"%0 is only available %select{|in %4 environment }3on %1 %2 or newer">,
InGroup<HLSLAvailability>, DefaultError;
def warn_hlsl_availability_unavailable :
Warning<err_unavailable.Summary>,
InGroup<HLSLAvailability>, DefaultError;

// Layout randomization diagnostics.
def err_non_designated_init_used : Error<
"a randomized struct can only be initialized with a designated initializer">;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/SemaHLSL.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ class SemaHLSL : public SemaBase {
void DiagnoseAttrStageMismatch(
const Attr *A, HLSLShaderAttr::ShaderType Stage,
std::initializer_list<HLSLShaderAttr::ShaderType> AllowedStages);
void DiagnoseAvailabilityViolations(TranslationUnitDecl *TU);
};

} // namespace clang
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,8 @@ static AvailabilityResult CheckAvailability(ASTContext &Context,
IdentifierInfo *IIEnv = A->getEnvironment();
StringRef TargetEnv =
Context.getTargetInfo().getTriple().getEnvironmentName();
StringRef EnvName = AvailabilityAttr::getPrettyEnviromentName(TargetEnv);
StringRef EnvName = AvailabilityAttr::getPrettyEnviromentName(
Context.getTargetInfo().getTriple().getEnvironment());
// Matching environment or no environment on attribute
if (!IIEnv || (!TargetEnv.empty() && IIEnv->getName() == TargetEnv)) {
if (Message) {
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1357,6 +1357,10 @@ void Sema::ActOnEndOfTranslationUnit() {
Consumer.CompleteExternalDeclaration(D);
}

if (LangOpts.HLSL)
HLSL().DiagnoseAvailabilityViolations(
getASTContext().getTranslationUnitDecl());

// If there were errors, disable 'unused' warnings since they will mostly be
// noise. Don't warn for a use from a module: either we should warn on all
// file-scope declarations in modules or not at all, but whether the
Expand Down
24 changes: 18 additions & 6 deletions clang/lib/Sema/SemaAvailability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DelayedDiagnostic.h"
Expand Down Expand Up @@ -228,8 +229,9 @@ shouldDiagnoseAvailabilityByDefault(const ASTContext &Context,
ForceAvailabilityFromVersion = VersionTuple(/*Major=*/10, /*Minor=*/13);
break;
case llvm::Triple::ShaderModel:
// Always enable availability diagnostics for shader models.
return true;
// FIXME: This will be updated when HLSL strict diagnostic mode
// is implemented (issue #90096)
return false;
default:
// New targets should always warn about availability.
return Triple.getVendor() == llvm::Triple::Apple;
Expand Down Expand Up @@ -409,10 +411,11 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
std::string PlatformName(
AvailabilityAttr::getPrettyPlatformName(TI.getPlatformName()));
llvm::StringRef TargetEnvironment(AvailabilityAttr::getPrettyEnviromentName(
TI.getTriple().getEnvironmentName()));
TI.getTriple().getEnvironment()));
llvm::StringRef AttrEnvironment =
AA->getEnvironment() ? AvailabilityAttr::getPrettyEnviromentName(
AA->getEnvironment()->getName())
AvailabilityAttr::getEnvironmentType(
AA->getEnvironment()->getName()))
: "";
bool UseEnvironment =
(!AttrEnvironment.empty() && !TargetEnvironment.empty());
Expand All @@ -438,6 +441,10 @@ static void DoEmitAvailabilityWarning(Sema &S, AvailabilityResult K,
<< S.Context.getTargetInfo().getPlatformMinVersion().getAsString()
<< UseEnvironment << AttrEnvironment << TargetEnvironment;

// Do not offer to silence the warning or fixits for HLSL
if (S.getLangOpts().HLSL)
return;

if (const auto *Enclosing = findEnclosingDeclToAnnotate(Ctx)) {
if (const auto *TD = dyn_cast<TagDecl>(Enclosing))
if (TD->getDeclName().isEmpty()) {
Expand Down Expand Up @@ -839,10 +846,11 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
std::string PlatformName(
AvailabilityAttr::getPrettyPlatformName(TI.getPlatformName()));
llvm::StringRef TargetEnvironment(AvailabilityAttr::getPrettyEnviromentName(
TI.getTriple().getEnvironmentName()));
TI.getTriple().getEnvironment()));
llvm::StringRef AttrEnvironment =
AA->getEnvironment() ? AvailabilityAttr::getPrettyEnviromentName(
AA->getEnvironment()->getName())
AvailabilityAttr::getEnvironmentType(
AA->getEnvironment()->getName()))
: "";
bool UseEnvironment =
(!AttrEnvironment.empty() && !TargetEnvironment.empty());
Expand All @@ -865,6 +873,10 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
<< SemaRef.Context.getTargetInfo().getPlatformMinVersion().getAsString()
<< UseEnvironment << AttrEnvironment << TargetEnvironment;

// Do not offer to silence the warning or fixits for HLSL
if (SemaRef.getLangOpts().HLSL)
return;

auto FixitDiag =
SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence)
<< Range << D
Expand Down
Loading
Loading