From d20cda028a11e50d94f8279a2a968a27d8483d55 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 16 Oct 2009 01:34:54 +0000 Subject: [PATCH] MC: When parsing a variable reference, substitute absolute variables immediately since they are allowed to be redefined. llvm-svn: 84230 --- llvm/lib/MC/MCAsmStreamer.cpp | 5 ++++- llvm/test/MC/AsmParser/labels.s | 18 +++++++++--------- llvm/test/MC/AsmParser/variables.s | 15 +++++++++++++++ llvm/tools/llvm-mc/AsmParser.cpp | 19 +++++++++++++++---- 4 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 llvm/test/MC/AsmParser/variables.s diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index e56e968380f4..1a6e8b6c8e1c 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -123,9 +123,12 @@ void MCAsmStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { OS << " = "; Value->print(OS, &MAI); OS << '\n'; + + // FIXME: Lift context changes into super class. + Symbol->setValue(Value); } -void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, +void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, SymbolAttr Attribute) { switch (Attribute) { case Global: OS << ".globl"; break; diff --git a/llvm/test/MC/AsmParser/labels.s b/llvm/test/MC/AsmParser/labels.s index 53da7edf97cb..456d61f06044 100644 --- a/llvm/test/MC/AsmParser/labels.s +++ b/llvm/test/MC/AsmParser/labels.s @@ -12,21 +12,21 @@ a: .long 0 .text -foo: +foo: // CHECK: addl $24, a$b(%eax) - addl $24, "a$b"(%eax) + addl $24, "a$b"(%eax) // CHECK: addl $24, a$b+10(%eax) addl $24, ("a$b" + 10)(%eax) - + // CHECK: b$c = 10 "b$c" = 10 -// CHECK: addl $b$c, %eax +// CHECK: addl $10, %eax addl "b$c", %eax - + // CHECK: "a 0" = 11 .set "a 0", 11 - -// CHECK: .long "a 0" + +// CHECK: .long 11 .long "a 0" // XXCHCK: .section "a 1,a 2" @@ -48,12 +48,12 @@ foo: .lcomm "a 7", 1 // FIXME: We don't bother to support .lsym. - + // CHECX: .lsym "a 8",1 // .lsym "a 8", 1 // CHECK: "a 9" = a-b .set "a 9", a - b - + // CHECK: .long "a 9" .long "a 9" diff --git a/llvm/test/MC/AsmParser/variables.s b/llvm/test/MC/AsmParser/variables.s new file mode 100644 index 000000000000..86fea276a732 --- /dev/null +++ b/llvm/test/MC/AsmParser/variables.s @@ -0,0 +1,15 @@ +// RUN: llvm-mc %s + + .data + t0_v0 = 1 + t0_v1 = t0_v0 + .if t0_v1 != 1 + .abort "invalid value" + .endif + + t1_v0 = 1 + t1_v1 = t0_v0 + t1_v0 = 2 + .if t0_v1 != 1 + .abort "invalid value" + .endif diff --git a/llvm/tools/llvm-mc/AsmParser.cpp b/llvm/tools/llvm-mc/AsmParser.cpp index aae27f5d7649..7174fa8ee8e5 100644 --- a/llvm/tools/llvm-mc/AsmParser.cpp +++ b/llvm/tools/llvm-mc/AsmParser.cpp @@ -21,6 +21,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCValue.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetAsmParser.h" @@ -220,12 +221,22 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res) { Res = MCUnaryExpr::CreateLNot(Res, getContext()); return false; case AsmToken::String: - case AsmToken::Identifier: - // This is a label, this should be parsed as part of an expression, to - // handle things like LFOO+4. - Res = MCSymbolRefExpr::Create(Lexer.getTok().getIdentifier(), getContext()); + case AsmToken::Identifier: { + // This is a symbol reference. + MCSymbol *Sym = CreateSymbol(Lexer.getTok().getIdentifier()); Lexer.Lex(); // Eat identifier. + + // If this is an absolute variable reference, substitute it now to preserve + // semantics in the face of reassignment. + if (Sym->getValue() && isa(Sym->getValue())) { + Res = Sym->getValue(); + return false; + } + + // Otherwise create a symbol ref. + Res = MCSymbolRefExpr::Create(Sym, getContext()); return false; + } case AsmToken::Integer: Res = MCConstantExpr::Create(Lexer.getTok().getIntVal(), getContext()); Lexer.Lex(); // Eat token.