[clang] KISHAN KUMAR S D, HRUTHIK K K , KIRAN V-R V COLLEGE OF ENGINEERING(CSE 6TH SEM)-Implement Clang identifiers to retrieve the mangled name and the fully qualified name of functions #5 (PR #145042)
KISHAN KUMAR S D via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 20 07:46:27 PDT 2025
https://github.com/kishan-kumar-s-d-444 created https://github.com/llvm/llvm-project/pull/145042
# Add `__fq_func__` and `__mangled_func__` predefined identifiers to Clang
## Summary
This pull request introduces two new predefined identifiers to Clang:
1. `__fq_func__` - Returns the fully qualified name of the current function
2. `__mangled_func__` - Returns the mangled name of the current function
## Affected Files
1. `llvm-project/clang/include/clang/AST/Expr.h`
2. `llvm-project/clang/lib/AST/Expr.cpp`
3. `llvm-project/clang/include/clang/Basic/TokenKinds.def`
4. `llvm-project/clang/lib/Sema/SemaExpr.cpp`
5. `llvm-project/clang/lib/Parse/ParseExpr.cpp`
## Motivation
The existing predefined identifiers have limitations:
- `__func__`: Only unqualified name
- `__PRETTY_FUNCTION__`: Detailed signature without full qualification
- No built-in way to get mangled names
New identifiers provide:
- Complete namespace/class qualification (`__fq_func__`)
- Exact linkage name (`__mangled_func__`)
- Consistent with existing identifier patterns
## Implementation Details
1. New `PredefinedIdentKind` enum values:
- `FQFunction`
- `MangledFunction`
2. Core implementations:
## 1) `Expr.h` → `llvm-project/clang/include/clang/AST/Expr.h`
```cpp
enum class PredefinedIdentKind {
Func,
Function,
LFunction, // Same as Function, but as wide string.
FuncDName,
FuncSig,
LFuncSig, // Same as FuncSig, but as wide string
PrettyFunction,
/// The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
PrettyFunctionNoVirtual,
FQFunction,
MangledFunction
};
```
## `2)Expr.cpp` -->`llvm-project/clang/lib/AST`
```
StringRef PredefinedExpr::getIdentKindName(PredefinedIdentKind IK) {
switch (IK) {
case PredefinedIdentKind::Func:
return "__func__";
case PredefinedIdentKind::Function:
return "__FUNCTION__";
case PredefinedIdentKind::FuncDName:
return "__FUNCDNAME__";
case PredefinedIdentKind::FQFunction:
return "__fq_func__";
case PredefinedIdentKind::MangledFunction:
return "__mangled_func__";
case PredefinedIdentKind::LFunction:
return "L__FUNCTION__";
case PredefinedIdentKind::PrettyFunction:
return "__PRETTY_FUNCTION__";
case PredefinedIdentKind::FuncSig:
return "__FUNCSIG__";
case PredefinedIdentKind::LFuncSig:
return "L__FUNCSIG__";
case PredefinedIdentKind::PrettyFunctionNoVirtual:
break;
}
llvm_unreachable("Unknown ident kind for PredefinedExpr");
}
```
```
std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK,
const Decl *CurrentDecl,
bool ForceElaboratedPrinting) {
ASTContext &Context = CurrentDecl->getASTContext();
if (IK == PredefinedIdentKind::FQFunction) {
if (const auto *ND = dyn_cast<NamedDecl>(CurrentDecl))
return ND->getQualifiedNameAsString();
return "<unknown>";
}
if (IK == PredefinedIdentKind::MangledFunction) {
if (const auto *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
std::unique_ptr<MangleContext> MC;
MC.reset(Context.createMangleContext());
SmallString<256> Buffer;
llvm::raw_svector_ostream Out(Buffer);
GlobalDecl GD;
if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(ND))
GD = GlobalDecl(CD, Ctor_Base);
else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(ND))
GD = GlobalDecl(DD, Dtor_Base);
else if (auto FD = dyn_cast<FunctionDecl>(ND)) {
GD = FD->isReferenceableKernel() ? GlobalDecl(FD) : GlobalDecl(ND);
} else
GD = GlobalDecl(ND);
MC->mangleName(GD, Out);
return std::string(Buffer);
}
return "<unknown>";
}
// Remaining Code continues
```
## `3)TokenKinds.def` -->`llvm-project/clang/include/clang/Basic/TokenKinds.def`
```
KEYWORD(__fq_func__, KEYALL)
KEYWORD(__mangled_func__, KEYALL)
```
## `4)SemaExpr.cpp` -->`llvm-project/clang/lib/Sema/SemaExpr.cpp`
```
static PredefinedIdentKind getPredefinedExprKind(tok::TokenKind Kind) {
switch (Kind) {
default:
llvm_unreachable("unexpected TokenKind");
case tok::kw___func__:
return PredefinedIdentKind::Func;
case tok::kw___fq_func__:
return PredefinedIdentKind::FQFunction;
case tok::kw___mangled_func__:
return PredefinedIdentKind::MangledFunction;
// Code Continues
```
## `5)ParseExpr.cpp` -->`llvm-project/clang/lib/Parse/ParseExpr.cpp`
```
case tok::kw_L__FUNCTION__:
case tok::kw_L__FUNCSIG__:
case tok::kw___PRETTY_FUNCTION__:
//Add below lines
case tok::kw___fq_func__:
case tok::kw___mangled_func__:
//end here
```
## Example Usage


