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/SkSLProgramElement.h" 12 #include "src/sksl/ir/SkSLBlock.h" 13 #include "src/sksl/ir/SkSLFunctionDeclaration.h" 14 15 namespace SkSL { 16 17 /** 18 * A function definition (a declaration plus an associated block of code). 19 */ 20 class FunctionDefinition final : public ProgramElement { 21 public: 22 inline static constexpr Kind kProgramElementKind = Kind::kFunction; 23 24 using FunctionSet = std::unordered_set<const FunctionDeclaration*>; 25 FunctionDefinition(int line,const FunctionDeclaration * declaration,bool builtin,std::unique_ptr<Statement> body,FunctionSet referencedBuiltinFunctions)26 FunctionDefinition(int line, const FunctionDeclaration* declaration, bool builtin, 27 std::unique_ptr<Statement> body, FunctionSet referencedBuiltinFunctions) 28 : INHERITED(line, kProgramElementKind) 29 , fDeclaration(declaration) 30 , fBuiltin(builtin) 31 , fBody(std::move(body)) 32 , fReferencedBuiltinFunctions(std::move(referencedBuiltinFunctions)) {} 33 34 /** 35 * Coerces `return` statements to the return type of the function, and reports errors in the 36 * function that can't be detected at the individual statement level: 37 * - `break` and `continue` statements must be in reasonable places. 38 * - non-void functions are required to return a value on all paths. 39 * - vertex main() functions don't allow early returns. 40 * 41 * This will return a FunctionDefinition even if an error is detected; this leads to better 42 * diagnostics overall. (Returning null here leads to spurious "function 'f()' was not defined" 43 * errors when trying to call a function with an error in it.) 44 */ 45 static std::unique_ptr<FunctionDefinition> Convert(const Context& context, 46 int line, 47 const FunctionDeclaration& function, 48 std::unique_ptr<Statement> body, 49 bool builtin); 50 declaration()51 const FunctionDeclaration& declaration() const { 52 return *fDeclaration; 53 } 54 isBuiltin()55 bool isBuiltin() const { 56 return fBuiltin; 57 } 58 body()59 std::unique_ptr<Statement>& body() { 60 return fBody; 61 } 62 body()63 const std::unique_ptr<Statement>& body() const { 64 return fBody; 65 } 66 referencedBuiltinFunctions()67 const FunctionSet& referencedBuiltinFunctions() const { 68 return fReferencedBuiltinFunctions; 69 } 70 clone()71 std::unique_ptr<ProgramElement> clone() const override { 72 return std::make_unique<FunctionDefinition>(fLine, &this->declaration(), 73 /*builtin=*/false, this->body()->clone(), 74 this->referencedBuiltinFunctions()); 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 // We track the builtin functions we reference so that we can ensure that all of them end up 86 // copied into the final output. 87 FunctionSet fReferencedBuiltinFunctions; 88 89 using INHERITED = ProgramElement; 90 }; 91 92 } // namespace SkSL 93 94 #endif 95