-
Notifications
You must be signed in to change notification settings - Fork 13.3k
[BPF] Fix issues with external declarations of C++ structor decls #137079
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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 llvm#130674 by @lexi-nadia .
@llvm/pr-subscribers-clang-codegen @llvm/pr-subscribers-clang Author: Reid Kleckner (rnk) ChangesUse 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 . Full diff: https://github.com/llvm/llvm-project/pull/137079.diff 3 Files Affected:
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 83d8d4f758195..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,30 +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);
- }
-}
-
-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));
- if (!Fn->getSubprogram())
- DI->EmitFunctionDecl(FD, 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);
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))
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
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 .