SkSL description methods are now only present in debug mode
As they are a significant chunk of code, this reduces the size of the release executable. Change-Id: Ib764b3ec6244629e50941b0101a540e49d56c320 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/261955 Reviewed-by: Greg Daniel <egdaniel@google.com> Reviewed-by: Kevin Lubick <kjlubick@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
ccd45a5efe
commit
2a099dae1e
@ -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
|
||||
|
@ -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 "<error>";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
@ -613,7 +613,9 @@ struct ASTNode {
|
||||
return iterator(fNodes, ID(-1));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const;
|
||||
#endif
|
||||
|
||||
std::vector<ASTNode>* fNodes;
|
||||
|
||||
|
@ -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::LValue> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<BasicBlock::Node>::iterator* iter,
|
||||
Expression* e) {
|
||||
@ -149,7 +151,10 @@ bool BasicBlock::tryRemoveLValueBefore(std::vector<BasicBlock::Node>::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<BasicBlock::Node>::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<Statement>* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 "<defined>";
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<Expression> clone() const override {
|
||||
return std::unique_ptr<Expression>(new Defined(fType));
|
||||
|
@ -101,9 +101,11 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return String("external<") + fName + ">";
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef Symbol INHERITED;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -611,7 +611,7 @@ std::unique_ptr<Statement> 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<Statement>(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<Expression> 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<Expression> IRGenerator::coerce(std::unique_ptr<Expression> 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<Expression> 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<Expression> 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<Expression> 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<Expression> 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<Expression> 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<Expression> IRGenerator::convertNumberConstructor(
|
||||
std::vector<std::unique_ptr<Expression>> 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<Expression> 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<Expression>(new Constructor(offset, type, std::move(args)));
|
||||
@ -1992,8 +1995,8 @@ std::unique_ptr<Expression> 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<Expression> 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<Expression> 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<Expression> 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<Expression> 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<Expression>(new PrefixExpression(Token::MINUS, std::move(base)));
|
||||
@ -2086,7 +2089,7 @@ std::unique_ptr<Expression> 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<Expression> 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<Expression> 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<Expression> 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<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
|
||||
}
|
||||
if (base->fType.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<Expression> IRGenerator::convertField(std::unique_ptr<Expression
|
||||
return std::unique_ptr<Expression>(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<Expression> IRGenerator::convertField(std::unique_ptr<Expression
|
||||
std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expression> 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<int> swizzleComponents;
|
||||
@ -2371,7 +2374,7 @@ std::unique_ptr<Expression> 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<Expression> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Expression> 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<Expression> fLeft;
|
||||
const Token::Kind fOperator;
|
||||
|
@ -40,6 +40,7 @@ struct Block : public Statement {
|
||||
return std::unique_ptr<Statement>(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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -24,9 +24,11 @@ struct BreakStatement : public Statement {
|
||||
return std::unique_ptr<Statement>(new BreakStatement(fOffset));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return String("break;");
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
@ -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<Expression>(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 {
|
||||
|
@ -24,9 +24,11 @@ struct ContinueStatement : public Statement {
|
||||
return std::unique_ptr<Statement>(new ContinueStatement(fOffset));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return String("continue;");
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
@ -24,9 +24,11 @@ struct DiscardStatement : public Statement {
|
||||
return std::unique_ptr<Statement>(new DiscardStatement(fOffset));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return String("discard;");
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef Statement INHERITED;
|
||||
};
|
||||
|
@ -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<Statement> fStatement;
|
||||
std::unique_ptr<Expression> fTest;
|
||||
|
@ -30,7 +30,7 @@ struct Enum : public ProgramElement {
|
||||
return std::unique_ptr<ProgramElement>(new Enum(fOffset, fTypeName, fSymbols));
|
||||
}
|
||||
|
||||
String description() const override {
|
||||
String code() const {
|
||||
String result = "enum class " + fTypeName + " {\n";
|
||||
String separator;
|
||||
std::vector<const Symbol*> 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<SymbolTable> fSymbols;
|
||||
|
@ -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
|
||||
|
@ -25,9 +25,11 @@ struct ExpressionStatement : public Statement {
|
||||
return std::unique_ptr<Statement>(new ExpressionStatement(fExpression->clone()));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return fExpression->description() + ";";
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<Expression> fExpression;
|
||||
|
||||
|
@ -24,9 +24,11 @@ struct Extension : public ProgramElement {
|
||||
return std::unique_ptr<ProgramElement>(new Extension(fOffset, fName));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return "#extension " + fName + " : enable";
|
||||
}
|
||||
#endif
|
||||
|
||||
const String fName;
|
||||
|
||||
|
@ -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<Expression> 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<std::unique_ptr<Expression>> fArguments;
|
||||
|
@ -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<Expression> clone() const override {
|
||||
return std::unique_ptr<Expression>(new ExternalValueReference(fOffset, fValue));
|
||||
|
@ -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;
|
||||
|
@ -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<Expression> 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<Expression> fBase;
|
||||
const int fFieldIndex;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<Expression> 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<std::unique_ptr<Expression>> fArguments;
|
||||
|
@ -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;
|
||||
|
@ -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<Statement> fBody;
|
||||
|
@ -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<Expression>(new FunctionReference(fOffset, fFunctions, &fType));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return String("<function>");
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::vector<const FunctionDeclaration*> fFunctions;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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<Expression> fTest;
|
||||
|
@ -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<Expression> 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<Expression> fBase;
|
||||
std::unique_ptr<Expression> fIndex;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -27,9 +27,11 @@ struct ModifiersDeclaration : public ProgramElement {
|
||||
return std::unique_ptr<ProgramElement>(new ModifiersDeclaration(fModifiers));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return fModifiers.description() + ";";
|
||||
}
|
||||
#endif
|
||||
|
||||
Modifiers fModifiers;
|
||||
|
||||
|
@ -24,9 +24,11 @@ struct Nop : public Statement {
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return String(";");
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<Statement> clone() const override {
|
||||
return std::unique_ptr<Statement>(new Nop());
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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<Expression> clone() const override {
|
||||
return std::unique_ptr<Expression>(new PostfixExpression(fOperand->clone(), fOperator));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return fOperand->description() + Compiler::OperatorName(fOperator);
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<Expression> fOperand;
|
||||
const Token::Kind fOperator;
|
||||
|
@ -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<Expression> constantPropagate(const IRGenerator& irGenerator,
|
||||
@ -65,9 +68,11 @@ struct PrefixExpression : public Expression {
|
||||
return std::unique_ptr<Expression>(new PrefixExpression(fOperator, fOperand->clone()));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return Compiler::OperatorName(fOperator) + fOperand->description();
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<Expression> fOperand;
|
||||
const Token::Kind fOperator;
|
||||
|
@ -31,6 +31,7 @@ struct ReturnStatement : public Statement {
|
||||
return std::unique_ptr<Statement>(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<Expression> fExpression;
|
||||
|
||||
|
@ -26,6 +26,7 @@ struct Section : public ProgramElement {
|
||||
return std::unique_ptr<ProgramElement>(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;
|
||||
|
@ -32,11 +32,13 @@ struct Setting : public Expression {
|
||||
return std::unique_ptr<Expression>(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;
|
||||
}
|
||||
|
||||
|
@ -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<Expression> fValue;
|
||||
|
@ -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<Expression> fValue;
|
||||
|
@ -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<Expression> clone() const override {
|
||||
return std::unique_ptr<Expression>(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<Expression> fBase;
|
||||
std::vector<int> fComponents;
|
||||
|
@ -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<Expression> 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<Expression> fTest;
|
||||
std::unique_ptr<Expression> fIfTrue;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<Expression> clone() const override {
|
||||
return std::unique_ptr<Expression>(new TypeReference(fOffset, fValue, &fType));
|
||||
|
@ -26,9 +26,11 @@ struct UnresolvedFunction : public Symbol {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return fName;
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::vector<const FunctionDeclaration*> fFunctions;
|
||||
|
||||
|
@ -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<std::unique_ptr<Expression>> 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<VarDeclaration>, but it significantly simplifies the
|
||||
|
@ -35,9 +35,11 @@ struct VarDeclarationsStatement : public Statement {
|
||||
return std::unique_ptr<Statement>(new VarDeclarationsStatement(std::move(cloned)));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return fDeclaration->description() + ";";
|
||||
}
|
||||
#endif
|
||||
|
||||
std::unique_ptr<VarDeclarations> fDeclaration;
|
||||
|
||||
|
@ -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) ||
|
||||
|
@ -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<Expression>(new VariableReference(fOffset, fVariable, fRefKind));
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
String description() const override {
|
||||
return fVariable.fName;
|
||||
}
|
||||
#endif
|
||||
|
||||
static std::unique_ptr<Expression> copy_constant(const IRGenerator& irGenerator,
|
||||
const Expression* expr);
|
||||
|
@ -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<Expression> fTest;
|
||||
std::unique_ptr<Statement> fStatement;
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
|
||||
|
@ -82,6 +82,7 @@ std::vector<int> RegexNode::createStates(NFA* nfa, const std::vector<int>& 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
|
||||
|
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user