Skip to content

[lldb] Automatically unwrap parameter packs in template argument accessors #5137

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lldb/include/lldb/API/SBType.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ class SBType {

lldb::SBType GetTemplateArgumentType(uint32_t idx);

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

lldb::SBType GetFunctionReturnType();
Expand Down
24 changes: 19 additions & 5 deletions lldb/include/lldb/Symbol/CompilerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,14 +344,28 @@ class CompilerType {
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) const;

size_t GetNumTemplateArguments() const;

lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const;
CompilerType GetTypeTemplateArgument(size_t idx) const;
/// Return the number of template arguments the type has.
/// If expand_pack is true, then variadic argument packs are automatically
/// expanded to their supplied arguments. If it is false an argument pack
/// will only count as 1 argument.
size_t GetNumTemplateArguments(bool expand_pack = false) const;

// Return the TemplateArgumentKind of the template argument at index idx.
// If expand_pack is true, then variadic argument packs are automatically
// expanded to their supplied arguments. With expand_pack set to false, an
// arguement pack will count as 1 argument and return a type of Pack.
lldb::TemplateArgumentKind
GetTemplateArgumentKind(size_t idx, bool expand_pack = false) const;
CompilerType GetTypeTemplateArgument(size_t idx,
bool expand_pack = false) const;

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

CompilerType GetTypeForFormatters() const;

Expand Down
14 changes: 9 additions & 5 deletions lldb/include/lldb/Symbol/TypeSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,14 +376,18 @@ class TypeSystem : public PluginInterface {
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) = 0;

virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type);
virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
bool expand_pack);

virtual lldb::TemplateArgumentKind
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx);
virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx);
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx,
bool expand_pack);
virtual CompilerType
GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
bool expand_pack);
virtual llvm::Optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx);
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
bool expand_pack);

// Dumping types

Expand Down
12 changes: 8 additions & 4 deletions lldb/source/API/SBType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,8 @@ uint32_t SBType::GetNumberOfTemplateArguments() {
LLDB_INSTRUMENT_VA(this);

if (IsValid())
return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments();
return m_opaque_sp->GetCompilerType(false).GetNumTemplateArguments(
/*expand_pack=*/true);
return 0;
}

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

CompilerType type;
const bool expand_pack = true;
switch(GetTemplateArgumentKind(idx)) {
case eTemplateArgumentKindType:
type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(idx);
type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(
idx, expand_pack);
break;
case eTemplateArgumentKindIntegral:
type = m_opaque_sp->GetCompilerType(false)
.GetIntegralTemplateArgument(idx)
.GetIntegralTemplateArgument(idx, expand_pack)
->type;
break;
default:
Expand All @@ -591,7 +594,8 @@ lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) {
LLDB_INSTRUMENT_VA(this, idx);

if (IsValid())
return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(idx);
return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(
idx, /*expand_pack=*/true);
return eTemplateArgumentKindNull;
}

Expand Down
81 changes: 62 additions & 19 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7103,7 +7103,8 @@ uint32_t TypeSystemClang::GetIndexOfChildWithName(
}

size_t
TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
bool expand_pack) {
if (!type)
return 0;

Expand All @@ -7118,8 +7119,17 @@ TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) {
const clang::ClassTemplateSpecializationDecl *template_decl =
llvm::dyn_cast<clang::ClassTemplateSpecializationDecl>(
cxx_record_decl);
if (template_decl)
return template_decl->getTemplateArgs().size();
if (template_decl) {
const auto &template_arg_list = template_decl->getTemplateArgs();
size_t num_args = template_arg_list.size();
assert(num_args && "template specialization without any args");
if (expand_pack && num_args) {
const auto &pack = template_arg_list[num_args - 1];
if (pack.getKind() == clang::TemplateArgument::Pack)
num_args += pack.pack_size() - 1;
}
return num_args;
}
}
}
break;
Expand Down Expand Up @@ -7156,15 +7166,51 @@ TypeSystemClang::GetAsTemplateSpecialization(
}
}

