Line data Source code
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 :
13 0 : std::vector<const FunctionDeclaration*> SymbolTable::GetFunctions(const Symbol& s) {
14 0 : switch (s.fKind) {
15 : case Symbol::kFunctionDeclaration_Kind:
16 0 : return { &((FunctionDeclaration&) s) };
17 : case Symbol::kUnresolvedFunction_Kind:
18 0 : return ((UnresolvedFunction&) s).fFunctions;
19 : default:
20 0 : return std::vector<const FunctionDeclaration*>();
21 : }
22 : }
23 :
24 0 : const Symbol* SymbolTable::operator[](const String& name) {
25 0 : const auto& entry = fSymbols.find(name);
26 0 : if (entry == fSymbols.end()) {
27 0 : if (fParent) {
28 0 : return (*fParent)[name];
29 : }
30 0 : return nullptr;
31 : }
32 0 : if (fParent) {
33 0 : auto functions = GetFunctions(*entry->second);
34 0 : if (functions.size() > 0) {
35 0 : bool modified = false;
36 0 : const Symbol* previous = (*fParent)[name];
37 0 : if (previous) {
38 0 : auto previousFunctions = GetFunctions(*previous);
39 0 : for (const FunctionDeclaration* prev : previousFunctions) {
40 0 : bool found = false;
41 0 : for (const FunctionDeclaration* current : functions) {
42 0 : if (current->matches(*prev)) {
43 0 : found = true;
44 0 : break;
45 : }
46 : }
47 0 : if (!found) {
48 0 : functions.push_back(prev);
49 0 : modified = true;
50 : }
51 : }
52 0 : if (modified) {
53 0 : ASSERT(functions.size() > 1);
54 0 : return this->takeOwnership(new UnresolvedFunction(functions));
55 : }
56 : }
57 : }
58 : }
59 0 : return entry->second;
60 : }
61 :
62 0 : Symbol* SymbolTable::takeOwnership(Symbol* s) {
63 0 : fOwnedPointers.push_back(std::unique_ptr<Symbol>(s));
64 0 : return s;
65 : }
66 :
67 0 : void SymbolTable::add(const String& name, std::unique_ptr<Symbol> symbol) {
68 0 : this->addWithoutOwnership(name, symbol.get());
69 0 : fOwnedPointers.push_back(std::move(symbol));
70 0 : }
71 :
72 0 : void SymbolTable::addWithoutOwnership(const String& name, const Symbol* symbol) {
73 0 : const auto& existing = fSymbols.find(name);
74 0 : if (existing == fSymbols.end()) {
75 0 : fSymbols[name] = symbol;
76 0 : } else if (symbol->fKind == Symbol::kFunctionDeclaration_Kind) {
77 0 : const Symbol* oldSymbol = existing->second;
78 0 : if (oldSymbol->fKind == Symbol::kFunctionDeclaration_Kind) {
79 0 : std::vector<const FunctionDeclaration*> functions;
80 0 : functions.push_back((const FunctionDeclaration*) oldSymbol);
81 0 : functions.push_back((const FunctionDeclaration*) symbol);
82 0 : UnresolvedFunction* u = new UnresolvedFunction(std::move(functions));
83 0 : fSymbols[name] = u;
84 0 : this->takeOwnership(u);
85 0 : } else if (oldSymbol->fKind == Symbol::kUnresolvedFunction_Kind) {
86 0 : std::vector<const FunctionDeclaration*> functions;
87 0 : for (const auto* f : ((UnresolvedFunction&) *oldSymbol).fFunctions) {
88 0 : functions.push_back(f);
89 : }
90 0 : functions.push_back((const FunctionDeclaration*) symbol);
91 0 : UnresolvedFunction* u = new UnresolvedFunction(std::move(functions));
92 0 : fSymbols[name] = u;
93 0 : this->takeOwnership(u);
94 : }
95 : } else {
96 0 : fErrorReporter.error(symbol->fPosition, "symbol '" + name + "' was already defined");
97 : }
98 0 : }
99 :
100 :
101 0 : void SymbolTable::markAllFunctionsBuiltin() {
102 0 : for (const auto& pair : fSymbols) {
103 0 : switch (pair.second->fKind) {
104 : case Symbol::kFunctionDeclaration_Kind:
105 0 : ((FunctionDeclaration&) *pair.second).fBuiltin = true;
106 0 : break;
107 : case Symbol::kUnresolvedFunction_Kind:
108 0 : for (auto& f : ((UnresolvedFunction&) *pair.second).fFunctions) {
109 0 : ((FunctionDeclaration*) f)->fBuiltin = true;
110 : }
111 0 : break;
112 : default:
113 0 : break;
114 : }
115 : }
116 0 : }
117 :
118 : } // namespace
|