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,std::unique_ptr<Statement> body)32 FunctionDefinition(Position pos, 33 const FunctionDeclaration* declaration, 34 std::unique_ptr<Statement> body) 35 : INHERITED(pos, kIRNodeKind) 36 , fDeclaration(declaration) 37 , fBody(std::move(body)) {} 38 39 /** 40 * Coerces `return` statements to the return type of the function, and reports errors in the 41 * function that can't be detected at the individual statement level: 42 * 43 * - `break` and `continue` statements must be in reasonable places. 44 * - Non-void functions are required to return a value on all paths. 45 * - Vertex main() functions don't allow early returns. 46 * - Limits on overall stack size are enforced. 47 * 48 * This will return a FunctionDefinition even if an error is detected; this leads to better 49 * diagnostics overall. (Returning null here leads to spurious "function 'f()' was not defined" 50 * errors when trying to call a function with an error in it.) 51 */ 52 static std::unique_ptr<FunctionDefinition> Convert(const Context& context, 53 Position pos, 54 const FunctionDeclaration& function, 55 std::unique_ptr<Statement> body); 56 57 static std::unique_ptr<FunctionDefinition> Make(const Context& context, 58 Position pos, 59 const FunctionDeclaration& function, 60 std::unique_ptr<Statement> body); 61 declaration()62 const FunctionDeclaration& declaration() const { 63 return *fDeclaration; 64 } 65 body()66 std::unique_ptr<Statement>& body() { 67 return fBody; 68 } 69 body()70 const std::unique_ptr<Statement>& body() const { 71 return fBody; 72 } 73 description()74 std::string description() const override { 75 return this->declaration().description() + " " + this->body()->description(); 76 } 77 78 private: 79 const FunctionDeclaration* fDeclaration; 80 std::unique_ptr<Statement> fBody; 81 82 using INHERITED = ProgramElement; 83 }; 84 85 } // namespace SkSL 86 87 #endif 88