blob: aeb69ee457f0490cc31dcbcce0e1ffab023dc939 [file] [log] [blame]
Ethan Nicholas6f4eee22021-01-11 12:37:42 -05001/*
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
Brian Osman00185012021-02-04 16:07:11 -05008#include "src/sksl/SkSLMangler.h"
9#include "src/sksl/ir/SkSLSymbolTable.h"
Ethan Nicholas6f4eee22021-01-11 12:37:42 -050010
11namespace SkSL {
12
John Stiles769146f2021-09-15 21:47:00 -040013String Mangler::uniqueName(skstd::string_view baseName, SymbolTable* symbolTable) {
Ethan Nicholas6f4eee22021-01-11 12:37:42 -050014 SkASSERT(symbolTable);
15 // The inliner runs more than once, so the base name might already have been mangled and have a
16 // prefix like "_123_x". Let's strip that prefix off to make the generated code easier to read.
Ethan Nicholasd2e09602021-06-10 11:21:59 -040017 if (baseName.starts_with("_")) {
Ethan Nicholas6f4eee22021-01-11 12:37:42 -050018 // Determine if we have a string of digits.
19 int offset = 1;
20 while (isdigit(baseName[offset])) {
21 ++offset;
22 }
23 // If we found digits, another underscore, and anything else, that's the mangler prefix.
24 // Strip it off.
25 if (offset > 1 && baseName[offset] == '_' && baseName[offset + 1] != '\0') {
John Stiles769146f2021-09-15 21:47:00 -040026 baseName.remove_prefix(offset + 1);
Ethan Nicholas6f4eee22021-01-11 12:37:42 -050027 } else {
28 // This name doesn't contain a mangler prefix, but it does start with an underscore.
29 // OpenGL disallows two consecutive underscores anywhere in the string, and we'll be
30 // adding one as part of the mangler prefix, so strip the leading underscore.
John Stiles769146f2021-09-15 21:47:00 -040031 baseName.remove_prefix(1);
Ethan Nicholas6f4eee22021-01-11 12:37:42 -050032 }
33 }
34
35 // Append a unique numeric prefix to avoid name overlap. Check the symbol table to make sure
36 // we're not reusing an existing name. (Note that within a single compilation pass, this check
37 // isn't fully comprehensive, as code isn't always generated in top-to-bottom order.)
38 String uniqueName;
39 for (;;) {
John Stiles769146f2021-09-15 21:47:00 -040040 uniqueName = String::printf("_%d_%.*s", fCounter++, (int)baseName.size(), baseName.data());
41 if ((*symbolTable)[uniqueName] == nullptr) {
Ethan Nicholas6f4eee22021-01-11 12:37:42 -050042 break;
43 }
44 }
45
46 return uniqueName;
47}
48
49} // namespace SkSL