SkSLFunctionDeclaration.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. #ifndef SKSL_FUNCTIONDECLARATION
  8. #define SKSL_FUNCTIONDECLARATION
  9. #include "src/sksl/ir/SkSLExpression.h"
  10. #include "src/sksl/ir/SkSLModifiers.h"
  11. #include "src/sksl/ir/SkSLSymbol.h"
  12. #include "src/sksl/ir/SkSLSymbolTable.h"
  13. #include "src/sksl/ir/SkSLType.h"
  14. #include "src/sksl/ir/SkSLVariable.h"
  15. namespace SkSL {
  16. /**
  17. * A function declaration (not a definition -- does not contain a body).
  18. */
  19. struct FunctionDeclaration : public Symbol {
  20. FunctionDeclaration(int offset, Modifiers modifiers, StringFragment name,
  21. std::vector<const Variable*> parameters, const Type& returnType)
  22. : INHERITED(offset, kFunctionDeclaration_Kind, std::move(name))
  23. , fDefined(false)
  24. , fBuiltin(false)
  25. , fModifiers(modifiers)
  26. , fParameters(std::move(parameters))
  27. , fReturnType(returnType) {}
  28. String description() const override {
  29. String result = fReturnType.description() + " " + fName + "(";
  30. String separator;
  31. for (auto p : fParameters) {
  32. result += separator;
  33. separator = ", ";
  34. result += p->description();
  35. }
  36. result += ")";
  37. return result;
  38. }
  39. bool matches(const FunctionDeclaration& f) const {
  40. if (fName != f.fName) {
  41. return false;
  42. }
  43. if (fParameters.size() != f.fParameters.size()) {
  44. return false;
  45. }
  46. for (size_t i = 0; i < fParameters.size(); i++) {
  47. if (fParameters[i]->fType != f.fParameters[i]->fType) {
  48. return false;
  49. }
  50. }
  51. return true;
  52. }
  53. /**
  54. * Determine the effective types of this function's parameters and return value when called with
  55. * the given arguments. This is relevant for functions with generic parameter types, where this
  56. * will collapse the generic types down into specific concrete types.
  57. *
  58. * Returns true if it was able to select a concrete set of types for the generic function, false
  59. * if there is no possible way this can match the argument types. Note that even a true return
  60. * does not guarantee that the function can be successfully called with those arguments, merely
  61. * indicates that an attempt should be made. If false is returned, the state of
  62. * outParameterTypes and outReturnType are undefined.
  63. */
  64. bool determineFinalTypes(const std::vector<std::unique_ptr<Expression>>& arguments,
  65. std::vector<const Type*>* outParameterTypes,
  66. const Type** outReturnType) const {
  67. SkASSERT(arguments.size() == fParameters.size());
  68. int genericIndex = -1;
  69. for (size_t i = 0; i < arguments.size(); i++) {
  70. if (fParameters[i]->fType.kind() == Type::kGeneric_Kind) {
  71. std::vector<const Type*> types = fParameters[i]->fType.coercibleTypes();
  72. if (genericIndex == -1) {
  73. for (size_t j = 0; j < types.size(); j++) {
  74. if (arguments[i]->fType.canCoerceTo(*types[j])) {
  75. genericIndex = j;
  76. break;
  77. }
  78. }
  79. if (genericIndex == -1) {
  80. return false;
  81. }
  82. }
  83. outParameterTypes->push_back(types[genericIndex]);
  84. } else {
  85. outParameterTypes->push_back(&fParameters[i]->fType);
  86. }
  87. }
  88. if (fReturnType.kind() == Type::kGeneric_Kind) {
  89. SkASSERT(genericIndex != -1);
  90. *outReturnType = fReturnType.coercibleTypes()[genericIndex];
  91. } else {
  92. *outReturnType = &fReturnType;
  93. }
  94. return true;
  95. }
  96. mutable bool fDefined;
  97. bool fBuiltin;
  98. Modifiers fModifiers;
  99. const std::vector<const Variable*> fParameters;
  100. const Type& fReturnType;
  101. typedef Symbol INHERITED;
  102. };
  103. } // namespace
  104. #endif