• 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_BLOCK
9 #define SKSL_BLOCK
10 
11 #include "include/private/SkSLDefines.h"
12 #include "include/private/SkSLIRNode.h"
13 #include "include/private/SkSLStatement.h"
14 #include "include/sksl/SkSLPosition.h"
15 
16 #include <memory>
17 #include <string>
18 #include <utility>
19 
20 namespace SkSL {
21 
22 class SymbolTable;
23 
24 /**
25  * A block of multiple statements functioning as a single statement.
26  */
27 class Block final : public Statement {
28 public:
29     inline static constexpr Kind kIRNodeKind = Kind::kBlock;
30 
31     // "kBracedScope" represents an actual language-level block. Other kinds of block are used to
32     // pass around multiple statements as if they were a single unit, with no semantic impact.
33     enum class Kind {
34         kUnbracedBlock,      // Represents a group of statements without curly braces.
35         kBracedScope,        // Represents a language-level Block, with curly braces.
36         kCompoundStatement,  // A block which conceptually represents a single statement, such as
37                              // `int a, b;`. (SkSL represents this internally as two statements:
38                              // `int a; int b;`) Allowed to optimize away to its interior Statement.
39                              // Treated as a single statement by the debugger.
40     };
41 
42     Block(Position pos, StatementArray statements,
43           Kind kind = Kind::kBracedScope, const std::shared_ptr<SymbolTable> symbols = nullptr)
INHERITED(pos,kIRNodeKind)44     : INHERITED(pos, kIRNodeKind)
45     , fChildren(std::move(statements))
46     , fBlockKind(kind)
47     , fSymbolTable(std::move(symbols)) {}
48 
49     // Make is allowed to simplify compound statements. For a single-statement unscoped Block,
50     // Make can return the Statement as-is. For an empty unscoped Block, Make can return Nop.
51     static std::unique_ptr<Statement> Make(Position pos,
52                                            StatementArray statements,
53                                            Kind kind = Kind::kBracedScope,
54                                            std::shared_ptr<SymbolTable> symbols = nullptr);
55 
56     // MakeBlock always makes a real Block object. This is important because many callers rely on
57     // Blocks specifically; e.g. a function body must be a scoped Block, nothing else will do.
58     static std::unique_ptr<Block> MakeBlock(Position pos,
59                                             StatementArray statements,
60                                             Kind kind = Kind::kBracedScope,
61                                             std::shared_ptr<SymbolTable> symbols = nullptr);
62 
children()63     const StatementArray& children() const {
64         return fChildren;
65     }
66 
children()67     StatementArray& children() {
68         return fChildren;
69     }
70 
isScope()71     bool isScope() const {
72         return fBlockKind == Kind::kBracedScope;
73     }
74 
blockKind()75     Kind blockKind() const {
76         return fBlockKind;
77     }
78 
setBlockKind(Kind kind)79     void setBlockKind(Kind kind) {
80         fBlockKind = kind;
81     }
82 
symbolTable()83     std::shared_ptr<SymbolTable> symbolTable() const {
84         return fSymbolTable;
85     }
86 
isEmpty()87     bool isEmpty() const override {
88         for (const std::unique_ptr<Statement>& stmt : this->children()) {
89             if (!stmt->isEmpty()) {
90                 return false;
91             }
92         }
93         return true;
94     }
95 
96     std::unique_ptr<Statement> clone() const override;
97 
98     std::string description() const override;
99 
100 private:
101     StatementArray fChildren;
102     Kind fBlockKind;
103     std::shared_ptr<SymbolTable> fSymbolTable;
104 
105     using INHERITED = Statement;
106 };
107 
108 }  // namespace SkSL
109 
110 #endif
111