diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-emit-c-like.cpp | 37 | ||||
| -rw-r--r-- | source/slang/slang-emit-glsl.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit-metal.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-emit-precedence.h | 2 |
4 files changed, 36 insertions, 7 deletions
diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index 25dff6083..bd3337769 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -639,6 +639,35 @@ bool CLikeSourceEmitter::maybeEmitParens(EmitOpInfo& outerPrec, const EmitOpInfo bool needParens = (prec.leftPrecedence <= outerPrec.leftPrecedence) || (prec.rightPrecedence <= outerPrec.rightPrecedence); + // While Slang correctly removes some of parentheses, DXC prints warnings + // for common mistakes when parentheses are not used with certain combinations + // of the operations. We emit parentheses to avoid the warnings. + // + // a | b & c => a | (b & c) + if (prec.leftPrecedence == EPrecedence::kEPrecedence_BitAnd_Left + && outerPrec.leftPrecedence == EPrecedence::kEPrecedence_BitOr_Right) + { + needParens = true; + } + // a & b | c => (a & b) | c + else if (prec.rightPrecedence == EPrecedence::kEPrecedence_BitAnd_Right + && outerPrec.rightPrecedence == EPrecedence::kEPrecedence_BitOr_Left) + { + needParens = true; + } + // a << b + c => a << (b + c) + else if (prec.leftPrecedence == EPrecedence::kEPrecedence_Additive_Left + && outerPrec.leftPrecedence == EPrecedence::kEPrecedence_Shift_Right) + { + needParens = true; + } + // a + b << c => (a + b) << c + else if (prec.rightPrecedence == EPrecedence::kEPrecedence_Additive_Right + && outerPrec.rightPrecedence == EPrecedence::kEPrecedence_Shift_Left) + { + needParens = true; + } + if (needParens) { m_writer->emit("("); @@ -2305,7 +2334,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO } } - emitOperand(operand, rightSide(prec, outerPrec)); + emitOperand(operand, rightSide(outerPrec, prec)); break; } case kIROp_Load: @@ -2455,7 +2484,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO needClose = maybeEmitParens(outerPrec, prec); emitOperand(inst->getOperand(0), leftSide(outerPrec, prec)); m_writer->emit(" + "); - emitOperand(inst->getOperand(1), rightSide(prec, outerPrec)); + emitOperand(inst->getOperand(1), rightSide(outerPrec, prec)); break; } case kIROp_GetElement: @@ -2472,7 +2501,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO m_writer->emit("["); emitOperand(inst->getOperand(1), getInfo(EmitOp::General)); m_writer->emit("]."); - emitOperand(inst->getOperand(0), rightSide(prec, outerPrec)); + emitOperand(inst->getOperand(0), rightSide(outerPrec, prec)); break; } else @@ -2558,7 +2587,7 @@ void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, const EmitOpInfo& inO m_writer->emit(" ? "); emitOperand(inst->getOperand(1), prec); m_writer->emit(" : "); - emitOperand(inst->getOperand(2), rightSide(prec, outerPrec)); + emitOperand(inst->getOperand(2), rightSide(outerPrec, prec)); } break; diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 293bcb891..32301c418 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -2064,7 +2064,7 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu } m_writer->emit(" = "); - emitOperand(inst->getOperand(2), rightSide(assignPrec, outerPrec)); + emitOperand(inst->getOperand(2), rightSide(outerPrec, assignPrec)); maybeCloseParens(assignNeedsClose); return true; } diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp index 17d074e75..bf4a67b09 100644 --- a/source/slang/slang-emit-metal.cpp +++ b/source/slang/slang-emit-metal.cpp @@ -283,7 +283,7 @@ bool MetalSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inO needClose = maybeEmitParens(outerPrec, prec); emitOperand(inst->getOperand(0), leftSide(outerPrec, prec)); m_writer->emit("+"); - emitOperand(inst->getOperand(1), rightSide(prec, outerPrec)); + emitOperand(inst->getOperand(1), rightSide(outerPrec, prec)); maybeCloseParens(needClose); return true; } diff --git a/source/slang/slang-emit-precedence.h b/source/slang/slang-emit-precedence.h index 1c8081079..f23287bcb 100644 --- a/source/slang/slang-emit-precedence.h +++ b/source/slang/slang-emit-precedence.h @@ -143,7 +143,7 @@ SLANG_INLINE EmitOpInfo leftSide(EmitOpInfo const& outerPrec, EmitOpInfo const& return result; } -SLANG_INLINE EmitOpInfo rightSide(EmitOpInfo const& prec, EmitOpInfo const& outerPrec) +SLANG_INLINE EmitOpInfo rightSide(EmitOpInfo const& outerPrec, EmitOpInfo const& prec) { EmitOpInfo result; result.op = nullptr; |
