• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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