Skip to content

[DebugInfo] Emit debug info for witness tables #81661

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

Open
wants to merge 2 commits into
base: release/6.2
Choose a base branch
from

Conversation

augusto2112
Copy link
Contributor

  • Explanation: This change emits debug info for witness tables passed into generic functions when a generic type is constrained to a protocol. This information is required for LLDB's generic expression evaluator to work in such functions.
  • Scope: Debug info generation for functions inside generic types with constrained generics.
  • Issues: rdar://104446865
  • Original PR: [DebugInfo] Emit debug info for witness tables #79171 and Fix accidental deletion of part of test #81660 (where I fix a test which I accidentally removed)
  • Risk: Medium, affects debug info generation for types with constrained generics, as well as emitting witness table refs for constrained generic paramenters.
  • Testing: Added a new test, updated many existing tests to account for the new debug info.
  • Reviewers: @adrian-prantl

This change emits debug info for witness tables passed into generic
functions when a generic type is constrained to a protocol. This
information is required for LLDB's generic expression evaluator
to work in such functions.

rdar://104446865
(cherry picked from commit 53d10f4c651934d1ac76b59f2f0ce2f52059f956)
Commit 53d10f4c651934d1ac76b59f2f0ce2f52059f956 accidentally deleted
parts of move_function_dbginfo test. This just reintroduces the deleted
lines

(cherry picked from commit 2a755b8)
@augusto2112 augusto2112 requested a review from a team as a code owner May 21, 2025 01:34
@augusto2112
Copy link
Contributor Author

@swift-ci test

@@ -1163,8 +1163,42 @@ class IRGenSILFunction :
emitPackCountDebugVariable(Shape);
}
});

if (auto *BGT = llvm::dyn_cast<BoundGenericType>(Ty)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also nest non-generic nominals inside other generic nominals, eg

struct G<T> {
  struct Inner {}
 }

Eg, G<Int>.Inner is not a BoundGenericType.

Just use getAnyNominal() instead

auto GE = Decl->getGenericEnvironment();
auto Requirements = BGT->getDecl()
->getGenericEnvironment()
->getGenericSignature()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can replace ->getGenericEnvironment()->getGenericSignature() with ->getGenericSignature()

auto ProtocolDecl = Requirement.getProtocolDecl();
auto ConformingType = Requirement.getFirstType();
Type Archetype;
if (auto GTPT = llvm::dyn_cast<GenericTypeParamType>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These conditionals are unnecessary. mapTypeIntoContext() takes a Type. Also, we use ConformingType->getAs<...> and not llvm::dyn_cast<>(ConformingType.getPointer())

Archetype = GE->mapTypeIntoContext(GTPT);
else if (auto DMT = llvm::dyn_cast<DependentMemberType>(
ConformingType.getPointer()))
Archetype = GE->mapTypeIntoContext(DMT);
Copy link
Contributor

@slavapestov slavapestov May 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what this code is trying to do, but it's not correct. The types Requirement are written with the generic signature of the BoundGenericType. The GE you have here on the other hand is a generic environment for the generic signature of the current function. So the mapTypeIntoContext() call will just return an ErrorType.

Also, you're not looking at the generic arguments of the BGT here. Presumably it should do that?

llvm::SmallString<16> name;
llvm::SmallString<16> displayName;
if (auto DMT =
llvm::dyn_cast<DependentMemberType>(interfaceType.getPointer())) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment about dyn_cast

name.append(member->getName().str());
displayName.append(member->getName().str());
};
name.append(DMT->getRootGenericParam()->getCanonicalName().str());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just print the generic param as the base case of the recursion? (where member->getBase() is not another DMT)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants