aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCExpr.cpp')
-rw-r--r--lib/MC/MCExpr.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/lib/MC/MCExpr.cpp b/lib/MC/MCExpr.cpp
index 312621509f..3a674d75ed 100644
--- a/lib/MC/MCExpr.cpp
+++ b/lib/MC/MCExpr.cpp
@@ -559,3 +559,45 @@ bool MCExpr::EvaluateAsRelocatableImpl(MCValue &Res,
assert(0 && "Invalid assembly expression kind!");
return false;
}
+
+const MCSection *MCExpr::FindAssociatedSection() const {
+ switch (getKind()) {
+ case Target:
+ // We never look through target specific expressions.
+ return cast<MCTargetExpr>(this)->FindAssociatedSection();
+
+ case Constant:
+ return MCSymbol::AbsolutePseudoSection;
+
+ case SymbolRef: {
+ const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this);
+ const MCSymbol &Sym = SRE->getSymbol();
+
+ if (Sym.isDefined())
+ return &Sym.getSection();
+
+ return 0;
+ }
+
+ case Unary:
+ return cast<MCUnaryExpr>(this)->getSubExpr()->FindAssociatedSection();
+
+ case Binary: {
+ const MCBinaryExpr *BE = cast<MCBinaryExpr>(this);
+ const MCSection *LHS_S = BE->getLHS()->FindAssociatedSection();
+ const MCSection *RHS_S = BE->getRHS()->FindAssociatedSection();
+
+ // If either section is absolute, return the other.
+ if (LHS_S == MCSymbol::AbsolutePseudoSection)
+ return RHS_S;
+ if (RHS_S == MCSymbol::AbsolutePseudoSection)
+ return LHS_S;
+
+ // Otherwise, return the first non-null section.
+ return LHS_S ? LHS_S : RHS_S;
+ }
+ }
+
+ assert(0 && "Invalid assembly expression kind!");
+ return 0;
+}