/src/skia/src/sksl/ir/SkSLConstructorStruct.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/ir/SkSLConstructorStruct.h" |
9 | | |
10 | | namespace SkSL { |
11 | | |
12 | | std::unique_ptr<Expression> ConstructorStruct::Convert(const Context& context, |
13 | | int offset, |
14 | | const Type& type, |
15 | 751 | ExpressionArray args) { |
16 | 751 | SkASSERTF(type.isStruct() && type.fields().size() > 0, "%s", type.description().c_str()); |
17 | | |
18 | | // Check that the number of constructor arguments matches the array size. |
19 | 751 | if (type.fields().size() != args.size()) { |
20 | 152 | context.errors().error(offset, |
21 | 152 | String::printf("invalid arguments to '%s' constructor " |
22 | 152 | "(expected %zu elements, but found %zu)", |
23 | 152 | type.displayName().c_str(), type.fields().size(), |
24 | 152 | args.size())); |
25 | 152 | return nullptr; |
26 | 152 | } |
27 | | |
28 | | // Convert each constructor argument to the struct's field type. |
29 | 1.16k | for (int index=0; index<args.count(); ++index) { |
30 | 661 | std::unique_ptr<Expression>& argument = args[index]; |
31 | 661 | const Type::Field& field = type.fields()[index]; |
32 | | |
33 | 661 | argument = field.fType->coerceExpression(std::move(argument), context); |
34 | 661 | if (!argument) { |
35 | 94 | return nullptr; |
36 | 94 | } |
37 | 661 | } |
38 | | |
39 | 505 | return ConstructorStruct::Make(context, offset, type, std::move(args)); |
40 | 599 | } |
41 | | |
42 | | [[maybe_unused]] static bool arguments_match_field_types(const ExpressionArray& args, |
43 | 505 | const Type& type) { |
44 | 505 | SkASSERT(type.fields().size() == args.size()); |
45 | | |
46 | 1.04k | for (int index = 0; index < args.count(); ++index) { |
47 | 537 | const std::unique_ptr<Expression>& argument = args[index]; |
48 | 537 | const Type::Field& field = type.fields()[index]; |
49 | 537 | if (argument->type() != *field.fType) { |
50 | 0 | return false; |
51 | 0 | } |
52 | 537 | } |
53 | | |
54 | 505 | return true; |
55 | 505 | } |
56 | | |
57 | | std::unique_ptr<Expression> ConstructorStruct::Make(const Context& context, |
58 | | int offset, |
59 | | const Type& type, |
60 | 505 | ExpressionArray args) { |
61 | 505 | SkASSERT(arguments_match_field_types(args, type)); |
62 | 505 | return std::make_unique<ConstructorStruct>(offset, type, std::move(args)); |
63 | 505 | } |
64 | | |
65 | | } // namespace SkSL |