• 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 struct ASTNode;
18 
19 /**
20  * A function definition (a declaration plus an associated block of code).
21  */
22 class FunctionDefinition final : public ProgramElement {
23 public:
24     inline static constexpr Kind kProgramElementKind = Kind::kFunction;
25 
26     using IntrinsicSet = std::unordered_set<const FunctionDeclaration*>;
27 
FunctionDefinition(int line,const FunctionDeclaration * declaration,bool builtin,std::unique_ptr<Statement> body,IntrinsicSet referencedIntrinsics)28     FunctionDefinition(int line, const FunctionDeclaration* declaration, bool builtin,
29                        std::unique_ptr<Statement> body, IntrinsicSet referencedIntrinsics)
30         : INHERITED(line, kProgramElementKind)
31         , fDeclaration(declaration)
32         , fBuiltin(builtin)
33         , fBody(std::move(body))
34         , fReferencedIntrinsics(std::move(referencedIntrinsics))
35         , fSource(nullptr) {}
36 
37     /**
38      * Coerces `return` statements to the return type of the function, and reports errors in the
39      * function that can't be detected at the individual statement level:
40      *     - `break` and `continue` statements must be in reasonable places.
41      *     - non-void functions are required to return a value on all paths.
42      *     - vertex main() functions don't allow early returns.
43      *
44      * This will return a FunctionDefinition even if an error is detected; this leads to better
45      * diagnostics overall. (Returning null here leads to spurious "function 'f()' was not defined"
46      * errors when trying to call a function with an error in it.)
47      */
48     static std::unique_ptr<FunctionDefinition> Convert(const Context& context,
49                                                        int line,
50                                                        const FunctionDeclaration& function,
51                                                        std::unique_ptr<Statement> body,
52                                                        bool builtin);
53 
declaration()54     const FunctionDeclaration& declaration() const {
55         return *fDeclaration;
56     }
57 
isBuiltin()58     bool isBuiltin() const {
59         return fBuiltin;
60     }
61 
body()62     std::unique_ptr<Statement>& body() {
63         return fBody;
64     }
65 
body()66     const std::unique_ptr<Statement>& body() const {
67         return fBody;
68     }
69 
referencedIntrinsics()70     const std::unordered_set<const FunctionDeclaration*>& referencedIntrinsics() const {
71         return fReferencedIntrinsics;
72     }
73 
source()74     const ASTNode* source() const {
75         return fSource;
76     }
77 
setSource(const ASTNode * source)78     void setSource(const ASTNode* source) {
79         fSource = source;
80     }
81 
clone()82     std::unique_ptr<ProgramElement> clone() const override {
83         return std::make_unique<FunctionDefinition>(fLine, &this->declaration(),
84                                                     /*builtin=*/false, this->body()->clone(),
85                                                     this->referencedIntrinsics());
86     }
87 
description()88     String description() const override {
89         return this->declaration().description() + " " + this->body()->description();
90     }
91 
92 private:
93     const FunctionDeclaration* fDeclaration;
94     bool fBuiltin;
95     std::unique_ptr<Statement> fBody;
96     // We track intrinsic functions we reference so that we can ensure that all of them end up
97     // copied into the final output.
98     IntrinsicSet fReferencedIntrinsics;
99     // This pointer may be null, and even when non-null is not guaranteed to remain valid for
100     // the entire lifespan of this object. The parse tree's lifespan is normally controlled by
101     // IRGenerator, so the IRGenerator being destroyed or being used to compile another file
102     // will invalidate this pointer.
103     const ASTNode* fSource;
104 
105     using INHERITED = ProgramElement;
106 };
107 
108 }  // namespace SkSL
109 
110 #endif
111