summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorEllie Hermaszewska <ellieh@nvidia.com>2023-04-17 22:22:13 +0800
committerGitHub <noreply@github.com>2023-04-17 22:22:13 +0800
commita3f622ace1bdef1f1a4150ec85d1328d1a589333 (patch)
treec1c620d0e69d39870fdbc76f5e584bae8594f0ba /source
parentf6ff73fe3156215e75708d155fd240788134b1f2 (diff)
WIP: "deprecated" attribute (#2698)
* Implement deprecated attribute * Prevent duplicate deprecated diagnostic on non-overloaded functions * Use FileCheck for deprecation test * formatting
Diffstat (limited to 'source')
-rw-r--r--source/slang/core.meta.slang3
-rw-r--r--source/slang/hlsl.meta.slang2
-rw-r--r--source/slang/slang-ast-modifier.h12
-rw-r--r--source/slang/slang-check-expr.cpp41
-rw-r--r--source/slang/slang-check-impl.h3
-rw-r--r--source/slang/slang-check-modifier.cpp12
-rw-r--r--source/slang/slang-diagnostic-defs.h2
7 files changed, 73 insertions, 2 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index 3f1e99880..849e4c642 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -3129,3 +3129,6 @@ attribute_syntax [noinline] : NoInlineAttribute;
__attributeTarget(StructDecl)
attribute_syntax [payload] : PayloadAttribute;
+
+__attributeTarget(DeclBase)
+attribute_syntax [deprecated(message: String)] : DeprecatedAttribute;
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 8ad99d71b..a47c0cb25 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -3140,12 +3140,14 @@ matrix<T,R,C> mul(matrix<T,R,N> right, matrix<T,N,C> left)
// noise (deprecated)
[__readNone]
+[deprecated("Always returns 0")]
float noise(float x)
{
return 0;
}
[__readNone]
+[deprecated("Always returns 0")]
__generic<let N : int> float noise(vector<float, N> x)
{
return 0;
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index 0b077477d..caa439704 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -1256,6 +1256,18 @@ class PayloadAttribute : public Attribute
SLANG_AST_CLASS(PayloadAttribute)
};
+ /// A `[deprecated("message")]` attribute indicates the target is
+ /// deprecated.
+ /// A compiler warning including the message will be raised if the
+ /// deprecated value is used.
+ ///
+class DeprecatedAttribute : public Attribute
+{
+ SLANG_AST_CLASS(DeprecatedAttribute)
+
+ String message;
+};
+
/// A modifier that applies to types rather than declarations.
///
/// In most cases, the Slang compiler assumes that a modifier should
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 507b8c30f..119077eca 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -254,7 +254,42 @@ namespace Slang
return SourceLoc();
}
- Expr* SemanticsVisitor::ConstructDeclRefExpr(
+ void SemanticsVisitor::diagnoseDeprecatedDeclRefUsage(
+ DeclRef<Decl> declRef,
+ SourceLoc loc,
+ Expr* originalExpr)
+ {
+ // This is slightly subtle, because we don't want to warn more than
+ // once for the same occurrence, however in some cases this function is
+ // called more than once for the same declref (specifically in the case
+ // of a non-overloaded function, once when the function is identified at
+ // first, and again when it's checked from
+ // CheckInvokeExprWithCheckedOperands).
+ //
+ // The correct fix is probably to make
+ // CheckInvokeExprWithCheckedOperands reuse the original declref,
+ // however that doesn't appear to be a simple change.
+ //
+ // What we do instead is see if there's already been a declRef
+ // constructed for this expression and rest assured that it's already
+ // had a diagnostic emitted.
+ auto originalAppExpr = as<AppExprBase>(originalExpr);
+ auto originalAppFunDecl = originalAppExpr ? as<DeclRefExpr>(originalAppExpr->functionExpr) : nullptr;
+ if(originalAppFunDecl && originalAppFunDecl->declRef)
+ {
+ return;
+ }
+ if (auto deprecatedAttr = declRef.getDecl()->findModifier<DeprecatedAttribute>())
+ {
+ getSink()->diagnose(
+ loc,
+ Diagnostics::deprecatedUsage,
+ declRef.getName(),
+ deprecatedAttr->message);
+ }
+ }
+
+ DeclRefExpr* SemanticsVisitor::ConstructDeclRefExpr(
DeclRef<Decl> declRef,
Expr* baseExpr,
SourceLoc loc,
@@ -264,6 +299,10 @@ namespace Slang
//
auto type = GetTypeForDeclRef(declRef, loc);
+ // This is the bottleneck for using declarations which might be
+ // deprecated, diagnose here.
+ diagnoseDeprecatedDeclRefUsage(declRef, loc, originalExpr);
+
// Construct an appropriate expression based on the structured of
// the declaration reference.
//
diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h
index 18a60b8b3..b4a779a66 100644
--- a/source/slang/slang-check-impl.h
+++ b/source/slang/slang-check-impl.h
@@ -575,8 +575,9 @@ namespace Slang
/// If `expr` has Ref<T> Type, convert it into an l-value expr that has T type.
Expr* maybeOpenRef(Expr* expr);
+ void diagnoseDeprecatedDeclRefUsage(DeclRef<Decl> declRef, SourceLoc loc, Expr* originalExpr);
- Expr* ConstructDeclRefExpr(
+ DeclRefExpr* ConstructDeclRefExpr(
DeclRef<Decl> declRef,
Expr* baseExpr,
SourceLoc loc,
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index d96d9e39e..e5627850b 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -713,6 +713,18 @@ namespace Slang
return false;
}
}
+ else if (auto deprecatedAttr = as<DeprecatedAttribute>(attr))
+ {
+ SLANG_ASSERT(attr->args.getCount() == 1);
+
+ String message;
+ if(!checkLiteralStringVal(attr->args[0], &message))
+ {
+ return false;
+ }
+
+ deprecatedAttr->message = message;
+ }
else
{
if(attr->args.getCount() == 0)
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 80ba1f55b..130102e44 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -361,6 +361,8 @@ DIAGNOSTIC(31148, Error, cannotResolveDerivativeFunction, "cannot resolve the cu
DIAGNOSTIC(31149, Error, differentiableGenericInterfaceMethodNotSupported, "`[ForwardDifferentiable] and [BackwardDifferentiable] are not supported on generic interface requirements.")
+DIAGNOSTIC(31200, Warning, deprecatedUsage, "$0 has been deprecated: $1")
+
// Enums
DIAGNOSTIC(32000, Error, invalidEnumTagType, "invalid tag type for 'enum': '$0'")