const TemplateArgument *
GetNthTemplateArgument(const clang::ClassTemplateSpecializationDecl *decl,
size_t idx, bool expand_pack) {
const auto &args = decl->getTemplateArgs();
const size_t args_size = args.size();

assert(args_size && "template specialization without any args");
if (!args_size)
return nullptr;

const size_t last_idx = args_size - 1;

// We're asked for a template argument that can't be a parameter pack, so
// return it without worrying about 'expand_pack'.
if (idx < last_idx)
return &args[idx];

// We're asked for the last template argument but we don't want/need to
// expand it.
if (!expand_pack || args[last_idx].getKind() != clang::TemplateArgument::Pack)
return idx >= args.size() ? nullptr : &args[idx];

// Index into the expanded pack.
// Note that 'idx' counts from the beginning of all template arguments
// (including the ones preceding the parameter pack).
const auto &pack = args[last_idx];
const size_t pack_idx = idx - last_idx;
const size_t pack_size = pack.pack_size();
assert(pack_idx < pack_size && "parameter pack index out-of-bounds");
return &pack.pack_elements()[pack_idx];
}

lldb::TemplateArgumentKind
TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
size_t arg_idx) {
size_t arg_idx, bool expand_pack) {
const clang::ClassTemplateSpecializationDecl *template_decl =
GetAsTemplateSpecialization(type);
if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size())
if (!template_decl)
return eTemplateArgumentKindNull;

const auto *arg = GetNthTemplateArgument(template_decl, arg_idx, expand_pack);
if (!arg)
return eTemplateArgumentKindNull;

switch (template_decl->getTemplateArgs()[arg_idx].getKind()) {
switch (arg->getKind()) {
case clang::TemplateArgument::Null:
return eTemplateArgumentKindNull;

Expand Down Expand Up @@ -7197,35 +7243,32 @@ TypeSystemClang::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,

CompilerType
TypeSystemClang::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) {
size_t idx, bool expand_pack) {
const clang::ClassTemplateSpecializationDecl *template_decl =
GetAsTemplateSpecialization(type);
if (!template_decl || idx >= template_decl->getTemplateArgs().size())
if (!template_decl)
return CompilerType();

const clang::TemplateArgument &template_arg =
template_decl->getTemplateArgs()[idx];
if (template_arg.getKind() != clang::TemplateArgument::Type)
const auto *arg = GetNthTemplateArgument(template_decl, idx, expand_pack);
if (!arg || arg->getKind() != clang::TemplateArgument::Type)
return CompilerType();

return GetType(template_arg.getAsType());
return GetType(arg->getAsType());
}

Optional<CompilerType::IntegralTemplateArgument>
TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) {
size_t idx, bool expand_pack) {
const clang::ClassTemplateSpecializationDecl *template_decl =
GetAsTemplateSpecialization(type);
if (! template_decl || idx >= template_decl->getTemplateArgs().size())
if (!template_decl)
return llvm::None;

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

return {
{template_arg.getAsIntegral(), GetType(template_arg.getIntegralType())}};
return {{arg->getAsIntegral(), GetType(arg->getIntegralType())}};
}

CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {
Expand Down
19 changes: 10 additions & 9 deletions lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class TypePayloadClang {
void SetOwningModule(OptionalClangModuleID id);
/// \}
};

/// A TypeSystem implementation based on Clang.
///
/// This class uses a single clang::ASTContext as the backend for storing
Expand Down Expand Up @@ -336,7 +336,7 @@ class TypeSystemClang : public TypeSystem {

llvm::SmallVector<const char *, 2> names;
llvm::SmallVector<clang::TemplateArgument, 2> args;

const char * pack_name = nullptr;
std::unique_ptr<TemplateParameterInfos> packed_args;
};
Expand Down Expand Up @@ -539,7 +539,7 @@ class TypeSystemClang : public TypeSystem {
#ifndef NDEBUG
bool Verify(lldb::opaque_compiler_type_t type) override;
#endif

bool IsArrayType(lldb::opaque_compiler_type_t type,
CompilerType *element_type, uint64_t *size,
bool *is_incomplete) override;
Expand Down Expand Up @@ -821,16 +821,17 @@ class TypeSystemClang : public TypeSystem {
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) override;

size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
bool expand_pack) override;

lldb::TemplateArgumentKind
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
size_t idx) override;
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx,
bool expand_pack) override;
CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) override;
size_t idx, bool expand_pack) override;
llvm::Optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) override;
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx,
bool expand_pack) override;

