SkSLSymbolTable.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. #include "src/sksl/ir/SkSLSymbolTable.h"
  8. #include "src/sksl/ir/SkSLUnresolvedFunction.h"
  9. namespace SkSL {
  10. std::vector<const FunctionDeclaration*> SymbolTable::GetFunctions(const Symbol& s) {
  11. switch (s.fKind) {
  12. case Symbol::kFunctionDeclaration_Kind:
  13. return { &((FunctionDeclaration&) s) };
  14. case Symbol::kUnresolvedFunction_Kind:
  15. return ((UnresolvedFunction&) s).fFunctions;
  16. default:
  17. return std::vector<const FunctionDeclaration*>();
  18. }
  19. }
  20. const Symbol* SymbolTable::operator[](StringFragment name) {
  21. const auto& entry = fSymbols.find(name);
  22. if (entry == fSymbols.end()) {
  23. if (fParent) {
  24. return (*fParent)[name];
  25. }
  26. return nullptr;
  27. }
  28. if (fParent) {
  29. auto functions = GetFunctions(*entry->second);
  30. if (functions.size() > 0) {
  31. bool modified = false;
  32. const Symbol* previous = (*fParent)[name];
  33. if (previous) {
  34. auto previousFunctions = GetFunctions(*previous);
  35. for (const FunctionDeclaration* prev : previousFunctions) {
  36. bool found = false;
  37. for (const FunctionDeclaration* current : functions) {
  38. if (current->matches(*prev)) {
  39. found = true;
  40. break;
  41. }
  42. }
  43. if (!found) {
  44. functions.push_back(prev);
  45. modified = true;
  46. }
  47. }
  48. if (modified) {
  49. SkASSERT(functions.size() > 1);
  50. return this->takeOwnership(std::unique_ptr<Symbol>(
  51. new UnresolvedFunction(functions)));
  52. }
  53. }
  54. }
  55. }
  56. return entry->second;
  57. }
  58. Symbol* SymbolTable::takeOwnership(std::unique_ptr<Symbol> s) {
  59. Symbol* result = s.get();
  60. fOwnedSymbols.push_back(std::move(s));
  61. return result;
  62. }
  63. IRNode* SymbolTable::takeOwnership(std::unique_ptr<IRNode> n) {
  64. IRNode* result = n.get();
  65. fOwnedNodes.push_back(std::move(n));
  66. return result;
  67. }
  68. void SymbolTable::add(StringFragment name, std::unique_ptr<Symbol> symbol) {
  69. this->addWithoutOwnership(name, symbol.get());
  70. this->takeOwnership(std::move(symbol));
  71. }
  72. void SymbolTable::addWithoutOwnership(StringFragment 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. std::unique_ptr<Symbol> u = std::unique_ptr<Symbol>(new UnresolvedFunction(std::move(
  83. functions)));
  84. fSymbols[name] = this->takeOwnership(std::move(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. std::unique_ptr<Symbol> u = std::unique_ptr<Symbol>(new UnresolvedFunction(std::move(
  92. functions)));
  93. fSymbols[name] = this->takeOwnership(std::move(u));
  94. }
  95. } else {
  96. fErrorReporter.error(symbol->fOffset, "symbol '" + name + "' was already defined");
  97. }
  98. }
  99. void SymbolTable::markAllFunctionsBuiltin() {
  100. for (const auto& pair : fSymbols) {
  101. switch (pair.second->fKind) {
  102. case Symbol::kFunctionDeclaration_Kind:
  103. ((FunctionDeclaration&) *pair.second).fBuiltin = true;
  104. break;
  105. case Symbol::kUnresolvedFunction_Kind:
  106. for (auto& f : ((UnresolvedFunction&) *pair.second).fFunctions) {
  107. ((FunctionDeclaration*) f)->fBuiltin = true;
  108. }
  109. break;
  110. default:
  111. break;
  112. }
  113. }
  114. }
  115. std::unordered_map<StringFragment, const Symbol*>::iterator SymbolTable::begin() {
  116. return fSymbols.begin();
  117. }
  118. std::unordered_map<StringFragment, const Symbol*>::iterator SymbolTable::end() {
  119. return fSymbols.end();
  120. }
  121. } // namespace