/src/skia/src/sksl/ir/SkSLVarDeclarations.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2021 Google LLC |
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 | | #include "src/sksl/SkSLAnalysis.h" |
9 | | #include "src/sksl/SkSLContext.h" |
10 | | #include "src/sksl/SkSLProgramSettings.h" |
11 | | #include "src/sksl/ir/SkSLVarDeclarations.h" |
12 | | |
13 | | namespace SkSL { |
14 | | |
15 | 0 | std::unique_ptr<Statement> VarDeclaration::clone() const { |
16 | 0 | return std::make_unique<VarDeclaration>(&this->var(), |
17 | 0 | &this->baseType(), |
18 | 0 | fArraySize, |
19 | 0 | this->value() ? this->value()->clone() : nullptr); |
20 | 0 | } |
21 | | |
22 | 0 | String VarDeclaration::description() const { |
23 | 0 | String result = this->var().modifiers().description() + this->baseType().description() + " " + |
24 | 0 | this->var().name(); |
25 | 0 | if (this->arraySize() > 0) { |
26 | 0 | result.appendf("[%d]", this->arraySize()); |
27 | 0 | } else if (this->arraySize() == Type::kUnsizedArray) { |
28 | 0 | result += "[]"; |
29 | 0 | } |
30 | 0 | if (this->value()) { |
31 | 0 | result += " = " + this->value()->description(); |
32 | 0 | } |
33 | 0 | result += ";"; |
34 | 0 | return result; |
35 | 0 | } |
36 | | |
37 | | std::unique_ptr<Statement> VarDeclaration::Convert(const Context& context, |
38 | | Variable* var, |
39 | 542k | std::unique_ptr<Expression> value) { |
40 | 542k | if (var->modifiers().fFlags & Modifiers::kConst_Flag) { |
41 | 3.47k | if (!value) { |
42 | 1.64k | context.errors().error(var->fOffset, "'const' variables must be initialized"); |
43 | 1.64k | return nullptr; |
44 | 1.64k | } |
45 | 1.82k | if (!Analysis::IsConstantExpression(*value)) { |
46 | 714 | context.errors().error(value->fOffset, |
47 | 714 | "'const' variable initializer must be a constant expression"); |
48 | 714 | return nullptr; |
49 | 714 | } |
50 | 540k | } |
51 | 540k | if (value) { |
52 | 82.2k | if (var->storage() == Variable::Storage::kGlobal && |
53 | 51.9k | !Analysis::IsConstantExpression(*value)) { |
54 | 29.8k | context.errors().error(value->fOffset, |
55 | 29.8k | "global variable initializer must be a constant expression"); |
56 | 29.8k | return nullptr; |
57 | 29.8k | } |
58 | 52.4k | if (var->type().isOpaque()) { |
59 | 1.60k | context.errors().error( |
60 | 1.60k | value->fOffset, |
61 | 1.60k | "opaque type '" + var->type().name() + "' cannot use initializer expressions"); |
62 | 1.60k | return nullptr; |
63 | 1.60k | } |
64 | 50.8k | if (var->modifiers().fFlags & Modifiers::kIn_Flag) { |
65 | 430 | context.errors().error(value->fOffset, |
66 | 430 | "'in' variables cannot use initializer expressions"); |
67 | 430 | return nullptr; |
68 | 430 | } |
69 | 50.3k | if (var->modifiers().fFlags & Modifiers::kUniform_Flag) { |
70 | 149 | context.errors().error(value->fOffset, |
71 | 149 | "'uniform' variables cannot use initializer expressions"); |
72 | 149 | return nullptr; |
73 | 149 | } |
74 | 50.2k | value = var->type().coerceExpression(std::move(value), context); |
75 | 50.2k | if (!value) { |
76 | 13.5k | return nullptr; |
77 | 13.5k | } |
78 | 494k | } |
79 | 494k | const Type* baseType = &var->type(); |
80 | 494k | int arraySize = 0; |
81 | 494k | if (baseType->isArray()) { |
82 | 22.1k | arraySize = baseType->columns(); |
83 | 22.1k | baseType = &baseType->componentType(); |
84 | 22.1k | } |
85 | 494k | return VarDeclaration::Make(context, var, baseType, arraySize, std::move(value)); |
86 | 494k | } |
87 | | |
88 | | std::unique_ptr<Statement> VarDeclaration::Make(const Context& context, |
89 | | Variable* var, |
90 | | const Type* baseType, |
91 | | int arraySize, |
92 | 1.70M | std::unique_ptr<Expression> value) { |
93 | 1.70M | SkASSERT(!baseType->isArray()); |
94 | | // 'const' variables must be initialized |
95 | 1.70M | SkASSERT(!(var->modifiers().fFlags & Modifiers::kConst_Flag) || value); |
96 | | // 'const' variable initializer must be a constant expression |
97 | 1.70M | SkASSERT(!(var->modifiers().fFlags & Modifiers::kConst_Flag) || |
98 | 1.70M | Analysis::IsConstantExpression(*value)); |
99 | | // global variable initializer must be a constant expression |
100 | 1.70M | SkASSERT(!(value && var->storage() == Variable::Storage::kGlobal && |
101 | 1.70M | !Analysis::IsConstantExpression(*value))); |
102 | | // opaque type cannot use initializer expressions |
103 | 1.70M | SkASSERT(!(value && var->type().isOpaque())); |
104 | | // 'in' variables cannot use initializer expressions |
105 | 1.70M | SkASSERT(!(value && (var->modifiers().fFlags & Modifiers::kIn_Flag))); |
106 | | // 'uniform' variables cannot use initializer expressions |
107 | 1.70M | SkASSERT(!(value && (var->modifiers().fFlags & Modifiers::kUniform_Flag))); |
108 | | |
109 | | // Detect and report out-of-range initial-values for this variable. |
110 | 1.70M | if (value) { |
111 | 932k | var->type().checkForOutOfRangeLiteral(context, *value); |
112 | 932k | } |
113 | | |
114 | 1.70M | auto result = std::make_unique<VarDeclaration>(var, baseType, arraySize, std::move(value)); |
115 | 1.70M | var->setDeclaration(result.get()); |
116 | 1.70M | return std::move(result); |
117 | 1.70M | } SkSL::VarDeclaration::Make(SkSL::Context const&, SkSL::Variable*, SkSL::Type const*, int, std::__1::unique_ptr<SkSL::Expression, std::__1::default_delete<SkSL::Expression> >) Line | Count | Source | 92 | 305 | std::unique_ptr<Expression> value) { | 93 | 305 | SkASSERT(!baseType->isArray()); | 94 | | // 'const' variables must be initialized | 95 | 305 | SkASSERT(!(var->modifiers().fFlags & Modifiers::kConst_Flag) || value); | 96 | | // 'const' variable initializer must be a constant expression | 97 | 305 | SkASSERT(!(var->modifiers().fFlags & Modifiers::kConst_Flag) || | 98 | 305 | Analysis::IsConstantExpression(*value)); | 99 | | // global variable initializer must be a constant expression | 100 | 305 | SkASSERT(!(value && var->storage() == Variable::Storage::kGlobal && | 101 | 305 | !Analysis::IsConstantExpression(*value))); | 102 | | // opaque type cannot use initializer expressions | 103 | 305 | SkASSERT(!(value && var->type().isOpaque())); | 104 | | // 'in' variables cannot use initializer expressions | 105 | 305 | SkASSERT(!(value && (var->modifiers().fFlags & Modifiers::kIn_Flag))); | 106 | | // 'uniform' variables cannot use initializer expressions | 107 | 305 | SkASSERT(!(value && (var->modifiers().fFlags & Modifiers::kUniform_Flag))); | 108 | | | 109 | | // Detect and report out-of-range initial-values for this variable. | 110 | 305 | if (value) { | 111 | 117 | var->type().checkForOutOfRangeLiteral(context, *value); | 112 | 117 | } | 113 | | | 114 | 305 | auto result = std::make_unique<VarDeclaration>(var, baseType, arraySize, std::move(value)); | 115 | 305 | var->setDeclaration(result.get()); | 116 | 305 | return std::move(result); | 117 | 305 | } |
SkSL::VarDeclaration::Make(SkSL::Context const&, SkSL::Variable*, SkSL::Type const*, int, std::__1::unique_ptr<SkSL::Expression, std::__1::default_delete<SkSL::Expression> >) Line | Count | Source | 92 | 1.70M | std::unique_ptr<Expression> value) { | 93 | 1.70M | SkASSERT(!baseType->isArray()); | 94 | | // 'const' variables must be initialized | 95 | 1.70M | SkASSERT(!(var->modifiers().fFlags & Modifiers::kConst_Flag) || value); | 96 | | // 'const' variable initializer must be a constant expression | 97 | 1.70M | SkASSERT(!(var->modifiers().fFlags & Modifiers::kConst_Flag) || | 98 | 1.70M | Analysis::IsConstantExpression(*value)); | 99 | | // global variable initializer must be a constant expression | 100 | 1.70M | SkASSERT(!(value && var->storage() == Variable::Storage::kGlobal && | 101 | 1.70M | !Analysis::IsConstantExpression(*value))); | 102 | | // opaque type cannot use initializer expressions | 103 | 1.70M | SkASSERT(!(value && var->type().isOpaque())); | 104 | | // 'in' variables cannot use initializer expressions | 105 | 1.70M | SkASSERT(!(value && (var->modifiers().fFlags & Modifiers::kIn_Flag))); | 106 | | // 'uniform' variables cannot use initializer expressions | 107 | 1.70M | SkASSERT(!(value && (var->modifiers().fFlags & Modifiers::kUniform_Flag))); | 108 | | | 109 | | // Detect and report out-of-range initial-values for this variable. | 110 | 1.70M | if (value) { | 111 | 932k | var->type().checkForOutOfRangeLiteral(context, *value); | 112 | 932k | } | 113 | | | 114 | 1.70M | auto result = std::make_unique<VarDeclaration>(var, baseType, arraySize, std::move(value)); | 115 | 1.70M | var->setDeclaration(result.get()); | 116 | 1.70M | return std::move(result); | 117 | 1.70M | } |
|
118 | | |
119 | | } // namespace SkSL |