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 #ifndef SKSL_FUNCTIONDEFINITION 9 #define SKSL_FUNCTIONDEFINITION 10 11 #include "src/sksl/SkSLPosition.h" 12 #include "src/sksl/ir/SkSLFunctionDeclaration.h" 13 #include "src/sksl/ir/SkSLIRNode.h" 14 #include "src/sksl/ir/SkSLProgramElement.h" 15 #include "src/sksl/ir/SkSLStatement.h" 16 17 #include <memory> 18 #include <string> 19 #include <utility> 20 21 namespace SkSL { 22 23 class Context; 24 25 /** 26 * A function definition (a declaration plus an associated block of code). 27 */ 28 class FunctionDefinition final : public ProgramElement { 29 public: 30 inline static constexpr Kind kIRNodeKind = Kind::kFunction; 31 FunctionDefinition(Position pos,const FunctionDeclaration * declaration,bool builtin,std::unique_ptr<Statement> body)32 FunctionDefinition(Position pos, 33 const FunctionDeclaration* declaration, 34 bool builtin, 35 std::unique_ptr<Statement> body) 36 : INHERITED(pos, kIRNodeKind) 37 , fDeclaration(declaration) 38 , fBuiltin(builtin) 39 , fBody(std::move(body)) {} 40 41 /** 42 * Coerces `return` statements to the return type of the function, and reports errors in the 43 * function that can't be detected at the individual statement level: 44 * 45 * - `break` and `continue` statements must be in reasonable places. 46 * - Non-void functions are required to return a value on all paths. 47 * - Vertex main() functions don't allow early returns. 48 * - Limits on overall stack size are enforced. 49 * 50 * This will return a FunctionDefinition even if an error is detected; this leads to better 51 * diagnostics overall. (Returning null here leads to spurious "function 'f()' was not defined" 52 * errors when trying to call a function with an error in it.) 53 */ 54 static std::unique_ptr<FunctionDefinition> Convert(const Context& context, 55 Position pos, 56 const FunctionDeclaration& function, 57 std::unique_ptr<Statement> body, 58 bool builtin); 59 60 static std::unique_ptr<FunctionDefinition> Make(const Context& context, 61 Position pos, 62 const FunctionDeclaration& function, 63 std::unique_ptr<Statement> body, 64 bool builtin); 65 declaration()66 const FunctionDeclaration& declaration() const { 67 return *fDeclaration; 68 } 69 isBuiltin()70 bool isBuiltin() const { 71 return fBuiltin; 72 } 73 body()74 std::unique_ptr<Statement>& body() { 75 return fBody; 76 } 77 body()78 const std::unique_ptr<Statement>& body() const { 79 return fBody; 80 } 81 description()82 std::string description() const override { 83 return this->declaration().description() + " " + this->body()->description(); 84 } 85 86 private: 87 const FunctionDeclaration* fDeclaration; 88 bool fBuiltin; 89 std::unique_ptr<Statement> fBody; 90 91 using INHERITED = ProgramElement; 92 }; 93 94 } // namespace SkSL 95 96 #endif 97