1 /*
2 * Copyright 2021 Google LLC.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "include/private/SkSLModifiers.h"
9
10 #include "include/sksl/SkSLErrorReporter.h"
11 #include "src/sksl/SkSLContext.h"
12
13 namespace SkSL {
14
checkPermitted(const Context & context,int line,int permittedModifierFlags,int permittedLayoutFlags) const15 bool Modifiers::checkPermitted(const Context& context, int line, int permittedModifierFlags,
16 int permittedLayoutFlags) const {
17 static constexpr struct { Modifiers::Flag flag; const char* name; } kModifierFlags[] = {
18 { Modifiers::kConst_Flag, "const" },
19 { Modifiers::kIn_Flag, "in" },
20 { Modifiers::kOut_Flag, "out" },
21 { Modifiers::kUniform_Flag, "uniform" },
22 { Modifiers::kFlat_Flag, "flat" },
23 { Modifiers::kNoPerspective_Flag, "noperspective" },
24 { Modifiers::kHasSideEffects_Flag, "sk_has_side_effects" },
25 { Modifiers::kInline_Flag, "inline" },
26 { Modifiers::kNoInline_Flag, "noinline" },
27 { Modifiers::kHighp_Flag, "highp" },
28 { Modifiers::kMediump_Flag, "mediump" },
29 { Modifiers::kLowp_Flag, "lowp" },
30 { Modifiers::kES3_Flag, "$es3" },
31 #ifdef SKSL_EXT
32 { Modifiers::kReadOnly_Flag, "readonly" },
33 { Modifiers::kWriteOnly_Flag, "writeonly" },
34 { Modifiers::kBuffer_Flag, "buffer" },
35 #endif
36 };
37
38 bool success = true;
39 int modifierFlags = fFlags;
40 for (const auto& f : kModifierFlags) {
41 if (modifierFlags & f.flag) {
42 if (!(permittedModifierFlags & f.flag)) {
43 context.fErrors->error(line, "'" + String(f.name) + "' is not permitted here");
44 success = false;
45 }
46 modifierFlags &= ~f.flag;
47 }
48 }
49 SkASSERT(modifierFlags == 0);
50
51 static constexpr struct { Layout::Flag flag; const char* name; } kLayoutFlags[] = {
52 { Layout::kOriginUpperLeft_Flag, "origin_upper_left"},
53 { Layout::kPushConstant_Flag, "push_constant"},
54 { Layout::kBlendSupportAllEquations_Flag, "blend_support_all_equations"},
55 { Layout::kSRGBUnpremul_Flag, "srgb_unpremul"},
56 { Layout::kLocation_Flag, "location"},
57 { Layout::kOffset_Flag, "offset"},
58 { Layout::kBinding_Flag, "binding"},
59 { Layout::kIndex_Flag, "index"},
60 { Layout::kSet_Flag, "set"},
61 { Layout::kBuiltin_Flag, "builtin"},
62 { Layout::kInputAttachmentIndex_Flag, "input_attachment_index"},
63 #ifdef SKSL_EXT
64 { Layout::kConstantId_Flag, "constant_id"},
65 #endif
66 };
67
68 int layoutFlags = fLayout.fFlags;
69 for (const auto& lf : kLayoutFlags) {
70 if (layoutFlags & lf.flag) {
71 if (!(permittedLayoutFlags & lf.flag)) {
72 context.fErrors->error(
73 line, "layout qualifier '" + String(lf.name) + "' is not permitted here");
74 success = false;
75 }
76 layoutFlags &= ~lf.flag;
77 }
78 }
79 SkASSERT(layoutFlags == 0);
80 return success;
81 }
82
83 } // namespace SkSL
84