Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(310)

Side by Side Diff: src/sksl/SkSLIRGenerator.cpp

Issue 2387643003: Revert of Turned on SkSL->GLSL compiler (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/sksl/SkSLIRGenerator.h ('k') | src/sksl/SkSLMain.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « src/sksl/SkSLIRGenerator.h ('k') | src/sksl/SkSLMain.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698