Skip to content

Commit 8abf6a9

Browse files
authored
Merge pull request #5137 from apple/🍒/rebranch/b706f56133a77f9d7c55270ac24ff59e6fce3fa4
[lldb] Automatically unwrap parameter packs in template argument accessors
2 parents af451be + 58d6125 commit 8abf6a9

File tree

15 files changed

+200
-73
lines changed

15 files changed

+200
-73
lines changed

lldb/include/lldb/API/SBType.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ class SBType {
182182

183183
lldb::SBType GetTemplateArgumentType(uint32_t idx);
184184

185+
/// Return the TemplateArgumentKind of the template argument at index idx.
186+
/// Variadic argument packs are automatically expanded.
185187
lldb::TemplateArgumentKind GetTemplateArgumentKind(uint32_t idx);
186188

187189
lldb::SBType GetFunctionReturnType();

lldb/include/lldb/Symbol/CompilerType.h

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,28 @@ class CompilerType {
344344
bool omit_empty_base_classes,
345345
std::vector<uint32_t> &child_indexes) const;
346346

347-
size_t GetNumTemplateArguments() const;
348-
349-
lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const;
350-
CompilerType GetTypeTemplateArgument(size_t idx) const;
347+
/// Return the number of template arguments the type has.
348+
/// If expand_pack is true, then variadic argument packs are automatically
349+
/// expanded to their supplied arguments. If it is false an argument pack
350+
/// will only count as 1 argument.
351+
size_t GetNumTemplateArguments(bool expand_pack = false) const;
352+
353+
// Return the TemplateArgumentKind of the template argument at index idx.
354+
// If expand_pack is true, then variadic argument packs are automatically
355+
// expanded to their supplied arguments. With expand_pack set to false, an
356+
// arguement pack will count as 1 argument and return a type of Pack.
357+
lldb::TemplateArgumentKind
358+
GetTemplateArgumentKind(size_t idx, bool expand_pack = false) const;
359+
CompilerType GetTypeTemplateArgument(size_t idx,
360+
bool expand_pack = false) const;
351361

352362
/// Returns the value of the template argument and its type.
363+
/// If expand_pack is true, then variadic argument packs are automatically
364+
/// expanded to their supplied arguments. With expand_pack set to false, an
365+
/// arguement pack will count as 1 argument and it is invalid to call this
366+
/// method on the pack argument.
353367
llvm::Optional<IntegralTemplateArgument>
354-
GetIntegralTemplateArgument(size_t idx) const;
368+
GetIntegralTemplateArgument(size_t idx, bool expand_pack = false) const;
355369

356370
CompilerType GetTypeForFormatters() const;
357371

lldb/include/lldb/Symbol/TypeSystem.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -376,14 +376,18 @@ class TypeSystem : public PluginInterface {
376376
bool omit_empty_base_classes,
377377
std::vector<uint32_t> &child_indexes) = 0;
378378

379-
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type);
379+
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
380+
bool expand_pack);
380381

381382
virtual lldb::TemplateArgumentKind
382-
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx);
383-
virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
384-
size_t idx);
383+
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx,
384+
bool expand_pack);
385+
virtual CompilerType
386+
GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
387+
bool expand_pack);
385388
virtual llvm::Optional<CompilerType::IntegralTemplateArgument>
386-
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx);
389+
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
390+
bool expand_pack);
387391

388392
// Dumping types
389393

lldb/source/API/SBType.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,8 @@ uint32_t SBType::GetNumberOfTemplateArguments() {
559559
LLDB_INSTRUMENT_VA(this);
560560

561561
if (IsValid())
562-
return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments();
562+
return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments(
563+
/*expand_pack=*/true);
563564
return 0;
564565
}
565566

