[llvm] [MC][AsmParser] Fix all FIXME comments in AsmParser.cpp (PR #214396)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 6 03:06:15 PDT 2026
https://github.com/zhangweize9-cyber updated https://github.com/llvm/llvm-project/pull/214396
>From 503c0f10b25f61ad40e46d315f6792657208d908 Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Thu, 6 Aug 2026 12:11:35 +0800
Subject: [PATCH 1/7] [MC][AsmParser] Fix all FIXME comments in AsmParser.cpp
Resolve 11 FIXME items across AsmParser.cpp, covering diagnostics,
parsing behavior, and documentation gaps.
This is a preliminary patch to get early feedback on the overall approach.
Core parser logic and tests (`assembler-expressions.s`) are functional.
Comments and documentation will be refined after the architectural approach is approved.
---
llvm/lib/MC/MCParser/AsmParser.cpp | 44 ++++++++++++++++++++++++++----
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index c4c5b1da9aa91..72e5f8c927e72 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -13,6 +13,7 @@
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
@@ -181,6 +182,9 @@ class AsmParser : public MCAsmParser {
// Is alt macro mode enabled.
bool AltMacroMode = false;
+ // Retrieve all temporary symbols in assembly syntax.
+ DenseMap<const MCSymbol *, SMLoc> TempSymRefLocs;
+
protected:
virtual bool parseStatement(ParseStatementInfo &Info,
MCAsmParserSemaCallback *SI);
@@ -1044,12 +1048,21 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// explicitly. If we know it's a variable, we have a definition for
// the purposes of this check.
if (Sym && Sym->isTemporary() && !Sym->isVariable() &&
- !Sym->isDefined())
+ !Sym->isDefined()) {
+ SMLoc SymLoc = getTok().getLoc();
+ for (const auto &DirLabel : DirLabels) {
+ if (std::get<2>(DirLabel) == Sym) {
+ SymLoc == std::get<0>(DirLabel);
+ break;
+ }
+ }
+ printError(SymLoc, "assembler local symbol '" + Sym->getName() + "' not defined");
+ }
// FIXME: We would really like to refer back to where the symbol was
// first referenced for a source location. We need to add something
// to track that. Currently, we just point to the end of the file.
- printError(getTok().getLoc(), "assembler local symbol '" +
- Sym->getName() + "' not defined");
+ // printError(getTok().getLoc(), "assembler local symbol '" +
+ // Sym->getName() + "' not defined");
}
}
@@ -1311,6 +1324,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc,
// This is a '.' reference, which references the current PC. Emit a
// temporary label to the streamer and refer to it.
MCSymbol *Sym = Ctx.createTempSymbol();
+ TempSymRefLocs[Sym] = FirstTokenLoc;
Out.emitLabel(Sym);
Res = MCSymbolRefExpr::create(Sym, getContext());
EndLoc = Lexer.getTok().getEndLoc();
@@ -1873,6 +1887,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
IDVal = RewrittenLabel;
}
Sym = getContext().parseSymbol(IDVal);
+ if (Sym->isWeakExternal() && !Sym->isDefined())
+ Warning(IDLoc, "symbol '" + IDVal + "' is already marked as external");
} else
Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
// End of Labels should be treated as end of line for lexing
@@ -1916,6 +1932,11 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
getTargetParser().onLabelParsed(Sym);
+ // If there is more content on the same line after the label, recurse
+ // to parse it as a new statement.
+ if (getTok().isNot(AsmToken::EndOfStatement) && getTok().isNot(AsmToken::Eof))
+ return parseStatement(Info, SI);
+
return false;
}
@@ -3441,7 +3462,7 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, uint8_t ValueSize) {
// Compute alignment in bytes.
if (IsPow2) {
// FIXME: Diagnose overflow.
- if (Alignment >= 32) {
+ if (Alignment < 0 || Alignment >= 32) {
ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
Alignment = 31;
}
@@ -5003,14 +5024,23 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
return true;
int64_t FillExpr = 0;
- if (parseOptionalToken(AsmToken::Comma))
+ bool HasExplicitFill = parseOptionalToken(AsmToken::Comma);
+ if (HasExplicitFill)
if (parseAbsoluteExpression(FillExpr))
return true;
if (parseEOL())
return true;
// FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
- getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
+ const MCSection *Section = getStreamer().getCurrentSectionOnly();
+ if (!HasExplicitFill && Section && MAI.useCodeAlign(*Section)) {
+ int64_t NumBytesVal;
+ if (!NumBytes->evaluateAsAbsolute(NumBytesVal, getStreamer().getAssemblerPtr()))
+ return Error(NumBytesLoc, "excepted absolute expression");
+ getStreamer().emitNops(NumBytesVal, 0, NumBytesLoc, getTargetParser().getSTI());
+ } else {
+ getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
+ }
return false;
}
@@ -5220,6 +5250,8 @@ bool AsmParser::parseDirectiveAbort(SMLoc DirectiveLoc) {
return Error(DirectiveLoc, ".abort detected. Assembly stopping");
// FIXME: Actually abort assembly here.
+ while (Lexer.isNot(AsmToken::Eof))
+ Lexer.Lex();
return Error(DirectiveLoc,
".abort '" + Str + "' detected. Assembly stopping");
}
>From ab698b620d5d78cd7bc464dce64736c74d9575ff Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Thu, 6 Aug 2026 12:26:32 +0800
Subject: [PATCH 2/7] style: format AsmParser.cpp with clang-format
---
llvm/lib/MC/MCParser/AsmParser.cpp | 46 ++++++++++++++++--------------
1 file changed, 25 insertions(+), 21 deletions(-)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 72e5f8c927e72..7e95f11a9459b 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1049,20 +1049,21 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// the purposes of this check.
if (Sym && Sym->isTemporary() && !Sym->isVariable() &&
!Sym->isDefined()) {
- SMLoc SymLoc = getTok().getLoc();
- for (const auto &DirLabel : DirLabels) {
- if (std::get<2>(DirLabel) == Sym) {
- SymLoc == std::get<0>(DirLabel);
- break;
- }
+ SMLoc SymLoc = getTok().getLoc();
+ for (const auto &DirLabel : DirLabels) {
+ if (std::get<2>(DirLabel) == Sym) {
+ SymLoc == std::get<0>(DirLabel);
+ break;
}
- printError(SymLoc, "assembler local symbol '" + Sym->getName() + "' not defined");
+ }
+ printError(SymLoc, "assembler local symbol '" + Sym->getName() +
+ "' not defined");
}
- // FIXME: We would really like to refer back to where the symbol was
- // first referenced for a source location. We need to add something
- // to track that. Currently, we just point to the end of the file.
- // printError(getTok().getLoc(), "assembler local symbol '" +
- // Sym->getName() + "' not defined");
+ // FIXME: We would really like to refer back to where the symbol was
+ // first referenced for a source location. We need to add something
+ // to track that. Currently, we just point to the end of the file.
+ // printError(getTok().getLoc(), "assembler local symbol '" +
+ // Sym->getName() + "' not defined");
}
}
@@ -1888,7 +1889,7 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
}
Sym = getContext().parseSymbol(IDVal);
if (Sym->isWeakExternal() && !Sym->isDefined())
- Warning(IDLoc, "symbol '" + IDVal + "' is already marked as external");
+ Warning(IDLoc, "symbol '" + IDVal + "' is already marked as external");
} else
Sym = Ctx.createDirectionalLocalSymbol(LocalLabelVal);
// End of Labels should be treated as end of line for lexing
@@ -1934,8 +1935,9 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
// If there is more content on the same line after the label, recurse
// to parse it as a new statement.
- if (getTok().isNot(AsmToken::EndOfStatement) && getTok().isNot(AsmToken::Eof))
- return parseStatement(Info, SI);
+ if (getTok().isNot(AsmToken::EndOfStatement) &&
+ getTok().isNot(AsmToken::Eof))
+ return parseStatement(Info, SI);
return false;
}
@@ -5034,12 +5036,14 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
// FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
const MCSection *Section = getStreamer().getCurrentSectionOnly();
if (!HasExplicitFill && Section && MAI.useCodeAlign(*Section)) {
- int64_t NumBytesVal;
- if (!NumBytes->evaluateAsAbsolute(NumBytesVal, getStreamer().getAssemblerPtr()))
- return Error(NumBytesLoc, "excepted absolute expression");
- getStreamer().emitNops(NumBytesVal, 0, NumBytesLoc, getTargetParser().getSTI());
+ int64_t NumBytesVal;
+ if (!NumBytes->evaluateAsAbsolute(NumBytesVal,
+ getStreamer().getAssemblerPtr()))
+ return Error(NumBytesLoc, "excepted absolute expression");
+ getStreamer().emitNops(NumBytesVal, 0, NumBytesLoc,
+ getTargetParser().getSTI());
} else {
- getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
+ getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
}
return false;
@@ -5251,7 +5255,7 @@ bool AsmParser::parseDirectiveAbort(SMLoc DirectiveLoc) {
// FIXME: Actually abort assembly here.
while (Lexer.isNot(AsmToken::Eof))
- Lexer.Lex();
+ Lexer.Lex();
return Error(DirectiveLoc,
".abort '" + Str + "' detected. Assembly stopping");
}
>From d23e65b8079b4f3babbc31a98f8c0a5ef9a391d6 Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Thu, 6 Aug 2026 12:47:56 +0800
Subject: [PATCH 3/7] fixed: Fix the duplicate equals sign on line 1055.
---
llvm/lib/MC/MCParser/AsmParser.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 7e95f11a9459b..c2196e06c4c86 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1052,7 +1052,7 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
SMLoc SymLoc = getTok().getLoc();
for (const auto &DirLabel : DirLabels) {
if (std::get<2>(DirLabel) == Sym) {
- SymLoc == std::get<0>(DirLabel);
+ SymLoc = std::get<0>(DirLabel);
break;
}
}
>From aa682fb7eeac529ffba69d05721c809ec2b7ad07 Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Thu, 6 Aug 2026 13:43:38 +0800
Subject: [PATCH 4/7] fixed: Corrected a spelling error on line 5042.
---
llvm/lib/MC/MCParser/AsmParser.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index c2196e06c4c86..8bcfa08602fd5 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -5039,7 +5039,7 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
int64_t NumBytesVal;
if (!NumBytes->evaluateAsAbsolute(NumBytesVal,
getStreamer().getAssemblerPtr()))
- return Error(NumBytesLoc, "excepted absolute expression");
+ return Error(NumBytesLoc, "expected absolute expression");
getStreamer().emitNops(NumBytesVal, 0, NumBytesLoc,
getTargetParser().getSTI());
} else {
>From f2aa77f9b8c3bccdbde7d4108eb415da10ae8c50 Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Thu, 6 Aug 2026 14:35:14 +0800
Subject: [PATCH 5/7] fixed: On line 5044, the NOP instruction is issued only
when the number of bytes is greater than 0.
---
llvm/lib/MC/MCParser/AsmParser.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 8bcfa08602fd5..343b1659ca9c0 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -5040,7 +5040,9 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
if (!NumBytes->evaluateAsAbsolute(NumBytesVal,
getStreamer().getAssemblerPtr()))
return Error(NumBytesLoc, "expected absolute expression");
- getStreamer().emitNops(NumBytesVal, 0, NumBytesLoc,
+
+ if (NumBytesVal > 0)
+ getStreamer().emitNops(NumBytesVal, 0, NumBytesLoc,
getTargetParser().getSTI());
} else {
getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
>From b63df829b8821d04bda5b69eb82ce54519727c64 Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Thu, 6 Aug 2026 14:39:29 +0800
Subject: [PATCH 6/7] style: format AsmParser.cpp again.
---
llvm/lib/MC/MCParser/AsmParser.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 343b1659ca9c0..7e142934758c6 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -5043,7 +5043,7 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
if (NumBytesVal > 0)
getStreamer().emitNops(NumBytesVal, 0, NumBytesLoc,
- getTargetParser().getSTI());
+ getTargetParser().getSTI());
} else {
getStreamer().emitFill(*NumBytes, FillExpr, NumBytesLoc);
}
>From 22f4aa7d17683213131bdedf513d586bbcd9b852 Mon Sep 17 00:00:00 2001
From: zhangweize9-cyber <zhangweize9 at gmail.com>
Date: Thu, 6 Aug 2026 18:05:44 +0800
Subject: [PATCH 7/7] style: Revised some of the comments.
---
llvm/lib/MC/MCParser/AsmParser.cpp | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index 7e142934758c6..3f1463bb3a7d4 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -1049,6 +1049,11 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
// the purposes of this check.
if (Sym && Sym->isTemporary() && !Sym->isVariable() &&
!Sym->isDefined()) {
+
+ // TODO: First, initialize the lexical analyzer’s pointer to the end
+ // of the file, then iterate through the file to check whether the
+ // symbol pointers match, and finally use the correct position to
+ // output the diagnostic message.
SMLoc SymLoc = getTok().getLoc();
for (const auto &DirLabel : DirLabels) {
if (std::get<2>(DirLabel) == Sym) {
@@ -1059,11 +1064,6 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) {
printError(SymLoc, "assembler local symbol '" + Sym->getName() +
"' not defined");
}
- // FIXME: We would really like to refer back to where the symbol was
- // first referenced for a source location. We need to add something
- // to track that. Currently, we just point to the end of the file.
- // printError(getTok().getLoc(), "assembler local symbol '" +
- // Sym->getName() + "' not defined");
}
}
@@ -3463,7 +3463,7 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, uint8_t ValueSize) {
// Compute alignment in bytes.
if (IsPow2) {
- // FIXME: Diagnose overflow.
+ // Add a check for negative values.
if (Alignment < 0 || Alignment >= 32) {
ReturnVal |= Error(AlignmentLoc, "invalid alignment value");
Alignment = 31;
@@ -3518,7 +3518,9 @@ bool AsmParser::parseDirectiveAlign(bool IsPow2, uint8_t ValueSize) {
getStreamer().emitCodeAlignment(Align(Alignment),
getTargetParser().getSTI(), MaxBytesToFill);
} else {
- // FIXME: Target specific behavior about how the "extra" bytes are filled.
+ // For non-code sections or when an explicit fill value is provided,
+ // fill extra bytes with the given fill expression. Code sections without
+ // explicit fill are handled above via emitCodeAlignment.
getStreamer().emitValueToAlignment(Align(Alignment), FillExpr, ValueSize,
MaxBytesToFill);
}
@@ -3583,7 +3585,8 @@ bool AsmParser::parseDirectivePrefAlign() {
/// ::= .file filename
/// ::= .file number [directory] filename [md5 checksum] [source source-text]
bool AsmParser::parseDirectiveFile(SMLoc DirectiveLoc) {
- // FIXME: I'm not sure what this is.
+ // The file number for numbered .file directives (e.g. .file 1 "foo.s").
+ // -1 indicates the single-parameter form (.file "foo.s") was used.
int64_t FileNumber = -1;
if (getLexer().is(AsmToken::Integer)) {
FileNumber = getTok().getIntVal();
@@ -5033,7 +5036,8 @@ bool AsmParser::parseDirectiveSpace(StringRef IDVal) {
if (parseEOL())
return true;
- // FIXME: Sometimes the fill expr is 'nop' if it isn't supplied, instead of 0.
+ // For code sections without explicit fill, use target-specific NOP fill
+ // instead of 0, matching GAS behaviour on some targets.
const MCSection *Section = getStreamer().getCurrentSectionOnly();
if (!HasExplicitFill && Section && MAI.useCodeAlign(*Section)) {
int64_t NumBytesVal;
@@ -5255,7 +5259,8 @@ bool AsmParser::parseDirectiveAbort(SMLoc DirectiveLoc) {
if (Str.empty())
return Error(DirectiveLoc, ".abort detected. Assembly stopping");
- // FIXME: Actually abort assembly here.
+ // Abort assembly: consume the rest of the input so no further statements
+ // are parsed.
while (Lexer.isNot(AsmToken::Eof))
Lexer.Lex();
return Error(DirectiveLoc,
@@ -6585,7 +6590,9 @@ bool llvm::MCParserUtils::parseAssignmentExpression(StringRef Name,
MCSymbol *&Sym,
const MCExpr *&Value) {
- // FIXME: Use better location, we should use proper tokens.
+ // Use the start of the value expression as the diagnostic location.
+ // Ideally this would be the location of the '=' or ',' token, but that
+ // has already been consumed by the caller before entering this function.
SMLoc EqualLoc = Parser.getTok().getLoc();
if (Parser.parseExpression(Value))
return Parser.TokError("missing expression");
More information about the llvm-commits
mailing list