summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/compiler-core/slang-diagnostic-sink.h3
-rw-r--r--source/slang/hlsl.meta.slang14
-rw-r--r--source/slang/slang-ast-modifier.cpp12
-rw-r--r--source/slang/slang-ast-modifier.h2
-rw-r--r--source/slang/slang-check-modifier.cpp201
-rw-r--r--source/slang/slang-diagnostic-defs.h3
-rw-r--r--source/slang/slang-parser.cpp2
7 files changed, 221 insertions, 16 deletions
diff --git a/source/compiler-core/slang-diagnostic-sink.h b/source/compiler-core/slang-diagnostic-sink.h
index 1969e66b6..6e3c4ccb8 100644
--- a/source/compiler-core/slang-diagnostic-sink.h
+++ b/source/compiler-core/slang-diagnostic-sink.h
@@ -102,6 +102,9 @@ void printDiagnosticArg(StringBuilder& sb, Token const& token);
struct IRInst;
void printDiagnosticArg(StringBuilder& sb, IRInst* irObject);
+
+class Modifier;
+void printDiagnosticArg(StringBuilder& sb, Modifier* modifier);
template<typename T>
void printDiagnosticArg(StringBuilder& sb, RefPtr<T> ptr)
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index ac8c59ac6..5bb5ce038 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -10599,9 +10599,7 @@ struct HitObject
case glsl:
{
// Save the attributes
- __ref attr_t attr = __hitObjectAttributes<attr_t>();
-
- attr = attributes;
+ __hitObjectAttributes<attr_t>() = attributes;
__glslMakeHit(
__return_val,
@@ -10670,9 +10668,7 @@ struct HitObject
case glsl:
{
// Save the attributes
- __ref attr_t attr = __hitObjectAttributes<attr_t>();
-
- attr = attributes;
+ __hitObjectAttributes<attr_t>() = attributes;
__glslMakeMotionHit(
__return_val,
@@ -10760,8 +10756,7 @@ struct HitObject
case glsl:
{
// Save the attributes
- __ref attr_t attr = __hitObjectAttributes<attr_t>();
- attr = attributes;
+ __hitObjectAttributes<attr_t>() = attributes;
__glslMakeHitWithIndex(
__return_val,
@@ -10824,8 +10819,7 @@ struct HitObject
case glsl:
{
// Save the attributes
- __ref attr_t attr = __hitObjectAttributes<attr_t>();
- attr = attributes;
+ __hitObjectAttributes<attr_t>() = attributes;
__glslMakeMotionHitWithIndex(
__return_val,
diff --git a/source/slang/slang-ast-modifier.cpp b/source/slang/slang-ast-modifier.cpp
index 84046a601..ba30a547d 100644
--- a/source/slang/slang-ast-modifier.cpp
+++ b/source/slang/slang-ast-modifier.cpp
@@ -10,4 +10,16 @@ const OrderedDictionary<DeclRefBase*, SubtypeWitness*>& DifferentiableAttribute:
m_mapToIDifferentiableWitness.add(m_typeToIDifferentiableWitnessMappings[i].key, m_typeToIDifferentiableWitnessMappings[i].value);
return m_mapToIDifferentiableWitness;
}
+
+void printDiagnosticArg(StringBuilder& sb, Modifier* modifier)
+{
+ if (!modifier)
+ return;
+ if (modifier->keywordName && modifier->keywordName->text.getLength())
+ sb << modifier->keywordName->text;
+ if (auto hlslSemantic = as<HLSLSemantic>(modifier))
+ sb << hlslSemantic->name.getContent();
+ return;
+}
+
} // namespace Slang
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index ae87c4e10..2b55c3414 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -13,7 +13,6 @@ namespace Slang {
class InModifier : public Modifier { SLANG_AST_CLASS(InModifier)};
class OutModifier : public Modifier { SLANG_AST_CLASS(OutModifier)};
class ConstModifier : public Modifier { SLANG_AST_CLASS(ConstModifier)};
-class InstanceModifier : public Modifier { SLANG_AST_CLASS(InstanceModifier)};
class BuiltinModifier : public Modifier { SLANG_AST_CLASS(BuiltinModifier)};
class InlineModifier : public Modifier { SLANG_AST_CLASS(InlineModifier)};
class VisibilityModifier : public Modifier {SLANG_AST_CLASS(VisibilityModifier)};
@@ -24,7 +23,6 @@ class RequireModifier : public Modifier { SLANG_AST_CLASS(RequireModifier)};
class ParamModifier : public Modifier { SLANG_AST_CLASS(ParamModifier)};
class ExternModifier : public Modifier { SLANG_AST_CLASS(ExternModifier)};
class HLSLExportModifier : public Modifier { SLANG_AST_CLASS(HLSLExportModifier) };
-class InputModifier : public Modifier { SLANG_AST_CLASS(InputModifier)};
class TransparentModifier : public Modifier { SLANG_AST_CLASS(TransparentModifier)};
class FromStdLibModifier : public Modifier { SLANG_AST_CLASS(FromStdLibModifier)};
class PrefixModifier : public Modifier { SLANG_AST_CLASS(PrefixModifier)};
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 20a393ff5..53d121b4b 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -919,6 +919,179 @@ namespace Slang
return attr;
}
+ ASTNodeType getModifierConflictGroupKind(ASTNodeType modifierType)
+ {
+ switch (modifierType)
+ {
+ // Allowed only on parameters and global variables.
+ case ASTNodeType::InModifier:
+ return modifierType;
+ case ASTNodeType::OutModifier:
+ case ASTNodeType::RefModifier:
+ case ASTNodeType::ConstRefModifier:
+ case ASTNodeType::InOutModifier:
+ return ASTNodeType::OutModifier;
+
+ // Modifiers that are their own exclusive group.
+ case ASTNodeType::GLSLLayoutModifier:
+ case ASTNodeType::GLSLParsedLayoutModifier:
+ case ASTNodeType::GLSLConstantIDLayoutModifier:
+ case ASTNodeType::GLSLLocationLayoutModifier:
+ case ASTNodeType::GLSLUnparsedLayoutModifier:
+ case ASTNodeType::GLSLLayoutModifierGroupMarker:
+ case ASTNodeType::GLSLLayoutModifierGroupBegin:
+ case ASTNodeType::GLSLLayoutModifierGroupEnd:
+ case ASTNodeType::GLSLBufferModifier:
+ case ASTNodeType::GLSLWriteOnlyModifier:
+ case ASTNodeType::GLSLReadOnlyModifier:
+ case ASTNodeType::GLSLPatchModifier:
+ case ASTNodeType::RayPayloadAccessSemantic:
+ case ASTNodeType::RayPayloadReadSemantic:
+ case ASTNodeType::RayPayloadWriteSemantic:
+ case ASTNodeType::GloballyCoherentModifier:
+ case ASTNodeType::PreciseModifier:
+ case ASTNodeType::IntrinsicOpModifier:
+ case ASTNodeType::InlineModifier:
+ case ASTNodeType::ExternModifier:
+ case ASTNodeType::HLSLExportModifier:
+ case ASTNodeType::ExternCppModifier:
+ case ASTNodeType::ExportedModifier:
+ case ASTNodeType::ConstModifier:
+ case ASTNodeType::ConstExprModifier:
+ case ASTNodeType::MatrixLayoutModifier:
+ case ASTNodeType::RowMajorLayoutModifier:
+ case ASTNodeType::HLSLRowMajorLayoutModifier:
+ case ASTNodeType::GLSLColumnMajorLayoutModifier:
+ case ASTNodeType::ColumnMajorLayoutModifier:
+ case ASTNodeType::HLSLColumnMajorLayoutModifier:
+ case ASTNodeType::GLSLRowMajorLayoutModifier:
+ case ASTNodeType::HLSLEffectSharedModifier:
+ case ASTNodeType::HLSLGroupSharedModifier:
+ case ASTNodeType::HLSLVolatileModifier:
+ case ASTNodeType::GLSLPrecisionModifier:
+ return modifierType;
+
+ case ASTNodeType::HLSLStaticModifier:
+ case ASTNodeType::ActualGlobalModifier:
+ case ASTNodeType::HLSLUniformModifier:
+ return ASTNodeType::HLSLStaticModifier;
+
+ case ASTNodeType::HLSLNoInterpolationModifier:
+ case ASTNodeType::HLSLNoPerspectiveModifier:
+ case ASTNodeType::HLSLLinearModifier:
+ case ASTNodeType::HLSLSampleModifier:
+ case ASTNodeType::HLSLCentroidModifier:
+ case ASTNodeType::PerVertexModifier:
+ return ASTNodeType::InterpolationModeModifier;
+
+ case ASTNodeType::PrefixModifier:
+ case ASTNodeType::PostfixModifier:
+ return ASTNodeType::PrefixModifier;
+
+ case ASTNodeType::BuiltinModifier:
+ case ASTNodeType::PublicModifier:
+ case ASTNodeType::PrivateModifier:
+ case ASTNodeType::InternalModifier:
+ return ASTNodeType::VisibilityModifier;
+
+ default:
+ return ASTNodeType::NodeBase;
+ }
+ }
+
+ bool isModifierAllowedOnDecl(ASTNodeType modifierType, Decl* decl)
+ {
+ switch (modifierType)
+ {
+ // Allowed only on parameters and global variables.
+ case ASTNodeType::InModifier:
+ case ASTNodeType::OutModifier:
+ case ASTNodeType::InOutModifier:
+ case ASTNodeType::RefModifier:
+ case ASTNodeType::ConstRefModifier:
+ case ASTNodeType::GLSLLayoutModifier:
+ case ASTNodeType::GLSLParsedLayoutModifier:
+ case ASTNodeType::GLSLConstantIDLayoutModifier:
+ case ASTNodeType::GLSLLocationLayoutModifier:
+ case ASTNodeType::GLSLUnparsedLayoutModifier:
+ case ASTNodeType::GLSLLayoutModifierGroupMarker:
+ case ASTNodeType::GLSLLayoutModifierGroupBegin:
+ case ASTNodeType::GLSLLayoutModifierGroupEnd:
+ case ASTNodeType::GLSLBufferModifier:
+ case ASTNodeType::GLSLWriteOnlyModifier:
+ case ASTNodeType::GLSLReadOnlyModifier:
+ case ASTNodeType::GLSLPatchModifier:
+ case ASTNodeType::RayPayloadAccessSemantic:
+ case ASTNodeType::RayPayloadReadSemantic:
+ case ASTNodeType::RayPayloadWriteSemantic:
+ case ASTNodeType::GloballyCoherentModifier:
+ return (as<VarDeclBase>(decl) && isGlobalDecl(decl)) || as<ParamDecl>(decl) || as<GLSLInterfaceBlockDecl>(decl);
+
+ // Allowed only on parameters, struct fields and global variables.
+ case ASTNodeType::InterpolationModeModifier:
+ case ASTNodeType::HLSLNoInterpolationModifier:
+ case ASTNodeType::HLSLNoPerspectiveModifier:
+ case ASTNodeType::HLSLLinearModifier:
+ case ASTNodeType::HLSLSampleModifier:
+ case ASTNodeType::HLSLCentroidModifier:
+ case ASTNodeType::PerVertexModifier:
+ case ASTNodeType::HLSLUniformModifier:
+ return (as<VarDeclBase>(decl) && (isGlobalDecl(decl) || as<StructDecl>(getParentDecl(decl)))) || as<ParamDecl>(decl);
+
+ case ASTNodeType::HLSLSemantic:
+ case ASTNodeType::HLSLLayoutSemantic:
+ case ASTNodeType::HLSLRegisterSemantic:
+ case ASTNodeType::HLSLPackOffsetSemantic:
+ case ASTNodeType::HLSLSimpleSemantic:
+ return (as<VarDeclBase>(decl) && (isGlobalDecl(decl) || as<StructDecl>(getParentDecl(decl)))) || as<ParamDecl>(decl) || as<FuncDecl>(decl);
+
+ // Allowed only on functions
+ case ASTNodeType::IntrinsicOpModifier:
+ case ASTNodeType::SpecializedForTargetModifier:
+ case ASTNodeType::InlineModifier:
+ case ASTNodeType::PrefixModifier:
+ case ASTNodeType::PostfixModifier:
+ return as<CallableDecl>(decl);
+
+ case ASTNodeType::BuiltinModifier:
+ case ASTNodeType::PublicModifier:
+ case ASTNodeType::PrivateModifier:
+ case ASTNodeType::InternalModifier:
+ case ASTNodeType::ExternModifier:
+ case ASTNodeType::HLSLExportModifier:
+ case ASTNodeType::ExternCppModifier:
+ return as<VarDeclBase>(decl) || as<AggTypeDeclBase>(decl) || as<NamespaceDeclBase>(decl) || as<CallableDecl>(decl)
+ || as<TypeDefDecl>(decl) || as<PropertyDecl>(decl) || as<SyntaxDecl>(decl) || as<AttributeDecl>(decl);
+
+ case ASTNodeType::ExportedModifier:
+ return as<ImportDecl>(decl);
+
+ case ASTNodeType::ConstModifier:
+ case ASTNodeType::HLSLStaticModifier:
+ case ASTNodeType::ConstExprModifier:
+ case ASTNodeType::PreciseModifier:
+ return as<VarDeclBase>(decl) || as<CallableDecl>(decl);
+
+ case ASTNodeType::ActualGlobalModifier:
+ case ASTNodeType::MatrixLayoutModifier:
+ case ASTNodeType::RowMajorLayoutModifier:
+ case ASTNodeType::HLSLRowMajorLayoutModifier:
+ case ASTNodeType::GLSLColumnMajorLayoutModifier:
+ case ASTNodeType::ColumnMajorLayoutModifier:
+ case ASTNodeType::HLSLColumnMajorLayoutModifier:
+ case ASTNodeType::GLSLRowMajorLayoutModifier:
+ case ASTNodeType::HLSLEffectSharedModifier:
+ case ASTNodeType::HLSLGroupSharedModifier:
+ case ASTNodeType::HLSLVolatileModifier:
+ return as<VarDeclBase>(decl) || as<GLSLInterfaceBlockDecl>(decl);
+
+ case ASTNodeType::GLSLPrecisionModifier:
+ return as<VarDeclBase>(decl) || as<GLSLInterfaceBlockDecl>(decl) || as<CallableDecl>(decl);
+ default:
+ return true;
+ }
+ }
+
Modifier* SemanticsVisitor::checkModifier(
Modifier* m,
ModifiableSyntaxNode* syntaxNode)
@@ -935,6 +1108,15 @@ namespace Slang
return checkAttribute(hlslUncheckedAttribute, syntaxNode);
}
+ if (auto decl = as<Decl>(syntaxNode))
+ {
+ if (!isModifierAllowedOnDecl(m->astNodeType, decl))
+ {
+ getSink()->diagnose(m, Diagnostics::modifierNotAllowed, m);
+ return m;
+ }
+ }
+
if (auto hlslSemantic = as<HLSLSimpleSemantic>(m))
{
if (hlslSemantic->name.getName() == getSession()->getCompletionRequestTokenName())
@@ -1164,9 +1346,25 @@ namespace Slang
Modifier* resultModifiers = nullptr;
Modifier** resultModifierLink = &resultModifiers;
+ // We will keep track of the modifiers for each conflict group.
+ Dictionary<ASTNodeType, Modifier*> mapExclusiveGroupToModifier;
+
Modifier* modifier = syntaxNode->modifiers.first;
- while(modifier)
+ while (modifier)
{
+ // Check if a modifier belonging to the same conflict group is already
+ // defined.
+ Modifier* existingModifier = nullptr;
+ auto conflictGroup = getModifierConflictGroupKind(modifier->astNodeType);
+ if (conflictGroup != ASTNodeType::NodeBase)
+ {
+ if (mapExclusiveGroupToModifier.tryGetValue(conflictGroup, existingModifier))
+ {
+ getSink()->diagnose(modifier->loc, Diagnostics::duplicateModifier, modifier, existingModifier);
+ }
+ mapExclusiveGroupToModifier[conflictGroup] = modifier;
+ }
+
// Because we are rewriting the list in place, we need to extract
// the next modifier here (not at the end of the loop).
auto next = modifier->next;
@@ -1177,6 +1375,7 @@ namespace Slang
modifier->next = nullptr;
auto checkedModifier = checkModifier(modifier, syntaxNode);
+
if(checkedModifier)
{
// If checking gave us a modifier to add, then we
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 5f28e2af2..429865b75 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -421,7 +421,8 @@ DIAGNOSTIC(31153, Error, cannotUseInterfaceRequirementAsDerivative, "cannot use
DIAGNOSTIC(31154, Error, customDerivativeSignatureThisParamMismatch, "custom derivative does not match expected signature on `this`. Either both the original and the derivative function are static, or they must have the same `this` type.")
DIAGNOSTIC(31155, Error, customDerivativeNotAllowedForMemberFunctionsOfDifferentiableType, "custom derivative is not allowed for non-static member functions of a differentiable type.")
DIAGNOSTIC(31200, Warning, deprecatedUsage, "$0 has been deprecated: $1")
-
+DIAGNOSTIC(31201, Error, modifierNotAllowed, "modifier '$0' is not allowed here.")
+DIAGNOSTIC(31202, Error, duplicateModifier, "modifier '$0' is redundant or conflicting with existing modifier '$1'")
// Enums
DIAGNOSTIC(32000, Error, invalidEnumTagType, "invalid tag type for 'enum': '$0'")
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 9914612ac..361786b6f 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -7756,13 +7756,11 @@ namespace Slang
// a new AST node of the corresponding type.
_makeParseModifier("in", InModifier::kReflectClassInfo),
- _makeParseModifier("input", InputModifier::kReflectClassInfo),
_makeParseModifier("out", OutModifier::kReflectClassInfo),
_makeParseModifier("inout", InOutModifier::kReflectClassInfo),
_makeParseModifier("__ref", RefModifier::kReflectClassInfo),
_makeParseModifier("__constref", ConstRefModifier::kReflectClassInfo),
_makeParseModifier("const", ConstModifier::kReflectClassInfo),
- _makeParseModifier("instance", InstanceModifier::kReflectClassInfo),
_makeParseModifier("__builtin", BuiltinModifier::kReflectClassInfo),
_makeParseModifier("highp", GLSLPrecisionModifier::kReflectClassInfo),
_makeParseModifier("lowp", GLSLPrecisionModifier::kReflectClassInfo),