OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkSLIRGenerator.h" | 8 #include "SkSLIRGenerator.h" |
9 | 9 |
10 #include "limits.h" | 10 #include "limits.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi
ers, varDecl.fName, | 182 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi
ers, varDecl.fName, |
183 *type, storage)); | 183 *type, storage)); |
184 std::unique_ptr<Expression> value; | 184 std::unique_ptr<Expression> value; |
185 if (varDecl.fValue) { | 185 if (varDecl.fValue) { |
186 value = this->convertExpression(*varDecl.fValue); | 186 value = this->convertExpression(*varDecl.fValue); |
187 if (!value) { | 187 if (!value) { |
188 return nullptr; | 188 return nullptr; |
189 } | 189 } |
190 value = this->coerce(std::move(value), *type); | 190 value = this->coerce(std::move(value), *type); |
191 } | 191 } |
192 if ("sk_FragColor" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) { | 192 if ("gl_FragCoord" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) { |
193 // already defined, ignore | |
194 } else if ((*fSymbolTable)[varDecl.fName] && | |
195 (*fSymbolTable)[varDecl.fName]->fKind == Symbol::kVariable_Ki
nd && | |
196 ((Variable*) (*fSymbolTable)[varDecl.fName])->fModifiers.fLay
out.fBuiltin >= 0) { | |
197 // already defined, just update the modifiers | 193 // already defined, just update the modifiers |
198 Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName]; | 194 Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName]; |
199 old->fModifiers = var->fModifiers; | 195 old->fModifiers = var->fModifiers; |
200 } else { | 196 } else { |
201 variables.emplace_back(var.get(), std::move(sizes), std::move(value)
); | 197 variables.emplace_back(var.get(), std::move(sizes), std::move(value)
); |
202 fSymbolTable->add(varDecl.fName, std::move(var)); | 198 fSymbolTable->add(varDecl.fName, std::move(var)); |
203 } | 199 } |
204 } | 200 } |
205 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition, | 201 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition, |
206 baseType, | 202 baseType, |
207 std::move(variab
les))); | 203 std::move(variab
les))); |
208 } | 204 } |
209 | 205 |
210 std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration( | |
211 const ASTModifi
ersDeclaration& m) { | |
212 Modifiers modifiers = this->convertModifiers(m.fModifiers); | |
213 return std::unique_ptr<ModifiersDeclaration>(new ModifiersDeclaration(modifi
ers)); | |
214 } | |
215 | |
216 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { | 206 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { |
217 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f
Test), | 207 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f
Test), |
218 *fContext.fBool_Type); | 208 *fContext.fBool_Type); |
219 if (!test) { | 209 if (!test) { |
220 return nullptr; | 210 return nullptr; |
221 } | 211 } |
222 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); | 212 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); |
223 if (!ifTrue) { | 213 if (!ifTrue) { |
224 return nullptr; | 214 return nullptr; |
225 } | 215 } |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 FunctionDeclaration newDecl(f.fPosition, f.fName, parame
ters, *returnType); | 412 FunctionDeclaration newDecl(f.fPosition, f.fName, parame
ters, *returnType); |
423 fErrors.error(f.fPosition, "functions '" + newDecl.descr
iption() + | 413 fErrors.error(f.fPosition, "functions '" + newDecl.descr
iption() + |
424 "' and '" + other->descriptio
n() + | 414 "' and '" + other->descriptio
n() + |
425 "' differ only in return type
"); | 415 "' differ only in return type
"); |
426 return nullptr; | 416 return nullptr; |
427 } | 417 } |
428 decl = other; | 418 decl = other; |
429 for (size_t i = 0; i < parameters.size(); i++) { | 419 for (size_t i = 0; i < parameters.size(); i++) { |
430 if (parameters[i]->fModifiers != other->fParameters[i]->
fModifiers) { | 420 if (parameters[i]->fModifiers != other->fParameters[i]->
fModifiers) { |
431 fErrors.error(f.fPosition, "modifiers on parameter "
+ | 421 fErrors.error(f.fPosition, "modifiers on parameter "
+ |
432 to_string((uint64_t) i +
1) + | 422 to_string(i + 1) + " diff
er between " + |
433 " differ between declarat
ion and " | 423 "declaration and definiti
on"); |
434 "definition"); | |
435 return nullptr; | 424 return nullptr; |
436 } | 425 } |
437 } | 426 } |
438 if (other->fDefined) { | 427 if (other->fDefined) { |
439 fErrors.error(f.fPosition, "duplicate definition of " + | 428 fErrors.error(f.fPosition, "duplicate definition of " + |
440 other->description()); | 429 other->description()); |
441 } | 430 } |
442 break; | 431 break; |
443 } | 432 } |
444 } | 433 } |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 return nullptr; | 609 return nullptr; |
621 } | 610 } |
622 if (type.kind() == Type::kScalar_Kind) { | 611 if (type.kind() == Type::kScalar_Kind) { |
623 std::vector<std::unique_ptr<Expression>> args; | 612 std::vector<std::unique_ptr<Expression>> args; |
624 args.push_back(std::move(expr)); | 613 args.push_back(std::move(expr)); |
625 ASTIdentifier id(Position(), type.description()); | 614 ASTIdentifier id(Position(), type.description()); |
626 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); | 615 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); |
627 ASSERT(ctor); | 616 ASSERT(ctor); |
628 return this->call(Position(), std::move(ctor), std::move(args)); | 617 return this->call(Position(), std::move(ctor), std::move(args)); |
629 } | 618 } |
630 std::vector<std::unique_ptr<Expression>> args; | 619 ABORT("cannot coerce %s to %s", expr->fType.description().c_str(), |
631 args.push_back(std::move(expr)); | 620 type.description().c_str()); |
632 return std::unique_ptr<Expression>(new Constructor(Position(), type, std::mo
ve(args))); | |
633 } | 621 } |
634 | 622 |
635 static bool is_matrix_multiply(const Type& left, const Type& right) { | 623 static bool is_matrix_multiply(const Type& left, const Type& right) { |
636 if (left.kind() == Type::kMatrix_Kind) { | 624 if (left.kind() == Type::kMatrix_Kind) { |
637 return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVect
or_Kind; | 625 return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVect
or_Kind; |
638 } | 626 } |
639 return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Ki
nd; | 627 return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Ki
nd; |
640 } | 628 } |
641 /** | 629 /** |
642 * Determines the operand and result types of a binary expression. Returns true
if the expression is | 630 * Determines the operand and result types of a binary expression. Returns true
if the expression is |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
837 std::move(test), | 825 std::move(test), |
838 std::move(ifTrue), | 826 std::move(ifTrue), |
839 std::move(ifFalse))
); | 827 std::move(ifFalse))
); |
840 } | 828 } |
841 | 829 |
842 std::unique_ptr<Expression> IRGenerator::call(Position position, | 830 std::unique_ptr<Expression> IRGenerator::call(Position position, |
843 const FunctionDeclaration& functio
n, | 831 const FunctionDeclaration& functio
n, |
844 std::vector<std::unique_ptr<Expres
sion>> arguments) { | 832 std::vector<std::unique_ptr<Expres
sion>> arguments) { |
845 if (function.fParameters.size() != arguments.size()) { | 833 if (function.fParameters.size() != arguments.size()) { |
846 std::string msg = "call to '" + function.fName + "' expected " + | 834 std::string msg = "call to '" + function.fName + "' expected " + |
847 to_string((uint64_t) function.fParameters.size(
)) + | 835 to_string(function.fParameters.size()) + |
848 " argument"; | 836 " argument"; |
849 if (function.fParameters.size() != 1) { | 837 if (function.fParameters.size() != 1) { |
850 msg += "s"; | 838 msg += "s"; |
851 } | 839 } |
852 msg += ", but found " + to_string((uint64_t) arguments.size()); | 840 msg += ", but found " + to_string(arguments.size()); |
853 fErrors.error(position, msg); | 841 fErrors.error(position, msg); |
854 return nullptr; | 842 return nullptr; |
855 } | 843 } |
856 for (size_t i = 0; i < arguments.size(); i++) { | 844 for (size_t i = 0; i < arguments.size(); i++) { |
857 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter
s[i]->fType); | 845 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter
s[i]->fType); |
858 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi
ers::kOut_Flag)) { | 846 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi
ers::kOut_Flag)) { |
859 this->markWrittenTo(*arguments[i]); | 847 this->markWrittenTo(*arguments[i]); |
860 } | 848 } |
861 } | 849 } |
862 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, | 850 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 } | 914 } |
927 return this->call(position, *ref->fFunctions[0], std::move(arguments)); | 915 return this->call(position, *ref->fFunctions[0], std::move(arguments)); |
928 } | 916 } |
929 | 917 |
930 std::unique_ptr<Expression> IRGenerator::convertConstructor( | 918 std::unique_ptr<Expression> IRGenerator::convertConstructor( |
931 Position position, | 919 Position position, |
932 const Type& type, | 920 const Type& type, |
933 std::vector<std::unique_ptr<
Expression>> args) { | 921 std::vector<std::unique_ptr<
Expression>> args) { |
934 // FIXME: add support for structs and arrays | 922 // FIXME: add support for structs and arrays |
935 Type::Kind kind = type.kind(); | 923 Type::Kind kind = type.kind(); |
936 if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_
Kind && | 924 if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_
Kind) { |
937 kind != Type::kArray_Kind) { | |
938 fErrors.error(position, "cannot construct '" + type.description() + "'")
; | 925 fErrors.error(position, "cannot construct '" + type.description() + "'")
; |
939 return nullptr; | 926 return nullptr; |
940 } | 927 } |
941 if (type == *fContext.fFloat_Type && args.size() == 1 && | 928 if (type == *fContext.fFloat_Type && args.size() == 1 && |
942 args[0]->fKind == Expression::kIntLiteral_Kind) { | 929 args[0]->fKind == Expression::kIntLiteral_Kind) { |
943 int64_t value = ((IntLiteral&) *args[0]).fValue; | 930 int64_t value = ((IntLiteral&) *args[0]).fValue; |
944 return std::unique_ptr<Expression>(new FloatLiteral(fContext, position,
(double) value)); | 931 return std::unique_ptr<Expression>(new FloatLiteral(fContext, position,
(double) value)); |
945 } | 932 } |
946 if (args.size() == 1 && args[0]->fType == type) { | 933 if (args.size() == 1 && args[0]->fType == type) { |
947 // argument is already the right type, just return it | 934 // argument is already the right type, just return it |
948 return std::move(args[0]); | 935 return std::move(args[0]); |
949 } | 936 } |
950 if (type.isNumber()) { | 937 if (type.isNumber()) { |
951 if (args.size() != 1) { | 938 if (args.size() != 1) { |
952 fErrors.error(position, "invalid arguments to '" + type.description(
) + | 939 fErrors.error(position, "invalid arguments to '" + type.description(
) + |
953 "' constructor, (expected exactly 1 argument
, but found " + | 940 "' constructor, (expected exactly 1 argument
, but found " + |
954 to_string((uint64_t) args.size()) + ")"); | 941 to_string(args.size()) + ")"); |
955 } | 942 } |
956 if (args[0]->fType == *fContext.fBool_Type) { | 943 if (args[0]->fType == *fContext.fBool_Type) { |
957 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position,
0)); | 944 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position,
0)); |
958 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, position, 1
)); | 945 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, position, 1
)); |
959 return std::unique_ptr<Expression>( | 946 return std::unique_ptr<Expression>( |
960 new TernaryExpression(position, std::mo
ve(args[0]), | 947 new TernaryExpression(position, std::mo
ve(args[0]), |
961 this->coerce(std:
:move(one), type), | 948 this->coerce(std:
:move(one), type), |
962 this->coerce(std:
:move(zero), | 949 this->coerce(std:
:move(zero), |
963 type
))); | 950 type
))); |
964 } else if (!args[0]->fType.isNumber()) { | 951 } else if (!args[0]->fType.isNumber()) { |
965 fErrors.error(position, "invalid argument to '" + type.description()
+ | 952 fErrors.error(position, "invalid argument to '" + type.description()
+ |
966 "' constructor (expected a number or bool, b
ut found '" + | 953 "' constructor (expected a number or bool, b
ut found '" + |
967 args[0]->fType.description() + "')"); | 954 args[0]->fType.description() + "')"); |
968 } | 955 } |
969 if (args[0]->fKind == Expression::kIntLiteral_Kind && (type == *fContext
.fInt_Type || | |
970 type == *fContext.fUInt_Type)) { | |
971 return std::unique_ptr<Expression>(new IntLiteral(fContext, | |
972 position, | |
973 ((IntLiteral&) *ar
gs[0]).fValue, | |
974 &type)); | |
975 } | |
976 } else if (kind == Type::kArray_Kind) { | |
977 const Type& base = type.componentType(); | |
978 for (size_t i = 0; i < args.size(); i++) { | |
979 args[i] = this->coerce(std::move(args[i]), base); | |
980 } | |
981 } else { | 956 } else { |
982 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind); | 957 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind); |
983 int actual = 0; | 958 int actual = 0; |
984 for (size_t i = 0; i < args.size(); i++) { | 959 for (size_t i = 0; i < args.size(); i++) { |
985 if (args[i]->fType.kind() == Type::kVector_Kind || | 960 if (args[i]->fType.kind() == Type::kVector_Kind || |
986 args[i]->fType.kind() == Type::kMatrix_Kind) { | 961 args[i]->fType.kind() == Type::kMatrix_Kind) { |
987 int columns = args[i]->fType.columns(); | 962 int columns = args[i]->fType.columns(); |
988 int rows = args[i]->fType.rows(); | 963 int rows = args[i]->fType.rows(); |
989 args[i] = this->coerce(std::move(args[i]), | 964 args[i] = this->coerce(std::move(args[i]), |
990 type.componentType().toCompound(fContext,
columns, rows)); | 965 type.componentType().toCompound(fContext,
columns, rows)); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1055 break; | 1030 break; |
1056 case Token::MINUSMINUS: | 1031 case Token::MINUSMINUS: |
1057 if (!base->fType.isNumber()) { | 1032 if (!base->fType.isNumber()) { |
1058 fErrors.error(expression.fPosition, | 1033 fErrors.error(expression.fPosition, |
1059 "'" + Token::OperatorName(expression.fOperator) + | 1034 "'" + Token::OperatorName(expression.fOperator) + |
1060 "' cannot operate on '" + base->fType.description(
) + "'"); | 1035 "' cannot operate on '" + base->fType.description(
) + "'"); |
1061 return nullptr; | 1036 return nullptr; |
1062 } | 1037 } |
1063 this->markWrittenTo(*base); | 1038 this->markWrittenTo(*base); |
1064 break; | 1039 break; |
1065 case Token::LOGICALNOT: | 1040 case Token::NOT: |
1066 if (base->fType != *fContext.fBool_Type) { | 1041 if (base->fType != *fContext.fBool_Type) { |
1067 fErrors.error(expression.fPosition, | 1042 fErrors.error(expression.fPosition, |
1068 "'" + Token::OperatorName(expression.fOperator) + | 1043 "'" + Token::OperatorName(expression.fOperator) + |
1069 "' cannot operate on '" + base->fType.description(
) + "'"); | 1044 "' cannot operate on '" + base->fType.description(
) + "'"); |
1070 return nullptr; | 1045 return nullptr; |
1071 } | 1046 } |
1072 break; | 1047 break; |
1073 case Token::BITWISENOT: | |
1074 if (base->fType != *fContext.fInt_Type) { | |
1075 fErrors.error(expression.fPosition, | |
1076 "'" + Token::OperatorName(expression.fOperator) + | |
1077 "' cannot operate on '" + base->fType.description(
) + "'"); | |
1078 return nullptr; | |
1079 } | |
1080 break; | |
1081 default: | 1048 default: |
1082 ABORT("unsupported prefix operator\n"); | 1049 ABORT("unsupported prefix operator\n"); |
1083 } | 1050 } |
1084 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator
, | 1051 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator
, |
1085 std::move(base))); | 1052 std::move(base))); |
1086 } | 1053 } |
1087 | 1054 |
1088 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
> base, | 1055 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
> base, |
1089 const ASTExpression& index
) { | 1056 const ASTExpression& index
) { |
1090 if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::k
Matrix_Kind && | 1057 if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::k
Matrix_Kind) { |
1091 base->fType.kind() != Type::kVector_Kind) { | |
1092 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy
pe.description() + | 1058 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy
pe.description() + |
1093 "'"); | 1059 "'"); |
1094 return nullptr; | 1060 return nullptr; |
1095 } | 1061 } |
1096 std::unique_ptr<Expression> converted = this->convertExpression(index); | 1062 std::unique_ptr<Expression> converted = this->convertExpression(index); |
1097 if (!converted) { | 1063 if (!converted) { |
1098 return nullptr; | 1064 return nullptr; |
1099 } | 1065 } |
1100 if (converted->fType != *fContext.fUInt_Type) { | 1066 converted = this->coerce(std::move(converted), *fContext.fInt_Type); |
1101 converted = this->coerce(std::move(converted), *fContext.fInt_Type); | 1067 if (!converted) { |
1102 if (!converted) { | 1068 return nullptr; |
1103 return nullptr; | |
1104 } | |
1105 } | 1069 } |
1106 return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(b
ase), | 1070 return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(b
ase), |
1107 std::move(converted))
); | 1071 std::move(converted))
); |
1108 } | 1072 } |
1109 | 1073 |
1110 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression
> base, | 1074 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression
> base, |
1111 const std::string& field)
{ | 1075 const std::string& field)
{ |
1112 auto fields = base->fType.fields(); | 1076 auto fields = base->fType.fields(); |
1113 for (size_t i = 0; i < fields.size(); i++) { | 1077 for (size_t i = 0; i < fields.size(); i++) { |
1114 if (fields[i].fName == field) { | 1078 if (fields[i].fName == field) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1172 return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base), sw
izzleComponents)); | 1136 return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base), sw
izzleComponents)); |
1173 } | 1137 } |
1174 | 1138 |
1175 std::unique_ptr<Expression> IRGenerator::convertSuffixExpression( | 1139 std::unique_ptr<Expression> IRGenerator::convertSuffixExpression( |
1176 const ASTSuffixExpre
ssion& expression) { | 1140 const ASTSuffixExpre
ssion& expression) { |
1177 std::unique_ptr<Expression> base = this->convertExpression(*expression.fBase
); | 1141 std::unique_ptr<Expression> base = this->convertExpression(*expression.fBase
); |
1178 if (!base) { | 1142 if (!base) { |
1179 return nullptr; | 1143 return nullptr; |
1180 } | 1144 } |
1181 switch (expression.fSuffix->fKind) { | 1145 switch (expression.fSuffix->fKind) { |
1182 case ASTSuffix::kIndex_Kind: { | 1146 case ASTSuffix::kIndex_Kind: |
1183 const ASTExpression* expr = ((ASTIndexSuffix&) *expression.fSuffix).
fExpression.get(); | 1147 return this->convertIndex(std::move(base), |
1184 if (expr) { | 1148 *((ASTIndexSuffix&) *expression.fSuffix).f
Expression); |
1185 return this->convertIndex(std::move(base), *expr); | |
1186 } else if (base->fKind == Expression::kTypeReference_Kind) { | |
1187 const Type& oldType = ((TypeReference&) *base).fValue; | |
1188 Type* newType = new Type(oldType.name() + "[]", Type::kArray_Kin
d, oldType, | |
1189 -1); | |
1190 fSymbolTable->takeOwnership(newType); | |
1191 return std::unique_ptr<Expression>(new TypeReference(fContext, b
ase->fPosition, | |
1192 *newType)); | |
1193 } else { | |
1194 fErrors.error(expression.fPosition, "'[]' must follow a type nam
e"); | |
1195 } | |
1196 } | |
1197 case ASTSuffix::kCall_Kind: { | 1149 case ASTSuffix::kCall_Kind: { |
1198 auto rawArguments = &((ASTCallSuffix&) *expression.fSuffix).fArgumen
ts; | 1150 auto rawArguments = &((ASTCallSuffix&) *expression.fSuffix).fArgumen
ts; |
1199 std::vector<std::unique_ptr<Expression>> arguments; | 1151 std::vector<std::unique_ptr<Expression>> arguments; |
1200 for (size_t i = 0; i < rawArguments->size(); i++) { | 1152 for (size_t i = 0; i < rawArguments->size(); i++) { |
1201 std::unique_ptr<Expression> converted = | 1153 std::unique_ptr<Expression> converted = |
1202 this->convertExpression(*(*rawArguments)[i]); | 1154 this->convertExpression(*(*rawArguments)[i]); |
1203 if (!converted) { | 1155 if (!converted) { |
1204 return nullptr; | 1156 return nullptr; |
1205 } | 1157 } |
1206 arguments.push_back(std::move(converted)); | 1158 arguments.push_back(std::move(converted)); |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1299 case Expression::kIndex_Kind: | 1251 case Expression::kIndex_Kind: |
1300 this->markWrittenTo(*((IndexExpression&) expr).fBase); | 1252 this->markWrittenTo(*((IndexExpression&) expr).fBase); |
1301 break; | 1253 break; |
1302 default: | 1254 default: |
1303 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); | 1255 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); |
1304 break; | 1256 break; |
1305 } | 1257 } |
1306 } | 1258 } |
1307 | 1259 |
1308 } | 1260 } |
OLD | NEW |