summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2011-01-28 03:04:41 +0000
committerNico Weber <nicolasweber@gmx.de>2011-01-28 03:04:41 +0000
commit4c4c7329603491838d9c089dfbce19915c1431ea (patch)
tree9b015136a2267066fce30fdf94492a5df156de58
parent40f64cb0de40802ddd2f928b62e9564e1e721ff3 (diff)
downloadllvm-4c4c7329603491838d9c089dfbce19915c1431ea.tar.gz
llvm-4c4c7329603491838d9c089dfbce19915c1431ea.tar.bz2
llvm-4c4c7329603491838d9c089dfbce19915c1431ea.tar.xz
PR8951: Support for .equiv in integrated assembler, patch by Jörg Sonnenberger!
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124467 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/MC/MCParser/AsmParser.cpp20
-rw-r--r--test/MC/AsmParser/equ.s9
2 files changed, 21 insertions, 8 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 9cb15b496f..17fe1437ce 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -168,7 +168,7 @@ private:
/// will be either the EndOfStatement or EOF.
StringRef ParseStringToEndOfStatement();
- bool ParseAssignment(StringRef Name);
+ bool ParseAssignment(StringRef Name, bool allow_redef);
bool ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc);
bool ParseBinOpRHS(unsigned Precedence, const MCExpr *&Res, SMLoc &EndLoc);
@@ -187,7 +187,7 @@ private:
bool ParseDirectiveFill(); // ".fill"
bool ParseDirectiveSpace(); // ".space"
bool ParseDirectiveZero(); // ".zero"
- bool ParseDirectiveSet(StringRef IDVal); // ".set" or ".equ"
+ bool ParseDirectiveSet(StringRef IDVal, bool allow_redef); // ".set", ".equ", ".equiv"
bool ParseDirectiveOrg(); // ".org"
// ".align{,32}", ".p2align{,w,l}"
bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
@@ -941,7 +941,7 @@ bool AsmParser::ParseStatement() {
// identifier '=' ... -> assignment statement
Lex();
- return ParseAssignment(IDVal);
+ return ParseAssignment(IDVal, true);
default: // Normal instruction or directive.
break;
@@ -956,7 +956,9 @@ bool AsmParser::ParseStatement() {
if (IDVal[0] == '.') {
// Assembler features
if (IDVal == ".set" || IDVal == ".equ")
- return ParseDirectiveSet(IDVal);
+ return ParseDirectiveSet(IDVal, true);
+ if (IDVal == ".equiv")
+ return ParseDirectiveSet(IDVal, false);
// Data directives
@@ -1263,7 +1265,7 @@ static void MarkUsed(const MCExpr *Value) {
}
}
-bool AsmParser::ParseAssignment(StringRef Name) {
+bool AsmParser::ParseAssignment(StringRef Name, bool allow_redef) {
// FIXME: Use better location, we should use proper tokens.
SMLoc EqualLoc = Lexer.getLoc();
@@ -1289,7 +1291,7 @@ bool AsmParser::ParseAssignment(StringRef Name) {
// FIXME: Diagnose assignment to protected identifier (e.g., register name).
if (Sym->isUndefined() && !Sym->isUsed() && !Sym->isVariable())
; // Allow redefinitions of undefined symbols only used in directives.
- else if (!Sym->isUndefined() && !Sym->isAbsolute())
+ else if (!Sym->isUndefined() && (!Sym->isAbsolute() || !allow_redef))
return Error(EqualLoc, "redefinition of '" + Name + "'");
else if (!Sym->isVariable())
return Error(EqualLoc, "invalid assignment to '" + Name + "'");
@@ -1350,8 +1352,10 @@ bool AsmParser::ParseIdentifier(StringRef &Res) {
}
/// ParseDirectiveSet:
+/// ::= .equ identifier ',' expression
+/// ::= .equiv identifier ',' expression
/// ::= .set identifier ',' expression
-bool AsmParser::ParseDirectiveSet(StringRef IDVal) {
+bool AsmParser::ParseDirectiveSet(StringRef IDVal, bool allow_redef) {
StringRef Name;
if (ParseIdentifier(Name))
@@ -1361,7 +1365,7 @@ bool AsmParser::ParseDirectiveSet(StringRef IDVal) {
return TokError("unexpected token in '" + Twine(IDVal) + "'");
Lex();
- return ParseAssignment(Name);
+ return ParseAssignment(Name, allow_redef);
}
bool AsmParser::ParseEscapedString(std::string &Data) {
diff --git a/test/MC/AsmParser/equ.s b/test/MC/AsmParser/equ.s
new file mode 100644
index 0000000000..568f58fa12
--- /dev/null
+++ b/test/MC/AsmParser/equ.s
@@ -0,0 +1,9 @@
+// RUN: not llvm-mc -n -triple i386-unknown-unknown %s 2> %t
+// RUN: FileCheck < %t %s
+
+.equ a, 0
+.set a, 1
+.equ a, 2
+.equiv a, 3
+// CHECK: error: redefinition of 'a'
+