• 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 "SkSLSymbolTable.h"
9 #include "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 [](const String & name)24 const Symbol* SymbolTable::operator[](const String& 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                     ASSERT(functions.size() > 1);
54                     return this->takeOwnership(new UnresolvedFunction(functions));
55                 }
56             }
57         }
58     }
59     return entry->second;
60 }
61 
takeOwnership(Symbol * s)62 Symbol* SymbolTable::takeOwnership(Symbol* s) {
63     fOwnedPointers.push_back(std::unique_ptr<Symbol>(s));
64     return s;
65 }
66 
add(const String & name,std::unique_ptr<Symbol> symbol)67 void SymbolTable::add(const String& name, std::unique_ptr<Symbol> symbol) {
68     this->addWithoutOwnership(name, symbol.get());
69     fOwnedPointers.push_back(std::move(symbol));
70 }
71 
addWithoutOwnership(const String & name,const Symbol * symbol)72 void SymbolTable::addWithoutOwnership(const String& name, const Symbol* symbol) {
73     const auto& existing = fSymbols.find(name);
74     if (existing == fSymbols.end()) {
75         fSymbols[name] = symbol;
76     } else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) {
77         const Symbol* oldSymbol = existing->second;
78         if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) {
79             std::vector<const FunctionDeclaration*> functions;
80             functions.push_back((const FunctionDeclaration*) oldSymbol);
81             functions.push_back((const FunctionDeclaration*) symbol);
82             UnresolvedFunction* u = new UnresolvedFunction(std::move(functions));
83             fSymbols[name] = u;
84             this->takeOwnership(u);
85         } else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) {
86             std::vector<const FunctionDeclaration*> functions;
87             for (const auto* f : ((UnresolvedFunction&) *oldSymbol).fFunctions) {
88                 functions.push_back(f);
89             }
90             functions.push_back((const FunctionDeclaration*) symbol);
91             UnresolvedFunction* u = new UnresolvedFunction(std::move(functions));
92             fSymbols[name] = u;
93             this->takeOwnership(u);
94         }
95     } else {
96         fErrorReporter.error(symbol->fPosition, "symbol '" + name + "' was already defined");
97     }
98 }
99 
100 
markAllFunctionsBuiltin()101 void SymbolTable::markAllFunctionsBuiltin() {
102     for (const auto& pair : fSymbols) {
103         switch (pair.second->fKind) {
104             case Symbol::kFunctionDeclaration_Kind:
105                 ((FunctionDeclaration&) *pair.second).fBuiltin = true;
106                 break;
107             case Symbol::kUnresolvedFunction_Kind:
108                 for (auto& f : ((UnresolvedFunction&) *pair.second).fFunctions) {
109                     ((FunctionDeclaration*) f)->fBuiltin = true;
110                 }
111                 break;
112             default:
113                 break;
114         }
115     }
116 }
117 
118 } // namespace
119