• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
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/ir/SkSLSymbolTable.h"
9 #include "src/sksl/ir/SkSLUnresolvedFunction.h"
10 
11 namespace SkSL {
12 
GetFunctions(const Symbol & s)13 std::vector<const FunctionDeclaration*> SymbolTable::GetFunctions(const Symbol& s) {
14     switch (s.fKind) {
15         case Symbol::kFunctionDeclaration_Kind:
16             return { &((FunctionDeclaration&) s) };
17         case Symbol::kUnresolvedFunction_Kind:
18             return ((UnresolvedFunction&) s).fFunctions;
19         default:
20             return std::vector<const FunctionDeclaration*>();
21     }
22 }
23 
operator [](StringFragment name)24 const Symbol* SymbolTable::operator[](StringFragment name) {
25     const auto& entry = fSymbols.find(name);
26     if (entry == fSymbols.end()) {
27         if (fParent) {
28             return (*fParent)[name];
29         }
30         return nullptr;
31     }
32     if (fParent) {
33         auto functions = GetFunctions(*entry->second);
34         if (functions.size() > 0) {
35             bool modified = false;
36             const Symbol* previous = (*fParent)[name];
37             if (previous) {
38                 auto previousFunctions = GetFunctions(*previous);
39                 for (const FunctionDeclaration* prev : previousFunctions) {
40                     bool found = false;
41                     for (const FunctionDeclaration* current : functions) {
42                         if (current->matches(*prev)) {
43                             found = true;
44                             break;
45                         }
46                     }
47                     if (!found) {
48                         functions.push_back(prev);
49                         modified = true;
50                     }
51                 }
52                 if (modified) {
53                     SkASSERT(functions.size() > 1);
54                     return this->takeOwnership(std::unique_ptr<Symbol>(
55                                                                 new UnresolvedFunction(functions)));
56                 }
57             }
58         }
59     }
60     return entry->second;
61 }
62 
takeOwnership(std::unique_ptr<Symbol> s)63 Symbol* SymbolTable::takeOwnership(std::unique_ptr<Symbol> s) {
64     Symbol* result = s.get();
65     fOwnedSymbols.push_back(std::move(s));
66     return result;
67 }
68 
takeOwnership(std::unique_ptr<IRNode> n)69 IRNode* SymbolTable::takeOwnership(std::unique_ptr<IRNode> n) {
70     IRNode* result = n.get();
71     fOwnedNodes.push_back(std::move(n));
72     return result;
73 }
74 
add(StringFragment name,std::unique_ptr<Symbol> symbol)75 void SymbolTable::add(StringFragment name, std::unique_ptr<Symbol> symbol) {
76     this->addWithoutOwnership(name, symbol.get());
77     this->takeOwnership(std::move(symbol));
78 }
79 
addWithoutOwnership(StringFragment name,const Symbol * symbol)80 void SymbolTable::addWithoutOwnership(StringFragment name, const Symbol* symbol) {
81     const auto& existing = fSymbols.find(name);
82     if (existing == fSymbols.end()) {
83         fSymbols[name] = symbol;
84     } else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) {
85         const Symbol* oldSymbol = existing->second;
86         if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) {
87             std::vector<const FunctionDeclaration*> functions;
88             functions.push_back((const FunctionDeclaration*) oldSymbol);
89             functions.push_back((const FunctionDeclaration*) symbol);
90             std::unique_ptr<Symbol> u = std::unique_ptr<Symbol>(new UnresolvedFunction(std::move(
91                                                                                        functions)));
92             fSymbols[name] = this->takeOwnership(std::move(u));
93         } else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) {
94             std::vector<const FunctionDeclaration*> functions;
95             for (const auto* f : ((UnresolvedFunction&) *oldSymbol).fFunctions) {
96                 functions.push_back(f);
97             }
98             functions.push_back((const FunctionDeclaration*) symbol);
99             std::unique_ptr<Symbol> u = std::unique_ptr<Symbol>(new UnresolvedFunction(std::move(
100                                                                                        functions)));
101             fSymbols[name] = this->takeOwnership(std::move(u));
102         }
103     } else {
104         fErrorReporter.error(symbol->fOffset, "symbol '" + name + "' was already defined");
105     }
106 }
107 
108 
markAllFunctionsBuiltin()109 void SymbolTable::markAllFunctionsBuiltin() {
110     for (const auto& pair : fSymbols) {
111         switch (pair.second->fKind) {
112             case Symbol::kFunctionDeclaration_Kind:
113                 if (!((FunctionDeclaration&)*pair.second).fDefined) {
114                     ((FunctionDeclaration&)*pair.second).fBuiltin = true;
115                 }
116                 break;
117             case Symbol::kUnresolvedFunction_Kind:
118                 for (auto& f : ((UnresolvedFunction&) *pair.second).fFunctions) {
119                     if (!((FunctionDeclaration*)f)->fDefined) {
120                         ((FunctionDeclaration*)f)->fBuiltin = true;
121                     }
122                 }
123                 break;
124             default:
125                 break;
126         }
127     }
128 }
129 
begin()130 std::unordered_map<StringFragment, const Symbol*>::iterator SymbolTable::begin() {
131     return fSymbols.begin();
132 }
133 
end()134 std::unordered_map<StringFragment, const Symbol*>::iterator SymbolTable::end() {
135     return fSymbols.end();
136 }
137 
138 
139 } // namespace
140