• 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 "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