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 "include/private/SkSLIRNode.h" 12 #include "include/private/SkSLProgramElement.h" 13 #include "include/private/SkSLStatement.h" 14 #include "include/sksl/SkSLPosition.h" 15 #include "src/sksl/ir/SkSLFunctionDeclaration.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, const FunctionDeclaration* declaration, bool builtin, 33 std::unique_ptr<Statement> body) 34 : INHERITED(pos, kIRNodeKind) 35 , fDeclaration(declaration) 36 , fBuiltin(builtin) 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 * - `break` and `continue` statements must be in reasonable places. 43 * - non-void functions are required to return a value on all paths. 44 * - vertex main() functions don't allow early returns. 45 * 46 * This will return a FunctionDefinition even if an error is detected; this leads to better 47 * diagnostics overall. (Returning null here leads to spurious "function 'f()' was not defined" 48 * errors when trying to call a function with an error in it.) 49 */ 50 static std::unique_ptr<FunctionDefinition> Convert(const Context& context, 51 Position pos, 52 const FunctionDeclaration& function, 53 std::unique_ptr<Statement> body, 54 bool builtin); 55 declaration()56 const FunctionDeclaration& declaration() const { 57 return *fDeclaration; 58 } 59 isBuiltin()60 bool isBuiltin() const { 61 return fBuiltin; 62 } 63 body()64 std::unique_ptr<Statement>& body() { 65 return fBody; 66 } 67 body()68 const std::unique_ptr<Statement>& body() const { 69 return fBody; 70 } 71 clone()72 std::unique_ptr<ProgramElement> clone() const override { 73 return std::make_unique<FunctionDefinition>(fPosition, &this->declaration(), 74 /*builtin=*/false, this->body()->clone()); 75 } 76 description()77 std::string description() const override { 78 return this->declaration().description() + " " + this->body()->description(); 79 } 80 81 private: 82 const FunctionDeclaration* fDeclaration; 83 bool fBuiltin; 84 std::unique_ptr<Statement> fBody; 85 86 using INHERITED = ProgramElement; 87 }; 88 89 } // namespace SkSL 90 91 #endif 92