[clang] [BPF] Fix issues with external declarations of C++ structor decls (PR #137079)
Reid Kleckner via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 23 16:02:34 PDT 2025
https://github.com/rnk created https://github.com/llvm/llvm-project/pull/137079
Use GetAddrOfGlobal, which is a more general API that takes a GlobalDecl, and handles declaring C++ destructors and other types in a general way. We can use this to generalize over functions and variable declarations.
This fixes issues reported on #130674 by @lexi-nadia .
>From e78b8012376798746b5cf4d664e656e22591acdb Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rnk at google.com>
Date: Wed, 23 Apr 2025 22:29:22 +0000
Subject: [PATCH 1/2] [BPF] Fix issues with external declarations of C++
structor decls
Use GetAddrOfGlobal, which is a more general API that takes a
GlobalDecl, and handles declaring C++ destructors and other types in a
general way. It's possible we can generalize this to handle external
variable declarations.
This fixes issues reported on #130674 by @lexi-nadia .
---
clang/lib/CodeGen/CodeGenModule.cpp | 16 +++++++++++-----
clang/test/CodeGenCXX/bpf-debug-structors.cpp | 14 ++++++++++++++
2 files changed, 25 insertions(+), 5 deletions(-)
create mode 100644 clang/test/CodeGenCXX/bpf-debug-structors.cpp
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 83d8d4f758195..a6dc9152a6020 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -5837,15 +5837,21 @@ void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) {
}
}
+static GlobalDecl getBaseVariantGlobalDecl(const FunctionDecl *FD) {
+ if (auto const *CD = dyn_cast<const CXXConstructorDecl>(FD))
+ return GlobalDecl(CD, CXXCtorType::Ctor_Base);
+ else if (auto const *DD = dyn_cast<const CXXDestructorDecl>(FD))
+ return GlobalDecl(DD, CXXDtorType::Dtor_Base);
+ return GlobalDecl(FD);
+}
+
void CodeGenModule::EmitExternalFunctionDeclaration(const FunctionDecl *FD) {
if (CGDebugInfo *DI = getModuleDebugInfo())
if (getCodeGenOpts().hasReducedDebugInfo()) {
- auto *Ty = getTypes().ConvertType(FD->getType());
- StringRef MangledName = getMangledName(FD);
- auto *Fn = cast<llvm::Function>(
- GetOrCreateLLVMFunction(MangledName, Ty, FD, /* ForVTable */ false));
+ GlobalDecl GD = getBaseVariantGlobalDecl(FD);
+ auto *Fn = cast<llvm::Function>(GetAddrOfGlobal(GD));
if (!Fn->getSubprogram())
- DI->EmitFunctionDecl(FD, FD->getLocation(), FD->getType(), Fn);
+ DI->EmitFunctionDecl(GD, FD->getLocation(), FD->getType(), Fn);
}
}
diff --git a/clang/test/CodeGenCXX/bpf-debug-structors.cpp b/clang/test/CodeGenCXX/bpf-debug-structors.cpp
new file mode 100644
index 0000000000000..c4c98486a776a
--- /dev/null
+++ b/clang/test/CodeGenCXX/bpf-debug-structors.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -debug-info-kind=constructor -triple bpf -emit-llvm %s -o - | FileCheck %s
+
+class Foo {
+public:
+ virtual ~Foo() noexcept;
+};
+
+class Bar : public Foo {
+public:
+ Bar() noexcept {}
+ ~Bar() noexcept override;
+};
+
+// CHECK: declare !dbg !{{[0-9]+}} void @_ZN3FooD2Ev(ptr noundef nonnull align 8 dereferenceable(8))
>From a4e45e8f0c1f736da18c07c095395cf300d1849c Mon Sep 17 00:00:00 2001
From: Reid Kleckner <rnk at google.com>
Date: Wed, 23 Apr 2025 23:01:40 +0000
Subject: [PATCH 2/2] Uniform var / fn handling
---
clang/lib/CodeGen/CodeGenModule.cpp | 60 +++++++++++++----------------
clang/lib/CodeGen/CodeGenModule.h | 2 -
2 files changed, 26 insertions(+), 36 deletions(-)
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index a6dc9152a6020..249a84c39a245 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -5378,11 +5378,33 @@ void CodeGenModule::EmitTentativeDefinition(const VarDecl *D) {
EmitGlobalVarDefinition(D);
}
+// Return a GlobalDecl. Use the base variants for destructors and constructors.
+static GlobalDecl getBaseVariantGlobalDecl(const NamedDecl *D) {
+ if (auto const *CD = dyn_cast<const CXXConstructorDecl>(D))
+ return GlobalDecl(CD, CXXCtorType::Ctor_Base);
+ else if (auto const *DD = dyn_cast<const CXXDestructorDecl>(D))
+ return GlobalDecl(DD, CXXDtorType::Dtor_Base);
+ return GlobalDecl(D);
+}
+
void CodeGenModule::EmitExternalDeclaration(const DeclaratorDecl *D) {
- if (auto const *V = dyn_cast<const VarDecl>(D))
- EmitExternalVarDeclaration(V);
- if (auto const *FD = dyn_cast<const FunctionDecl>(D))
- EmitExternalFunctionDeclaration(FD);
+ CGDebugInfo *DI = getModuleDebugInfo();
+ if (!DI || !getCodeGenOpts().hasReducedDebugInfo())
+ return;
+
+ GlobalDecl GD = getBaseVariantGlobalDecl(D);
+ if (!GD)
+ return;
+
+ llvm::Constant *Addr = GetAddrOfGlobal(GD)->stripPointerCasts();
+ if (const auto *VD = dyn_cast<VarDecl>(D)) {
+ DI->EmitExternalVariable(
+ cast<llvm::GlobalVariable>(Addr->stripPointerCasts()), VD);
+ } else if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+ llvm::Function *Fn = cast<llvm::Function>(Addr);
+ if (!Fn->getSubprogram())
+ DI->EmitFunctionDecl(GD, FD->getLocation(), FD->getType(), Fn);
+ }
}
CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {
@@ -5825,36 +5847,6 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
DI->EmitGlobalVariable(GV, D);
}
-void CodeGenModule::EmitExternalVarDeclaration(const VarDecl *D) {
- if (CGDebugInfo *DI = getModuleDebugInfo())
- if (getCodeGenOpts().hasReducedDebugInfo()) {
- QualType ASTTy = D->getType();
- llvm::Type *Ty = getTypes().ConvertTypeForMem(D->getType());
- llvm::Constant *GV =
- GetOrCreateLLVMGlobal(D->getName(), Ty, ASTTy.getAddressSpace(), D);
- DI->EmitExternalVariable(
- cast<llvm::GlobalVariable>(GV->stripPointerCasts()), D);
- }
-}
-
-static GlobalDecl getBaseVariantGlobalDecl(const FunctionDecl *FD) {
- if (auto const *CD = dyn_cast<const CXXConstructorDecl>(FD))
- return GlobalDecl(CD, CXXCtorType::Ctor_Base);
- else if (auto const *DD = dyn_cast<const CXXDestructorDecl>(FD))
- return GlobalDecl(DD, CXXDtorType::Dtor_Base);
- return GlobalDecl(FD);
-}
-
-void CodeGenModule::EmitExternalFunctionDeclaration(const FunctionDecl *FD) {
- if (CGDebugInfo *DI = getModuleDebugInfo())
- if (getCodeGenOpts().hasReducedDebugInfo()) {
- GlobalDecl GD = getBaseVariantGlobalDecl(FD);
- auto *Fn = cast<llvm::Function>(GetAddrOfGlobal(GD));
- if (!Fn->getSubprogram())
- DI->EmitFunctionDecl(GD, FD->getLocation(), FD->getType(), Fn);
- }
-}
-
static bool isVarDeclStrongDefinition(const ASTContext &Context,
CodeGenModule &CGM, const VarDecl *D,
bool NoCommon) {
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 9a0bc675e0baa..59f400570fb7a 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1852,8 +1852,6 @@ class CodeGenModule : public CodeGenTypeCache {
void EmitMultiVersionFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false);
- void EmitExternalVarDeclaration(const VarDecl *D);
- void EmitExternalFunctionDeclaration(const FunctionDecl *D);
void EmitAliasDefinition(GlobalDecl GD);
void emitIFuncDefinition(GlobalDecl GD);
void emitCPUDispatchDefinition(GlobalDecl GD);
More information about the cfe-commits
mailing list