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