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 };
32
33 bool success = true;
34 int modifierFlags = fFlags;
35 for (const auto& f : kModifierFlags) {
36 if (modifierFlags & f.flag) {
37 if (!(permittedModifierFlags & f.flag)) {
38 context.fErrors->error(line, "'" + String(f.name) + "' is not permitted here");
39 success = false;
40 }
41 modifierFlags &= ~f.flag;
42 }
43 }
44 SkASSERT(modifierFlags == 0);
45
46 static constexpr struct { Layout::Flag flag; const char* name; } kLayoutFlags[] = {
47 { Layout::kOriginUpperLeft_Flag, "origin_upper_left"},
48 { Layout::kPushConstant_Flag, "push_constant"},
49 { Layout::kBlendSupportAllEquations_Flag, "blend_support_all_equations"},
50 { Layout::kSRGBUnpremul_Flag, "srgb_unpremul"},
51 { Layout::kLocation_Flag, "location"},
52 { Layout::kOffset_Flag, "offset"},
53 { Layout::kBinding_Flag, "binding"},
54 { Layout::kIndex_Flag, "index"},
55 { Layout::kSet_Flag, "set"},
56 { Layout::kBuiltin_Flag, "builtin"},
57 { Layout::kInputAttachmentIndex_Flag, "input_attachment_index"},
58 };
59
60 int layoutFlags = fLayout.fFlags;
61 for (const auto& lf : kLayoutFlags) {
62 if (layoutFlags & lf.flag) {
63 if (!(permittedLayoutFlags & lf.flag)) {
64 context.fErrors->error(
65 line, "layout qualifier '" + String(lf.name) + "' is not permitted here");
66 success = false;
67 }
68 layoutFlags &= ~lf.flag;
69 }
70 }
71 SkASSERT(layoutFlags == 0);
72 return success;
73 }
74
75 } // namespace SkSL
76