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