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   --- 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits