summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-emit-c-like.cpp37
-rw-r--r--source/slang/slang-emit-glsl.cpp2
-rw-r--r--source/slang/slang-emit-metal.cpp2
-rw-r--r--source/slang/slang-emit-precedence.h2
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;