• 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 #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