This is an archive of the discontinued LLVM Phabricator instance.

Allow Template argument accessors to automatically unwrap parameter packs
ClosedPublic

Authored by JDevlieghere on Aug 28 2018, 3:47 PM.

Details

Summary

When looking at template arguments in LLDB, we usually care about what
the user passed in his code, not whether some of those arguments where
passed as a variadic parameter pack.

This patch extends all the C++ APIs to look at template parameters to
take an additional 'expand_pack' boolean that automatically unwraps the
potential argument packs. The equivalent SBAPI calls have been changed
to pass true for this parameter.

A byproduct of the patch is to also fix the support for template type
that have only a parameter pack as argument (like the OnlyPack type in
the test). Those were not recognized as template instanciations before.

The added test verifies that the SBAPI is able to iterate over the
arguments of a variadic template.

Diff Detail

Event Timeline

friss created this revision.Aug 28 2018, 3:47 PM

Looks fine. A bit of cleanup might be nice on the TypeSystem.h to provide default implementations that just return 0 for some of these that every type system currently is required to override for no reason (all template related type system calls seem to have default "return 0;" functions in each type system. We can make future changes to these touch fewer files if we provide default implementations in TypeSystem.h.

include/lldb/Symbol/CompilerType.h
367–376 ↗(On Diff #162973)

I know there wasn't documentation on these functions, but it might be nice to docuement what "expand_pack" means.

include/lldb/Symbol/GoASTContext.h
313–316 ↗(On Diff #162973)

We should make a default implementation of this function in TypeSystem.h so not every TypeSystem subclass needs to make a do nothing and return 0 function. It will make future changes easier and touch less files.

include/lldb/Symbol/OCamlASTContext.h
230–233 ↗(On Diff #162973)

We should make a default implementation of this function in TypeSystem.h so not every TypeSystem subclass needs to make a do nothing and return 0 function. It will make future changes easier and touch less files.

source/Symbol/JavaASTContext.cpp
881–885 ↗(On Diff #162973)

We should make a default implementation of this function in TypeSystem.h so not every TypeSystem subclass needs to make a do nothing and return 0 function. It will make future changes easier and touch less files.

shafik added a subscriber: shafik.Aug 29 2018, 10:36 AM
shafik added inline comments.
include/lldb/Symbol/ClangASTContext.h
284 ↗(On Diff #162973)

Is this saying that an empty parameter pack is invalid? We can have an empty parameter pack

https://godbolt.org/z/8zCFz9

792 ↗(On Diff #162973)

Why not default to false here?

794 ↗(On Diff #162973)

Why not default to false here?

797 ↗(On Diff #162973)

Why not default to false here?

source/Symbol/ClangASTContext.cpp
7569 ↗(On Diff #162973)

Do we need to check num_args != 0

7664 ↗(On Diff #162973)

The asset before we do math making this assumption i.e. args.size() - 1

friss added inline comments.Aug 29 2018, 5:47 PM
include/lldb/Symbol/ClangASTContext.h
284 ↗(On Diff #162973)

That's a good question. I need to check what the DWARF looks like for an empty parameter pack. I would expect it not to be mentioned at all, but if it's there we need to support it.

include/lldb/Symbol/GoASTContext.h
313–316 ↗(On Diff #162973)

I've done this in r341006, I'll rebase soon.

friss marked 2 inline comments as done.Aug 30 2018, 11:43 AM
friss added inline comments.
include/lldb/Symbol/ClangASTContext.h
284 ↗(On Diff #162973)

This was a good catch. The fact that there is an empty pack was recorded in the debug info and this made us consider the type as invalid. I've added a test to cover this.

792 ↗(On Diff #162973)

I added the defaults at the top to keep the semantics for the existing code, but it turns out there's no code using those interfaces that I haven't updated. I'll remove the defaults from everywhere.

source/Symbol/ClangASTContext.cpp
7664 ↗(On Diff #162973)

The assert is also wrong because of the empty pack issue. I'll update the patch.

friss added inline comments.Aug 30 2018, 11:46 AM
source/Symbol/ClangASTContext.cpp
7664 ↗(On Diff #162973)

Actually, this is not true. The Decl will always have at least one argument which is the pack. The pack can be empty, but the Decl still records it as one argument. The assert should be hoisted though.

friss updated this revision to Diff 163399.Aug 30 2018, 1:33 PM

Address feedback

clayborg accepted this revision.Aug 30 2018, 1:42 PM

Looks good to me. Jim should take a look as well.

This revision is now accepted and ready to land.Aug 30 2018, 1:42 PM
jingham requested changes to this revision.Sep 13 2018, 5:54 PM

I'm a little worried that we have asserts with no backstops here. We ship in general with asserts off, so if some type is not copasetic we will probably crash shortly afterwards (in one case we assert num_args but then do an array access of num_args - 1)...

Seems like in the places where you've added asserts, we could return 0 (no template arguments) and though we wouldn't print the type correctly lldb wouldn't crash. We should always assume that debug info might a little crappy and not crash. Maybe these Decl's have been vetted earlier? If that's the case I withdraw the objection.

source/Symbol/ClangASTContext.cpp
7568–7570 ↗(On Diff #163399)

IIUC, we would get into this state because debug information is messed up. lldb should never crash because of mal-formed debug information. It's fine to assert here so that if this happens say in a new compiler we can catch it in the test suite. But you should also return 0, since that's a straightforward workaround for bad debug information.

This revision now requires changes to proceed.Sep 13 2018, 5:54 PM
oliora added a subscriber: oliora.Feb 6 2019, 6:59 AM

Do we have any callers that call GetNumTemplateArguments with false? If not, remove the argument?

JDevlieghere commandeered this revision.Aug 10 2022, 9:00 PM
JDevlieghere added a reviewer: friss.

Commandeering this from Fred

Herald added a project: Restricted Project. · View Herald Transcript
  • Rebase
  • Address Jim's code review feedback

Do we have any callers that call GetNumTemplateArguments with false? If not, remove the argument?

Yup, there's a bunch of uses in Language/CPlusPlus/LibCxx*.cpp

Michael137 accepted this revision.Aug 16 2022, 4:53 AM

LGTM

Just had some minor stylistic/documentation suggestions

lldb/source/API/SBType.cpp
576

Minor: this could be an opportunity to add documentation for this API in SBType.h, mentioning that parameter packs are always expanded

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
7122
7167

Do we use args.size() - 1 enough times throughout this function that it warrants something like const auto lastIdx = args.size() - 1;?

7172

In my opinion this series of checks is subtle enough to warrant some comments. But not a blocker

7175
7179
7181

Do we want a defensive check on 'idx' here? Something along the lines of

const auto pack_idx  = idx - (args.size() - 1);
const auto pack_size = pack.pack_size();
assert (pack_idx < pack_size && "Parameter pack index out-of-bounds");
if (pack_idx >= pack_size)
  return nullptr;
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
325

Minor: this comment applies to the condition on line 330 now. Could move it down?

JDevlieghere marked 8 inline comments as done.Aug 16 2022, 6:10 PM

Thanks for the review Michael. I've addressed all your comments in the version I landed.

This revision was not accepted when it landed; it landed in state Needs Review.Aug 16 2022, 6:10 PM
This revision was automatically updated to reflect the committed changes.
Herald added a project: Restricted Project. · View Herald TranscriptAug 16 2022, 6:10 PM