• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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