>From fdf7f676690f7af5109970f239eba8f34850442f Mon Sep 17 00:00:00 2001
From: KISHAN KUMAR S D <kishankumarsd444 at gmail.com>
Date: Fri, 20 Jun 2025 19:35:57 +0530
Subject: [PATCH 1/5] Update Expr.h
---
clang/include/clang/AST/Expr.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 9fc23d30b733f..2da16d4dc069d 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -2003,7 +2003,9 @@ enum class PredefinedIdentKind {
PrettyFunction,
/// The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
- PrettyFunctionNoVirtual
+ PrettyFunctionNoVirtual,
+ FQFunction,
+ MangledFunction
};
/// [C99 6.4.2.2] - A predefined identifier such as __func__.
>From b814391bd581ab82acf30366ffd3952f3f72a490 Mon Sep 17 00:00:00 2001
From: KISHAN KUMAR S D <kishankumarsd444 at gmail.com>
Date: Fri, 20 Jun 2025 19:38:50 +0530
Subject: [PATCH 2/5] Update TokenKinds.def
---
clang/include/clang/Basic/TokenKinds.def | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 94e72fea56a68..1f9f0d60e8b02 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -480,6 +480,9 @@ KEYWORD(__thread , KEYALL)
KEYWORD(__FUNCTION__ , KEYALL)
KEYWORD(__PRETTY_FUNCTION__ , KEYALL)
KEYWORD(__auto_type , KEYALL)
+KEYWORD(__fq_func__, KEYALL)
+KEYWORD(__mangled_func__, KEYALL)
+
// MS Extensions
KEYWORD(__FUNCDNAME__ , KEYMS)
>From fe6fc7ba8183b267ee00fdc66c3060f1449194b2 Mon Sep 17 00:00:00 2001
From: KISHAN KUMAR S D <kishankumarsd444 at gmail.com>
Date: Fri, 20 Jun 2025 19:39:32 +0530
Subject: [PATCH 3/5] Update Expr.cpp
---
clang/lib/AST/Expr.cpp | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index c3722c65abf6e..12b6745536d53 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -653,6 +653,10 @@ StringRef PredefinedExpr::getIdentKindName(PredefinedIdentKind IK) {
return "__FUNCTION__";
case PredefinedIdentKind::FuncDName:
return "__FUNCDNAME__";
+ case PredefinedIdentKind::FQFunction:
+ return "__fq_func__";
+ case PredefinedIdentKind::MangledFunction:
+ return "__mangled_func__";
case PredefinedIdentKind::LFunction:
return "L__FUNCTION__";
case PredefinedIdentKind::PrettyFunction:
@@ -674,6 +678,34 @@ std::string PredefinedExpr::ComputeName(PredefinedIdentKind IK,
bool ForceElaboratedPrinting) {
ASTContext &Context = CurrentDecl->getASTContext();
+ if (IK == PredefinedIdentKind::FQFunction) {
+ if (const auto *ND = dyn_cast<NamedDecl>(CurrentDecl))
+ return ND->getQualifiedNameAsString();
+ return "<unknown>";
+}
+
+if (IK == PredefinedIdentKind::MangledFunction) {
+ if (const auto *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
+ std::unique_ptr<MangleContext> MC;
+ MC.reset(Context.createMangleContext());
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ GlobalDecl GD;
+ if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(ND))
+ GD = GlobalDecl(CD, Ctor_Base);
+ else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(ND))
+ GD = GlobalDecl(DD, Dtor_Base);
+ else if (auto FD = dyn_cast<FunctionDecl>(ND)) {
+ GD = FD->isReferenceableKernel() ? GlobalDecl(FD) : GlobalDecl(ND);
+ } else
+ GD = GlobalDecl(ND);
+ MC->mangleName(GD, Out);
+ return std::string(Buffer);
+ }
+ return "<unknown>";
+}
+
+
if (IK == PredefinedIdentKind::FuncDName) {
if (const NamedDecl *ND = dyn_cast<NamedDecl>(CurrentDecl)) {
std::unique_ptr<MangleContext> MC;
>From add48ac76f28fa94ff4aed30116722a2b24799fb Mon Sep 17 00:00:00 2001
From: KISHAN KUMAR S D <kishankumarsd444 at gmail.com>
Date: Fri, 20 Jun 2025 19:40:35 +0530
Subject: [PATCH 4/5] Update SemaExpr.cpp
---
clang/lib/Sema/SemaExpr.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 413eff4aa294a..2e5cd6a821c70 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1992,6 +1992,10 @@ static PredefinedIdentKind getPredefinedExprKind(tok::TokenKind Kind) {
llvm_unreachable("unexpected TokenKind");
case tok::kw___func__:
return PredefinedIdentKind::Func; // [C99 6.4.2.2]
+ case tok::kw___fq_func__:
+ return PredefinedIdentKind::FQFunction;
+ case tok::kw___mangled_func__:
+ return PredefinedIdentKind::MangledFunction;
case tok::kw___FUNCTION__:
return PredefinedIdentKind::Function;
case tok::kw___FUNCDNAME__:
>From f5847a1c5a93bb0e70eae2e211abe50a1cd3677d Mon Sep 17 00:00:00 2001
From: KISHAN KUMAR S D <kishankumarsd444 at gmail.com>
Date: Fri, 20 Jun 2025 19:41:40 +0530
Subject: [PATCH 5/5] Update ParseExpr.cpp
---
clang/lib/Parse/ParseExpr.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 3cf3d4ea7d705..afd28da1e2bc4 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1042,6 +1042,8 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
case tok::kw_L__FUNCTION__: // primary-expression: L__FUNCTION__ [MS]
case tok::kw_L__FUNCSIG__: // primary-expression: L__FUNCSIG__ [MS]
case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU]
+ case tok::kw___fq_func__: // <-- Add this line
+ case tok::kw___mangled_func__:
// Function local predefined macros are represented by PredefinedExpr except
// when Microsoft extensions are enabled and one of these macros is adjacent
// to a string literal or another one of these macros.
More information about the cfe-commits
mailing list