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 @@ -1547,8 +1547,14 @@ } MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName); - if (!Sym) + if (!Sym) { + // Variables use case-insensitive symbol names; if this is a variable, we + // find the symbol using its canonical name. + auto VarIt = Variables.find(SymbolName.lower()); + if (VarIt != Variables.end()) + SymbolName = VarIt->second.Name; Sym = getContext().getOrCreateSymbol(SymbolName); + } // If this is an absolute variable reference, substitute it now to preserve // semantics in the face of reassignment. @@ -3268,7 +3274,7 @@ /// | name "textequ" text-list bool MasmParser::parseDirectiveEquate(StringRef IDVal, StringRef Name, DirectiveKind DirKind) { - Variable &Var = Variables[Name]; + Variable &Var = Variables[Name.lower()]; if (Var.Name.empty()) { Var.Name = Name; } else if (!Var.Redefinable) { @@ -3276,6 +3282,7 @@ } Var.Redefinable = (DirKind != DK_EQU); + SMLoc StartLoc = Lexer.getLoc(); if (DirKind == DK_EQU || DirKind == DK_TEXTEQU) { // "equ" and "textequ" both allow text expressions. std::string Value; @@ -3301,7 +3308,7 @@ // Parse as expression assignment. const MCExpr *Expr; - SMLoc EndLoc, StartLoc = Lexer.getLoc(); + SMLoc EndLoc; if (parseExpression(Expr, EndLoc)) return addErrorSuffix(" in '" + Twine(IDVal) + "' directive"); MCSymbol *Sym = getContext().getOrCreateSymbol(Var.Name); @@ -3378,21 +3385,30 @@ case AsmToken::LessGreater: return parseAngleBracketString(Data); case AsmToken::Identifier: { + // This must be a text macro; we need to expand it accordingly. StringRef ID; if (parseIdentifier(ID)) return true; Data = ID.str(); - auto it = Variables.find(ID); - if (it == Variables.end()) + auto it = Variables.find(ID.lower()); + if (it == Variables.end()) { + // Not a variable; since we haven't used the token, put it back for better + // error recovery. + getLexer().UnLex(AsmToken(AsmToken::Identifier, ID)); return true; + } while (it != Variables.end()) { const Variable &Var = it->second; - if (!Var.IsText) + if (!Var.IsText) { + // Not a text macro; not usable in TextItem context. Since we haven't + // used the token, put it back for better error recovery. + getLexer().UnLex(AsmToken(AsmToken::Identifier, ID)); return true; + } Data = Var.TextValue; - it = Variables.find(Data); + it = Variables.find(StringRef(Data).lower()); } return false; } @@ -5946,10 +5962,10 @@ parseToken(AsmToken::EndOfStatement, "unexpected token in 'ifdef'")) return true; - if (Variables.find(Name) != Variables.end()) { + if (Variables.find(Name.lower()) != Variables.end()) { is_defined = true; } else { - MCSymbol *Sym = getContext().lookupSymbol(Name); + MCSymbol *Sym = getContext().lookupSymbol(Name.lower()); is_defined = (Sym && !Sym->isUndefined(false)); } } @@ -6068,7 +6084,7 @@ "unexpected token in 'elseifdef'")) return true; - if (Variables.find(Name) != Variables.end()) { + if (Variables.find(Name.lower()) != Variables.end()) { is_defined = true; } else { MCSymbol *Sym = getContext().lookupSymbol(Name); @@ -6238,7 +6254,7 @@ if (check(parseIdentifier(Name), "expected identifier after '.errdef'")) return true; - if (Variables.find(Name) != Variables.end()) { + if (Variables.find(Name.lower()) != Variables.end()) { IsDefined = true; } else { MCSymbol *Sym = getContext().lookupSymbol(Name); diff --git a/llvm/test/tools/llvm-ml/variable.asm b/llvm/test/tools/llvm-ml/variable.asm --- a/llvm/test/tools/llvm-ml/variable.asm +++ b/llvm/test/tools/llvm-ml/variable.asm @@ -3,11 +3,21 @@ .data t1_value equ 1 or 2 -t1 BYTE t1_value DUP (0) -; CHECK: t1: +t1 BYTE t1_VALUE DUP (0) +; CHECK-LABEL: t1: ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .byte 0 ; CHECK-NOT: .byte 0 +t2_value equ 4 or t1_value +t2 BYTE t2_VALUE +; CHECK-LABEL: t2: +; CHECK-NEXT: .byte 7 + +t3_value equ t1_VALUE or 8 +t3 BYTE t3_VALUE +; CHECK-LABEL: t3: +; CHECK-NEXT: .byte 11 + END