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