Index: include/lldb/Symbol/ClangASTContext.h =================================================================== --- include/lldb/Symbol/ClangASTContext.h +++ include/lldb/Symbol/ClangASTContext.h @@ -782,9 +782,14 @@ size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; - CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, - size_t idx, - lldb::TemplateArgumentKind &kind) override; + lldb::TemplateArgumentKind + GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, + size_t idx) override; + CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx) override; + std::pair + GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx) override; CompilerType GetTypeForFormatters(void *type) override; @@ -971,6 +976,9 @@ return m_origins; } protected: + const clang::ClassTemplateSpecializationDecl * + GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); + //------------------------------------------------------------------ // Classes that inherit from ClangASTContext can see and modify these //------------------------------------------------------------------ Index: include/lldb/Symbol/CompilerType.h =================================================================== --- include/lldb/Symbol/CompilerType.h +++ include/lldb/Symbol/CompilerType.h @@ -365,8 +365,12 @@ size_t GetNumTemplateArguments() const; - CompilerType GetTemplateArgument(size_t idx, - lldb::TemplateArgumentKind &kind) const; + lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const; + CompilerType GetTypeTemplateArgument(size_t idx) const; + + // Returns the value of the template argument and its type. In case the + // argument is not found, returns an invalid CompilerType. + std::pair GetIntegralTemplateArgument(size_t idx) const; CompilerType GetTypeForFormatters() const; Index: include/lldb/Symbol/GoASTContext.h =================================================================== --- include/lldb/Symbol/GoASTContext.h +++ include/lldb/Symbol/GoASTContext.h @@ -315,12 +315,6 @@ return 0; } - CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, - size_t idx, - lldb::TemplateArgumentKind &kind) override { - return CompilerType(); - } - //---------------------------------------------------------------------- // Dumping types //---------------------------------------------------------------------- Index: include/lldb/Symbol/JavaASTContext.h =================================================================== --- include/lldb/Symbol/JavaASTContext.h +++ include/lldb/Symbol/JavaASTContext.h @@ -203,10 +203,6 @@ size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; - CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, - size_t idx, - lldb::TemplateArgumentKind &kind) override; - int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, Index: include/lldb/Symbol/OCamlASTContext.h =================================================================== --- include/lldb/Symbol/OCamlASTContext.h +++ include/lldb/Symbol/OCamlASTContext.h @@ -231,12 +231,6 @@ return 0; } - CompilerType GetTemplateArgument(lldb::opaque_compiler_type_t type, - size_t idx, - lldb::TemplateArgumentKind &kind) override { - return CompilerType(); - } - void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, Index: include/lldb/Symbol/TypeSystem.h =================================================================== --- include/lldb/Symbol/TypeSystem.h +++ include/lldb/Symbol/TypeSystem.h @@ -351,9 +351,13 @@ virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) = 0; - virtual CompilerType - GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, - lldb::TemplateArgumentKind &kind) = 0; + 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); + virtual std::pair + GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx); //---------------------------------------------------------------------- // Dumping types Index: include/lldb/lldb-enumerations.h =================================================================== --- include/lldb/lldb-enumerations.h +++ include/lldb/lldb-enumerations.h @@ -767,8 +767,8 @@ eTemplateArgumentKindTemplate, eTemplateArgumentKindTemplateExpansion, eTemplateArgumentKindExpression, - eTemplateArgumentKindPack - + eTemplateArgumentKindPack, + eTemplateArgumentKindNullPtr, }; //---------------------------------------------------------------------- Index: source/API/SBType.cpp =================================================================== --- source/API/SBType.cpp +++ source/API/SBType.cpp @@ -415,21 +415,31 @@ } lldb::SBType SBType::GetTemplateArgumentType(uint32_t idx) { - if (IsValid()) { - TemplateArgumentKind kind = eTemplateArgumentKindNull; - CompilerType template_arg_type = - m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind); - if (template_arg_type.IsValid()) - return SBType(template_arg_type); + if (!IsValid()) + return SBType(); + + CompilerType type; + switch(GetTemplateArgumentKind(idx)) { + case eTemplateArgumentKindType: + type = m_opaque_sp->GetCompilerType(false).GetTypeTemplateArgument(idx); + break; + case eTemplateArgumentKindIntegral: + type = m_opaque_sp->GetCompilerType(false) + .GetIntegralTemplateArgument(idx) + .second; + break; + default: + break; } + if (type.IsValid()) + return SBType(type); return SBType(); } lldb::TemplateArgumentKind SBType::GetTemplateArgumentKind(uint32_t idx) { - TemplateArgumentKind kind = eTemplateArgumentKindNull; if (IsValid()) - m_opaque_sp->GetCompilerType(false).GetTemplateArgument(idx, kind); - return kind; + return m_opaque_sp->GetCompilerType(false).GetTemplateArgumentKind(idx); + return eTemplateArgumentKindNull; } SBTypeList::SBTypeList() : m_opaque_ap(new TypeListImpl()) {} Index: source/Plugins/Language/CPlusPlus/LibCxx.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -153,12 +153,11 @@ .get(); if (m_pair_ptr) { auto __i_(valobj_sp->GetChildMemberWithName(g___i_, true)); - lldb::TemplateArgumentKind kind; if (!__i_) { m_pair_ptr = nullptr; return false; } - CompilerType pair_type(__i_->GetCompilerType().GetTemplateArgument(0, kind)); + CompilerType pair_type(__i_->GetCompilerType().GetTypeTemplateArgument(0)); std::string name; uint64_t bit_offset_ptr; uint32_t bitfield_bit_size_ptr; bool is_bitfield_ptr; pair_type = pair_type.GetFieldAtIndex(0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr); if (!pair_type) { Index: source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -94,9 +94,8 @@ m_start = nullptr; m_num_elements = 0; - lldb::TemplateArgumentKind kind; - m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind); - if (kind != lldb::eTemplateArgumentKindType || !m_element_type.IsValid()) + m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0); + if (!m_element_type.IsValid()) return false; m_element_size = m_element_type.GetByteSize(nullptr); Index: source/Plugins/Language/CPlusPlus/LibCxxList.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -192,8 +192,7 @@ if (list_type.GetNumTemplateArguments() == 0) return false; - TemplateArgumentKind kind; - m_element_type = list_type.GetTemplateArgument(0, kind); + m_element_type = list_type.GetTypeTemplateArgument(0); return false; } Index: source/Plugins/Language/CPlusPlus/LibCxxMap.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -268,13 +268,12 @@ m_element_type = deref->GetCompilerType(); return true; } - lldb::TemplateArgumentKind kind; deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3}); if (!deref) return false; - m_element_type = - deref->GetCompilerType().GetTemplateArgument(1, kind).GetTemplateArgument( - 1, kind); + m_element_type = deref->GetCompilerType() + .GetTypeTemplateArgument(1) + .GetTypeTemplateArgument(1); if (m_element_type) { std::string name; uint64_t bit_offset_ptr; @@ -285,7 +284,7 @@ m_element_type = m_element_type.GetTypedefedType(); return m_element_type.IsValid(); } else { - m_element_type = m_backend.GetCompilerType().GetTemplateArgument(0, kind); + m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0); return m_element_type.IsValid(); } } Index: source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -121,11 +121,10 @@ if (!first_sp) return nullptr; m_element_type = first_sp->GetCompilerType(); - lldb::TemplateArgumentKind kind; - m_element_type = m_element_type.GetTemplateArgument(0, kind); + m_element_type = m_element_type.GetTypeTemplateArgument(0); m_element_type = m_element_type.GetPointeeType(); m_node_type = m_element_type; - m_element_type = m_element_type.GetTemplateArgument(0, kind); + m_element_type = m_element_type.GetTypeTemplateArgument(0); std::string name; m_element_type = m_element_type.GetFieldAtIndex(0, name, nullptr, nullptr, nullptr); Index: source/Plugins/Language/CPlusPlus/LibCxxVector.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -290,8 +290,7 @@ CompilerType type = valobj_sp->GetCompilerType(); if (!type.IsValid() || type.GetNumTemplateArguments() == 0) return nullptr; - TemplateArgumentKind kind; - CompilerType arg_type = type.GetTemplateArgument(0, kind); + CompilerType arg_type = type.GetTypeTemplateArgument(0); if (arg_type.GetTypeName() == ConstString("bool")) return new LibcxxVectorBoolSyntheticFrontEnd(valobj_sp); return new LibcxxStdVectorSyntheticFrontEnd(valobj_sp); Index: source/Plugins/Language/CPlusPlus/LibStdcpp.cpp =================================================================== --- source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -117,11 +117,8 @@ CompilerType my_type(valobj_sp->GetCompilerType()); if (my_type.GetNumTemplateArguments() >= 1) { - TemplateArgumentKind kind; - CompilerType pair_type = my_type.GetTemplateArgument(0, kind); - if (kind != eTemplateArgumentKindType && - kind != eTemplateArgumentKindTemplate && - kind != eTemplateArgumentKindTemplateExpansion) + CompilerType pair_type = my_type.GetTypeTemplateArgument(0); + if (!pair_type) return false; m_pair_type = pair_type; } else Index: source/Symbol/ClangASTContext.cpp =================================================================== --- source/Symbol/ClangASTContext.cpp +++ source/Symbol/ClangASTContext.cpp @@ -7549,99 +7549,122 @@ return 0; } -CompilerType -ClangASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type, - size_t arg_idx, - lldb::TemplateArgumentKind &kind) { +const clang::ClassTemplateSpecializationDecl * +ClangASTContext::GetAsTemplateSpecialization( + lldb::opaque_compiler_type_t type) { if (!type) - return CompilerType(); + return nullptr; clang::QualType qual_type(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { - case clang::Type::Record: - if (GetCompleteType(type)) { - const clang::CXXRecordDecl *cxx_record_decl = - qual_type->getAsCXXRecordDecl(); - if (cxx_record_decl) { - const clang::ClassTemplateSpecializationDecl *template_decl = - llvm::dyn_cast( - cxx_record_decl); - if (template_decl && - arg_idx < template_decl->getTemplateArgs().size()) { - const clang::TemplateArgument &template_arg = - template_decl->getTemplateArgs()[arg_idx]; - switch (template_arg.getKind()) { - case clang::TemplateArgument::Null: - kind = eTemplateArgumentKindNull; - return CompilerType(); - - case clang::TemplateArgument::Type: - kind = eTemplateArgumentKindType; - return CompilerType(getASTContext(), template_arg.getAsType()); - - case clang::TemplateArgument::Declaration: - kind = eTemplateArgumentKindDeclaration; - return CompilerType(); - - case clang::TemplateArgument::Integral: - kind = eTemplateArgumentKindIntegral; - return CompilerType(getASTContext(), - template_arg.getIntegralType()); - - case clang::TemplateArgument::Template: - kind = eTemplateArgumentKindTemplate; - return CompilerType(); - - case clang::TemplateArgument::TemplateExpansion: - kind = eTemplateArgumentKindTemplateExpansion; - return CompilerType(); - - case clang::TemplateArgument::Expression: - kind = eTemplateArgumentKindExpression; - return CompilerType(); - - case clang::TemplateArgument::Pack: - kind = eTemplateArgumentKindPack; - return CompilerType(); - - default: - llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind"); - } - } - } - } - break; + case clang::Type::Record: { + if (! GetCompleteType(type)) + return nullptr; + const clang::CXXRecordDecl *cxx_record_decl = + qual_type->getAsCXXRecordDecl(); + if (!cxx_record_decl) + return nullptr; + return llvm::dyn_cast( + cxx_record_decl); + } case clang::Type::Typedef: - return (CompilerType(getASTContext(), - llvm::cast(qual_type) - ->getDecl() - ->getUnderlyingType())) - .GetTemplateArgument(arg_idx, kind); + return GetAsTemplateSpecialization(llvm::cast(qual_type) + ->getDecl() + ->getUnderlyingType() + .getAsOpaquePtr()); case clang::Type::Auto: - return (CompilerType( - getASTContext(), - llvm::cast(qual_type)->getDeducedType())) - .GetTemplateArgument(arg_idx, kind); + return GetAsTemplateSpecialization(llvm::cast(qual_type) + ->getDeducedType() + .getAsOpaquePtr()); case clang::Type::Elaborated: - return (CompilerType( - getASTContext(), - llvm::cast(qual_type)->getNamedType())) - .GetTemplateArgument(arg_idx, kind); + return GetAsTemplateSpecialization( + llvm::cast(qual_type) + ->getNamedType() + .getAsOpaquePtr()); case clang::Type::Paren: - return (CompilerType(getASTContext(), - llvm::cast(qual_type)->desugar())) - .GetTemplateArgument(arg_idx, kind); + return GetAsTemplateSpecialization( + llvm::cast(qual_type)->desugar().getAsOpaquePtr()); default: - break; + return nullptr; } - kind = eTemplateArgumentKindNull; - return CompilerType(); +} + +lldb::TemplateArgumentKind +ClangASTContext::GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, + size_t arg_idx) { + const clang::ClassTemplateSpecializationDecl *template_decl = + GetAsTemplateSpecialization(type); + if (! template_decl || arg_idx >= template_decl->getTemplateArgs().size()) + return eTemplateArgumentKindNull; + + switch (template_decl->getTemplateArgs()[arg_idx].getKind()) { + case clang::TemplateArgument::Null: + return eTemplateArgumentKindNull; + + case clang::TemplateArgument::NullPtr: + return eTemplateArgumentKindNullPtr; + + case clang::TemplateArgument::Type: + return eTemplateArgumentKindType; + + case clang::TemplateArgument::Declaration: + return eTemplateArgumentKindDeclaration; + + case clang::TemplateArgument::Integral: + return eTemplateArgumentKindIntegral; + + case clang::TemplateArgument::Template: + return eTemplateArgumentKindTemplate; + + case clang::TemplateArgument::TemplateExpansion: + return eTemplateArgumentKindTemplateExpansion; + + case clang::TemplateArgument::Expression: + return eTemplateArgumentKindExpression; + + case clang::TemplateArgument::Pack: + return eTemplateArgumentKindPack; + } + llvm_unreachable("Unhandled clang::TemplateArgument::ArgKind"); +} + +CompilerType +ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx) { + const clang::ClassTemplateSpecializationDecl *template_decl = + GetAsTemplateSpecialization(type); + if (!template_decl || idx >= template_decl->getTemplateArgs().size()) + return CompilerType(); + + const clang::TemplateArgument &template_arg = + template_decl->getTemplateArgs()[idx]; + if (template_arg.getKind() != clang::TemplateArgument::Type) + return CompilerType(); + + return CompilerType(getASTContext(), template_arg.getAsType()); +} + +std::pair +ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, + size_t idx) { + const clang::ClassTemplateSpecializationDecl *template_decl = + GetAsTemplateSpecialization(type); + if (! template_decl || idx >= template_decl->getTemplateArgs().size()) + return {llvm::APSInt(0), CompilerType()}; + + const clang::TemplateArgument &template_arg = + template_decl->getTemplateArgs()[idx]; + if (template_arg.getKind() != clang::TemplateArgument::Integral) + return {llvm::APSInt(0), CompilerType()}; + + return {template_arg.getAsIntegral(), + CompilerType(getASTContext(), template_arg.getIntegralType())}; } CompilerType ClangASTContext::GetTypeForFormatters(void *type) { Index: source/Symbol/CompilerType.cpp =================================================================== --- source/Symbol/CompilerType.cpp +++ source/Symbol/CompilerType.cpp @@ -690,15 +690,27 @@ return 0; } -CompilerType -CompilerType::GetTemplateArgument(size_t idx, - lldb::TemplateArgumentKind &kind) const { +TemplateArgumentKind CompilerType::GetTemplateArgumentKind(size_t idx) const { + if (IsValid()) + return m_type_system->GetTemplateArgumentKind(m_type, idx); + return eTemplateArgumentKindNull; +} + +CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const { if (IsValid()) { - return m_type_system->GetTemplateArgument(m_type, idx, kind); + return m_type_system->GetTypeTemplateArgument(m_type, idx); } return CompilerType(); } +std::pair +CompilerType::GetIntegralTemplateArgument(size_t idx) const +{ + if (IsValid()) + return m_type_system->GetIntegralTemplateArgument(m_type, idx); + return {llvm::APSInt(0), CompilerType()}; +} + CompilerType CompilerType::GetTypeForFormatters() const { if (IsValid()) return m_type_system->GetTypeForFormatters(m_type); Index: source/Symbol/JavaASTContext.cpp =================================================================== --- source/Symbol/JavaASTContext.cpp +++ source/Symbol/JavaASTContext.cpp @@ -884,13 +884,6 @@ return 0; } -CompilerType -JavaASTContext::GetTemplateArgument(lldb::opaque_compiler_type_t type, - size_t idx, - lldb::TemplateArgumentKind &kind) { - return CompilerType(); -} - uint32_t JavaASTContext::GetNumFields(lldb::opaque_compiler_type_t type) { if (JavaObjectType *obj = llvm::dyn_cast(static_cast(type))) { Index: source/Symbol/TypeSystem.cpp =================================================================== --- source/Symbol/TypeSystem.cpp +++ source/Symbol/TypeSystem.cpp @@ -23,6 +23,7 @@ #include "lldb/Symbol/CompilerType.h" using namespace lldb_private; +using namespace lldb; TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {} @@ -100,6 +101,22 @@ return CompilerType(this, type); } +TemplateArgumentKind +TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) { + return eTemplateArgumentKindNull; +} + +CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type, + size_t idx) { + return CompilerType(); +} + +std::pair +TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type, + size_t idx) { + return {llvm::APSInt(0), CompilerType()}; +} + LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) { return eLazyBoolCalculate; } Index: unittests/Symbol/TestClangASTContext.cpp =================================================================== --- unittests/Symbol/TestClangASTContext.cpp +++ unittests/Symbol/TestClangASTContext.cpp @@ -406,18 +406,28 @@ type, "foo_def", CompilerDeclContext(m_ast.get(), m_ast->GetTranslationUnitDecl())); + CompilerType auto_type(m_ast->getASTContext(), + m_ast->getASTContext()->getAutoType( + ClangUtil::GetCanonicalQualType(typedef_type), + clang::AutoTypeKeyword::Auto, false)); + CompilerType int_type(m_ast->getASTContext(), m_ast->getASTContext()->IntTy); - for(CompilerType t: { type, typedef_type }) { + for(CompilerType t: { type, typedef_type, auto_type }) { SCOPED_TRACE(t.GetTypeName().AsCString()); - TemplateArgumentKind kind; - - CompilerType arg = - m_ast->GetTemplateArgument(t.GetOpaqueQualType(), 0, kind); - EXPECT_EQ(kind, eTemplateArgumentKindType); - EXPECT_EQ(arg, int_type); - arg = m_ast->GetTemplateArgument(t.GetOpaqueQualType(), 1, kind); - EXPECT_EQ(kind, eTemplateArgumentKindIntegral); - EXPECT_EQ(arg, int_type); + EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 0), + eTemplateArgumentKindType); + EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0), + int_type); + auto p = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0); + EXPECT_EQ(p.second, CompilerType()); + + EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1), + eTemplateArgumentKindIntegral); + EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1), + CompilerType()); + p = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1); + EXPECT_EQ(p.first, llvm::APSInt(47)); + EXPECT_EQ(p.second, int_type); } }