}
}
-void MCExpr::print(raw_ostream &OS) const {
+void MCExpr::print(raw_ostream &OS, const MCAsmInfo *MAI) const {
switch (getKind()) {
case MCExpr::Target:
- return cast<MCTargetExpr>(this)->printImpl(OS);
+ return cast<MCTargetExpr>(this)->printImpl(OS, MAI);
case MCExpr::Constant:
OS << cast<MCConstantExpr>(*this).getValue();
return;
const MCSymbol &Sym = SRE.getSymbol();
// Parenthesize names that start with $ so that they don't look like
// absolute names.
- bool UseParens = !Sym.getName().empty() && Sym.getName()[0] == '$';
- if (UseParens)
- OS << '(' << Sym << ')';
- else
- OS << Sym;
+ bool UseParens = Sym.getName()[0] == '$';
+ if (UseParens) {
+ OS << '(';
+ Sym.print(OS, MAI);
+ OS << ')';
+ } else
+ Sym.print(OS, MAI);
if (SRE.getKind() != MCSymbolRefExpr::VK_None)
SRE.printVariantKind(OS);
case MCUnaryExpr::Not: OS << '~'; break;
case MCUnaryExpr::Plus: OS << '+'; break;
}
- OS << *UE.getSubExpr();
+ UE.getSubExpr()->print(OS, MAI);
return;
}
// Only print parens around the LHS if it is non-trivial.
if (isa<MCConstantExpr>(BE.getLHS()) || isa<MCSymbolRefExpr>(BE.getLHS())) {
- OS << *BE.getLHS();
+ BE.getLHS()->print(OS, MAI);
} else {
- OS << '(' << *BE.getLHS() << ')';
+ OS << '(';
+ BE.getLHS()->print(OS, MAI);
+ OS << ')';
}
switch (BE.getOpcode()) {
// Only print parens around the LHS if it is non-trivial.
if (isa<MCConstantExpr>(BE.getRHS()) || isa<MCSymbolRefExpr>(BE.getRHS())) {
- OS << *BE.getRHS();
+ BE.getRHS()->print(OS, MAI);
} else {
- OS << '(' << *BE.getRHS() << ')';
+ OS << '(';
+ BE.getRHS()->print(OS, MAI);
+ OS << ')';
}
return;
}
if (SA.isUndefined() || SB.isUndefined())
return;
- if (!Asm->getWriter().IsSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
+ if (!Asm->getWriter().isSymbolRefDifferenceFullyResolved(*Asm, A, B, InSet))
return;
if (SA.getFragment() == SB.getFragment()) {
case MCBinaryExpr::AShr: Result = LHS >> RHS; break;
case MCBinaryExpr::Add: Result = LHS + RHS; break;
case MCBinaryExpr::And: Result = LHS & RHS; break;
- case MCBinaryExpr::Div: Result = LHS / RHS; break;
+ case MCBinaryExpr::Div:
+ // Handle division by zero. gas just emits a warning and keeps going,
+ // we try to be stricter.
+ // FIXME: Currently the caller of this function has no way to understand
+ // we're bailing out because of 'division by zero'. Therefore, it will
+ // emit a 'expected relocatable expression' error. It would be nice to
+ // change this code to emit a better diagnostic.
+ if (RHS == 0)
+ return false;
+ Result = LHS / RHS;
+ break;
case MCBinaryExpr::EQ: Result = LHS == RHS; break;
case MCBinaryExpr::GT: Result = LHS > RHS; break;
case MCBinaryExpr::GTE: Result = LHS >= RHS; break;
case MCBinaryExpr::Mul: Result = LHS * RHS; break;
case MCBinaryExpr::NE: Result = LHS != RHS; break;
case MCBinaryExpr::Or: Result = LHS | RHS; break;
- case MCBinaryExpr::Shl: Result = LHS << RHS; break;
+ case MCBinaryExpr::Shl: Result = uint64_t(LHS) << uint64_t(RHS); break;
case MCBinaryExpr::Sub: Result = LHS - RHS; break;
case MCBinaryExpr::Xor: Result = LHS ^ RHS; break;
}