@@ -570,13 +571,15 @@ lldb::SBType SBType::GetTemplateArgumentType(uint32_t idx) {
570571
return SBType();
571572

572573
CompilerType type;
574+
const bool expand_pack = true;
573575
switch(GetTemplateArgumentKind(idx)) {
574576
case eTemplateArgumentKindType:
575-
type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(idx);
577+
type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(
578+
idx, expand_pack);
576579
break;
577580
case eTemplateArgumentKindIntegral:
578581
type = m_opaque_sp->GetCompilerType(false)
579-
.GetIntegralTemplateArgument(idx)
582+
.GetIntegralTemplateArgument(idx, expand_pack)
580583
->type;
581584
break;
582585
default:
@@ -591,7 +594,8 @@ lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) {
591594
LLDB_INSTRUMENT_VA(this, idx);
592595

593596
if (IsValid())
594-
return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(idx);
597+
return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(
598+
idx, /*expand_pack=*/true);
595599
return eTemplateArgumentKindNull;
596600
}
597601

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

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7103,7 +7103,8 @@ uint32_t TypeSystemClang::GetIndexOfChildWithName(
71037103
}
71047104

71057105
size_t
7106-
TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
7106+
TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
7107+
bool expand_pack) {
71077108
if (!type)
71087109
return 0;
71097110

@@ -7118,8 +7119,17 @@ TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
71187119
const clang::ClassTemplateSpecializationDecl *template_decl =
71197120
llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
71207121
cxx_record_decl);
7121-
if (template_decl)
7122-
return template_decl->getTemplateArgs().size();
7122+
if (template_decl) {
7123+
const auto &template_arg_list = template_decl->getTemplateArgs();
7124+
size_t num_args = template_arg_list.size();
7125+
assert(num_args && "template specialization without any args");
7126+
if (expand_pack && num_args) {
7127+
const auto &pack = template_arg_list[num_args - 1];
7128+
if (pack.getKind() == clang::TemplateArgument::Pack)
7129+
num_args += pack.pack_size() - 1;
7130+
}
7131+
return num_args;
7132+
}
71237133
}
71247134
}
71257135
break;
@@ -7156,15 +7166,51 @@ TypeSystemClang::GetAsTemplateSpecialization(
71567166
}
71577167
}
71587168

7169+
const TemplateArgument *
7170+
GetNthTemplateArgument(const clang::ClassTemplateSpecializationDecl *decl,
7171+
size_t idx, bool expand_pack) {
7172+
const auto &args = decl->getTemplateArgs();
7173+
const size_t args_size = args.size();
7174+
7175+
assert(args_size && "template specialization without any args");
7176+
if (!args_size)
7177+
return nullptr;
7178+
7179+
const size_t last_idx = args_size - 1;
7180+
7181+
// We're asked for a template argument that can't be a parameter pack, so
7182+
// return it without worrying about 'expand_pack'.
7183+
if (idx < last_idx)
7184+
return &args[idx];
7185+
7186+
// We're asked for the last template argument but we don't want/need to
7187+
// expand it.
7188+
if (!expand_pack || args[last_idx].getKind() != clang::TemplateArgument::Pack)
7189+
return idx >= args.size() ? nullptr : &args[idx];
7190+
7191+
// Index into the expanded pack.
7192+
// Note that 'idx' counts from the beginning of all template arguments
7193+
// (including the ones preceding the parameter pack).
7194+
const auto &pack = args[last_idx];
7195+
const size_t pack_idx = idx - last_idx;
7196+
const size_t pack_size = pack.pack_size();
7197+
assert(pack_idx < pack_size && "parameter pack index out-of-bounds");
7198+
return &pack.pack_elements()[pack_idx];
7199+
}
7200+
71597201
lldb::TemplateArgumentKind
71607202
TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
7161-
size_t arg_idx) {
7203+
size_t arg_idx, bool expand_pack) {
71627204
const clang::ClassTemplateSpecializationDecl *template_decl =
71637205
GetAsTemplateSpecialization(type);
7164-
if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size())
7206+
if (!template_decl)
7207+
return eTemplateArgumentKindNull;
7208+
7209+
const auto *arg = GetNthTemplateArgument(template_decl, arg_idx, expand_pack);
7210+
if (!arg)
71657211
return eTemplateArgumentKindNull;
71667212

