diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -153,6 +153,9 @@ /// This is appended to emitted labels. Defaults to ":" const char *LabelSuffix; + /// Emit labels in purely upper case. Defaults to false. + bool EmitLabelsInUpperCase = false; + // Print the EH begin symbol with an assignment. Defaults to false. bool UseAssignmentForEHBegin = false; @@ -637,6 +640,7 @@ return EmitGNUAsmStartIndentationMarker; } const char *getLabelSuffix() const { return LabelSuffix; } + bool shouldEmitLabelsInUpperCase() const { return EmitLabelsInUpperCase; } bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; } bool needsLocalForSize() const { return NeedsLocalForSize; } diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -1231,7 +1231,8 @@ MCSymbol *Sym = getContext().getInlineAsmLabel(SymbolName); if (!Sym) - Sym = getContext().getOrCreateSymbol(SymbolName); + Sym = getContext().getOrCreateSymbol( + MAI.shouldEmitLabelsInUpperCase() ? SymbolName.upper() : SymbolName); // If this is an absolute variable reference, substitute it now to preserve // semantics in the face of reassignment. @@ -6212,8 +6213,10 @@ return Error(LabelLoc, "Cannot have just a label for an HLASM inline asm statement"); - // FIXME: Later on, ensure emitted labels are case-insensitive. - MCSymbol *Sym = getContext().getOrCreateSymbol(LabelVal); + MCSymbol *Sym = getContext().getOrCreateSymbol( + getContext().getAsmInfo()->shouldEmitLabelsInUpperCase() + ? LabelVal.upper() + : LabelVal); getTargetParser().doBeforeLabelEmit(Sym); diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp --- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp +++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp @@ -31,6 +31,7 @@ StarIsPC = (AssemblerDialect == AD_HLASM); EmitGNUAsmStartIndentationMarker = (AssemblerDialect == AD_ATT); AllowAtInName = (AssemblerDialect == AD_HLASM); + EmitLabelsInUpperCase = (AssemblerDialect == AD_HLASM); ZeroDirective = "\t.space\t"; Data64bitsDirective = "\t.quad\t"; diff --git a/llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp b/llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp --- a/llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp +++ b/llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp @@ -49,6 +49,7 @@ } void setAllowDotIsPC(bool Value) { DotIsPC = Value; } void setAssemblerDialect(unsigned Value) { AssemblerDialect = Value; } + void setEmitLabelsInUpperCase(bool Value) { EmitLabelsInUpperCase = Value; } }; // Setup a testing class that the GTest framework can call. @@ -750,4 +751,36 @@ AsmStr += "#"; EXPECT_EQ(true, MUPMAI->isValidUnquotedName(AsmStr)); } + +TEST_F(SystemZAsmLexerTest, CheckLabelCaseUpperCase2) { + StringRef AsmStr = "label\nlabel"; + + // Setup. + setupCallToAsmParser(AsmStr); + + // Lex initially to get the string. + Parser->getLexer().Lex(); + + const MCExpr *Expr; + bool ParsePrimaryExpr = Parser->parseExpression(Expr); + EXPECT_EQ(ParsePrimaryExpr, false); + + const MCSymbolRefExpr *SymbolExpr = dyn_cast(Expr); + EXPECT_NE(SymbolExpr, nullptr); + EXPECT_NE(&SymbolExpr->getSymbol(), nullptr); + EXPECT_EQ((&SymbolExpr->getSymbol())->getName(), StringRef("label")); + + // Lex the end of statement token. + Parser->getLexer().Lex(); + + MUPMAI->setEmitLabelsInUpperCase(true); + + ParsePrimaryExpr = Parser->parseExpression(Expr); + EXPECT_EQ(ParsePrimaryExpr, false); + + SymbolExpr = dyn_cast(Expr); + EXPECT_NE(SymbolExpr, nullptr); + EXPECT_NE(&SymbolExpr->getSymbol(), nullptr); + EXPECT_EQ((&SymbolExpr->getSymbol())->getName(), StringRef("LABEL")); +} } // end anonymous namespace