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 @@ -202,6 +202,13 @@ /// Defaults to false. bool AllowAtAtStartOfIdentifier = false; + /// This is true if the assembler allows the "#" character at the start of + /// a string to be lexed as an AsmToken::Identifier. + /// If the CommentString is also set to "#", setting this option will have + /// no effect, and the string will be lexed as a comment. + /// Defaults to false. + bool AllowHashAtStartOfIdentifier = false; + /// If this is true, symbol names with invalid characters will be printed in /// quotes. bool SupportsQuotedNames = true; @@ -626,6 +633,9 @@ bool doesAllowDollarAtStartOfIdentifier() const { return AllowDollarAtStartOfIdentifier; } + bool doesAllowHashAtStartOfIdentifier() const { + return AllowHashAtStartOfIdentifier; + } bool supportsNameQuoting() const { return SupportsQuotedNames; } bool doesSupportDataRegionDirectives() const { diff --git a/llvm/lib/MC/MCParser/AsmLexer.cpp b/llvm/lib/MC/MCParser/AsmLexer.cpp --- a/llvm/lib/MC/MCParser/AsmLexer.cpp +++ b/llvm/lib/MC/MCParser/AsmLexer.cpp @@ -907,7 +907,11 @@ case '/': IsAtStartOfStatement = OldIsAtStartOfStatement; return LexSlash(); - case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1)); + case '#': { + if (MAI.doesAllowHashAtStartOfIdentifier()) + return LexIdentifier(); + return AsmToken(AsmToken::Hash, StringRef(TokStart, 1)); + } case '\'': return LexSingleQuote(); case '"': return LexQuote(); case '0': case '1': case '2': case '3': case '4': 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 @@ -24,6 +24,10 @@ CommentString = AssemblerDialect == AD_HLASM ? "*" : "#"; RestrictCommentStringToStartOfStatement = (AssemblerDialect == AD_HLASM); AllowAdditionalComments = (AssemblerDialect == AD_ATT); + AllowAtAtStartOfIdentifier = (AssemblerDialect == AD_HLASM); + AllowDollarAtStartOfIdentifier = (AssemblerDialect == AD_HLASM); + AllowHashAtStartOfIdentifier = (AssemblerDialect == AD_HLASM); + ZeroDirective = "\t.space\t"; Data64bitsDirective = "\t.quad\t"; UsesELFSectionDirectiveForBSS = true; 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 @@ -44,6 +44,9 @@ void setAllowDollarAtStartOfIdentifier(bool Value) { AllowDollarAtStartOfIdentifier = Value; } + void setAllowHashAtStartOfIdentifier(bool Value) { + AllowHashAtStartOfIdentifier = Value; + } }; // Setup a testing class that the GTest framework can call. @@ -571,4 +574,22 @@ {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); lexAndCheckTokens(AsmStr, ExpectedTokens); } + +TEST_F(SystemZAsmLexerTest, CheckAcceptHashAtStartOfIdentifier) { + StringRef AsmStr = "##a#b$c"; + + // Setup. + MUPMAI->setAllowHashAtStartOfIdentifier(true); + MUPMAI->setCommentString("*"); + MUPMAI->setAllowAdditionalComments(false); + setupCallToAsmParser(AsmStr); + Parser->getLexer().setAllowHashInIdentifier(true); + + // Lex initially to get the string. + Parser->getLexer().Lex(); + + SmallVector ExpectedTokens( + {AsmToken::Identifier, AsmToken::EndOfStatement, AsmToken::Eof}); + lexAndCheckTokens(AsmStr, ExpectedTokens); +} } // end anonymous namespace