Skip to content

Commit b605cfb

Browse files
committed
[AsmParser][SystemZ][z/OS] Reland "Introduce HLASM Comment Syntax"
- Previously, https://reviews.llvm.org/D97703 was [[ https://reviews.llvm.org/D98543 | reverted ]] as it broke when building the unit tests when shared libs on. - This patch reverts the "revert" and makes two minor changes - The first is it also links in the MCParser lib when building the unittest. This should resolve the issue when building with with shared libs on and off - The second renames the name of the unit test from `SystemZAsmLexer` to `SystemZAsmLexerTests` since the convention for unittest binaries is to suffix the name of the unit test with "Tests" Reviewed By: Kai Differential Revision: https://reviews.llvm.org/D98666
1 parent d5df500 commit b605cfb

File tree

5 files changed

+190
-2
lines changed

5 files changed

+190
-2
lines changed

llvm/include/llvm/MC/MCAsmInfo.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,14 @@ class MCAsmInfo {
122122
/// other when on the same line. Defaults to ';'
123123
const char *SeparatorString;
124124

125-
/// This indicates the comment character used by the assembler. Defaults to
125+
/// This indicates the comment string used by the assembler. Defaults to
126126
/// "#"
127127
StringRef CommentString;
128128

129+
/// This indicates whether the comment string is only accepted as a comment
130+
/// at the beginning of statements. Defaults to false.
131+
bool RestrictCommentStringToStartOfStatement = false;
132+
129133
/// This is appended to emitted labels. Defaults to ":"
130134
const char *LabelSuffix;
131135

@@ -557,6 +561,9 @@ class MCAsmInfo {
557561
unsigned getCommentColumn() const { return 40; }
558562

559563
StringRef getCommentString() const { return CommentString; }
564+
bool getRestrictCommentStringToStartOfStatement() const {
565+
return RestrictCommentStringToStartOfStatement;
566+
}
560567
const char *getLabelSuffix() const { return LabelSuffix; }
561568

562569
bool useAssignmentForEHBegin() const { return UseAssignmentForEHBegin; }

llvm/lib/MC/MCParser/AsmLexer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,9 @@ size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
659659
}
660660

661661
bool AsmLexer::isAtStartOfComment(const char *Ptr) {
662+
if (MAI.getRestrictCommentStringToStartOfStatement() && !IsAtStartOfStatement)
663+
return false;
664+
662665
StringRef CommentString = MAI.getCommentString();
663666

664667
if (CommentString.size() == 1)

llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmInfo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ SystemZMCAsmInfo::SystemZMCAsmInfo(const Triple &TT) {
2121

2222
MaxInstLength = 6;
2323

24-
CommentString = "#";
24+
CommentString = AssemblerDialect == AD_HLASM ? "*" : "#";
25+
RestrictCommentStringToStartOfStatement = (AssemblerDialect == AD_HLASM);
2526
ZeroDirective = "\t.space\t";
2627
Data64bitsDirective = "\t.quad\t";
2728
UsesELFSectionDirectiveForBSS = true;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
include_directories(
2+
${LLVM_MAIN_SRC_DIR}/lib/Target/SystemZ
3+
)
4+
5+
set(LLVM_LINK_COMPONENTS
6+
SystemZ
7+
MCParser
8+
MC
9+
Support
10+
)
11+
12+
add_llvm_unittest(SystemZAsmLexerTests
13+
SystemZAsmLexerTest.cpp
14+
)
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
//===- llvm/unittests/MC/SystemZ/SystemZAsmLexerTest.cpp ----------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===--------------------------------------------------------------------===//
8+
#include "llvm/MC/MCAsmInfo.h"
9+
#include "llvm/MC/MCContext.h"
10+
#include "llvm/MC/MCObjectFileInfo.h"
11+
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
12+
#include "llvm/MC/MCRegisterInfo.h"
13+
#include "llvm/MC/MCStreamer.h"
14+
#include "llvm/Support/MemoryBuffer.h"
15+
#include "llvm/Support/SourceMgr.h"
16+
#include "llvm/Support/TargetRegistry.h"
17+
#include "llvm/Support/TargetSelect.h"
18+
19+
#include "gtest/gtest.h"
20+
21+
using namespace llvm;
22+
23+
namespace {
24+
25+
// Come up with our hacked version of MCAsmInfo.
26+
// This hacked version derives from the main MCAsmInfo instance.
27+
// Here, we're free to override whatever we want, without polluting
28+
// the main MCAsmInfo interface.
29+
class MockedUpMCAsmInfo : public MCAsmInfo {
30+
public:
31+
void setRestrictCommentStringToStartOfStatement(bool Value) {
32+
RestrictCommentStringToStartOfStatement = Value;
33+
}
34+
void setCommentString(StringRef Value) { CommentString = Value; }
35+
};
36+
37+
// Setup a testing class that the GTest framework can call.
38+
class SystemZAsmLexerTest : public ::testing::Test {
39+
protected:
40+
static void SetUpTestCase() {
41+
LLVMInitializeSystemZTargetInfo();
42+
LLVMInitializeSystemZTargetMC();
43+
}
44+
45+
std::unique_ptr<MCRegisterInfo> MRI;
46+
std::unique_ptr<MockedUpMCAsmInfo> MUPMAI;
47+
std::unique_ptr<const MCInstrInfo> MII;
48+
std::unique_ptr<MCStreamer> Str;
49+
std::unique_ptr<MCAsmParser> Parser;
50+
51+
std::string TripleName;
52+
llvm::Triple Triple;
53+
const Target *TheTarget;
54+
55+
const MCTargetOptions MCOptions;
56+
MCObjectFileInfo MOFI;
57+
58+
// Get the SystemZ Target info.
59+
static const Target *getTarget(std::string Triple) {
60+
std::string Error;
61+
llvm::Triple TripleName(Triple);
62+
const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error);
63+
if (!TheTarget)
64+
return nullptr;
65+
66+
return TheTarget;
67+
}
68+
69+
SystemZAsmLexerTest() {
70+
// We will use the SystemZ triple, because of missing
71+
// Object File and Streamer support for the z/OS target.
72+
TripleName = "s390x-ibm-linux";
73+
Triple = llvm::Triple(TripleName);
74+
75+
TheTarget = getTarget(TripleName);
76+
EXPECT_NE(TheTarget, nullptr);
77+
78+
MRI.reset(TheTarget->createMCRegInfo(TripleName));
79+
EXPECT_NE(MRI, nullptr);
80+
81+
std::unique_ptr<MCAsmInfo> MAI;
82+
MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
83+
EXPECT_NE(MAI, nullptr);
84+
85+
// Now we cast to our mocked up version of MCAsmInfo.
86+
MUPMAI.reset(static_cast<MockedUpMCAsmInfo *>(MAI.release()));
87+
// MUPMAI should "hold" MAI.
88+
EXPECT_NE(MUPMAI, nullptr);
89+
// After releasing, MAI should now be null.
90+
EXPECT_EQ(MAI, nullptr);
91+
}
92+
93+
void setupCallToAsmParser(StringRef AsmStr) {
94+
std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(AsmStr));
95+
SourceMgr SrcMgr;
96+
SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
97+
98+
llvm::Triple Triple(TripleName);
99+
MCContext Ctx(MUPMAI.get(), MRI.get(), &MOFI, &SrcMgr, &MCOptions);
100+
MOFI.InitMCObjectFileInfo(Triple, false, Ctx, false);
101+
102+
Str.reset(TheTarget->createNullStreamer(Ctx));
103+
104+
Parser.reset(createMCAsmParser(SrcMgr, Ctx, *Str, *MUPMAI));
105+
// Lex initially to get the string.
106+
Parser->getLexer().Lex();
107+
}
108+
109+
void lexAndCheckTokens(StringRef AsmStr,
110+
SmallVector<AsmToken::TokenKind> ExpectedTokens) {
111+
// Get reference to AsmLexer.
112+
MCAsmLexer &Lexer = Parser->getLexer();
113+
// Loop through all expected tokens checking one by one.
114+
for (size_t I = 0; I < ExpectedTokens.size(); ++I) {
115+
EXPECT_EQ(Lexer.getTok().getKind(), ExpectedTokens[I]);
116+
Lexer.Lex();
117+
}
118+
}
119+
};
120+
121+
TEST_F(SystemZAsmLexerTest, CheckDontRestrictCommentStringToStartOfStatement) {
122+
StringRef AsmStr = "jne #-4";
123+
124+
// Setup.
125+
setupCallToAsmParser(AsmStr);
126+
127+
SmallVector<AsmToken::TokenKind> ExpectedTokens(
128+
{AsmToken::Identifier, AsmToken::EndOfStatement});
129+
lexAndCheckTokens(AsmStr /* "jne #-4" */, ExpectedTokens);
130+
}
131+
132+
// Testing MCAsmInfo's RestrictCommentStringToStartOfStatement attribute.
133+
TEST_F(SystemZAsmLexerTest, CheckRestrictCommentStringToStartOfStatement) {
134+
StringRef AsmStr = "jne #-4";
135+
136+
// Setup.
137+
MUPMAI->setRestrictCommentStringToStartOfStatement(true);
138+
setupCallToAsmParser(AsmStr);
139+
140+
// When we are restricting the comment string to only the start of the
141+
// statement, The sequence of tokens we are expecting are: Identifier - "jne"
142+
// Hash - '#'
143+
// Minus - '-'
144+
// Integer - '4'
145+
SmallVector<AsmToken::TokenKind> ExpectedTokens(
146+
{AsmToken::Identifier, AsmToken::Hash, AsmToken::Minus,
147+
AsmToken::Integer});
148+
lexAndCheckTokens(AsmStr /* "jne #-4" */, ExpectedTokens);
149+
}
150+
151+
// Test HLASM Comment Syntax ('*')
152+
TEST_F(SystemZAsmLexerTest, CheckHLASMComment) {
153+
StringRef AsmStr = "* lhi 1,10";
154+
155+
// Setup.
156+
MUPMAI->setCommentString("*");
157+
setupCallToAsmParser(AsmStr);
158+
159+
SmallVector<AsmToken::TokenKind> ExpectedTokens(
160+
{AsmToken::EndOfStatement, AsmToken::Eof});
161+
lexAndCheckTokens(AsmStr /* "* lhi 1,10" */, ExpectedTokens);
162+
}
163+
} // end anonymous namespace

0 commit comments

Comments
 (0)