Skip to content

Commit

Permalink
add debug info for function parameter types (#4804)
Browse files Browse the repository at this point in the history
* add debug info for function parameter types

* [rework after checking clang IR]

---------

Co-authored-by: Martin Kinkelin <[email protected]>
  • Loading branch information
rainers and kinke authored Jan 16, 2025
1 parent af128ea commit d607a27
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 8 deletions.
50 changes: 43 additions & 7 deletions gen/dibuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,16 +720,52 @@ DIType DIBuilder::CreateAArrayType(TypeAArray *type) {

////////////////////////////////////////////////////////////////////////////////

DISubroutineType DIBuilder::CreateFunctionType(Type *type) {
DISubroutineType DIBuilder::CreateFunctionType(Type *type,
FuncDeclaration *fd) {
TypeFunction *t = type->isTypeFunction();
assert(t);

Type *retType = t->next;
llvm::SmallVector<LLMetadata *, 8> params;
auto pushParam = [&](Type *type, bool isRef) {
auto ditype = CreateTypeDescription(type);
if (isRef) {
if (!ditype) { // void or noreturn
ditype = CreateTypeDescription(Type::tuns8);
}
ditype = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type,
ditype, target.ptrsize * 8);
}
params.emplace_back(ditype);
};

// Create "dummy" subroutine type for the return type
LLMetadata *params = {CreateTypeDescription(retType)};
auto paramsArray = DBuilder.getOrCreateTypeArray(params);
// the first 'param' is the return value
pushParam(t->next, t->isref());

// then the implicit 'this'/context pointer
if (fd) {
DIType pointeeType = nullptr;
if (auto parentAggregate = fd->isThis()) {
pointeeType = CreateCompositeType(parentAggregate->type);
} else if (fd->isNested()) {
pointeeType = CreateTypeDescription(Type::tuns8); // cannot use void
}

if (pointeeType) {
DIType ditype = DBuilder.createReferenceType(
llvm::dwarf::DW_TAG_pointer_type, pointeeType, target.ptrsize * 8);
ditype = DBuilder.createObjectPointerType(ditype);
params.emplace_back(ditype);
}
}

// and finally the formal parameters
const auto len = t->parameterList.length();
for (size_t i = 0; i < len; i++) {
const auto param = t->parameterList[i];
pushParam(param->type, param->isReference());
}

auto paramsArray = DBuilder.getOrCreateTypeArray(params);
return DBuilder.createSubroutineType(paramsArray, DIFlags::FlagZero, 0);
}

Expand Down Expand Up @@ -971,7 +1007,7 @@ DISubprogram DIBuilder::EmitSubProgram(FuncDeclaration *fd) {
flags, dispFlags);

// Now create subroutine type.
diFnType = CreateFunctionType(fd->type);
diFnType = CreateFunctionType(fd->type, fd);
}

// FIXME: duplicates?
Expand Down Expand Up @@ -1010,7 +1046,7 @@ DISubprogram DIBuilder::EmitThunk(llvm::Function *Thunk, FuncDeclaration *fd) {
"Compilation unit missing or corrupted in DIBuilder::EmitThunk");

// Create subroutine type (thunk has same type as wrapped function)
DISubroutineType DIFnType = CreateFunctionType(fd->type);
DISubroutineType DIFnType = CreateFunctionType(fd->type, fd);

const auto scope = GetSymbolScope(fd);
const auto name = (llvm::Twine(fd->toChars()) + ".__thunk").str();
Expand Down
2 changes: 1 addition & 1 deletion gen/dibuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class DIBuilder {
DIType CreateArrayType(TypeArray *type);
DIType CreateSArrayType(TypeSArray *type);
DIType CreateAArrayType(TypeAArray *type);
DISubroutineType CreateFunctionType(Type *type);
DISubroutineType CreateFunctionType(Type *type, FuncDeclaration *fd = nullptr);
DISubroutineType CreateEmptyFunctionType();
DIType CreateDelegateType(TypeDelegate *type);
DIType CreateUnspecifiedType(Dsymbol *sym);
Expand Down

0 comments on commit d607a27

Please sign in to comment.