diff --git a/llvm/lib/MC/MCParser/MasmParser.cpp b/llvm/lib/MC/MCParser/MasmParser.cpp --- a/llvm/lib/MC/MCParser/MasmParser.cpp +++ b/llvm/lib/MC/MCParser/MasmParser.cpp @@ -383,8 +383,10 @@ /// maps assembly-time variable names to variables. struct Variable { + enum RedefinableKind { NOT_REDEFINABLE, WARN_ON_REDEFINITION, REDEFINABLE }; + StringRef Name; - bool Redefinable = true; + RedefinableKind Redefinable = REDEFINABLE; bool IsText = false; int64_t NumericValue = 0; std::string TextValue; @@ -865,7 +867,7 @@ // "=", "equ", "textequ" bool parseDirectiveEquate(StringRef IDVal, StringRef Name, - DirectiveKind DirKind); + DirectiveKind DirKind, SMLoc NameLoc); bool parseDirectiveOrg(); // ".org" bool parseDirectiveAlign(); // "align" @@ -2479,7 +2481,7 @@ case DK_EQU: case DK_TEXTEQU: Lex(); - return parseDirectiveEquate(nextVal, IDVal, DirKind); + return parseDirectiveEquate(nextVal, IDVal, DirKind, IDLoc); case DK_BYTE: case DK_SBYTE: case DK_DB: @@ -3271,14 +3273,20 @@ /// | name "equ" text-list /// | name "textequ" text-list bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name, - DirectiveKind DirKind) { + DirectiveKind DirKind, SMLoc NameLoc) { Variable &Var = Variables[Name.lower()]; if (Var.Name.empty()) { Var.Name = Name; - } else if (!Var.Redefinable) { + } else if (Var.Redefinable == Variable::NOT_REDEFINABLE) { return TokError("invalid variable redefinition"); + } else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION && + Warning(NameLoc, "redefining '" + Name + + "', already defined on the command line")) { + return true; } - Var.Redefinable = (DirKind != DK_EQU); + + if (DirKind == DK_EQU) + Var.Redefinable = Variable::NOT_REDEFINABLE; SMLoc StartLoc = Lexer.getLoc(); if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) { @@ -3310,7 +3318,7 @@ if (parseExpression(Expr, EndLoc)) return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name); - Sym->setRedefinable(Var.Redefinable); + Sym->setRedefinable(Var.Redefinable != Variable::NOT_REDEFINABLE); Sym->setVariableValue(Expr); Sym->setExternal(false); @@ -6925,10 +6933,14 @@ Variable &Var = Variables[Name.lower()]; if (Var.Name.empty()) { Var.Name = Name; - } else if (!Var.Redefinable) { - return TokError("invalid variable redefinition"); + } else if (Var.Redefinable == Variable::NOT_REDEFINABLE) { + return Error(SMLoc(), "invalid variable redefinition"); + } else if (Var.Redefinable == Variable::WARN_ON_REDEFINITION && + Warning(SMLoc(), "redefining '" + Name + + "', already defined on the command line")) { + return true; } - Var.Redefinable = true; + Var.Redefinable = Variable::WARN_ON_REDEFINITION; Var.IsText = true; Var.TextValue = Value.str(); return false; diff --git a/llvm/test/tools/llvm-ml/command_line_defines.asm b/llvm/test/tools/llvm-ml/command_line_defines.asm --- a/llvm/test/tools/llvm-ml/command_line_defines.asm +++ b/llvm/test/tools/llvm-ml/command_line_defines.asm @@ -1,4 +1,4 @@ -; RUN: llvm-ml -filetype=s %s /Fo - /DT1=test1 /D T2=test2 | FileCheck %s +; RUN: llvm-ml -filetype=s %s /Fo - /DT1=test1 /D T2=test2 /Dtest5=def | FileCheck %s .code @@ -35,4 +35,7 @@ ; CHECK: xor ebx, ebx ; CHECK: ret +t5: +test5 textequ + end