[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)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 20 07:47:13 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: KISHAN KUMAR S D (kishan-kumar-s-d-444)

<details>
<summary>Changes</summary>

# 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
![CODE SNIPPET](https://github.com/user-attachments/assets/44c87dce-1e1b-458e-bc63-e9d8432c649c)
![OUTPUT](https://github.com/user-attachments/assets/c7e4fe2d-98cb-4d3b-b3b1-9ff909d5a2ac)




---
Full diff: https://github.com/llvm/llvm-project/pull/145042.diff


5 Files Affected:

- (modified) clang/include/clang/AST/Expr.h (+3-1) 
- (modified) clang/include/clang/Basic/TokenKinds.def (+3) 
- (modified) clang/lib/AST/Expr.cpp (+32) 
- (modified) clang/lib/Parse/ParseExpr.cpp (+2) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+4) 


``````````diff
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__.
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)
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;
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.
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__:

``````````

</details>


https://github.com/llvm/llvm-project/pull/145042


More information about the cfe-commits mailing list