diff options
| author | Ellie Hermaszewska <ellieh@nvidia.com> | 2023-04-17 22:22:13 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-17 22:22:13 +0800 |
| commit | a3f622ace1bdef1f1a4150ec85d1328d1a589333 (patch) | |
| tree | c1c620d0e69d39870fdbc76f5e584bae8594f0ba /source | |
| parent | f6ff73fe3156215e75708d155fd240788134b1f2 (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.slang | 3 | ||||
| -rw-r--r-- | source/slang/hlsl.meta.slang | 2 | ||||
| -rw-r--r-- | source/slang/slang-ast-modifier.h | 12 | ||||
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 41 | ||||
| -rw-r--r-- | source/slang/slang-check-impl.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 12 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 2 |
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'") |
