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