CompilerType GetTypeForFormatters(void *type) override;

Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7396,7 +7396,8 @@ size_t SwiftASTContext::GetIndexOfChildMemberWithName(
return 0;
}

size_t SwiftASTContext::GetNumTemplateArguments(opaque_compiler_type_t type) {
size_t SwiftASTContext::GetNumTemplateArguments(opaque_compiler_type_t type,
bool expand_pack) {
VALID_OR_RETURN_CHECK_TYPE(type, 0);

swift::CanType swift_can_type(GetCanonicalSwiftType(type));
Expand Down
3 changes: 2 additions & 1 deletion lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -654,7 +654,8 @@ class SwiftASTContext : public TypeSystemSwift {
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) override;

size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
bool expand_pack) override;

lldb::GenericKind GetGenericArgumentKind(lldb::opaque_compiler_type_t type,
size_t idx);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3067,7 +3067,8 @@ size_t TypeSystemSwiftTypeRef::GetIndexOfChildMemberWithName(
}

size_t
TypeSystemSwiftTypeRef::GetNumTemplateArguments(opaque_compiler_type_t type) {
TypeSystemSwiftTypeRef::GetNumTemplateArguments(opaque_compiler_type_t type,
bool expand_pack) {
auto impl = [&]() -> size_t {
using namespace swift::Demangle;
Demangler dem;
Expand Down Expand Up @@ -3096,7 +3097,8 @@ TypeSystemSwiftTypeRef::GetNumTemplateArguments(opaque_compiler_type_t type) {
return 0;
};
VALIDATE_AND_RETURN(impl, GetNumTemplateArguments, type, g_no_exe_ctx,
(ReconstructType(type)), (ReconstructType(type)));
(ReconstructType(type), expand_pack),
(ReconstructType(type), expand_pack));
}

CompilerType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
const char *name, ExecutionContext *exe_ctx,
bool omit_empty_base_classes,
std::vector<uint32_t> &child_indexes) override;
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
bool expand_pack) override;
CompilerType GetTypeForFormatters(lldb::opaque_compiler_type_t type) override;
LazyBool ShouldPrintAsOneLiner(lldb::opaque_compiler_type_t type,
ValueObject *valobj) override;
Expand Down
18 changes: 10 additions & 8 deletions lldb/source/Symbol/CompilerType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,30 +675,32 @@ size_t CompilerType::GetIndexOfChildMemberWithName(
return 0;
}

size_t CompilerType::GetNumTemplateArguments() const {
size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
if (IsValid()) {
return m_type_system->GetNumTemplateArguments(m_type);
return m_type_system->GetNumTemplateArguments(m_type, expand_pack);
}
return 0;
}

TemplateArgumentKind CompilerType::GetTemplateArgumentKind(size_t idx) const {
TemplateArgumentKind
CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
if (IsValid())
return m_type_system->GetTemplateArgumentKind(m_type, idx);
return m_type_system->GetTemplateArgumentKind(m_type, idx, expand_pack);
return eTemplateArgumentKindNull;
}

CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const {
CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
bool expand_pack) const {
if (IsValid()) {
return m_type_system->GetTypeTemplateArgument(m_type, idx);
return m_type_system->GetTypeTemplateArgument(m_type, idx, expand_pack);
}
return CompilerType();
}

llvm::Optional<CompilerType::IntegralTemplateArgument>
CompilerType::GetIntegralTemplateArgument(size_t idx) const {
CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
if (IsValid())
return m_type_system->GetIntegralTemplateArgument(m_type, idx);
return m_type_system->GetIntegralTemplateArgument(m_type, idx, expand_pack);
return llvm::None;
}

Expand Down
Loading