Skip to content

Commit d607a27

Browse files
rainerskinke
andauthored
add debug info for function parameter types (#4804)
* add debug info for function parameter types * [rework after checking clang IR] --------- Co-authored-by: Martin Kinkelin <[email protected]>
1 parent af128ea commit d607a27

File tree

2 files changed

+44
-8
lines changed

2 files changed

+44
-8
lines changed

gen/dibuilder.cpp

+43-7
Original file line numberDiff line numberDiff line change
@@ -720,16 +720,52 @@ DIType DIBuilder::CreateAArrayType(TypeAArray *type) {
720720

721721
////////////////////////////////////////////////////////////////////////////////
722722

723-
DISubroutineType DIBuilder::CreateFunctionType(Type *type) {
723+
DISubroutineType DIBuilder::CreateFunctionType(Type *type,
724+
FuncDeclaration *fd) {
724725
TypeFunction *t = type->isTypeFunction();
725726
assert(t);
726727

727-
Type *retType = t->next;
728+
llvm::SmallVector<LLMetadata *, 8> params;
729+
auto pushParam = [&](Type *type, bool isRef) {
730+
auto ditype = CreateTypeDescription(type);
731+
if (isRef) {
732+
if (!ditype) { // void or noreturn
733+
ditype = CreateTypeDescription(Type::tuns8);
734+
}
735+
ditype = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type,
736+
ditype, target.ptrsize * 8);
737+
}
738+
params.emplace_back(ditype);
739+
};
728740

729-
// Create "dummy" subroutine type for the return type
730-
LLMetadata *params = {CreateTypeDescription(retType)};
731-
auto paramsArray = DBuilder.getOrCreateTypeArray(params);
741+
// the first 'param' is the return value
742+
pushParam(t->next, t->isref());
743+
744+
// then the implicit 'this'/context pointer
745+
if (fd) {
746+
DIType pointeeType = nullptr;
747+
if (auto parentAggregate = fd->isThis()) {
748+
pointeeType = CreateCompositeType(parentAggregate->type);
749+
} else if (fd->isNested()) {
750+
pointeeType = CreateTypeDescription(Type::tuns8); // cannot use void
751+
}
732752

753+
if (pointeeType) {
754+
DIType ditype = DBuilder.createReferenceType(
755+
llvm::dwarf::DW_TAG_pointer_type, pointeeType, target.ptrsize * 8);
756+
ditype = DBuilder.createObjectPointerType(ditype);
757+
params.emplace_back(ditype);
758+
}
759+
}
760+
761+
// and finally the formal parameters
762+
const auto len = t->parameterList.length();
763+
for (size_t i = 0; i < len; i++) {
764+
const auto param = t->parameterList[i];
765+
pushParam(param->type, param->isReference());
766+
}
767+
768+
auto paramsArray = DBuilder.getOrCreateTypeArray(params);
733769
return DBuilder.createSubroutineType(paramsArray, DIFlags::FlagZero, 0);
734770
}
735771

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

9731009
// Now create subroutine type.
974-
diFnType = CreateFunctionType(fd->type);
1010+
diFnType = CreateFunctionType(fd->type, fd);
9751011
}
9761012

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

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

10151051
const auto scope = GetSymbolScope(fd);
10161052
const auto name = (llvm::Twine(fd->toChars()) + ".__thunk").str();

gen/dibuilder.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class DIBuilder {
184184
DIType CreateArrayType(TypeArray *type);
185185
DIType CreateSArrayType(TypeSArray *type);
186186
DIType CreateAArrayType(TypeAArray *type);
187-
DISubroutineType CreateFunctionType(Type *type);
187+
DISubroutineType CreateFunctionType(Type *type, FuncDeclaration *fd = nullptr);
188188
DISubroutineType CreateEmptyFunctionType();
189189
DIType CreateDelegateType(TypeDelegate *type);
190190
DIType CreateUnspecifiedType(Dsymbol *sym);

0 commit comments

Comments
 (0)