Add permittedLayoutFlags to checkModifiers
For now, just use this to prevent *any* layout qualifiers from appearing
on functions, or their parameters.
Bug: skia:11301
Change-Id: I05d8118c7121048c6ef49695a54e3714a8f8687e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/376796
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/gn/sksl_tests.gni b/gn/sksl_tests.gni
index 88ba6f1..fefbb09 100644
--- a/gn/sksl_tests.gni
+++ b/gn/sksl_tests.gni
@@ -124,6 +124,7 @@
"/sksl/errors/InvalidOutParams.sksl",
"/sksl/errors/InvalidToken.sksl",
"/sksl/errors/InvalidUnary.sksl",
+ "/sksl/errors/LayoutInFunctions.sksl",
"/sksl/errors/LayoutMultiplePrimitiveTypes.sksl",
"/sksl/errors/LayoutRepeatedQualifiers.sksl",
"/sksl/errors/MismatchedNumbers.sksl",
diff --git a/resources/sksl/errors/LayoutInFunctions.sksl b/resources/sksl/errors/LayoutInFunctions.sksl
new file mode 100644
index 0000000..3b4aa9f
--- /dev/null
+++ b/resources/sksl/errors/LayoutInFunctions.sksl
@@ -0,0 +1,43 @@
+layout (
+ origin_upper_left,
+ override_coverage,
+ push_constant,
+ blend_support_all_equations,
+ tracked,
+ srgb_unpremul,
+ key,
+ location = 1,
+ offset = 1,
+ binding = 1,
+ index = 1,
+ set = 1,
+ builtin = 1,
+ input_attachment_index = 1,
+ max_vertices = 1,
+ invocations = 1,
+ marker = one,
+ when = one,
+ ctype = int)
+void on_return() {}
+
+void on_param(
+layout (
+ origin_upper_left,
+ override_coverage,
+ push_constant,
+ blend_support_all_equations,
+ tracked,
+ srgb_unpremul,
+ key,
+ location = 1,
+ offset = 1,
+ binding = 1,
+ index = 1,
+ set = 1,
+ builtin = 1,
+ input_attachment_index = 1,
+ max_vertices = 1,
+ invocations = 1,
+ marker = one,
+ when = one,
+ ctype = int) float x) {}
diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp
index c6881fd..7534900 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -376,7 +376,8 @@
Modifiers::kFlat_Flag | Modifiers::kVarying_Flag |
Modifiers::kNoPerspective_Flag;
}
- this->checkModifiers(offset, modifiers, permitted);
+ // TODO(skbug.com/11301): Migrate above checks into building a mask of permitted layout flags
+ this->checkModifiers(offset, modifiers, permitted, /*permittedLayoutFlags=*/~0);
}
std::unique_ptr<Variable> IRGenerator::convertVar(int offset, const Modifiers& modifiers,
@@ -861,26 +862,63 @@
return ExpressionStatement::Make(fContext, std::move(result));
}
-void IRGenerator::checkModifiers(int offset, const Modifiers& modifiers, int permitted) {
+void IRGenerator::checkModifiers(int offset,
+ const Modifiers& modifiers,
+ int permittedModifierFlags,
+ int permittedLayoutFlags) {
int flags = modifiers.fFlags;
- #define CHECK(flag, name) \
- if (!flags) return; \
- if (flags & flag) { \
- if (!(permitted & flag)) { \
- this->errorReporter().error(offset, "'" name "' is not permitted here"); \
- } \
- flags &= ~flag; \
+ auto checkModifier = [&](Modifiers::Flag flag, const char* name) {
+ if (flags & flag) {
+ if (!(permittedModifierFlags & flag)) {
+ this->errorReporter().error(offset, "'" + String(name) + "' is not permitted here");
+ }
+ flags &= ~flag;
}
- CHECK(Modifiers::kConst_Flag, "const")
- CHECK(Modifiers::kIn_Flag, "in")
- CHECK(Modifiers::kOut_Flag, "out")
- CHECK(Modifiers::kUniform_Flag, "uniform")
- CHECK(Modifiers::kFlat_Flag, "flat")
- CHECK(Modifiers::kNoPerspective_Flag, "noperspective")
- CHECK(Modifiers::kHasSideEffects_Flag, "sk_has_side_effects")
- CHECK(Modifiers::kVarying_Flag, "varying")
- CHECK(Modifiers::kInline_Flag, "inline")
+ };
+
+ checkModifier(Modifiers::kConst_Flag, "const");
+ checkModifier(Modifiers::kIn_Flag, "in");
+ checkModifier(Modifiers::kOut_Flag, "out");
+ checkModifier(Modifiers::kUniform_Flag, "uniform");
+ checkModifier(Modifiers::kFlat_Flag, "flat");
+ checkModifier(Modifiers::kNoPerspective_Flag, "noperspective");
+ checkModifier(Modifiers::kHasSideEffects_Flag, "sk_has_side_effects");
+ checkModifier(Modifiers::kVarying_Flag, "varying");
+ checkModifier(Modifiers::kInline_Flag, "inline");
SkASSERT(flags == 0);
+
+ int layoutFlags = modifiers.fLayout.fFlags;
+ auto checkLayout = [&](Layout::Flag flag, const char* name) {
+ if (layoutFlags & flag) {
+ if (!(permittedLayoutFlags & flag)) {
+ this->errorReporter().error(
+ offset, "layout qualifier '" + String(name) + "' is not permitted here");
+ }
+ layoutFlags &= ~flag;
+ }
+ };
+
+ checkLayout(Layout::kOriginUpperLeft_Flag, "origin_upper_left");
+ checkLayout(Layout::kOverrideCoverage_Flag, "override_coverage");
+ checkLayout(Layout::kPushConstant_Flag, "push_constant");
+ checkLayout(Layout::kBlendSupportAllEquations_Flag, "blend_support_all_equations");
+ checkLayout(Layout::kTracked_Flag, "tracked");
+ checkLayout(Layout::kSRGBUnpremul_Flag, "srgb_unpremul");
+ checkLayout(Layout::kKey_Flag, "key");
+ checkLayout(Layout::kLocation_Flag, "location");
+ checkLayout(Layout::kOffset_Flag, "offset");
+ checkLayout(Layout::kBinding_Flag, "binding");
+ checkLayout(Layout::kIndex_Flag, "index");
+ checkLayout(Layout::kSet_Flag, "set");
+ checkLayout(Layout::kBuiltin_Flag, "builtin");
+ checkLayout(Layout::kInputAttachmentIndex_Flag, "input_attachment_index");
+ checkLayout(Layout::kPrimitive_Flag, "primitive-type");
+ checkLayout(Layout::kMaxVertices_Flag, "max_vertices");
+ checkLayout(Layout::kInvocations_Flag, "invocations");
+ checkLayout(Layout::kMarker_Flag, "marker");
+ checkLayout(Layout::kWhen_Flag, "when");
+ checkLayout(Layout::kCType_Flag, "ctype");
+ SkASSERT(layoutFlags == 0);
}
void IRGenerator::finalizeFunction(FunctionDefinition& f) {
@@ -1009,16 +1047,17 @@
return;
}
const ASTNode::FunctionData& funcData = f.getFunctionData();
- this->checkModifiers(f.fOffset, funcData.fModifiers, Modifiers::kHasSideEffects_Flag |
- Modifiers::kInline_Flag);
+ this->checkModifiers(f.fOffset, funcData.fModifiers,
+ Modifiers::kHasSideEffects_Flag | Modifiers::kInline_Flag,
+ /*permittedLayoutFlags=*/0);
std::vector<const Variable*> parameters;
for (size_t i = 0; i < funcData.fParameterCount; ++i) {
const ASTNode& param = *(iter++);
SkASSERT(param.fKind == ASTNode::Kind::kParameter);
ASTNode::ParameterData pd = param.getParameterData();
- this->checkModifiers(param.fOffset, pd.fModifiers, Modifiers::kConst_Flag |
- Modifiers::kIn_Flag |
- Modifiers::kOut_Flag);
+ this->checkModifiers(param.fOffset, pd.fModifiers,
+ Modifiers::kConst_Flag | Modifiers::kIn_Flag | Modifiers::kOut_Flag,
+ /*permittedLayoutFlags=*/0);
auto paramIter = param.begin();
const Type* type = this->convertType(*(paramIter++));
if (!type) {
diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h
index ce1c6b3..06dcc59 100644
--- a/src/sksl/SkSLIRGenerator.h
+++ b/src/sksl/SkSLIRGenerator.h
@@ -150,8 +150,13 @@
*/
std::unique_ptr<ModifiersPool> releaseModifiers();
- void checkModifiers(int offset, const Modifiers& modifiers, int permitted);
- void checkVarDeclaration(int offset, const Modifiers& modifiers, const Type* baseType,
+ void checkModifiers(int offset,
+ const Modifiers& modifiers,
+ int permittedModifierFlags,
+ int permittedLayoutFlags);
+ void checkVarDeclaration(int offset,
+ const Modifiers& modifiers,
+ const Type* baseType,
Variable::Storage storage);
std::unique_ptr<Variable> convertVar(int offset, const Modifiers& modifiers,
const Type* baseType, StringFragment name, bool isArray,
diff --git a/tests/sksl/errors/LayoutInFunctions.glsl b/tests/sksl/errors/LayoutInFunctions.glsl
new file mode 100644
index 0000000..7a10dd3
--- /dev/null
+++ b/tests/sksl/errors/LayoutInFunctions.glsl
@@ -0,0 +1,41 @@
+### Compilation failed:
+
+error: 21: layout qualifier 'origin_upper_left' is not permitted here
+error: 21: layout qualifier 'override_coverage' is not permitted here
+error: 21: layout qualifier 'push_constant' is not permitted here
+error: 21: layout qualifier 'blend_support_all_equations' is not permitted here
+error: 21: layout qualifier 'tracked' is not permitted here
+error: 21: layout qualifier 'srgb_unpremul' is not permitted here
+error: 21: layout qualifier 'key' is not permitted here
+error: 21: layout qualifier 'location' is not permitted here
+error: 21: layout qualifier 'offset' is not permitted here
+error: 21: layout qualifier 'binding' is not permitted here
+error: 21: layout qualifier 'index' is not permitted here
+error: 21: layout qualifier 'set' is not permitted here
+error: 21: layout qualifier 'builtin' is not permitted here
+error: 21: layout qualifier 'input_attachment_index' is not permitted here
+error: 21: layout qualifier 'max_vertices' is not permitted here
+error: 21: layout qualifier 'invocations' is not permitted here
+error: 21: layout qualifier 'marker' is not permitted here
+error: 21: layout qualifier 'when' is not permitted here
+error: 21: layout qualifier 'ctype' is not permitted here
+error: 43: layout qualifier 'origin_upper_left' is not permitted here
+error: 43: layout qualifier 'override_coverage' is not permitted here
+error: 43: layout qualifier 'push_constant' is not permitted here
+error: 43: layout qualifier 'blend_support_all_equations' is not permitted here
+error: 43: layout qualifier 'tracked' is not permitted here
+error: 43: layout qualifier 'srgb_unpremul' is not permitted here
+error: 43: layout qualifier 'key' is not permitted here
+error: 43: layout qualifier 'location' is not permitted here
+error: 43: layout qualifier 'offset' is not permitted here
+error: 43: layout qualifier 'binding' is not permitted here
+error: 43: layout qualifier 'index' is not permitted here
+error: 43: layout qualifier 'set' is not permitted here
+error: 43: layout qualifier 'builtin' is not permitted here
+error: 43: layout qualifier 'input_attachment_index' is not permitted here
+error: 43: layout qualifier 'max_vertices' is not permitted here
+error: 43: layout qualifier 'invocations' is not permitted here
+error: 43: layout qualifier 'marker' is not permitted here
+error: 43: layout qualifier 'when' is not permitted here
+error: 43: layout qualifier 'ctype' is not permitted here
+38 errors