[llvm] [AsmParser] Track value references and function arguments (PR #174566)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 28 03:04:24 PST 2026
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,
Albert =?utf-8?q?Havliček?= <ahavlicek at azul.com>,Bertik23
<39457484+Bertik23 at users.noreply.github.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/174566 at github.com>
https://github.com/Bertik23 updated https://github.com/llvm/llvm-project/pull/174566
>From 536a246e8ac39dcfce94f4c7b34960c0313d8e4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 09:50:58 +0000
Subject: [PATCH 01/12] Store value references in AsmParserContext
---
.../include/llvm/AsmParser/AsmParserContext.h | 16 ++++++++++++++++
llvm/lib/AsmParser/AsmParserContext.cpp | 19 +++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/llvm/include/llvm/AsmParser/AsmParserContext.h b/llvm/include/llvm/AsmParser/AsmParserContext.h
index 8f7823a9ae07c..912c765c521ba 100644
--- a/llvm/include/llvm/AsmParser/AsmParserContext.h
+++ b/llvm/include/llvm/AsmParser/AsmParserContext.h
@@ -54,6 +54,13 @@ class AsmParserContext {
IMap::Allocator IAllocator;
IMap InstructionsInverse = IMap(IAllocator);
+ using VMap =
+ IntervalMap<FileLoc, Value *,
+ IntervalMapImpl::NodeSizer<FileLoc, Value *>::LeafSize,
+ IntervalMapHalfOpenInfo<FileLoc>>;
+ VMap::Allocator VAllocator;
+ VMap ReferencedValues = VMap(VAllocator);
+
public:
LLVM_ABI std::optional<FileLocRange>
getFunctionLocation(const Function *) const;
@@ -85,9 +92,18 @@ class AsmParserContext {
/// If no instruction occupies the queried location, or the record is missing,
/// a nullptr is returned.
Instruction *getInstructionAtLocation(const FileLoc &) const;
+ /// Get value referenced at the requested location.
+ /// If no value occupies the queried location, or the record is missing,
+ /// a nullptr is returned.
+ Value *getValueReferencedAtLocation(const FileLoc &) const;
+ /// Get value referenced at the requested location range.
+ /// If no value occupies the queried location, or the record is missing,
+ /// a nullptr is returned.
+ Value *getValueReferencedAtLocation(const FileLocRange &) const;
bool addFunctionLocation(Function *, const FileLocRange &);
bool addBlockLocation(BasicBlock *, const FileLocRange &);
bool addInstructionLocation(Instruction *, const FileLocRange &);
+ bool addValueReferenceAtLocation(Value *, const FileLocRange &);
};
} // namespace llvm
diff --git a/llvm/lib/AsmParser/AsmParserContext.cpp b/llvm/lib/AsmParser/AsmParserContext.cpp
index 453e6994d2b9e..9b6294556f185 100644
--- a/llvm/lib/AsmParser/AsmParserContext.cpp
+++ b/llvm/lib/AsmParser/AsmParserContext.cpp
@@ -68,6 +68,19 @@ AsmParserContext::getInstructionAtLocation(const FileLoc &Query) const {
return InstructionsInverse.lookup(Query, nullptr);
}
+Value *AsmParserContext::getValueReferencedAtLocation(
+ const FileLocRange &Query) const {
+ auto It = ReferencedValues.find(Query.Start);
+ if (It.stop() <= Query.End)
+ return *It;
+ return nullptr;
+}
+
+Value *
+AsmParserContext::getValueReferencedAtLocation(const FileLoc &Query) const {
+ return ReferencedValues.lookup(Query, nullptr);
+}
+
bool AsmParserContext::addFunctionLocation(Function *F,
const FileLocRange &Loc) {
bool Inserted = Functions.insert({F, Loc}).second;
@@ -92,4 +105,10 @@ bool AsmParserContext::addInstructionLocation(Instruction *I,
return Inserted;
}
+bool AsmParserContext::addValueReferenceAtLocation(Value *V,
+ const FileLocRange &Loc) {
+ ReferencedValues.insert(Loc.Start, Loc.End, V);
+ return true;
+}
+
} // namespace llvm
>From a03f7a81983ecbc5883bdbea953e5fc384e075c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 10:02:50 +0000
Subject: [PATCH 02/12] Store function arguments in AsmParserContext
---
llvm/include/llvm/AsmParser/AsmParserContext.h | 18 ++++++++++++++++++
llvm/lib/AsmParser/AsmParserContext.cpp | 13 +++++++++++++
2 files changed, 31 insertions(+)
diff --git a/llvm/include/llvm/AsmParser/AsmParserContext.h b/llvm/include/llvm/AsmParser/AsmParserContext.h
index 912c765c521ba..023d50017cf27 100644
--- a/llvm/include/llvm/AsmParser/AsmParserContext.h
+++ b/llvm/include/llvm/AsmParser/AsmParserContext.h
@@ -39,6 +39,15 @@ class AsmParserContext {
DenseMap<Function *, FileLocRange> Functions;
FMap::Allocator FAllocator;
FMap FunctionsInverse = FMap(FAllocator);
+
+ DenseMap<Argument *, FileLocRange> FunctionArguments;
+ using FAMap =
+ IntervalMap<FileLoc, Argument *,
+ IntervalMapImpl::NodeSizer<FileLoc, Argument *>::LeafSize,
+ IntervalMapHalfOpenInfo<FileLoc>>;
+ FAMap::Allocator FAAllocator;
+ FAMap FunctionArgumentsInverse = FAMap(FAAllocator);
+
DenseMap<BasicBlock *, FileLocRange> Blocks;
using BBMap =
IntervalMap<FileLoc, BasicBlock *,
@@ -79,6 +88,14 @@ class AsmParserContext {
/// Get the block at the requested location range.
/// If no single block occupies the queried range, or the record is missing, a
/// nullptr is returned.
+ Argument *getFunctionArgumentAtLocation(const FileLocRange &) const;
+ /// Get the function at the requested location.
+ /// If no function occupies the queried location, or the record is missing, a
+ /// nullptr is returned.
+ Argument *getFunctionArgumentAtLocation(const FileLoc &) const;
+ /// Get the block at the requested location range.
+ /// If no single block occupies the queried range, or the record is missing, a
+ /// nullptr is returned.
BasicBlock *getBlockAtLocation(const FileLocRange &) const;
/// Get the block at the requested location.
/// If no block occupies the queried location, or the record is missing, a
@@ -101,6 +118,7 @@ class AsmParserContext {
/// a nullptr is returned.
Value *getValueReferencedAtLocation(const FileLocRange &) const;
bool addFunctionLocation(Function *, const FileLocRange &);
+ bool addFunctionArgumentLocation(Argument *, const FileLocRange &);
bool addBlockLocation(BasicBlock *, const FileLocRange &);
bool addInstructionLocation(Instruction *, const FileLocRange &);
bool addValueReferenceAtLocation(Value *, const FileLocRange &);
diff --git a/llvm/lib/AsmParser/AsmParserContext.cpp b/llvm/lib/AsmParser/AsmParserContext.cpp
index 9b6294556f185..ce847b164ccbb 100644
--- a/llvm/lib/AsmParser/AsmParserContext.cpp
+++ b/llvm/lib/AsmParser/AsmParserContext.cpp
@@ -43,6 +43,19 @@ Function *AsmParserContext::getFunctionAtLocation(const FileLoc &Query) const {
return FunctionsInverse.lookup(Query, nullptr);
}
+Argument *AsmParserContext::getFunctionArgumentAtLocation(
+ const FileLocRange &Query) const {
+ auto It = FunctionArgumentsInverse.find(Query.Start);
+ if (It.stop() <= Query.End)
+ return *It;
+ return nullptr;
+}
+
+Argument *
+AsmParserContext::getFunctionArgumentAtLocation(const FileLoc &Query) const {
+ return FunctionArgumentsInverse.lookup(Query, nullptr);
+}
+
BasicBlock *
AsmParserContext::getBlockAtLocation(const FileLocRange &Query) const {
auto It = BlocksInverse.find(Query.Start);
>From ad617793d86ca44413b52d216dfbdaca168cba52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 10:15:40 +0000
Subject: [PATCH 03/12] Pass function argument locations to ParserContext
---
llvm/include/llvm/AsmParser/LLParser.h | 6 ++++--
llvm/lib/AsmParser/LLParser.cpp | 10 +++++++++-
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index 9eb31d7e0a451..c36c338255ce8 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -612,10 +612,12 @@ namespace llvm {
struct ArgInfo {
LocTy Loc;
Type *Ty;
+ FileLocRange IdentLoc;
AttributeSet Attrs;
std::string Name;
- ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N)
- : Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
+ ArgInfo(LocTy L, Type *ty, FileLocRange IdentLoc, AttributeSet Attr,
+ const std::string &N)
+ : Loc(L), Ty(ty), IdentLoc(IdentLoc), Attrs(Attr), Name(N) {}
};
bool parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
SmallVectorImpl<unsigned> &UnnamedArgNums,
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 03b808c4fdeef..df76598e1363a 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3401,16 +3401,22 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
return error(TypeLoc, "argument can not have void type");
std::string Name;
+ FileLoc NameStart;
+ FileLoc NameEnd;
if (Lex.getKind() == lltok::LocalVar) {
Name = Lex.getStrVal();
+ NameStart = Lex.getTokLineColumnPos();
Lex.Lex();
+ NameEnd = Lex.getPrevTokEndLineColumnPos();
} else {
unsigned ArgID;
if (Lex.getKind() == lltok::LocalVarID) {
ArgID = Lex.getUIntVal();
+ NameStart = Lex.getTokLineColumnPos();
if (checkValueID(TypeLoc, "argument", "%", CurValID, ArgID))
return true;
Lex.Lex();
+ NameEnd = Lex.getPrevTokEndLineColumnPos();
} else {
ArgID = CurValID;
}
@@ -3421,7 +3427,7 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
if (!FunctionType::isValidArgumentType(ArgTy))
return error(TypeLoc, "invalid type for function argument");
- ArgList.emplace_back(TypeLoc, ArgTy,
+ ArgList.emplace_back(TypeLoc, ArgTy, FileLocRange(NameStart, NameEnd),
AttributeSet::get(ArgTy->getContext(), Attrs),
std::move(Name));
} while (EatIfPresent(lltok::comma));
@@ -6933,6 +6939,8 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
// Add all of the arguments we parsed to the function.
Function::arg_iterator ArgIt = Fn->arg_begin();
for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) {
+ if (ParserContext)
+ ParserContext->addFunctionArgumentLocation(&*ArgIt, ArgList[i].IdentLoc);
// If the argument has a name, insert it into the argument symbol table.
if (ArgList[i].Name.empty()) continue;
>From a53fe92c0732fe5b4371e87625d2c2e6e5971864 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 10:24:08 +0000
Subject: [PATCH 04/12] Pass value references locations to ParserContext
---
llvm/lib/AsmParser/LLParser.cpp | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index df76598e1363a..84c8149fbd64d 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6691,8 +6691,13 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) {
bool LLParser::parseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
V = nullptr;
ValID ID;
- return parseValID(ID, PFS, Ty) ||
- convertValIDToValue(Ty, ID, V, PFS);
+
+ FileLoc Start = Lex.getTokLineColumnPos();
+ bool Ret = parseValID(ID, PFS, Ty) || convertValIDToValue(Ty, ID, V, PFS);
+ FileLoc End = Lex.getPrevTokEndLineColumnPos();
+ if (ParserContext)
+ ParserContext->addValueReferenceAtLocation(V, FileLocRange(Start, End));
+ return Ret;
}
bool LLParser::parseTypeAndValue(Value *&V, PerFunctionState *PFS) {
>From 773224a6b259177e2d89c2dcf1c1003ed0e197ce Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 10:45:07 +0000
Subject: [PATCH 05/12] Implement forgotten function
---
llvm/lib/AsmParser/AsmParserContext.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/llvm/lib/AsmParser/AsmParserContext.cpp b/llvm/lib/AsmParser/AsmParserContext.cpp
index ce847b164ccbb..ab9af50f552cc 100644
--- a/llvm/lib/AsmParser/AsmParserContext.cpp
+++ b/llvm/lib/AsmParser/AsmParserContext.cpp
@@ -102,6 +102,14 @@ bool AsmParserContext::addFunctionLocation(Function *F,
return Inserted;
}
+bool AsmParserContext::addFunctionArgumentLocation(Argument *FA,
+ const FileLocRange &Loc) {
+ bool Inserted = FunctionArguments.insert({FA, Loc}).second;
+ if (Inserted)
+ FunctionArgumentsInverse.insert(Loc.Start, Loc.End, FA);
+ return Inserted;
+}
+
bool AsmParserContext::addBlockLocation(BasicBlock *BB,
const FileLocRange &Loc) {
bool Inserted = Blocks.insert({BB, Loc}).second;
>From 3850c75197f8b86c7fd6da59f90bf973dd4b8183 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 10:47:05 +0000
Subject: [PATCH 06/12] getFunctionArgumentLocation
---
llvm/include/llvm/AsmParser/AsmParserContext.h | 2 ++
llvm/lib/AsmParser/AsmParserContext.cpp | 7 +++++++
2 files changed, 9 insertions(+)
diff --git a/llvm/include/llvm/AsmParser/AsmParserContext.h b/llvm/include/llvm/AsmParser/AsmParserContext.h
index 023d50017cf27..53f611348f7d6 100644
--- a/llvm/include/llvm/AsmParser/AsmParserContext.h
+++ b/llvm/include/llvm/AsmParser/AsmParserContext.h
@@ -74,6 +74,8 @@ class AsmParserContext {
LLVM_ABI std::optional<FileLocRange>
getFunctionLocation(const Function *) const;
LLVM_ABI std::optional<FileLocRange>
+ getFunctionArgumentLocation(const Argument *) const;
+ LLVM_ABI std::optional<FileLocRange>
getBlockLocation(const BasicBlock *) const;
LLVM_ABI std::optional<FileLocRange>
getInstructionLocation(const Instruction *) const;
diff --git a/llvm/lib/AsmParser/AsmParserContext.cpp b/llvm/lib/AsmParser/AsmParserContext.cpp
index ab9af50f552cc..a5f2ddf1219b2 100644
--- a/llvm/lib/AsmParser/AsmParserContext.cpp
+++ b/llvm/lib/AsmParser/AsmParserContext.cpp
@@ -17,6 +17,13 @@ AsmParserContext::getFunctionLocation(const Function *F) const {
return std::nullopt;
}
+std::optional<FileLocRange>
+AsmParserContext::getFunctionArgumentLocation(const Argument *F) const {
+ if (auto FIt = FunctionArguments.find(F); FIt != FunctionArguments.end())
+ return FIt->second;
+ return std::nullopt;
+}
+
std::optional<FileLocRange>
AsmParserContext::getBlockLocation(const BasicBlock *BB) const {
if (auto BBIt = Blocks.find(BB); BBIt != Blocks.end())
>From 1261024cb0dbb24d141d3c289f9fdaf53d9d44ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 10:47:53 +0000
Subject: [PATCH 07/12] Tests value references and function arguments
---
llvm/unittests/AsmParser/AsmParserTest.cpp | 23 +++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index f67ed150817f2..351fd5260d7bf 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -495,9 +495,9 @@ TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
} while (false)
TEST(AsmParserTest, ParserObjectLocations) {
- StringRef Source = "define i32 @main() {\n"
+ StringRef Source = "define i32 @main(i32 %arg) {\n"
"entry:\n"
- " %a = add i32 1, 2\n"
+ " %a = add i32 1, %arg\n"
" ret i32 %a\n"
"}\n";
LLVMContext Ctx;
@@ -527,7 +527,7 @@ TEST(AsmParserTest, ParserObjectLocations) {
ParserContext.getBlockAtLocation(*MaybeEntryBBLoc));
SmallVector<FileLocRange> InstructionLocations = {
- FileLocRange(FileLoc{2, 4}, FileLoc{2, 21}),
+ FileLocRange(FileLoc{2, 4}, FileLoc{2, 24}),
FileLocRange(FileLoc{3, 4}, FileLoc{3, 14})};
for (const auto &[Inst, ExpectedLoc] : zip(EntryBB, InstructionLocations)) {
@@ -538,6 +538,23 @@ TEST(AsmParserTest, ParserObjectLocations) {
ASSERT_EQ(ParserContext.getInstructionAtLocation(MaybeInstLoc->Start),
ParserContext.getInstructionAtLocation(*MaybeInstLoc));
}
+
+ SmallVector<FileLocRange> FunctionArgumentLocations = {
+ FileLocRange(FileLoc{0, 21}, FileLoc{0, 25}),
+ };
+ for (const auto &[Arg, ExpectedLoc] :
+ zip(MainFn->args(), FunctionArgumentLocations)) {
+ auto MaybeArgLoc = ParserContext.getFunctionArgumentLocation(&Arg);
+ ASSERT_TRUE(MaybeArgLoc.has_value());
+ auto ArgLoc = MaybeArgLoc.value();
+ ASSERT_EQ_LOC(ArgLoc, ExpectedLoc);
+ ASSERT_EQ(ParserContext.getFunctionArgumentAtLocation(ArgLoc.Start),
+ ParserContext.getFunctionArgumentAtLocation(ArgLoc));
+ }
+ ASSERT_EQ(&*MainFn->arg_begin(),
+ ParserContext.getValueReferencedAtLocation(FileLoc(2, 22)));
+ ASSERT_EQ(&*EntryBB.begin(),
+ ParserContext.getValueReferencedAtLocation(FileLoc(3, 13)));
}
} // end anonymous namespace
>From f7fb5c39b90229184b45242efd148d06ce704914 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 14:19:11 +0000
Subject: [PATCH 08/12] Fix unnamed function arguments
---
llvm/include/llvm/AsmParser/LLParser.h | 6 +++---
llvm/lib/AsmParser/LLParser.cpp | 27 +++++++++++++++-----------
2 files changed, 19 insertions(+), 14 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/LLParser.h b/llvm/include/llvm/AsmParser/LLParser.h
index c36c338255ce8..d7a772268ae8e 100644
--- a/llvm/include/llvm/AsmParser/LLParser.h
+++ b/llvm/include/llvm/AsmParser/LLParser.h
@@ -612,11 +612,11 @@ namespace llvm {
struct ArgInfo {
LocTy Loc;
Type *Ty;
- FileLocRange IdentLoc;
+ std::optional<FileLocRange> IdentLoc;
AttributeSet Attrs;
std::string Name;
- ArgInfo(LocTy L, Type *ty, FileLocRange IdentLoc, AttributeSet Attr,
- const std::string &N)
+ ArgInfo(LocTy L, Type *ty, std::optional<FileLocRange> IdentLoc,
+ AttributeSet Attr, const std::string &N)
: Loc(L), Ty(ty), IdentLoc(IdentLoc), Attrs(Attr), Name(N) {}
};
bool parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 84c8149fbd64d..5f4bbb6e7cadd 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3401,24 +3401,26 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
return error(TypeLoc, "argument can not have void type");
std::string Name;
- FileLoc NameStart;
- FileLoc NameEnd;
+ FileLoc IdentStart;
+ FileLoc IdentEnd;
+ bool Unnamed = false;
if (Lex.getKind() == lltok::LocalVar) {
Name = Lex.getStrVal();
- NameStart = Lex.getTokLineColumnPos();
+ IdentStart = Lex.getTokLineColumnPos();
Lex.Lex();
- NameEnd = Lex.getPrevTokEndLineColumnPos();
+ IdentEnd = Lex.getPrevTokEndLineColumnPos();
} else {
unsigned ArgID;
if (Lex.getKind() == lltok::LocalVarID) {
ArgID = Lex.getUIntVal();
- NameStart = Lex.getTokLineColumnPos();
+ IdentStart = Lex.getTokLineColumnPos();
if (checkValueID(TypeLoc, "argument", "%", CurValID, ArgID))
return true;
Lex.Lex();
- NameEnd = Lex.getPrevTokEndLineColumnPos();
+ IdentEnd = Lex.getPrevTokEndLineColumnPos();
} else {
ArgID = CurValID;
+ Unnamed = true;
}
UnnamedArgNums.push_back(ArgID);
CurValID = ArgID + 1;
@@ -3427,9 +3429,11 @@ bool LLParser::parseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
if (!FunctionType::isValidArgumentType(ArgTy))
return error(TypeLoc, "invalid type for function argument");
- ArgList.emplace_back(TypeLoc, ArgTy, FileLocRange(NameStart, NameEnd),
- AttributeSet::get(ArgTy->getContext(), Attrs),
- std::move(Name));
+ ArgList.emplace_back(
+ TypeLoc, ArgTy,
+ Unnamed ? std::nullopt
+ : std::make_optional(FileLocRange(IdentStart, IdentEnd)),
+ AttributeSet::get(ArgTy->getContext(), Attrs), std::move(Name));
} while (EatIfPresent(lltok::comma));
}
@@ -6944,8 +6948,9 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
// Add all of the arguments we parsed to the function.
Function::arg_iterator ArgIt = Fn->arg_begin();
for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) {
- if (ParserContext)
- ParserContext->addFunctionArgumentLocation(&*ArgIt, ArgList[i].IdentLoc);
+ if (ParserContext && ArgList[i].IdentLoc)
+ ParserContext->addFunctionArgumentLocation(&*ArgIt,
+ ArgList[i].IdentLoc.value());
// If the argument has a name, insert it into the argument symbol table.
if (ArgList[i].Name.empty()) continue;
>From 84db52621b8ff9787245fddadb7dfc495f9f1418 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Tue, 6 Jan 2026 14:26:44 +0000
Subject: [PATCH 09/12] Add test for unnamed arguments
---
llvm/unittests/AsmParser/AsmParserTest.cpp | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index 351fd5260d7bf..f5ea544660013 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -495,7 +495,7 @@ TEST(AsmParserTest, DIExpressionBodyAtBeginningWithSlotMappingParsing) {
} while (false)
TEST(AsmParserTest, ParserObjectLocations) {
- StringRef Source = "define i32 @main(i32 %arg) {\n"
+ StringRef Source = "define i32 @main(i32 %arg, i64) {\n"
"entry:\n"
" %a = add i32 1, %arg\n"
" ret i32 %a\n"
@@ -539,15 +539,16 @@ TEST(AsmParserTest, ParserObjectLocations) {
ParserContext.getInstructionAtLocation(*MaybeInstLoc));
}
- SmallVector<FileLocRange> FunctionArgumentLocations = {
- FileLocRange(FileLoc{0, 21}, FileLoc{0, 25}),
- };
+ SmallVector<std::optional<FileLocRange>> FunctionArgumentLocations = {
+ FileLocRange(FileLoc{0, 21}, FileLoc{0, 25}), std::nullopt};
for (const auto &[Arg, ExpectedLoc] :
zip(MainFn->args(), FunctionArgumentLocations)) {
auto MaybeArgLoc = ParserContext.getFunctionArgumentLocation(&Arg);
- ASSERT_TRUE(MaybeArgLoc.has_value());
+ ASSERT_EQ(MaybeArgLoc.has_value(), ExpectedLoc.has_value());
+ if (!ExpectedLoc.has_value())
+ continue;
auto ArgLoc = MaybeArgLoc.value();
- ASSERT_EQ_LOC(ArgLoc, ExpectedLoc);
+ ASSERT_EQ_LOC(ArgLoc, ExpectedLoc.value());
ASSERT_EQ(ParserContext.getFunctionArgumentAtLocation(ArgLoc.Start),
ParserContext.getFunctionArgumentAtLocation(ArgLoc));
}
>From 230e1885e848d8701a34f39cacc18888e504b9a8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Wed, 7 Jan 2026 14:58:28 +0000
Subject: [PATCH 10/12] Join Argument and Instruction maps and their API
---
.../include/llvm/AsmParser/AsmParserContext.h | 42 +++-----------
llvm/lib/AsmParser/AsmParserContext.cpp | 55 +++++--------------
llvm/lib/AsmParser/LLParser.cpp | 6 +-
llvm/unittests/AsmParser/AsmParserTest.cpp | 13 +++--
4 files changed, 34 insertions(+), 82 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/AsmParserContext.h b/llvm/include/llvm/AsmParser/AsmParserContext.h
index 53f611348f7d6..f08bc80612813 100644
--- a/llvm/include/llvm/AsmParser/AsmParserContext.h
+++ b/llvm/include/llvm/AsmParser/AsmParserContext.h
@@ -40,14 +40,6 @@ class AsmParserContext {
FMap::Allocator FAllocator;
FMap FunctionsInverse = FMap(FAllocator);
- DenseMap<Argument *, FileLocRange> FunctionArguments;
- using FAMap =
- IntervalMap<FileLoc, Argument *,
- IntervalMapImpl::NodeSizer<FileLoc, Argument *>::LeafSize,
- IntervalMapHalfOpenInfo<FileLoc>>;
- FAMap::Allocator FAAllocator;
- FAMap FunctionArgumentsInverse = FAMap(FAAllocator);
-
DenseMap<BasicBlock *, FileLocRange> Blocks;
using BBMap =
IntervalMap<FileLoc, BasicBlock *,
@@ -55,30 +47,23 @@ class AsmParserContext {
IntervalMapHalfOpenInfo<FileLoc>>;
BBMap::Allocator BBAllocator;
BBMap BlocksInverse = BBMap(BBAllocator);
- DenseMap<Instruction *, FileLocRange> Instructions;
- using IMap =
- IntervalMap<FileLoc, Instruction *,
- IntervalMapImpl::NodeSizer<FileLoc, Instruction *>::LeafSize,
- IntervalMapHalfOpenInfo<FileLoc>>;
- IMap::Allocator IAllocator;
- IMap InstructionsInverse = IMap(IAllocator);
-
+ DenseMap<Value *, FileLocRange> InstructionsAndArguments;
using VMap =
IntervalMap<FileLoc, Value *,
IntervalMapImpl::NodeSizer<FileLoc, Value *>::LeafSize,
IntervalMapHalfOpenInfo<FileLoc>>;
VMap::Allocator VAllocator;
+ VMap InstructionsAndArgumentsInverse = VMap(VAllocator);
+
VMap ReferencedValues = VMap(VAllocator);
public:
LLVM_ABI std::optional<FileLocRange>
getFunctionLocation(const Function *) const;
LLVM_ABI std::optional<FileLocRange>
- getFunctionArgumentLocation(const Argument *) const;
- LLVM_ABI std::optional<FileLocRange>
getBlockLocation(const BasicBlock *) const;
LLVM_ABI std::optional<FileLocRange>
- getInstructionLocation(const Instruction *) const;
+ getInstructionOrArgumentLocation(const Value *) const;
/// Get the function at the requested location range.
/// If no single function occupies the queried range, or the record is
/// missing, a nullptr is returned.
@@ -90,14 +75,6 @@ class AsmParserContext {
/// Get the block at the requested location range.
/// If no single block occupies the queried range, or the record is missing, a
/// nullptr is returned.
- Argument *getFunctionArgumentAtLocation(const FileLocRange &) const;
- /// Get the function at the requested location.
- /// If no function occupies the queried location, or the record is missing, a
- /// nullptr is returned.
- Argument *getFunctionArgumentAtLocation(const FileLoc &) const;
- /// Get the block at the requested location range.
- /// If no single block occupies the queried range, or the record is missing, a
- /// nullptr is returned.
BasicBlock *getBlockAtLocation(const FileLocRange &) const;
/// Get the block at the requested location.
/// If no block occupies the queried location, or the record is missing, a
@@ -106,12 +83,12 @@ class AsmParserContext {
/// Get the instruction at the requested location range.
/// If no single instruction occupies the queried range, or the record is
/// missing, a nullptr is returned.
- Instruction *getInstructionAtLocation(const FileLocRange &) const;
- /// Get the instruction at the requested location.
+ Value *getInstructionOrArgumentAtLocation(const FileLocRange &) const;
+ /// Get the instruction or function argument at the requested location.
/// If no instruction occupies the queried location, or the record is missing,
/// a nullptr is returned.
- Instruction *getInstructionAtLocation(const FileLoc &) const;
- /// Get value referenced at the requested location.
+ Value *getInstructionOrArgumentAtLocation(const FileLoc &) const;
+ /// Get value referenced or function argument at the requested location.
/// If no value occupies the queried location, or the record is missing,
/// a nullptr is returned.
Value *getValueReferencedAtLocation(const FileLoc &) const;
@@ -120,9 +97,8 @@ class AsmParserContext {
/// a nullptr is returned.
Value *getValueReferencedAtLocation(const FileLocRange &) const;
bool addFunctionLocation(Function *, const FileLocRange &);
- bool addFunctionArgumentLocation(Argument *, const FileLocRange &);
bool addBlockLocation(BasicBlock *, const FileLocRange &);
- bool addInstructionLocation(Instruction *, const FileLocRange &);
+ bool addInstructionOrArgumentLocation(Value *, const FileLocRange &);
bool addValueReferenceAtLocation(Value *, const FileLocRange &);
};
} // namespace llvm
diff --git a/llvm/lib/AsmParser/AsmParserContext.cpp b/llvm/lib/AsmParser/AsmParserContext.cpp
index a5f2ddf1219b2..fdc9940bb44b3 100644
--- a/llvm/lib/AsmParser/AsmParserContext.cpp
+++ b/llvm/lib/AsmParser/AsmParserContext.cpp
@@ -17,13 +17,6 @@ AsmParserContext::getFunctionLocation(const Function *F) const {
return std::nullopt;
}
-std::optional<FileLocRange>
-AsmParserContext::getFunctionArgumentLocation(const Argument *F) const {
- if (auto FIt = FunctionArguments.find(F); FIt != FunctionArguments.end())
- return FIt->second;
- return std::nullopt;
-}
-
std::optional<FileLocRange>
AsmParserContext::getBlockLocation(const BasicBlock *BB) const {
if (auto BBIt = Blocks.find(BB); BBIt != Blocks.end())
@@ -32,8 +25,10 @@ AsmParserContext::getBlockLocation(const BasicBlock *BB) const {
}
std::optional<FileLocRange>
-AsmParserContext::getInstructionLocation(const Instruction *I) const {
- if (auto IIt = Instructions.find(I); IIt != Instructions.end())
+AsmParserContext::getInstructionOrArgumentLocation(const Value *IA) const {
+ assert(isa<Instruction>(IA) || isa<Argument>(IA));
+ if (auto IIt = InstructionsAndArguments.find(IA);
+ IIt != InstructionsAndArguments.end())
return IIt->second;
return std::nullopt;
}
@@ -50,19 +45,6 @@ Function *AsmParserContext::getFunctionAtLocation(const FileLoc &Query) const {
return FunctionsInverse.lookup(Query, nullptr);
}
-Argument *AsmParserContext::getFunctionArgumentAtLocation(
- const FileLocRange &Query) const {
- auto It = FunctionArgumentsInverse.find(Query.Start);
- if (It.stop() <= Query.End)
- return *It;
- return nullptr;
-}
-
-Argument *
-AsmParserContext::getFunctionArgumentAtLocation(const FileLoc &Query) const {
- return FunctionArgumentsInverse.lookup(Query, nullptr);
-}
-
BasicBlock *
AsmParserContext::getBlockAtLocation(const FileLocRange &Query) const {
auto It = BlocksInverse.find(Query.Start);
@@ -75,17 +57,17 @@ BasicBlock *AsmParserContext::getBlockAtLocation(const FileLoc &Query) const {
return BlocksInverse.lookup(Query, nullptr);
}
-Instruction *
-AsmParserContext::getInstructionAtLocation(const FileLocRange &Query) const {
- auto It = InstructionsInverse.find(Query.Start);
+Value *AsmParserContext::getInstructionOrArgumentAtLocation(
+ const FileLocRange &Query) const {
+ auto It = InstructionsAndArgumentsInverse.find(Query.Start);
if (It.stop() <= Query.End)
return *It;
return nullptr;
}
-Instruction *
-AsmParserContext::getInstructionAtLocation(const FileLoc &Query) const {
- return InstructionsInverse.lookup(Query, nullptr);
+Value *AsmParserContext::getInstructionOrArgumentAtLocation(
+ const FileLoc &Query) const {
+ return InstructionsAndArgumentsInverse.lookup(Query, nullptr);
}
Value *AsmParserContext::getValueReferencedAtLocation(
@@ -109,14 +91,6 @@ bool AsmParserContext::addFunctionLocation(Function *F,
return Inserted;
}
-bool AsmParserContext::addFunctionArgumentLocation(Argument *FA,
- const FileLocRange &Loc) {
- bool Inserted = FunctionArguments.insert({FA, Loc}).second;
- if (Inserted)
- FunctionArgumentsInverse.insert(Loc.Start, Loc.End, FA);
- return Inserted;
-}
-
bool AsmParserContext::addBlockLocation(BasicBlock *BB,
const FileLocRange &Loc) {
bool Inserted = Blocks.insert({BB, Loc}).second;
@@ -125,11 +99,12 @@ bool AsmParserContext::addBlockLocation(BasicBlock *BB,
return Inserted;
}
-bool AsmParserContext::addInstructionLocation(Instruction *I,
- const FileLocRange &Loc) {
- bool Inserted = Instructions.insert({I, Loc}).second;
+bool AsmParserContext::addInstructionOrArgumentLocation(
+ Value *IA, const FileLocRange &Loc) {
+ assert(isa<Instruction>(IA) || isa<Argument>(IA));
+ bool Inserted = InstructionsAndArguments.insert({IA, Loc}).second;
if (Inserted)
- InstructionsInverse.insert(Loc.Start, Loc.End, I);
+ InstructionsAndArgumentsInverse.insert(Loc.Start, Loc.End, IA);
return Inserted;
}
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 5f4bbb6e7cadd..04b0eb733206b 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6949,8 +6949,8 @@ bool LLParser::parseFunctionHeader(Function *&Fn, bool IsDefine,
Function::arg_iterator ArgIt = Fn->arg_begin();
for (unsigned i = 0, e = ArgList.size(); i != e; ++i, ++ArgIt) {
if (ParserContext && ArgList[i].IdentLoc)
- ParserContext->addFunctionArgumentLocation(&*ArgIt,
- ArgList[i].IdentLoc.value());
+ ParserContext->addInstructionOrArgumentLocation(
+ &*ArgIt, ArgList[i].IdentLoc.value());
// If the argument has a name, insert it into the argument symbol table.
if (ArgList[i].Name.empty()) continue;
@@ -7160,7 +7160,7 @@ bool LLParser::parseBasicBlock(PerFunctionState &PFS) {
BB->insertDbgRecordBefore(DR.release(), Inst->getIterator());
TrailingDbgRecord.clear();
if (ParserContext) {
- ParserContext->addInstructionLocation(
+ ParserContext->addInstructionOrArgumentLocation(
Inst, FileLocRange(InstStart, Lex.getPrevTokEndLineColumnPos()));
}
} while (!Inst->isTerminator());
diff --git a/llvm/unittests/AsmParser/AsmParserTest.cpp b/llvm/unittests/AsmParser/AsmParserTest.cpp
index f5ea544660013..1ef1fa36ebdcf 100644
--- a/llvm/unittests/AsmParser/AsmParserTest.cpp
+++ b/llvm/unittests/AsmParser/AsmParserTest.cpp
@@ -531,26 +531,27 @@ TEST(AsmParserTest, ParserObjectLocations) {
FileLocRange(FileLoc{3, 4}, FileLoc{3, 14})};
for (const auto &[Inst, ExpectedLoc] : zip(EntryBB, InstructionLocations)) {
- auto MaybeInstLoc = ParserContext.getInstructionLocation(&Inst);
+ auto MaybeInstLoc = ParserContext.getInstructionOrArgumentLocation(&Inst);
ASSERT_TRUE(MaybeMainLoc.has_value());
auto InstLoc = MaybeInstLoc.value();
ASSERT_EQ_LOC(InstLoc, ExpectedLoc);
- ASSERT_EQ(ParserContext.getInstructionAtLocation(MaybeInstLoc->Start),
- ParserContext.getInstructionAtLocation(*MaybeInstLoc));
+ ASSERT_EQ(
+ ParserContext.getInstructionOrArgumentAtLocation(MaybeInstLoc->Start),
+ ParserContext.getInstructionOrArgumentAtLocation(*MaybeInstLoc));
}
SmallVector<std::optional<FileLocRange>> FunctionArgumentLocations = {
FileLocRange(FileLoc{0, 21}, FileLoc{0, 25}), std::nullopt};
for (const auto &[Arg, ExpectedLoc] :
zip(MainFn->args(), FunctionArgumentLocations)) {
- auto MaybeArgLoc = ParserContext.getFunctionArgumentLocation(&Arg);
+ auto MaybeArgLoc = ParserContext.getInstructionOrArgumentLocation(&Arg);
ASSERT_EQ(MaybeArgLoc.has_value(), ExpectedLoc.has_value());
if (!ExpectedLoc.has_value())
continue;
auto ArgLoc = MaybeArgLoc.value();
ASSERT_EQ_LOC(ArgLoc, ExpectedLoc.value());
- ASSERT_EQ(ParserContext.getFunctionArgumentAtLocation(ArgLoc.Start),
- ParserContext.getFunctionArgumentAtLocation(ArgLoc));
+ ASSERT_EQ(ParserContext.getInstructionOrArgumentAtLocation(ArgLoc.Start),
+ ParserContext.getInstructionOrArgumentAtLocation(ArgLoc));
}
ASSERT_EQ(&*MainFn->arg_begin(),
ParserContext.getValueReferencedAtLocation(FileLoc(2, 22)));
>From 7f3093a1c3549fa95b9bfccee5d08fbf05daa916 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Albert=20Havli=C4=8Dek?= <ahavlicek at azul.com>
Date: Wed, 7 Jan 2026 15:01:55 +0000
Subject: [PATCH 11/12] Fix comment typo
---
llvm/include/llvm/AsmParser/AsmParserContext.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/AsmParser/AsmParserContext.h b/llvm/include/llvm/AsmParser/AsmParserContext.h
index f08bc80612813..665d56883d753 100644
--- a/llvm/include/llvm/AsmParser/AsmParserContext.h
+++ b/llvm/include/llvm/AsmParser/AsmParserContext.h
@@ -80,7 +80,7 @@ class AsmParserContext {
/// If no block occupies the queried location, or the record is missing, a
/// nullptr is returned.
BasicBlock *getBlockAtLocation(const FileLoc &) const;
- /// Get the instruction at the requested location range.
+ /// Get the instruction or function argument at the requested location range.
/// If no single instruction occupies the queried range, or the record is
/// missing, a nullptr is returned.
Value *getInstructionOrArgumentAtLocation(const FileLocRange &) const;
@@ -88,7 +88,7 @@ class AsmParserContext {
/// If no instruction occupies the queried location, or the record is missing,
/// a nullptr is returned.
Value *getInstructionOrArgumentAtLocation(const FileLoc &) const;
- /// Get value referenced or function argument at the requested location.
+ /// Get value referenced at the requested location.
/// If no value occupies the queried location, or the record is missing,
/// a nullptr is returned.
Value *getValueReferencedAtLocation(const FileLoc &) const;
>From ec2d0de409a9149c5f885dd3fef9008a753f4701 Mon Sep 17 00:00:00 2001
From: Bertik23 <39457484+Bertik23 at users.noreply.github.com>
Date: Wed, 28 Jan 2026 12:04:10 +0100
Subject: [PATCH 12/12] Add value to context only if succesfully parsed
Co-authored-by: Nikita Popov <github at npopov.com>
---
llvm/lib/AsmParser/LLParser.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 04b0eb733206b..d622f2d9d3f7c 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -6699,7 +6699,7 @@ bool LLParser::parseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
FileLoc Start = Lex.getTokLineColumnPos();
bool Ret = parseValID(ID, PFS, Ty) || convertValIDToValue(Ty, ID, V, PFS);
FileLoc End = Lex.getPrevTokEndLineColumnPos();
- if (ParserContext)
+ if (!Ret && ParserContext)
ParserContext->addValueReferenceAtLocation(V, FileLocRange(Start, End));
return Ret;
}
More information about the llvm-commits
mailing list