Skip to content

Commit 5c3c0a8

Browse files
committed
[ELF] Replace inExpr with lexState. NFC
We may add another state State::Wild to behave more lik GNU ld.
1 parent 14776c6 commit 5c3c0a8

File tree

3 files changed

+31
-24
lines changed

3 files changed

+31
-24
lines changed

lld/ELF/ScriptLexer.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ void ScriptLexer::lex() {
105105
curBuf = buffers.pop_back_val();
106106
continue;
107107
}
108-
curTokState = inExpr;
108+
curTokState = lexState;
109109

110110
// Quoted token. Note that double-quote characters are parts of a token
111111
// because, in a glob match context, only unquoted tokens are interpreted
@@ -142,18 +142,21 @@ void ScriptLexer::lex() {
142142
// C-like languages, so that you can write "file-name.cpp" as one bare
143143
// token.
144144
size_t pos;
145-
if (inExpr) {
145+
switch (lexState) {
146+
case State::Script:
147+
pos = s.find_first_not_of(
148+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
149+
"0123456789_.$/\\~=+[]*?-!^:");
150+
break;
151+
case State::Expr:
146152
pos = s.find_first_not_of(
147153
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
148154
"0123456789_.$");
149155
if (pos == 0 && s.size() >= 2 &&
150156
((s[0] == s[1] && strchr("<>&|", s[0])) ||
151157
is_contained({"==", "!=", "<=", ">=", "<<", ">>"}, s.substr(0, 2))))
152158
pos = 2;
153-
} else {
154-
pos = s.find_first_not_of(
155-
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
156-
"0123456789_.$/\\~=+[]*?-!^:");
159+
break;
157160
}
158161

159162
if (pos == 0)
@@ -208,8 +211,8 @@ StringRef ScriptLexer::next() {
208211
}
209212

210213
StringRef ScriptLexer::peek() {
211-
// curTok is invalid if curTokState and inExpr mismatch.
212-
if (curTok.size() && curTokState != inExpr) {
214+
// curTok is invalid if curTokState and lexState mismatch.
215+
if (curTok.size() && curTokState != lexState) {
213216
curBuf.s = StringRef(curTok.data(), curBuf.s.end() - curTok.data());
214217
curTok = {};
215218
}

lld/ELF/ScriptLexer.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ class ScriptLexer {
4141
// Used to detect INCLUDE() cycles.
4242
llvm::DenseSet<StringRef> activeFilenames;
4343

44+
enum class State {
45+
Script,
46+
Expr,
47+
};
48+
4449
struct Token {
4550
StringRef str;
4651
explicit operator bool() const { return !str.empty(); }
@@ -54,8 +59,9 @@ class ScriptLexer {
5459
// expression state changes.
5560
StringRef curTok;
5661
size_t prevTokLine = 1;
57-
// The inExpr state when curTok is cached.
58-
bool curTokState = false;
62+
// The lex state when curTok is cached.
63+
State curTokState = State::Script;
64+
State lexState = State::Script;
5965
bool eof = false;
6066

6167
public:
@@ -75,7 +81,6 @@ class ScriptLexer {
7581
MemoryBufferRef getCurrentMB();
7682

7783
std::vector<MemoryBufferRef> mbs;
78-
bool inExpr = false;
7984

8085
private:
8186
StringRef getLine();

lld/ELF/ScriptParser.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ void ScriptParser::readLinkerScript() {
289289
void ScriptParser::readDefsym() {
290290
if (errCount(ctx))
291291
return;
292-
inExpr = true;
292+
SaveAndRestore saved(lexState, State::Expr);
293293
StringRef name = readName();
294294
expect("=");
295295
Expr e = readExpr();
@@ -954,8 +954,8 @@ bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok) {
954954
// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
955955
void ScriptParser::readSectionAddressType(OutputSection *cmd) {
956956
if (consume("(")) {
957-
// Temporarily set inExpr to support TYPE=<value> without spaces.
958-
SaveAndRestore saved(inExpr, true);
957+
// Temporarily set lexState to support TYPE=<value> without spaces.
958+
SaveAndRestore saved(lexState, State::Expr);
959959
if (readSectionDirective(cmd, peek()))
960960
return;
961961
cmd->addrExpr = readExpr();
@@ -965,7 +965,7 @@ void ScriptParser::readSectionAddressType(OutputSection *cmd) {
965965
}
966966

967967
if (consume("(")) {
968-
SaveAndRestore saved(inExpr, true);
968+
SaveAndRestore saved(lexState, State::Expr);
969969
StringRef tok = peek();
970970
if (!readSectionDirective(cmd, tok))
971971
setError("unknown section directive: " + tok);
@@ -1087,10 +1087,10 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
10871087
osec->phdrs = readOutputSectionPhdrs();
10881088

10891089
if (peek() == "=" || peek().starts_with("=")) {
1090-
inExpr = true;
1090+
lexState = State::Expr;
10911091
consume("=");
10921092
osec->filler = readFill();
1093-
inExpr = false;
1093+
lexState = State::Script;
10941094
}
10951095

10961096
// Consume optional comma following output section command.
@@ -1162,7 +1162,7 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
11621162
bool savedSeenRelroEnd = ctx.script->seenRelroEnd;
11631163
const StringRef op = peek();
11641164
{
1165-
SaveAndRestore saved(inExpr, true);
1165+
SaveAndRestore saved(lexState, State::Expr);
11661166
if (op.starts_with("=")) {
11671167
// Support = followed by an expression without whitespace.
11681168
cmd = readSymbolAssignment(unquote(tok));
@@ -1235,7 +1235,7 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
12351235
Expr ScriptParser::readExpr() {
12361236
// Our lexer is context-aware. Set the in-expression bit so that
12371237
// they apply different tokenization rules.
1238-
SaveAndRestore saved(inExpr, true);
1238+
SaveAndRestore saved(lexState, State::Expr);
12391239
Expr e = readExpr1(readPrimary(), 0);
12401240
return e;
12411241
}
@@ -1452,12 +1452,11 @@ std::pair<uint64_t, uint64_t> ScriptParser::readInputSectionFlags() {
14521452

14531453
StringRef ScriptParser::readParenName() {
14541454
expect("(");
1455-
bool orig = inExpr;
1456-
inExpr = false;
1457-
StringRef tok = readName();
1458-
inExpr = orig;
1455+
auto saved = std::exchange(lexState, State::Script);
1456+
StringRef name = readName();
1457+
lexState = saved;
14591458
expect(")");
1460-
return tok;
1459+
return name;
14611460
}
14621461

14631462
static void checkIfExists(LinkerScript &script, const OutputSection &osec,

0 commit comments

Comments
 (0)