7167-
switch (template_decl->getTemplateArgs()[arg_idx].getKind()) {
7213+
switch (arg->getKind()) {
71687214
case clang::TemplateArgument::Null:
71697215
return eTemplateArgumentKindNull;
71707216

@@ -7197,35 +7243,32 @@ TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
71977243

71987244
CompilerType
71997245
TypeSystemClang::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
7200-
size_t idx) {
7246+
size_t idx, bool expand_pack) {
72017247
const clang::ClassTemplateSpecializationDecl *template_decl =
72027248
GetAsTemplateSpecialization(type);
7203-
if (!template_decl || idx >= template_decl->getTemplateArgs().size())
7249+
if (!template_decl)
72047250
return CompilerType();
72057251

7206-
const clang::TemplateArgument &template_arg =
7207-
template_decl->getTemplateArgs()[idx];
7208-
if (template_arg.getKind() != clang::TemplateArgument::Type)
7252+
const auto *arg = GetNthTemplateArgument(template_decl, idx, expand_pack);
7253+
if (!arg || arg->getKind() != clang::TemplateArgument::Type)
72097254
return CompilerType();
72107255

7211-
return GetType(template_arg.getAsType());
7256+
return GetType(arg->getAsType());
72127257
}
72137258

72147259
Optional<CompilerType::IntegralTemplateArgument>
72157260
TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
7216-
size_t idx) {
7261+
size_t idx, bool expand_pack) {
72177262
const clang::ClassTemplateSpecializationDecl *template_decl =
72187263
GetAsTemplateSpecialization(type);
7219-
if (! template_decl || idx >= template_decl->getTemplateArgs().size())
7264+
if (!template_decl)
72207265
return llvm::None;
72217266

7222-
const clang::TemplateArgument &template_arg =
7223-
template_decl->getTemplateArgs()[idx];
7224-
if (template_arg.getKind() != clang::TemplateArgument::Integral)
7267+
const auto *arg = GetNthTemplateArgument(template_decl, idx, expand_pack);
7268+
if (!arg || arg->getKind() != clang::TemplateArgument::Integral)
72257269
return llvm::None;
72267270

7227-
return {
7228-
{template_arg.getAsIntegral(), GetType(template_arg.getIntegralType())}};
7271+
return {{arg->getAsIntegral(), GetType(arg->getIntegralType())}};
72297272
}
72307273

72317274
CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {

lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class TypePayloadClang {
9191
void SetOwningModule(OptionalClangModuleID id);
9292
/// \}
9393
};
94-
94+
9595
/// A TypeSystem implementation based on Clang.
9696
///
9797
/// This class uses a single clang::ASTContext as the backend for storing
@@ -336,7 +336,7 @@ class TypeSystemClang : public TypeSystem {
336336

337337
llvm::SmallVector<const char *, 2> names;
338338
llvm::SmallVector<clang::TemplateArgument, 2> args;
339-
339+
340340
const char * pack_name = nullptr;
341341
std::unique_ptr<TemplateParameterInfos> packed_args;
342342
};
@@ -539,7 +539,7 @@ class TypeSystemClang : public TypeSystem {
539539
#ifndef NDEBUG
540540
bool Verify(lldb::opaque_compiler_type_t type) override;
541541
#endif
542-
542+
543543
bool IsArrayType(lldb::opaque_compiler_type_t type,
544544
CompilerType *element_type, uint64_t *size,
545545
bool *is_incomplete) override;
@@ -821,16 +821,17 @@ class TypeSystemClang : public TypeSystem {
821821
bool omit_empty_base_classes,
822822
std::vector<uint32_t> &child_indexes) override;
823823

824-
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
824+
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
825+
bool expand_pack) override;
825826

826827
lldb::TemplateArgumentKind
827-
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
828-
size_t idx) override;
828+
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx,
829+
bool expand_pack) override;
829830
CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
830-
size_t idx) override;
831+
size_t idx, bool expand_pack) override;
831832
llvm::Optional<CompilerType::IntegralTemplateArgument>
832-
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
833-
size_t idx) override;
833+
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
834+
bool expand_pack) override;
834835

835836
CompilerType GetTypeForFormatters(void *type) override;
836837

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7396,7 +7396,8 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName(
73967396
return 0;
73977397
}
73987398

