xref: /aosp_15_r20/external/skia/src/sksl/ir/SkSLFunctionDefinition.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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