llvm-mc: Support reassignment of variables in one special case, when the
[oota-llvm.git] / lib / MC / MCParser / AsmParser.cpp
index e5af357de34d37ea0bec6e6f0b1f968354e2511e..0df839b84d9bf6d020e03f606858e37a54cd1dfc 100644 (file)
@@ -189,6 +189,9 @@ bool AsmParser::ParsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
     std::pair<StringRef, StringRef> Split = getTok().getIdentifier().split('@');
     MCSymbol *Sym = CreateSymbol(Split.first);
 
+    // Mark the symbol as used in an expression.
+    Sym->setUsedInExpr(true);
+
     // Lookup the symbol variant if used.
     MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None;
     if (Split.first.size() != getTok().getIdentifier().size())
@@ -788,7 +791,9 @@ bool AsmParser::ParseAssignment(const StringRef &Name) {
     //
     // FIXME: Diagnostics. Note the location of the definition as a label.
     // FIXME: Diagnose assignment to protected identifier (e.g., register name).
-    if (!Sym->isUndefined() && !Sym->isAbsolute())
+    if (Sym->isUndefined() && !Sym->isUsedInExpr())
+      ; // Allow redefinitions of undefined symbols only used in directives.
+    else if (!Sym->isUndefined() && !Sym->isAbsolute())
       return Error(EqualLoc, "redefinition of '" + Name + "'");
     else if (!Sym->isVariable())
       return Error(EqualLoc, "invalid assignment to '" + Name + "'");
@@ -800,6 +805,8 @@ bool AsmParser::ParseAssignment(const StringRef &Name) {
 
   // FIXME: Handle '.'.
 
+  Sym->setUsedInExpr(true);
+
   // Do the assignment.
   Out.EmitAssignment(Sym, Value);