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