xref: /third_party/skia/src/sksl/SkSLMangler.cpp (revision cb93a386)
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 "src/sksl/SkSLMangler.h"
9cb93a386Sopenharmony_ci#include "src/sksl/ir/SkSLSymbolTable.h"
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_cinamespace SkSL {
12cb93a386Sopenharmony_ci
13cb93a386Sopenharmony_ciString Mangler::uniqueName(skstd::string_view baseName, SymbolTable* symbolTable) {
14cb93a386Sopenharmony_ci    SkASSERT(symbolTable);
15cb93a386Sopenharmony_ci    // The inliner runs more than once, so the base name might already have been mangled and have a
16cb93a386Sopenharmony_ci    // prefix like "_123_x". Let's strip that prefix off to make the generated code easier to read.
17cb93a386Sopenharmony_ci    if (baseName.starts_with("_")) {
18cb93a386Sopenharmony_ci        // Determine if we have a string of digits.
19cb93a386Sopenharmony_ci        int offset = 1;
20cb93a386Sopenharmony_ci        while (isdigit(baseName[offset])) {
21cb93a386Sopenharmony_ci            ++offset;
22cb93a386Sopenharmony_ci        }
23cb93a386Sopenharmony_ci        // If we found digits, another underscore, and anything else, that's the mangler prefix.
24cb93a386Sopenharmony_ci        // Strip it off.
25cb93a386Sopenharmony_ci        if (offset > 1 && baseName[offset] == '_' && baseName[offset + 1] != '\0') {
26cb93a386Sopenharmony_ci            baseName.remove_prefix(offset + 1);
27cb93a386Sopenharmony_ci        } else {
28cb93a386Sopenharmony_ci            // This name doesn't contain a mangler prefix, but it does start with an underscore.
29cb93a386Sopenharmony_ci            // OpenGL disallows two consecutive underscores anywhere in the string, and we'll be
30cb93a386Sopenharmony_ci            // adding one as part of the mangler prefix, so strip the leading underscore.
31cb93a386Sopenharmony_ci            baseName.remove_prefix(1);
32cb93a386Sopenharmony_ci        }
33cb93a386Sopenharmony_ci    }
34cb93a386Sopenharmony_ci
35cb93a386Sopenharmony_ci    // Append a unique numeric prefix to avoid name overlap. Check the symbol table to make sure
36cb93a386Sopenharmony_ci    // we're not reusing an existing name. (Note that within a single compilation pass, this check
37cb93a386Sopenharmony_ci    // isn't fully comprehensive, as code isn't always generated in top-to-bottom order.)
38cb93a386Sopenharmony_ci    String uniqueName;
39cb93a386Sopenharmony_ci    for (;;) {
40cb93a386Sopenharmony_ci        uniqueName = String::printf("_%d_%.*s", fCounter++, (int)baseName.size(), baseName.data());
41cb93a386Sopenharmony_ci        if ((*symbolTable)[uniqueName] == nullptr) {
42cb93a386Sopenharmony_ci            break;
43cb93a386Sopenharmony_ci        }
44cb93a386Sopenharmony_ci    }
45cb93a386Sopenharmony_ci
46cb93a386Sopenharmony_ci    return uniqueName;
47cb93a386Sopenharmony_ci}
48cb93a386Sopenharmony_ci
49cb93a386Sopenharmony_ci} // namespace SkSL
50