From d607a2747a567a3f646d0e2eeee1a6cdf4c0b124 Mon Sep 17 00:00:00 2001 From: Rainer Schuetze Date: Thu, 16 Jan 2025 11:25:57 +0100 Subject: [PATCH] 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 --- gen/dibuilder.cpp | 50 ++++++++++++++++++++++++++++++++++++++++------- gen/dibuilder.h | 2 +- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/gen/dibuilder.cpp b/gen/dibuilder.cpp index 1ae5658960e..5843c98e588 100644 --- a/gen/dibuilder.cpp +++ b/gen/dibuilder.cpp @@ -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 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); } @@ -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? @@ -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(); diff --git a/gen/dibuilder.h b/gen/dibuilder.h index e6c31da43e4..094bd93d2bf 100644 --- a/gen/dibuilder.h +++ b/gen/dibuilder.h @@ -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);