7399-
size_t SwiftASTContext::GetNumTemplateArguments(opaque_compiler_type_t type) {
7399+
size_t SwiftASTContext::GetNumTemplateArguments(opaque_compiler_type_t type,
7400+
bool expand_pack) {
74007401
VALID_OR_RETURN_CHECK_TYPE(type, 0);
74017402

74027403
swift::CanType swift_can_type(GetCanonicalSwiftType(type));

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,8 @@ class SwiftASTContext : public TypeSystemSwift {
654654
bool omit_empty_base_classes,
655655
std::vector<uint32_t> &child_indexes) override;
656656

657-
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
657+
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
658+
bool expand_pack) override;
658659

659660
lldb::GenericKind GetGenericArgumentKind(lldb::opaque_compiler_type_t type,
660661
size_t idx);

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3067,7 +3067,8 @@ size_t TypeSystemSwiftTypeRef::GetIndexOfChildMemberWithName(
30673067
}
30683068

30693069
size_t
3070-
TypeSystemSwiftTypeRef::GetNumTemplateArguments(opaque_compiler_type_t type) {
3070+
TypeSystemSwiftTypeRef::GetNumTemplateArguments(opaque_compiler_type_t type,
3071+
bool expand_pack) {
30713072
auto impl = [&]() -> size_t {
30723073
using namespace swift::Demangle;
30733074
Demangler dem;
@@ -3096,7 +3097,8 @@ TypeSystemSwiftTypeRef::GetNumTemplateArguments(opaque_compiler_type_t type) {
30963097
return 0;
30973098
};
30983099
VALIDATE_AND_RETURN(impl, GetNumTemplateArguments, type, g_no_exe_ctx,
3099-
(ReconstructType(type)), (ReconstructType(type)));
3100+
(ReconstructType(type), expand_pack),
3101+
(ReconstructType(type), expand_pack));
31003102
}
31013103

31023104
CompilerType

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,8 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
191191
const char *name, ExecutionContext *exe_ctx,
192192
bool omit_empty_base_classes,
193193
std::vector<uint32_t> &child_indexes) override;
194-
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
194+
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
195+
bool expand_pack) override;
195196
CompilerType GetTypeForFormatters(lldb::opaque_compiler_type_t type) override;
196197
LazyBool ShouldPrintAsOneLiner(lldb::opaque_compiler_type_t type,
197198
ValueObject *valobj) override;

lldb/source/Symbol/CompilerType.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -675,30 +675,32 @@ size_t CompilerType::GetIndexOfChildMemberWithName(
675675
return 0;
676676
}
677677

678-
size_t CompilerType::GetNumTemplateArguments() const {
678+
size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
679679
if (IsValid()) {
680-
return m_type_system->GetNumTemplateArguments(m_type);
680+
return m_type_system->GetNumTemplateArguments(m_type, expand_pack);
681681
}
682682
return 0;
683683
}
684684

685-
TemplateArgumentKind CompilerType::GetTemplateArgumentKind(size_t idx) const {
685+
TemplateArgumentKind
686+
CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
686687
if (IsValid())
687-
return m_type_system->GetTemplateArgumentKind(m_type, idx);
688+
return m_type_system->GetTemplateArgumentKind(m_type, idx, expand_pack);
688689
return eTemplateArgumentKindNull;
689690
}
690691

691-
CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const {
692+
CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
693+
bool expand_pack) const {
692694
if (IsValid()) {
693-
return m_type_system->GetTypeTemplateArgument(m_type, idx);
695+
return m_type_system->GetTypeTemplateArgument(m_type, idx, expand_pack);
694696
}
695697
return CompilerType();
696698
}
697699

698700
llvm::Optional<CompilerType::IntegralTemplateArgument>
699-
CompilerType::GetIntegralTemplateArgument(size_t idx) const {
701+
CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
700702
if (IsValid())
701-
return m_type_system->GetIntegralTemplateArgument(m_type, idx);
703+
return m_type_system->GetIntegralTemplateArgument(m_type, idx, expand_pack);
702704
return llvm::None;
703705
}
704706

0 commit comments

Comments
 (0)