diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp index ad35d4124f..0f9220bd4d 100644 --- a/src/core/SkRuntimeEffect.cpp +++ b/src/core/SkRuntimeEffect.cpp @@ -115,8 +115,7 @@ SkRuntimeEffect::EffectResult SkRuntimeEffect::Make(SkString sksl) { SET_TYPES(Variable::Type::kFloat4x4, kHalf4x4_GrSLType); } else { RETURN_FAILURE("Invalid input/uniform type: '%s'", - type->description().c_str()); - + type->displayName().c_str()); } #undef SET_TYPES diff --git a/src/sksl/SkSLASTNode.cpp b/src/sksl/SkSLASTNode.cpp index 34e59ebb32..7c5a2033a0 100644 --- a/src/sksl/SkSLASTNode.cpp +++ b/src/sksl/SkSLASTNode.cpp @@ -11,6 +11,7 @@ namespace SkSL { +#ifdef SK_DEBUG String ASTNode::description() const { switch (fKind) { case Kind::kNull: return ""; @@ -234,5 +235,6 @@ String ASTNode::description() const { return ""; } } +#endif } // namespace diff --git a/src/sksl/SkSLASTNode.h b/src/sksl/SkSLASTNode.h index 59005a1adc..72cfcdafda 100644 --- a/src/sksl/SkSLASTNode.h +++ b/src/sksl/SkSLASTNode.h @@ -613,7 +613,9 @@ struct ASTNode { return iterator(fNodes, ID(-1)); } +#ifdef SK_DEBUG String description() const; +#endif std::vector* fNodes; diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp index e7c214bcfd..961569d7cc 100644 --- a/src/sksl/SkSLByteCodeGenerator.cpp +++ b/src/sksl/SkSLByteCodeGenerator.cpp @@ -27,7 +27,7 @@ static TypeCategory type_category(const Type& type) { SkASSERT(type.fName == "float" || type.fName == "half"); return TypeCategory::kFloat; } - ABORT("unsupported type: %s\n", type.description().c_str()); + ABORT("unsupported type: %s\n", type.displayName().c_str()); } } @@ -1303,7 +1303,9 @@ void ByteCodeGenerator::writeExpression(const Expression& e, bool discard) { this->writeTernaryExpression((TernaryExpression&) e); break; default: +#ifdef SK_DEBUG printf("unsupported expression %s\n", e.description().c_str()); +#endif SkASSERT(false); } if (discard) { @@ -1455,7 +1457,9 @@ std::unique_ptr ByteCodeGenerator::getLValue(const Ex } case Expression::kTernary_Kind: default: - printf("unsupported lvalue %s\n", e.description().c_str()); +#ifdef SK_DEBUG + ABORT("unsupported lvalue %s\n", e.description().c_str()); +#endif return nullptr; } } diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp index 8ef2dd59e8..1160631077 100644 --- a/src/sksl/SkSLCFGGenerator.cpp +++ b/src/sksl/SkSLCFGGenerator.cpp @@ -51,6 +51,7 @@ void CFG::addExit(BlockId from, BlockId to) { } } +#ifdef SK_DEBUG void CFG::dump() { for (size_t i = 0; i < fBlocks.size(); i++) { printf("Block %d\n-------\nBefore: ", (int) i); @@ -82,6 +83,7 @@ void CFG::dump() { printf("\n\n"); } } +#endif bool BasicBlock::tryRemoveExpressionBefore(std::vector::iterator* iter, Expression* e) { @@ -149,7 +151,10 @@ bool BasicBlock::tryRemoveLValueBefore(std::vector::iterator* } return this->tryRemoveLValueBefore(iter, ((TernaryExpression*) lvalue)->fIfFalse.get()); default: +#ifdef SK_DEBUG ABORT("invalid lvalue: %s\n", lvalue->description().c_str()); +#endif + return false; } } @@ -247,7 +252,10 @@ bool BasicBlock::tryRemoveExpression(std::vector::iterator* it *iter = fNodes.erase(*iter); return true; default: +#ifdef SK_DEBUG ABORT("unhandled expression: %s\n", expr->description().c_str()); +#endif + return false; } } @@ -655,8 +663,10 @@ void CFGGenerator::addStatement(CFG& cfg, std::unique_ptr* s) { case Statement::kNop_Kind: break; default: - printf("statement: %s\n", (*s)->description().c_str()); - ABORT("unsupported statement kind"); +#ifdef SK_DEBUG + ABORT("unsupported statement: %s\n", (*s)->description().c_str()); +#endif + break; } } diff --git a/src/sksl/SkSLCFGGenerator.h b/src/sksl/SkSLCFGGenerator.h index 7bcb89e360..895f3e0092 100644 --- a/src/sksl/SkSLCFGGenerator.h +++ b/src/sksl/SkSLCFGGenerator.h @@ -53,6 +53,7 @@ struct BasicBlock { *fStatement = std::move(stmt); } +#ifdef SK_DEBUG String description() const { if (fKind == kStatement_Kind) { return (*fStatement)->description(); @@ -61,6 +62,7 @@ struct BasicBlock { return (*fExpression)->description(); } } +#endif Kind fKind; // if false, this node should not be subject to constant propagation. This happens with diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index 96918bdb0e..d4c0e2e221 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -526,7 +526,8 @@ static bool is_dead(const Expression& lvalue) { return is_dead(*((FieldAccess&) lvalue).fBase); case Expression::kIndex_Kind: { const IndexExpression& idx = (IndexExpression&) lvalue; - return is_dead(*idx.fBase) && !idx.fIndex->hasSideEffects(); + return is_dead(*idx.fBase) && + !idx.fIndex->hasProperty(Expression::Property::kSideEffects); } case Expression::kTernary_Kind: { const TernaryExpression& t = (TernaryExpression&) lvalue; @@ -535,7 +536,10 @@ static bool is_dead(const Expression& lvalue) { case Expression::kExternalValue_Kind: return false; default: +#ifdef SK_DEBUG ABORT("invalid lvalue: %s\n", lvalue.description().c_str()); +#endif + return false; } } diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h index acfafc587d..c9603189de 100644 --- a/src/sksl/SkSLContext.h +++ b/src/sksl/SkSLContext.h @@ -392,13 +392,15 @@ private: Defined(const Type& type) : INHERITED(-1, kDefined_Kind, type) {} - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { return false; } +#ifdef SK_DEBUG String description() const override { return ""; } +#endif std::unique_ptr clone() const override { return std::unique_ptr(new Defined(fType)); diff --git a/src/sksl/SkSLExternalValue.h b/src/sksl/SkSLExternalValue.h index d8aba5de49..2909fe8caa 100644 --- a/src/sksl/SkSLExternalValue.h +++ b/src/sksl/SkSLExternalValue.h @@ -101,9 +101,11 @@ public: return nullptr; } +#ifdef SK_DEBUG String description() const override { return String("external<") + fName + ">"; } +#endif private: typedef Symbol INHERITED; diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index c555b8a33d..49050e21c6 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -235,7 +235,10 @@ void GLSLCodeGenerator::writeExpression(const Expression& expr, Precedence paren this->writeIndexExpression((IndexExpression&) expr); break; default: +#ifdef SK_DEBUG ABORT("unsupported expression: %s", expr.description().c_str()); +#endif + break; } } @@ -1099,7 +1102,7 @@ void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Compiler::IsAssignment(b.fOperator) && Expression::kFieldAccess_Kind == b.fLeft->fKind && is_sk_position((FieldAccess&) *b.fLeft) && - !strstr(b.fRight->description().c_str(), "sk_RTAdjust") && + !b.fRight->containsRTAdjust() && !fProgram.fSettings.fCaps->canUseFragCoord(); if (positionWorkaround) { this->write("sk_FragCoord_Workaround = ("); @@ -1500,7 +1503,10 @@ void GLSLCodeGenerator::writeStatement(const Statement& s) { this->write(";"); break; default: +#ifdef SK_DEBUG ABORT("unsupported statement: %s", s.description().c_str()); +#endif + break; } } @@ -1707,8 +1713,10 @@ void GLSLCodeGenerator::writeProgramElement(const ProgramElement& e) { case ProgramElement::kEnum_Kind: break; default: - printf("%s\n", e.description().c_str()); - ABORT("unsupported program element"); +#ifdef SK_DEBUG + printf("unsupported program element %s\n", e.description().c_str()); +#endif + SkASSERT(false); } } diff --git a/src/sksl/SkSLHCodeGenerator.cpp b/src/sksl/SkSLHCodeGenerator.cpp index 0790a1eff8..745130b2c7 100644 --- a/src/sksl/SkSLHCodeGenerator.cpp +++ b/src/sksl/SkSLHCodeGenerator.cpp @@ -356,7 +356,7 @@ bool HCodeGenerator::generateCode() { fFullName.c_str()); for (const auto& p : fProgram) { if (ProgramElement::kEnum_Kind == p.fKind && !((Enum&) p).fBuiltin) { - this->writef("%s\n", p.description().c_str()); + this->writef("%s\n", ((Enum&) p).code().c_str()); } } this->writeSection(CLASS_SECTION); diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp index bd608a4c0b..44b420070d 100644 --- a/src/sksl/SkSLIRGenerator.cpp +++ b/src/sksl/SkSLIRGenerator.cpp @@ -611,7 +611,7 @@ std::unique_ptr IRGenerator::convertReturn(const ASTNode& r) { } else { if (fCurrentFunction->fReturnType != *fContext.fVoid_Type) { fErrors.error(r.fOffset, "expected function to return '" + - fCurrentFunction->fReturnType.description() + "'"); + fCurrentFunction->fReturnType.displayName() + "'"); } return std::unique_ptr(new ReturnStatement(r.fOffset)); } @@ -836,8 +836,8 @@ void IRGenerator::convertFunction(const ASTNode& f) { if (*returnType != other->fReturnType) { FunctionDeclaration newDecl(f.fOffset, fd.fModifiers, fd.fName, parameters, *returnType); - fErrors.error(f.fOffset, "functions '" + newDecl.description() + - "' and '" + other->description() + + fErrors.error(f.fOffset, "functions '" + newDecl.declaration() + + "' and '" + other->declaration() + "' differ only in return type"); return; } @@ -853,7 +853,7 @@ void IRGenerator::convertFunction(const ASTNode& f) { } if (other->fDefined && !other->fBuiltin) { fErrors.error(f.fOffset, "duplicate definition of " + - other->description()); + other->declaration()); } break; } @@ -1151,7 +1151,10 @@ std::unique_ptr IRGenerator::convertExpression(const ASTNode& expr) case ASTNode::Kind::kTernary: return this->convertTernaryExpression(expr); default: +#ifdef SK_DEBUG ABORT("unsupported expression: %s\n", expr.description().c_str()); +#endif + return nullptr; } } @@ -1269,8 +1272,8 @@ std::unique_ptr IRGenerator::coerce(std::unique_ptr expr return nullptr; } if (expr->coercionCost(type) == INT_MAX) { - fErrors.error(expr->fOffset, "expected '" + type.description() + "', but found '" + - expr->fType.description() + "'"); + fErrors.error(expr->fOffset, "expected '" + type.displayName() + "', but found '" + + expr->fType.displayName() + "'"); return nullptr; } if (type.kind() == Type::kScalar_Kind) { @@ -1697,8 +1700,8 @@ std::unique_ptr IRGenerator::convertBinaryExpression(const ASTNode& &resultType, !Compiler::IsAssignment(op))) { fErrors.error(expression.fOffset, String("type mismatch: '") + Compiler::OperatorName(expression.getToken().fKind) + - "' cannot operate on '" + left->fType.description() + - "', '" + right->fType.description() + "'"); + "' cannot operate on '" + left->fType.displayName() + + "', '" + right->fType.displayName() + "'"); return nullptr; } if (Compiler::IsAssignment(op)) { @@ -1743,8 +1746,8 @@ std::unique_ptr IRGenerator::convertTernaryExpression(const ASTNode& if (!determine_binary_type(fContext, Token::EQEQ, ifTrue->fType, ifFalse->fType, &trueType, &falseType, &resultType, true) || trueType != falseType) { fErrors.error(node.fOffset, "ternary operator result mismatch: '" + - ifTrue->fType.description() + "', '" + - ifFalse->fType.description() + "'"); + ifTrue->fType.displayName() + "', '" + + ifFalse->fType.displayName() + "'"); return nullptr; } ifTrue = this->coerce(std::move(ifTrue), *trueType); @@ -1801,7 +1804,7 @@ std::unique_ptr IRGenerator::call(int offset, for (size_t i = 0; i < arguments.size(); i++) { msg += separator; separator = ", "; - msg += arguments[i]->fType.description(); + msg += arguments[i]->fType.displayName(); } msg += ")"; fErrors.error(offset, msg); @@ -1903,7 +1906,7 @@ std::unique_ptr IRGenerator::call(int offset, for (size_t i = 0; i < arguments.size(); i++) { msg += separator; separator = ", "; - msg += arguments[i]->fType.description(); + msg += arguments[i]->fType.displayName(); } msg += ")"; fErrors.error(offset, msg); @@ -1912,7 +1915,7 @@ std::unique_ptr IRGenerator::call(int offset, return this->call(offset, *ref->fFunctions[0], std::move(arguments)); } default: - fErrors.error(offset, "'" + functionValue->description() + "' is not a function"); + fErrors.error(offset, "not a function"); return nullptr; } } @@ -1923,7 +1926,7 @@ std::unique_ptr IRGenerator::convertNumberConstructor( std::vector> args) { SkASSERT(type.isNumber()); if (args.size() != 1) { - fErrors.error(offset, "invalid arguments to '" + type.description() + + fErrors.error(offset, "invalid arguments to '" + type.displayName() + "' constructor, (expected exactly 1 argument, but found " + to_string((uint64_t) args.size()) + ")"); return nullptr; @@ -1955,9 +1958,9 @@ std::unique_ptr IRGenerator::convertNumberConstructor( type))); } if (!args[0]->fType.isNumber()) { - fErrors.error(offset, "invalid argument to '" + type.description() + + fErrors.error(offset, "invalid argument to '" + type.displayName() + "' constructor (expected a number or bool, but found '" + - args[0]->fType.description() + "')"); + args[0]->fType.displayName() + "')"); return nullptr; } return std::unique_ptr(new Constructor(offset, type, std::move(args))); @@ -1992,8 +1995,8 @@ std::unique_ptr IRGenerator::convertCompoundConstructor( if (args[i]->fType.kind() == Type::kVector_Kind) { if (type.componentType().isNumber() != args[i]->fType.componentType().isNumber()) { - fErrors.error(offset, "'" + args[i]->fType.description() + "' is not a valid " - "parameter to '" + type.description() + + fErrors.error(offset, "'" + args[i]->fType.displayName() + "' is not a valid " + "parameter to '" + type.displayName() + "' constructor"); return nullptr; } @@ -2007,13 +2010,13 @@ std::unique_ptr IRGenerator::convertCompoundConstructor( } } } else { - fErrors.error(offset, "'" + args[i]->fType.description() + "' is not a valid " - "parameter to '" + type.description() + "' constructor"); + fErrors.error(offset, "'" + args[i]->fType.displayName() + "' is not a valid " + "parameter to '" + type.displayName() + "' constructor"); return nullptr; } } if (actual != 1 && actual != expected) { - fErrors.error(offset, "invalid arguments to '" + type.description() + + fErrors.error(offset, "invalid arguments to '" + type.displayName() + "' constructor (expected " + to_string(expected) + " scalars, but found " + to_string(actual) + ")"); return nullptr; @@ -2046,7 +2049,7 @@ std::unique_ptr IRGenerator::convertConstructor( } else if (kind == Type::kVector_Kind || kind == Type::kMatrix_Kind) { return this->convertCompoundConstructor(offset, type, std::move(args)); } else { - fErrors.error(offset, "cannot construct '" + type.description() + "'"); + fErrors.error(offset, "cannot construct '" + type.displayName() + "'"); return nullptr; } } @@ -2062,7 +2065,7 @@ std::unique_ptr IRGenerator::convertPrefixExpression(const ASTNode& if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind && base->fType != *fContext.fFloatLiteral_Type) { fErrors.error(expression.fOffset, - "'+' cannot operate on '" + base->fType.description() + "'"); + "'+' cannot operate on '" + base->fType.displayName() + "'"); return nullptr; } return base; @@ -2078,7 +2081,7 @@ std::unique_ptr IRGenerator::convertPrefixExpression(const ASTNode& } if (!base->fType.isNumber() && base->fType.kind() != Type::kVector_Kind) { fErrors.error(expression.fOffset, - "'-' cannot operate on '" + base->fType.description() + "'"); + "'-' cannot operate on '" + base->fType.displayName() + "'"); return nullptr; } return std::unique_ptr(new PrefixExpression(Token::MINUS, std::move(base))); @@ -2086,7 +2089,7 @@ std::unique_ptr IRGenerator::convertPrefixExpression(const ASTNode& if (!base->fType.isNumber()) { fErrors.error(expression.fOffset, String("'") + Compiler::OperatorName(expression.getToken().fKind) + - "' cannot operate on '" + base->fType.description() + "'"); + "' cannot operate on '" + base->fType.displayName() + "'"); return nullptr; } this->setRefKind(*base, VariableReference::kReadWrite_RefKind); @@ -2095,7 +2098,7 @@ std::unique_ptr IRGenerator::convertPrefixExpression(const ASTNode& if (!base->fType.isNumber()) { fErrors.error(expression.fOffset, String("'") + Compiler::OperatorName(expression.getToken().fKind) + - "' cannot operate on '" + base->fType.description() + "'"); + "' cannot operate on '" + base->fType.displayName() + "'"); return nullptr; } this->setRefKind(*base, VariableReference::kReadWrite_RefKind); @@ -2104,7 +2107,7 @@ std::unique_ptr IRGenerator::convertPrefixExpression(const ASTNode& if (base->fType != *fContext.fBool_Type) { fErrors.error(expression.fOffset, String("'") + Compiler::OperatorName(expression.getToken().fKind) + - "' cannot operate on '" + base->fType.description() + "'"); + "' cannot operate on '" + base->fType.displayName() + "'"); return nullptr; } if (base->fKind == Expression::kBoolLiteral_Kind) { @@ -2116,7 +2119,7 @@ std::unique_ptr IRGenerator::convertPrefixExpression(const ASTNode& if (base->fType != *fContext.fInt_Type && base->fType != *fContext.fUInt_Type) { fErrors.error(expression.fOffset, String("'") + Compiler::OperatorName(expression.getToken().fKind) + - "' cannot operate on '" + base->fType.description() + "'"); + "' cannot operate on '" + base->fType.displayName() + "'"); return nullptr; } break; @@ -2146,7 +2149,7 @@ std::unique_ptr IRGenerator::convertIndex(std::unique_ptrfType.kind() != Type::kArray_Kind && base->fType.kind() != Type::kMatrix_Kind && base->fType.kind() != Type::kVector_Kind) { - fErrors.error(base->fOffset, "expected array, but found '" + base->fType.description() + + fErrors.error(base->fOffset, "expected array, but found '" + base->fType.displayName() + "'"); return nullptr; } @@ -2182,7 +2185,7 @@ std::unique_ptr IRGenerator::convertField(std::unique_ptr(new FieldAccess(std::move(base), (int) i)); } } - fErrors.error(base->fOffset, "type '" + base->fType.description() + "' does not have a " + fErrors.error(base->fOffset, "type '" + base->fType.displayName() + "' does not have a " "field named '" + field + ""); return nullptr; } @@ -2190,7 +2193,7 @@ std::unique_ptr IRGenerator::convertField(std::unique_ptr IRGenerator::convertSwizzle(std::unique_ptr base, StringFragment fields) { if (base->fType.kind() != Type::kVector_Kind) { - fErrors.error(base->fOffset, "cannot swizzle type '" + base->fType.description() + "'"); + fErrors.error(base->fOffset, "cannot swizzle type '" + base->fType.displayName() + "'"); return nullptr; } std::vector swizzleComponents; @@ -2371,7 +2374,7 @@ std::unique_ptr IRGenerator::convertFieldExpression(const ASTNode& f return this->convertField(std::move(base), field); default: fErrors.error(base->fOffset, "cannot swizzle value of type '" + - base->fType.description() + "'"); + base->fType.displayName() + "'"); return nullptr; } } @@ -2384,7 +2387,7 @@ std::unique_ptr IRGenerator::convertPostfixExpression(const ASTNode& if (!base->fType.isNumber()) { fErrors.error(expression.fOffset, "'" + String(Compiler::OperatorName(expression.getToken().fKind)) + - "' cannot operate on '" + base->fType.description() + "'"); + "' cannot operate on '" + base->fType.displayName() + "'"); return nullptr; } this->setRefKind(*base, VariableReference::kReadWrite_RefKind); @@ -2464,7 +2467,7 @@ void IRGenerator::setRefKind(const Expression& expr, VariableReference::RefKind break; } default: - fErrors.error(expr.fOffset, "cannot assign to '" + expr.description() + "'"); + fErrors.error(expr.fOffset, "cannot assign to this expression"); break; } } @@ -2531,7 +2534,10 @@ void IRGenerator::convertProgram(Program::Kind kind, break; } default: +#ifdef SK_DEBUG ABORT("unsupported declaration: %s\n", decl.description().c_str()); +#endif + break; } } } diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp index 66f73dfecd..b4f75e2cd3 100644 --- a/src/sksl/SkSLMetalCodeGenerator.cpp +++ b/src/sksl/SkSLMetalCodeGenerator.cpp @@ -158,7 +158,10 @@ void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence pare this->writeIndexExpression((IndexExpression&) expr); break; default: +#ifdef SK_DEBUG ABORT("unsupported expression: %s", expr.description().c_str()); +#endif + break; } } @@ -1177,7 +1180,10 @@ void MetalCodeGenerator::writeStatement(const Statement& s) { this->write(";"); break; default: +#ifdef SK_DEBUG ABORT("unsupported statement: %s", s.description().c_str()); +#endif + break; } } @@ -1498,8 +1504,10 @@ void MetalCodeGenerator::writeProgramElement(const ProgramElement& e) { this->writeLine(";"); break; default: - printf("%s\n", e.description().c_str()); - ABORT("unsupported program element"); +#ifdef SK_DEBUG + ABORT("unsupported program element: %s\n", e.description().c_str()); +#endif + break; } } diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index 858d8ca7cf..dede8a5fe0 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -560,7 +560,9 @@ SpvId SPIRVCodeGenerator::getType(const Type& rawType, const MemoryLayout& layou if (type == *fContext.fVoid_Type) { this->writeInstruction(SpvOpTypeVoid, result, fConstantBuffer); } else { +#ifdef SK_DEBUG ABORT("invalid type: %s", type.description().c_str()); +#endif } } fTypeMap[key] = result; @@ -578,12 +580,12 @@ SpvId SPIRVCodeGenerator::getImageType(const Type& type) { } SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { - String key = function.fReturnType.description() + "("; + String key = function.fReturnType.displayName() + "("; String separator; for (size_t i = 0; i < function.fParameters.size(); i++) { key += separator; separator = ", "; - key += function.fParameters[i]->fType.description(); + key += function.fParameters[i]->fType.displayName(); } key += ")"; auto entry = fTypeMap.find(key); @@ -641,7 +643,7 @@ SpvId SPIRVCodeGenerator::getPointerType(const Type& type, SpvStorageClass_ stor SpvId SPIRVCodeGenerator::getPointerType(const Type& rawType, const MemoryLayout& layout, SpvStorageClass_ storageClass) { Type type = this->getActualType(rawType); - String key = type.description() + "*" + to_string(layout.fStd) + to_string(storageClass); + String key = type.displayName() + "*" + to_string(layout.fStd) + to_string(storageClass); auto entry = fTypeMap.find(key); if (entry == fTypeMap.end()) { SpvId result = this->nextId(); @@ -682,7 +684,10 @@ SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, OutputStream& case Expression::kIndex_Kind: return this->writeIndexExpression((IndexExpression&) expr, out); default: +#ifdef SK_DEBUG ABORT("unsupported expression: %s", expr.description().c_str()); +#endif + break; } return -1; } @@ -1507,7 +1512,10 @@ SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, OutputStream& o case Type::kArray_Kind: return this->writeArrayConstructor(c, out); default: +#ifdef SK_DEBUG ABORT("unsupported constructor: %s", c.description().c_str()); +#endif + return -1; } } @@ -1972,7 +1980,9 @@ SpvId SPIRVCodeGenerator::writeBinaryOperation(const Type& resultType, this->writeInstruction(ifBool, this->getType(resultType), result, lhs, rhs, out); return result; // skip RelaxedPrecision check } else { +#ifdef SK_DEBUG ABORT("invalid operandType: %s", operandType.description().c_str()); +#endif } if (getActualType(resultType) == operandType && !resultType.highPrecision()) { this->writeInstruction(SpvOpDecorate, result, SpvDecorationRelaxedPrecision, @@ -2388,7 +2398,9 @@ SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, Outpu } else if (is_signed(fContext, p.fType)) { this->writeInstruction(SpvOpSNegate, typeId, result, expr, out); } else { +#ifdef SK_DEBUG ABORT("unsupported prefix expression %s", p.description().c_str()); +#endif } this->writePrecisionModifier(p.fType, result); return result; @@ -2428,7 +2440,10 @@ SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, Outpu return result; } default: +#ifdef SK_DEBUG ABORT("unsupported prefix expression: %s", p.description().c_str()); +#endif + return -1; } } @@ -2450,7 +2465,10 @@ SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, Out return result; } default: +#ifdef SK_DEBUG ABORT("unsupported postfix expression %s", p.description().c_str()); +#endif + return -1; } } @@ -2868,7 +2886,10 @@ void SPIRVCodeGenerator::writeStatement(const Statement& s, OutputStream& out) { this->writeInstruction(SpvOpKill, out); break; default: +#ifdef SK_DEBUG ABORT("unsupported statement: %s", s.description().c_str()); +#endif + break; } } diff --git a/src/sksl/ir/SkSLBinaryExpression.h b/src/sksl/ir/SkSLBinaryExpression.h index 4ab25d2287..f6d37d3fd3 100644 --- a/src/sksl/ir/SkSLBinaryExpression.h +++ b/src/sksl/ir/SkSLBinaryExpression.h @@ -34,9 +34,11 @@ struct BinaryExpression : public Expression { *fRight); } - bool hasSideEffects() const override { - return Compiler::IsAssignment(fOperator) || fLeft->hasSideEffects() || - fRight->hasSideEffects(); + bool hasProperty(Property property) const override { + if (property == Property::kSideEffects && Compiler::IsAssignment(fOperator)) { + return true; + } + return fLeft->hasProperty(property) || fRight->hasProperty(property); } std::unique_ptr clone() const override { @@ -44,10 +46,12 @@ struct BinaryExpression : public Expression { fRight->clone(), fType)); } +#ifdef SK_DEBUG String description() const override { return "(" + fLeft->description() + " " + Compiler::OperatorName(fOperator) + " " + fRight->description() + ")"; } +#endif std::unique_ptr fLeft; const Token::Kind fOperator; diff --git a/src/sksl/ir/SkSLBlock.h b/src/sksl/ir/SkSLBlock.h index 8a4449a01c..3ef82cb830 100644 --- a/src/sksl/ir/SkSLBlock.h +++ b/src/sksl/ir/SkSLBlock.h @@ -40,6 +40,7 @@ struct Block : public Statement { return std::unique_ptr(new Block(fOffset, std::move(cloned), fSymbols)); } +#ifdef SK_DEBUG String description() const override { String result("{"); for (size_t i = 0; i < fStatements.size(); i++) { @@ -49,6 +50,7 @@ struct Block : public Statement { result += "\n}\n"; return result; } +#endif // it's important to keep fStatements defined after (and thus destroyed before) fSymbols, // because destroying statements can modify reference counts in symbols diff --git a/src/sksl/ir/SkSLBoolLiteral.h b/src/sksl/ir/SkSLBoolLiteral.h index b99aec89c4..df6d4b9c0f 100644 --- a/src/sksl/ir/SkSLBoolLiteral.h +++ b/src/sksl/ir/SkSLBoolLiteral.h @@ -21,11 +21,13 @@ struct BoolLiteral : public Expression { : INHERITED(offset, kBoolLiteral_Kind, *context.fBool_Type) , fValue(value) {} +#ifdef SK_DEBUG String description() const override { return String(fValue ? "true" : "false"); } +#endif - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { return false; } diff --git a/src/sksl/ir/SkSLBreakStatement.h b/src/sksl/ir/SkSLBreakStatement.h index ae0c1987e9..18520a7493 100644 --- a/src/sksl/ir/SkSLBreakStatement.h +++ b/src/sksl/ir/SkSLBreakStatement.h @@ -24,9 +24,11 @@ struct BreakStatement : public Statement { return std::unique_ptr(new BreakStatement(fOffset)); } +#ifdef SK_DEBUG String description() const override { return String("break;"); } +#endif typedef Statement INHERITED; }; diff --git a/src/sksl/ir/SkSLConstructor.h b/src/sksl/ir/SkSLConstructor.h index 8d7a4989da..8af1d0f6ab 100644 --- a/src/sksl/ir/SkSLConstructor.h +++ b/src/sksl/ir/SkSLConstructor.h @@ -50,9 +50,9 @@ struct Constructor : public Expression { return nullptr; } - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { for (const auto& arg : fArguments) { - if (arg->hasSideEffects()) { + if (arg->hasProperty(property)) { return true; } } @@ -67,6 +67,7 @@ struct Constructor : public Expression { return std::unique_ptr(new Constructor(fOffset, fType, std::move(cloned))); } +#ifdef SK_DEBUG String description() const override { String result = fType.description() + "("; String separator; @@ -78,6 +79,7 @@ struct Constructor : public Expression { result += ")"; return result; } +#endif bool isConstant() const override { for (size_t i = 0; i < fArguments.size(); i++) { @@ -156,7 +158,10 @@ struct Constructor : public Expression { current += arg->fType.columns(); } } +#ifdef SK_DEBUG ABORT("failed to find vector component %d in %s\n", index, description().c_str()); +#endif + return -1; } SKSL_FLOAT getFVecComponent(int n) const override { diff --git a/src/sksl/ir/SkSLContinueStatement.h b/src/sksl/ir/SkSLContinueStatement.h index ecd9c3f497..139951dc75 100644 --- a/src/sksl/ir/SkSLContinueStatement.h +++ b/src/sksl/ir/SkSLContinueStatement.h @@ -24,9 +24,11 @@ struct ContinueStatement : public Statement { return std::unique_ptr(new ContinueStatement(fOffset)); } +#ifdef SK_DEBUG String description() const override { return String("continue;"); } +#endif typedef Statement INHERITED; }; diff --git a/src/sksl/ir/SkSLDiscardStatement.h b/src/sksl/ir/SkSLDiscardStatement.h index 40f625c178..9c1b042106 100644 --- a/src/sksl/ir/SkSLDiscardStatement.h +++ b/src/sksl/ir/SkSLDiscardStatement.h @@ -24,9 +24,11 @@ struct DiscardStatement : public Statement { return std::unique_ptr(new DiscardStatement(fOffset)); } +#ifdef SK_DEBUG String description() const override { return String("discard;"); } +#endif typedef Statement INHERITED; }; diff --git a/src/sksl/ir/SkSLDoStatement.h b/src/sksl/ir/SkSLDoStatement.h index 5cab5c8bcd..a5d16f95e4 100644 --- a/src/sksl/ir/SkSLDoStatement.h +++ b/src/sksl/ir/SkSLDoStatement.h @@ -28,9 +28,11 @@ struct DoStatement : public Statement { fTest->clone())); } +#ifdef SK_DEBUG String description() const override { return "do " + fStatement->description() + " while (" + fTest->description() + ");"; } +#endif std::unique_ptr fStatement; std::unique_ptr fTest; diff --git a/src/sksl/ir/SkSLEnum.h b/src/sksl/ir/SkSLEnum.h index a22db36577..7d10b8fd84 100644 --- a/src/sksl/ir/SkSLEnum.h +++ b/src/sksl/ir/SkSLEnum.h @@ -30,7 +30,7 @@ struct Enum : public ProgramElement { return std::unique_ptr(new Enum(fOffset, fTypeName, fSymbols)); } - String description() const override { + String code() const { String result = "enum class " + fTypeName + " {\n"; String separator; std::vector sortedSymbols; @@ -40,14 +40,22 @@ struct Enum : public ProgramElement { std::sort(sortedSymbols.begin(), sortedSymbols.end(), [](const Symbol* a, const Symbol* b) { return a->fName < b->fName; }); for (const auto& s : sortedSymbols) { + const Expression& initialValue = *((Variable*) s)->fInitialValue; + SkASSERT(initialValue.fKind == Expression::kIntLiteral_Kind); result += separator + " " + s->fName + " = " + - ((Variable*) s)->fInitialValue->description(); + to_string(((IntLiteral&) initialValue).fValue); separator = ",\n"; } result += "\n};"; return result; } +#ifdef SK_DEBUG + String description() const override { + return this->code(); + } +#endif + bool fBuiltin = false; const StringFragment fTypeName; const std::shared_ptr fSymbols; diff --git a/src/sksl/ir/SkSLExpression.h b/src/sksl/ir/SkSLExpression.h index 928295dc72..e61cedfb7c 100644 --- a/src/sksl/ir/SkSLExpression.h +++ b/src/sksl/ir/SkSLExpression.h @@ -47,6 +47,11 @@ struct Expression : public IRNode { kDefined_Kind }; + enum class Property { + kSideEffects, + kContainsRTAdjust + }; + Expression(int offset, Kind kind, const Type& type) : INHERITED(offset) , fKind(kind) @@ -85,12 +90,15 @@ struct Expression : public IRNode { ABORT("not a constant float"); } - /** - * Returns true if evaluating the expression potentially has side effects. Expressions may never - * return false if they actually have side effects, but it is legal (though suboptimal) to - * return true if there are not actually any side effects. - */ - virtual bool hasSideEffects() const = 0; + virtual bool hasProperty(Property property) const = 0; + + bool hasSideEffects() const { + return this->hasProperty(Property::kSideEffects); + } + + bool containsRTAdjust() const { + return this->hasProperty(Property::kContainsRTAdjust); + } /** * Given a map of known constant variable values, substitute them in for references to those diff --git a/src/sksl/ir/SkSLExpressionStatement.h b/src/sksl/ir/SkSLExpressionStatement.h index 80a8d316c7..6a2a415fe6 100644 --- a/src/sksl/ir/SkSLExpressionStatement.h +++ b/src/sksl/ir/SkSLExpressionStatement.h @@ -25,9 +25,11 @@ struct ExpressionStatement : public Statement { return std::unique_ptr(new ExpressionStatement(fExpression->clone())); } +#ifdef SK_DEBUG String description() const override { return fExpression->description() + ";"; } +#endif std::unique_ptr fExpression; diff --git a/src/sksl/ir/SkSLExtension.h b/src/sksl/ir/SkSLExtension.h index 5eed97508f..68379048ec 100644 --- a/src/sksl/ir/SkSLExtension.h +++ b/src/sksl/ir/SkSLExtension.h @@ -24,9 +24,11 @@ struct Extension : public ProgramElement { return std::unique_ptr(new Extension(fOffset, fName)); } +#ifdef SK_DEBUG String description() const override { return "#extension " + fName + " : enable"; } +#endif const String fName; diff --git a/src/sksl/ir/SkSLExternalFunctionCall.h b/src/sksl/ir/SkSLExternalFunctionCall.h index 3c52a10de6..a33f5d8272 100644 --- a/src/sksl/ir/SkSLExternalFunctionCall.h +++ b/src/sksl/ir/SkSLExternalFunctionCall.h @@ -24,8 +24,16 @@ struct ExternalFunctionCall : public Expression { , fFunction(function) , fArguments(std::move(arguments)) {} - bool hasSideEffects() const override { - return true; + bool hasProperty(Property property) const override { + if (property == Property::kSideEffects) { + return true; + } + for (const auto& arg : fArguments) { + if (arg->hasProperty(property)) { + return true; + } + } + return false; } std::unique_ptr clone() const override { @@ -39,6 +47,7 @@ struct ExternalFunctionCall : public Expression { std::move(cloned))); } +#ifdef SK_DEBUG String description() const override { String result = String(fFunction->fName) + "("; String separator; @@ -50,6 +59,7 @@ struct ExternalFunctionCall : public Expression { result += ")"; return result; } +#endif ExternalValue* fFunction; std::vector> fArguments; diff --git a/src/sksl/ir/SkSLExternalValueReference.h b/src/sksl/ir/SkSLExternalValueReference.h index ee8e81e12a..fa307d9bfd 100644 --- a/src/sksl/ir/SkSLExternalValueReference.h +++ b/src/sksl/ir/SkSLExternalValueReference.h @@ -21,13 +21,15 @@ struct ExternalValueReference : public Expression { : INHERITED(offset, kExternalValue_Kind, ev->type()) , fValue(ev) {} - bool hasSideEffects() const override { - return true; + bool hasProperty(Property property) const override { + return property == Property::kSideEffects; } +#ifdef SK_DEBUG String description() const override { return String(fValue->fName); } +#endif std::unique_ptr clone() const override { return std::unique_ptr(new ExternalValueReference(fOffset, fValue)); diff --git a/src/sksl/ir/SkSLField.h b/src/sksl/ir/SkSLField.h index d187a8032b..c3dda2042e 100644 --- a/src/sksl/ir/SkSLField.h +++ b/src/sksl/ir/SkSLField.h @@ -27,9 +27,11 @@ struct Field : public Symbol { , fOwner(owner) , fFieldIndex(fieldIndex) {} +#ifdef SK_DEBUG virtual String description() const override { return fOwner.description() + "." + fOwner.fType.fields()[fFieldIndex].fName; } +#endif const Variable& fOwner; const int fFieldIndex; diff --git a/src/sksl/ir/SkSLFieldAccess.h b/src/sksl/ir/SkSLFieldAccess.h index 7576c0a31e..9dc0b2c269 100644 --- a/src/sksl/ir/SkSLFieldAccess.h +++ b/src/sksl/ir/SkSLFieldAccess.h @@ -31,8 +31,8 @@ struct FieldAccess : public Expression { , fFieldIndex(fieldIndex) , fOwnerKind(ownerKind) {} - bool hasSideEffects() const override { - return fBase->hasSideEffects(); + bool hasProperty(Property property) const override { + return fBase->hasProperty(property); } std::unique_ptr clone() const override { @@ -40,9 +40,11 @@ struct FieldAccess : public Expression { fOwnerKind)); } +#ifdef SK_DEBUG String description() const override { return fBase->description() + "." + fBase->fType.fields()[fFieldIndex].fName; } +#endif std::unique_ptr fBase; const int fFieldIndex; diff --git a/src/sksl/ir/SkSLFloatLiteral.h b/src/sksl/ir/SkSLFloatLiteral.h index 2ed2b796b1..7cd3c15cb6 100644 --- a/src/sksl/ir/SkSLFloatLiteral.h +++ b/src/sksl/ir/SkSLFloatLiteral.h @@ -25,11 +25,13 @@ struct FloatLiteral : public Expression { : INHERITED(offset, kFloatLiteral_Kind, *type) , fValue(value) {} +#ifdef SK_DEBUG String description() const override { return to_string(fValue); } +#endif - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { return false; } diff --git a/src/sksl/ir/SkSLForStatement.h b/src/sksl/ir/SkSLForStatement.h index 4906e192a6..96eaa6ff1c 100644 --- a/src/sksl/ir/SkSLForStatement.h +++ b/src/sksl/ir/SkSLForStatement.h @@ -34,6 +34,7 @@ struct ForStatement : public Statement { fStatement->clone(), fSymbols)); } +#ifdef SK_DEBUG String description() const override { String result("for ("); if (fInitializer) { @@ -50,6 +51,7 @@ struct ForStatement : public Statement { result += ") " + fStatement->description(); return result; } +#endif // it's important to keep fSymbols defined first (and thus destroyed last) because destroying // the other fields can update symbol reference counts diff --git a/src/sksl/ir/SkSLFunctionCall.h b/src/sksl/ir/SkSLFunctionCall.h index 90c173f66a..19d262b034 100644 --- a/src/sksl/ir/SkSLFunctionCall.h +++ b/src/sksl/ir/SkSLFunctionCall.h @@ -23,13 +23,17 @@ struct FunctionCall : public Expression { , fFunction(std::move(function)) , fArguments(std::move(arguments)) {} - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { + if (property == Property::kSideEffects && (fFunction.fModifiers.fFlags & + Modifiers::kHasSideEffects_Flag)) { + return true; + } for (const auto& arg : fArguments) { - if (arg->hasSideEffects()) { + if (arg->hasProperty(property)) { return true; } } - return fFunction.fModifiers.fFlags & Modifiers::kHasSideEffects_Flag; + return false; } std::unique_ptr clone() const override { @@ -41,6 +45,7 @@ struct FunctionCall : public Expression { std::move(cloned))); } +#ifdef SK_DEBUG String description() const override { String result = String(fFunction.fName) + "("; String separator; @@ -52,6 +57,7 @@ struct FunctionCall : public Expression { result += ")"; return result; } +#endif const FunctionDeclaration& fFunction; std::vector> fArguments; diff --git a/src/sksl/ir/SkSLFunctionDeclaration.h b/src/sksl/ir/SkSLFunctionDeclaration.h index 9b6d25e483..11b04a5d89 100644 --- a/src/sksl/ir/SkSLFunctionDeclaration.h +++ b/src/sksl/ir/SkSLFunctionDeclaration.h @@ -30,18 +30,24 @@ struct FunctionDeclaration : public Symbol { , fParameters(std::move(parameters)) , fReturnType(returnType) {} - String description() const override { - String result = fReturnType.description() + " " + fName + "("; + String declaration() const { + String result = fReturnType.displayName() + " " + fName + "("; String separator; for (auto p : fParameters) { result += separator; separator = ", "; - result += p->description(); + result += p->fName; } result += ")"; return result; } +#ifdef SK_DEBUG + String description() const override { + return this->declaration(); + } +#endif + bool matches(const FunctionDeclaration& f) const { if (fName != f.fName) { return false; diff --git a/src/sksl/ir/SkSLFunctionDefinition.h b/src/sksl/ir/SkSLFunctionDefinition.h index 511a0f8c20..bd2f8bce83 100644 --- a/src/sksl/ir/SkSLFunctionDefinition.h +++ b/src/sksl/ir/SkSLFunctionDefinition.h @@ -31,9 +31,11 @@ struct FunctionDefinition : public ProgramElement { fBody->clone())); } +#ifdef SK_DEBUG String description() const override { return fDeclaration.description() + " " + fBody->description(); } +#endif const FunctionDeclaration& fDeclaration; std::unique_ptr fBody; diff --git a/src/sksl/ir/SkSLFunctionReference.h b/src/sksl/ir/SkSLFunctionReference.h index e78f1cd641..3c36e027f3 100644 --- a/src/sksl/ir/SkSLFunctionReference.h +++ b/src/sksl/ir/SkSLFunctionReference.h @@ -24,7 +24,7 @@ struct FunctionReference : public Expression { : INHERITED(offset, kFunctionReference_Kind, *context.fInvalid_Type) , fFunctions(function) {} - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { return false; } @@ -32,9 +32,11 @@ struct FunctionReference : public Expression { return std::unique_ptr(new FunctionReference(fOffset, fFunctions, &fType)); } +#ifdef SK_DEBUG String description() const override { return String(""); } +#endif const std::vector fFunctions; diff --git a/src/sksl/ir/SkSLIRNode.h b/src/sksl/ir/SkSLIRNode.h index ca9ea99998..52e5d9c7e7 100644 --- a/src/sksl/ir/SkSLIRNode.h +++ b/src/sksl/ir/SkSLIRNode.h @@ -23,7 +23,9 @@ struct IRNode { virtual ~IRNode() {} +#ifdef SK_DEBUG virtual String description() const = 0; +#endif // character offset of this element within the program being compiled, for error reporting // purposes diff --git a/src/sksl/ir/SkSLIfStatement.h b/src/sksl/ir/SkSLIfStatement.h index 5d0a22b647..441836cc95 100644 --- a/src/sksl/ir/SkSLIfStatement.h +++ b/src/sksl/ir/SkSLIfStatement.h @@ -30,6 +30,7 @@ struct IfStatement : public Statement { fIfTrue->clone(), fIfFalse ? fIfFalse->clone() : nullptr)); } +#ifdef SK_DEBUG String description() const override { String result; if (fIsStatic) { @@ -41,6 +42,7 @@ struct IfStatement : public Statement { } return result; } +#endif bool fIsStatic; std::unique_ptr fTest; diff --git a/src/sksl/ir/SkSLIndexExpression.h b/src/sksl/ir/SkSLIndexExpression.h index 7c5c1290b8..9c545a8b1e 100644 --- a/src/sksl/ir/SkSLIndexExpression.h +++ b/src/sksl/ir/SkSLIndexExpression.h @@ -58,8 +58,8 @@ struct IndexExpression : public Expression { SkASSERT(fIndex->fType == *context.fInt_Type || fIndex->fType == *context.fUInt_Type); } - bool hasSideEffects() const override { - return fBase->hasSideEffects() || fIndex->hasSideEffects(); + bool hasProperty(Property property) const override { + return fBase->hasProperty(property) || fIndex->hasProperty(property); } std::unique_ptr clone() const override { @@ -67,9 +67,11 @@ struct IndexExpression : public Expression { &fType)); } +#ifdef SK_DEBUG String description() const override { return fBase->description() + "[" + fIndex->description() + "]"; } +#endif std::unique_ptr fBase; std::unique_ptr fIndex; diff --git a/src/sksl/ir/SkSLIntLiteral.h b/src/sksl/ir/SkSLIntLiteral.h index fa45978663..3cfd7fd461 100644 --- a/src/sksl/ir/SkSLIntLiteral.h +++ b/src/sksl/ir/SkSLIntLiteral.h @@ -27,11 +27,13 @@ struct IntLiteral : public Expression { : INHERITED(offset, kIntLiteral_Kind, *type) , fValue(value) {} +#ifdef SK_DEBUG String description() const override { return to_string(fValue); } +#endif - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { return false; } diff --git a/src/sksl/ir/SkSLInterfaceBlock.h b/src/sksl/ir/SkSLInterfaceBlock.h index 3dfd9fdf29..a232e628e5 100644 --- a/src/sksl/ir/SkSLInterfaceBlock.h +++ b/src/sksl/ir/SkSLInterfaceBlock.h @@ -46,6 +46,7 @@ struct InterfaceBlock : public ProgramElement { fTypeOwner)); } +#ifdef SK_DEBUG String description() const override { String result = fVariable.fModifiers.description() + fTypeName + " {\n"; const Type* structType = &fVariable.fType; @@ -68,6 +69,7 @@ struct InterfaceBlock : public ProgramElement { } return result + ";"; } +#endif const Variable& fVariable; const String fTypeName; diff --git a/src/sksl/ir/SkSLModifiersDeclaration.h b/src/sksl/ir/SkSLModifiersDeclaration.h index 1dc74149e6..673baf62fd 100644 --- a/src/sksl/ir/SkSLModifiersDeclaration.h +++ b/src/sksl/ir/SkSLModifiersDeclaration.h @@ -27,9 +27,11 @@ struct ModifiersDeclaration : public ProgramElement { return std::unique_ptr(new ModifiersDeclaration(fModifiers)); } +#ifdef SK_DEBUG String description() const override { return fModifiers.description() + ";"; } +#endif Modifiers fModifiers; diff --git a/src/sksl/ir/SkSLNop.h b/src/sksl/ir/SkSLNop.h index 2ead371f87..02d1ebcc64 100644 --- a/src/sksl/ir/SkSLNop.h +++ b/src/sksl/ir/SkSLNop.h @@ -24,9 +24,11 @@ struct Nop : public Statement { return true; } +#ifdef SK_DEBUG String description() const override { return String(";"); } +#endif std::unique_ptr clone() const override { return std::unique_ptr(new Nop()); diff --git a/src/sksl/ir/SkSLNullLiteral.h b/src/sksl/ir/SkSLNullLiteral.h index 2d8816d6a2..e2b7bd9e5b 100644 --- a/src/sksl/ir/SkSLNullLiteral.h +++ b/src/sksl/ir/SkSLNullLiteral.h @@ -23,11 +23,13 @@ struct NullLiteral : public Expression { NullLiteral(int offset, const Type& type) : INHERITED(offset, kNullLiteral_Kind, type) {} +#ifdef SK_DEBUG String description() const override { return "null"; } +#endif - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { return false; } diff --git a/src/sksl/ir/SkSLPostfixExpression.h b/src/sksl/ir/SkSLPostfixExpression.h index c11e2085e4..2ee77dbd49 100644 --- a/src/sksl/ir/SkSLPostfixExpression.h +++ b/src/sksl/ir/SkSLPostfixExpression.h @@ -23,17 +23,22 @@ struct PostfixExpression : public Expression { , fOperand(std::move(operand)) , fOperator(op) {} - bool hasSideEffects() const override { - return true; + bool hasProperty(Property property) const override { + if (property == Property::kSideEffects) { + return true; + } + return fOperand->hasProperty(property); } std::unique_ptr clone() const override { return std::unique_ptr(new PostfixExpression(fOperand->clone(), fOperator)); } +#ifdef SK_DEBUG String description() const override { return fOperand->description() + Compiler::OperatorName(fOperator); } +#endif std::unique_ptr fOperand; const Token::Kind fOperator; diff --git a/src/sksl/ir/SkSLPrefixExpression.h b/src/sksl/ir/SkSLPrefixExpression.h index 408f1d0864..7a02df8da8 100644 --- a/src/sksl/ir/SkSLPrefixExpression.h +++ b/src/sksl/ir/SkSLPrefixExpression.h @@ -29,9 +29,12 @@ struct PrefixExpression : public Expression { return fOperator == Token::MINUS && fOperand->isConstant(); } - bool hasSideEffects() const override { - return fOperator == Token::PLUSPLUS || fOperator == Token::MINUSMINUS || - fOperand->hasSideEffects(); + bool hasProperty(Property property) const override { + if (property == Property::kSideEffects && (fOperator == Token::PLUSPLUS || + fOperator == Token::MINUSMINUS)) { + return true; + } + return fOperand->hasProperty(property); } std::unique_ptr constantPropagate(const IRGenerator& irGenerator, @@ -65,9 +68,11 @@ struct PrefixExpression : public Expression { return std::unique_ptr(new PrefixExpression(fOperator, fOperand->clone())); } +#ifdef SK_DEBUG String description() const override { return Compiler::OperatorName(fOperator) + fOperand->description(); } +#endif std::unique_ptr fOperand; const Token::Kind fOperator; diff --git a/src/sksl/ir/SkSLReturnStatement.h b/src/sksl/ir/SkSLReturnStatement.h index e61fa36c74..cc6292c068 100644 --- a/src/sksl/ir/SkSLReturnStatement.h +++ b/src/sksl/ir/SkSLReturnStatement.h @@ -31,6 +31,7 @@ struct ReturnStatement : public Statement { return std::unique_ptr(new ReturnStatement(fOffset)); } +#ifdef SK_DEBUG String description() const override { if (fExpression) { return "return " + fExpression->description() + ";"; @@ -38,6 +39,7 @@ struct ReturnStatement : public Statement { return String("return;"); } } +#endif std::unique_ptr fExpression; diff --git a/src/sksl/ir/SkSLSection.h b/src/sksl/ir/SkSLSection.h index 20856127ca..54fa7d78d0 100644 --- a/src/sksl/ir/SkSLSection.h +++ b/src/sksl/ir/SkSLSection.h @@ -26,6 +26,7 @@ struct Section : public ProgramElement { return std::unique_ptr(new Section(fOffset, fName, fArgument, fText)); } +#ifdef SK_DEBUG String description() const override { String result = "@" + fName; if (fArgument.size()) { @@ -34,6 +35,7 @@ struct Section : public ProgramElement { result += " { " + fText + " }"; return result; } +#endif const String fName; const String fArgument; diff --git a/src/sksl/ir/SkSLSetting.h b/src/sksl/ir/SkSLSetting.h index 33c8a31acc..755c4ee441 100644 --- a/src/sksl/ir/SkSLSetting.h +++ b/src/sksl/ir/SkSLSetting.h @@ -32,11 +32,13 @@ struct Setting : public Expression { return std::unique_ptr(new Setting(fOffset, fName, fValue->clone())); } +#ifdef SK_DEBUG String description() const override { return fName; } +#endif - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { return false; } diff --git a/src/sksl/ir/SkSLSwitchCase.h b/src/sksl/ir/SkSLSwitchCase.h index b1ddb012ec..a59dbe7efe 100644 --- a/src/sksl/ir/SkSLSwitchCase.h +++ b/src/sksl/ir/SkSLSwitchCase.h @@ -33,6 +33,7 @@ struct SwitchCase : public Statement { std::move(cloned))); } +#ifdef SK_DEBUG String description() const override { String result; if (fValue) { @@ -45,6 +46,7 @@ struct SwitchCase : public Statement { } return result; } +#endif // null value implies "default" case std::unique_ptr fValue; diff --git a/src/sksl/ir/SkSLSwitchStatement.h b/src/sksl/ir/SkSLSwitchStatement.h index 0777c5c5c6..b8d8886e29 100644 --- a/src/sksl/ir/SkSLSwitchStatement.h +++ b/src/sksl/ir/SkSLSwitchStatement.h @@ -37,6 +37,7 @@ struct SwitchStatement : public Statement { std::move(cloned), fSymbols)); } +#ifdef SK_DEBUG String description() const override { String result; if (fIsStatic) { @@ -49,6 +50,7 @@ struct SwitchStatement : public Statement { result += "}"; return result; } +#endif bool fIsStatic; std::unique_ptr fValue; diff --git a/src/sksl/ir/SkSLSwizzle.h b/src/sksl/ir/SkSLSwizzle.h index 5067b844a4..59df63127f 100644 --- a/src/sksl/ir/SkSLSwizzle.h +++ b/src/sksl/ir/SkSLSwizzle.h @@ -93,7 +93,10 @@ static const Type& get_type(const Context& context, Expression& value, size_t co case 4: return *context.fBool4_Type; } } +#ifdef SK_DEBUG ABORT("cannot swizzle %s\n", value.description().c_str()); +#endif + return value.fType; } /** @@ -129,14 +132,15 @@ struct Swizzle : public Expression { return nullptr; } - bool hasSideEffects() const override { - return fBase->hasSideEffects(); + bool hasProperty(Property property) const override { + return fBase->hasProperty(property); } std::unique_ptr clone() const override { return std::unique_ptr(new Swizzle(fType, fBase->clone(), fComponents)); } +#ifdef SK_DEBUG String description() const override { String result = fBase->description() + "."; for (int x : fComponents) { @@ -144,6 +148,7 @@ struct Swizzle : public Expression { } return result; } +#endif std::unique_ptr fBase; std::vector fComponents; diff --git a/src/sksl/ir/SkSLTernaryExpression.h b/src/sksl/ir/SkSLTernaryExpression.h index e2bf9ed28b..8cdfaddc74 100644 --- a/src/sksl/ir/SkSLTernaryExpression.h +++ b/src/sksl/ir/SkSLTernaryExpression.h @@ -26,8 +26,9 @@ struct TernaryExpression : public Expression { SkASSERT(fIfTrue->fType == fIfFalse->fType); } - bool hasSideEffects() const override { - return fTest->hasSideEffects() || fIfTrue->hasSideEffects() || fIfFalse->hasSideEffects(); + bool hasProperty(Property property) const override { + return fTest->hasProperty(property) || fIfTrue->hasProperty(property) || + fIfFalse->hasProperty(property); } std::unique_ptr clone() const override { @@ -36,10 +37,12 @@ struct TernaryExpression : public Expression { fIfFalse->clone())); } +#ifdef SK_DEBUG String description() const override { return "(" + fTest->description() + " ? " + fIfTrue->description() + " : " + fIfFalse->description() + ")"; } +#endif std::unique_ptr fTest; std::unique_ptr fIfTrue; diff --git a/src/sksl/ir/SkSLType.cpp b/src/sksl/ir/SkSLType.cpp index 5d735fc11f..cd18e8ed91 100644 --- a/src/sksl/ir/SkSLType.cpp +++ b/src/sksl/ir/SkSLType.cpp @@ -226,7 +226,10 @@ const Type& Type::toCompound(const Context& context, int columns, int rows) cons default: ABORT("unsupported row count (%d)", rows); } } +#ifdef SK_DEBUG ABORT("unsupported scalar_to_compound type %s", this->description().c_str()); +#endif + return *context.fVoid_Type; } } // namespace diff --git a/src/sksl/ir/SkSLType.h b/src/sksl/ir/SkSLType.h index 49ea8a5531..16ec9beb7f 100644 --- a/src/sksl/ir/SkSLType.h +++ b/src/sksl/ir/SkSLType.h @@ -33,7 +33,7 @@ public: , fType(std::move(type)) {} const String description() const { - return fType->description() + " " + fName + ";"; + return fType->displayName() + " " + fName + ";"; } Modifiers fModifiers; @@ -232,7 +232,7 @@ public: return fNameString; } - String description() const override { + const String displayName() const { if (fNameString == "$floatLiteral") { return "float"; } @@ -242,6 +242,12 @@ public: return fNameString; } +#ifdef SK_DEBUG + String description() const override { + return this->displayName(); + } +#endif + bool operator==(const Type& other) const { return fName == other.fName; } diff --git a/src/sksl/ir/SkSLTypeReference.h b/src/sksl/ir/SkSLTypeReference.h index 20a533aeb0..fbf717e074 100644 --- a/src/sksl/ir/SkSLTypeReference.h +++ b/src/sksl/ir/SkSLTypeReference.h @@ -22,13 +22,15 @@ struct TypeReference : public Expression { : INHERITED(offset, kTypeReference_Kind, *context.fInvalid_Type) , fValue(value) {} - bool hasSideEffects() const override { + bool hasProperty(Property property) const override { return false; } +#ifdef SK_DEBUG String description() const override { return String(fValue.fName); } +#endif std::unique_ptr clone() const override { return std::unique_ptr(new TypeReference(fOffset, fValue, &fType)); diff --git a/src/sksl/ir/SkSLUnresolvedFunction.h b/src/sksl/ir/SkSLUnresolvedFunction.h index d32cd42856..13cec1824b 100644 --- a/src/sksl/ir/SkSLUnresolvedFunction.h +++ b/src/sksl/ir/SkSLUnresolvedFunction.h @@ -26,9 +26,11 @@ struct UnresolvedFunction : public Symbol { #endif } +#ifdef SK_DEBUG String description() const override { return fName; } +#endif const std::vector fFunctions; diff --git a/src/sksl/ir/SkSLVarDeclarations.h b/src/sksl/ir/SkSLVarDeclarations.h index 82dbd8616d..0425e4cd45 100644 --- a/src/sksl/ir/SkSLVarDeclarations.h +++ b/src/sksl/ir/SkSLVarDeclarations.h @@ -42,6 +42,7 @@ struct VarDeclaration : public Statement { fValue ? fValue->clone() : nullptr)); } +#ifdef SK_DEBUG String description() const override { String result = fVar->fName; for (const auto& size : fSizes) { @@ -56,6 +57,7 @@ struct VarDeclaration : public Statement { } return result; } +#endif const Variable* fVar; std::vector> fSizes; @@ -87,6 +89,7 @@ struct VarDeclarations : public ProgramElement { std::move(cloned))); } +#ifdef SK_DEBUG String description() const override { if (!fVars.size()) { return String(); @@ -101,6 +104,7 @@ struct VarDeclarations : public ProgramElement { } return result; } +#endif const Type& fBaseType; // this *should* be a vector of unique_ptr, but it significantly simplifies the diff --git a/src/sksl/ir/SkSLVarDeclarationsStatement.h b/src/sksl/ir/SkSLVarDeclarationsStatement.h index 465b691936..c5126fa57a 100644 --- a/src/sksl/ir/SkSLVarDeclarationsStatement.h +++ b/src/sksl/ir/SkSLVarDeclarationsStatement.h @@ -35,9 +35,11 @@ struct VarDeclarationsStatement : public Statement { return std::unique_ptr(new VarDeclarationsStatement(std::move(cloned))); } +#ifdef SK_DEBUG String description() const override { return fDeclaration->description() + ";"; } +#endif std::unique_ptr fDeclaration; diff --git a/src/sksl/ir/SkSLVariable.h b/src/sksl/ir/SkSLVariable.h index bdf5cd8f79..8b0de4c636 100644 --- a/src/sksl/ir/SkSLVariable.h +++ b/src/sksl/ir/SkSLVariable.h @@ -48,9 +48,11 @@ struct Variable : public Symbol { SkASSERT(!fReadCount && !fWriteCount); } +#ifdef SK_DEBUG virtual String description() const override { return fModifiers.description() + fType.fName + " " + fName; } +#endif bool dead() const { if ((fStorage != kLocal_Storage && fReadCount) || diff --git a/src/sksl/ir/SkSLVariableReference.h b/src/sksl/ir/SkSLVariableReference.h index 6c8a92305d..be29b4976c 100644 --- a/src/sksl/ir/SkSLVariableReference.h +++ b/src/sksl/ir/SkSLVariableReference.h @@ -41,8 +41,14 @@ struct VariableReference : public Expression { void setRefKind(RefKind refKind); - bool hasSideEffects() const override { - return false; + bool hasProperty(Property property) const override { + switch (property) { + case Property::kSideEffects: return false; + case Property::kContainsRTAdjust: return fVariable.fName == "sk_RTAdjust"; + default: + SkASSERT(false); + return false; + } } bool isConstant() const override { @@ -53,9 +59,11 @@ struct VariableReference : public Expression { return std::unique_ptr(new VariableReference(fOffset, fVariable, fRefKind)); } +#ifdef SK_DEBUG String description() const override { return fVariable.fName; } +#endif static std::unique_ptr copy_constant(const IRGenerator& irGenerator, const Expression* expr); diff --git a/src/sksl/ir/SkSLWhileStatement.h b/src/sksl/ir/SkSLWhileStatement.h index 8e311a090a..ee1e5046a8 100644 --- a/src/sksl/ir/SkSLWhileStatement.h +++ b/src/sksl/ir/SkSLWhileStatement.h @@ -28,9 +28,11 @@ struct WhileStatement : public Statement { fStatement->clone())); } +#ifdef SK_DEBUG String description() const override { return "while (" + fTest->description() + ") " + fStatement->description(); } +#endif std::unique_ptr fTest; std::unique_ptr fStatement; diff --git a/src/sksl/lex/DFAState.h b/src/sksl/lex/DFAState.h index 141078a769..a09d7ba673 100644 --- a/src/sksl/lex/DFAState.h +++ b/src/sksl/lex/DFAState.h @@ -28,6 +28,7 @@ struct DFAState { return !(*this == other); } +#ifdef SK_DEBUG std::string description() const { std::string result = "<"; const char* separator = ""; @@ -39,6 +40,7 @@ struct DFAState { result += ">"; return result; } +#endif }; DFAState() diff --git a/src/sksl/lex/NFAState.h b/src/sksl/lex/NFAState.h index 6f6e289b7f..25578b3a47 100644 --- a/src/sksl/lex/NFAState.h +++ b/src/sksl/lex/NFAState.h @@ -79,6 +79,7 @@ struct NFAState { } } +#ifdef SK_DEBUG std::string description() const { switch (fKind) { case kAccept_Kind: @@ -134,6 +135,7 @@ struct NFAState { ABORT("unreachable"); } } +#endif Kind fKind; diff --git a/src/sksl/lex/RegexNode.cpp b/src/sksl/lex/RegexNode.cpp index 90eeda2bff..3ddb1ffa38 100644 --- a/src/sksl/lex/RegexNode.cpp +++ b/src/sksl/lex/RegexNode.cpp @@ -82,6 +82,7 @@ std::vector RegexNode::createStates(NFA* nfa, const std::vector& accep return result; } +#ifdef SK_DEBUG std::string RegexNode::description() const { switch (fKind) { case kChar_Kind: @@ -115,3 +116,4 @@ std::string RegexNode::description() const { return "<" + std::to_string(fKind) + ">"; } } +#endif diff --git a/tests/SkSLErrorTest.cpp b/tests/SkSLErrorTest.cpp index 1fbf29e4e1..53214d2584 100644 --- a/tests/SkSLErrorTest.cpp +++ b/tests/SkSLErrorTest.cpp @@ -270,7 +270,7 @@ DEF_TEST(SkSLBinaryTypeMismatch, r) { DEF_TEST(SkSLCallNonFunction, r) { test_failure(r, "void main() { float x = 3; x(); }", - "error: 1: 'x' is not a function\n1 error\n"); + "error: 1: not a function\n1 error\n"); } DEF_TEST(SkSLInvalidUnary, r) { @@ -302,7 +302,7 @@ DEF_TEST(SkSLInvalidUnary, r) { DEF_TEST(SkSLInvalidAssignment, r) { test_failure(r, "void main() { 1 = 2; }", - "error: 1: cannot assign to '1'\n1 error\n"); + "error: 1: cannot assign to this expression\n1 error\n"); test_failure(r, "uniform int x; void main() { x = 0; }", "error: 1: cannot modify immutable variable 'x'\n1 error\n");