Skip to content

[clang][DebugInfo] Emit DW_AT_object_pointer on function declarations with explicit this #122928

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2016,20 +2016,29 @@ llvm::DISubroutineType *CGDebugInfo::getOrCreateInstanceMethodType(
// First element is always return type. For 'void' functions it is NULL.
Elts.push_back(Args[0]);

// "this" pointer is always first argument.
// ThisPtr may be null if the member function has an explicit 'this'
// parameter.
if (!ThisPtr.isNull()) {
const bool HasExplicitObjectParameter = ThisPtr.isNull();

// "this" pointer is always first argument. For explicit "this"
// parameters, it will already be in Args[1].
if (!HasExplicitObjectParameter) {
llvm::DIType *ThisPtrType = getOrCreateType(ThisPtr, Unit);
TypeCache[ThisPtr.getAsOpaquePtr()].reset(ThisPtrType);
ThisPtrType = DBuilder.createObjectPointerType(ThisPtrType);
ThisPtrType =
DBuilder.createObjectPointerType(ThisPtrType, /*Implicit=*/true);
Elts.push_back(ThisPtrType);
}

// Copy rest of the arguments.
for (unsigned i = 1, e = Args.size(); i != e; ++i)
Elts.push_back(Args[i]);

// Attach FlagObjectPointer to the explicit "this" parameter.
if (HasExplicitObjectParameter) {
assert(Elts.size() >= 2 && Args.size() >= 2 &&
"Expected at least return type and object parameter.");
Elts[1] = DBuilder.createObjectPointerType(Args[1], /*Implicit=*/false);
}

llvm::DITypeRefArray EltTypeArray = DBuilder.getOrCreateTypeArray(Elts);

return DBuilder.createSubroutineType(EltTypeArray, OriginalFunc->getFlags(),
Expand Down Expand Up @@ -5118,7 +5127,7 @@ llvm::DIType *CGDebugInfo::CreateSelfType(const QualType &QualTy,
llvm::DIType *CachedTy = getTypeOrNull(QualTy);
if (CachedTy)
Ty = CachedTy;
return DBuilder.createObjectPointerType(Ty);
return DBuilder.createObjectPointerType(Ty, /*Implicit=*/true);
}

void CGDebugInfo::EmitDeclareOfBlockDeclRefVariable(
Expand Down
7 changes: 3 additions & 4 deletions clang/test/CodeGenCXX/debug-info-object-pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type
// CHECK-SAME: flags: DIFlagArtificial | DIFlagObjectPointer
//
// // FIXME: DIFlagObjectPointer not attached to the explicit object
// // argument in the subprogram declaration.
// CHECK: !DISubprogram(name: "explicit_this",
// flags: DIFlagPrototyped
// CHECK-NOT: DIFlagObjectPointer
// CHECK-NOT: DIFlagArtificial
//
// CHECK: !DIDerivedType(tag: DW_TAG_rvalue_reference_type
// CHECK-SAME: flags: DIFlagObjectPointer)
//
// CHECK: !DILocalVariable(name: "this", arg: 1
// CHECK-SAME: flags: DIFlagArtificial | DIFlagObjectPointer
Expand Down
11 changes: 7 additions & 4 deletions llvm/include/llvm-c/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -870,13 +870,16 @@ LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder,
LLVMMetadataRef Ty);

/**
* Create a uniqued DIType* clone with FlagObjectPointer and FlagArtificial set.
* Create a uniqued DIType* clone with FlagObjectPointer. If \c Implicit
* is true, then also set FlagArtificial.
* \param Builder The DIBuilder.
* \param Type The underlying type to which this pointer points.
* \param Implicit Indicates whether this pointer was implicitly generated
* (i.e., not spelled out in source).
*/
LLVMMetadataRef
LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,
LLVMMetadataRef Type);
LLVMMetadataRef LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,
LLVMMetadataRef Type,
LLVMBool Implicit);

/**
* Create debugging information entry for a qualified
Expand Down
6 changes: 3 additions & 3 deletions llvm/include/llvm/IR/DIBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -662,9 +662,9 @@ namespace llvm {
/// Create a uniqued clone of \p Ty with FlagArtificial set.
static DIType *createArtificialType(DIType *Ty);

/// Create a uniqued clone of \p Ty with FlagObjectPointer and
/// FlagArtificial set.
static DIType *createObjectPointerType(DIType *Ty);
/// Create a uniqued clone of \p Ty with FlagObjectPointer set.
/// If \p Implicit is true, also set FlagArtificial.
static DIType *createObjectPointerType(DIType *Ty, bool Implicit);

/// Create a permanent forward-declared type.
DICompositeType *createForwardDecl(unsigned Tag, StringRef Name,
Expand Down
8 changes: 6 additions & 2 deletions llvm/lib/IR/DIBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -644,11 +644,15 @@ DIType *DIBuilder::createArtificialType(DIType *Ty) {
return createTypeWithFlags(Ty, DINode::FlagArtificial);
}

DIType *DIBuilder::createObjectPointerType(DIType *Ty) {
DIType *DIBuilder::createObjectPointerType(DIType *Ty, bool Implicit) {
// FIXME: Restrict this to the nodes where it's valid.
if (Ty->isObjectPointer())
return Ty;
DINode::DIFlags Flags = DINode::FlagObjectPointer | DINode::FlagArtificial;
DINode::DIFlags Flags = DINode::FlagObjectPointer;

if (Implicit)
Flags |= DINode::FlagArtificial;

return createTypeWithFlags(Ty, Flags);
}

Expand Down
9 changes: 5 additions & 4 deletions llvm/lib/IR/DebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1432,10 +1432,11 @@ LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder,
PropertyAttributes, unwrapDI<DIType>(Ty)));
}

LLVMMetadataRef
LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,
LLVMMetadataRef Type) {
return wrap(unwrap(Builder)->createObjectPointerType(unwrapDI<DIType>(Type)));
LLVMMetadataRef LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,
LLVMMetadataRef Type,
LLVMBool Implicit) {
return wrap(unwrap(Builder)->createObjectPointerType(unwrapDI<DIType>(Type),
Implicit));
}

LLVMMetadataRef
Expand Down
Loading