Fix assertion in ClangASTContext

Summary:
llvm::APSInt(0) asserts because it creates an int with bit-width 0 and
not (as I thought) a value 0.

Theoretically it should be sufficient to change this to APSInt(1), as
the intention there was that the value of the first argument should be
ignored if the type is invalid, but that would look dodgy.

Instead, I use llvm::Optional to denote an invalid value and use a
special struct instead of a std::pair, to reduce typing and increase
clarity.

Reviewers: clayborg

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D40615

llvm-svn: 319414
This commit is contained in:
Pavel Labath 2017-11-30 10:16:54 +00:00
parent da34247a6a
commit f59056ff93
9 changed files with 36 additions and 31 deletions

View File

@ -787,7 +787,7 @@ public:
size_t idx) override; size_t idx) override;
CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) override; size_t idx) override;
std::pair<llvm::APSInt, CompilerType> llvm::Optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) override; size_t idx) override;

View File

@ -20,6 +20,7 @@
// Project includes // Project includes
#include "lldb/Core/ClangForward.h" #include "lldb/Core/ClangForward.h"
#include "lldb/lldb-private.h" #include "lldb/lldb-private.h"
#include "llvm/ADT/APSInt.h"
namespace lldb_private { namespace lldb_private {
@ -290,6 +291,8 @@ public:
// Exploring the type // Exploring the type
//---------------------------------------------------------------------- //----------------------------------------------------------------------
struct IntegralTemplateArgument;
uint64_t GetByteSize(ExecutionContextScope *exe_scope) const; uint64_t GetByteSize(ExecutionContextScope *exe_scope) const;
uint64_t GetBitSize(ExecutionContextScope *exe_scope) const; uint64_t GetBitSize(ExecutionContextScope *exe_scope) const;
@ -368,9 +371,9 @@ public:
lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const; lldb::TemplateArgumentKind GetTemplateArgumentKind(size_t idx) const;
CompilerType GetTypeTemplateArgument(size_t idx) const; CompilerType GetTypeTemplateArgument(size_t idx) const;
// Returns the value of the template argument and its type. In case the // Returns the value of the template argument and its type.
// argument is not found, returns an invalid CompilerType. llvm::Optional<IntegralTemplateArgument>
std::pair<llvm::APSInt, CompilerType> GetIntegralTemplateArgument(size_t idx) const; GetIntegralTemplateArgument(size_t idx) const;
CompilerType GetTypeForFormatters() const; CompilerType GetTypeForFormatters() const;
@ -433,6 +436,11 @@ private:
bool operator==(const CompilerType &lhs, const CompilerType &rhs); bool operator==(const CompilerType &lhs, const CompilerType &rhs);
bool operator!=(const CompilerType &lhs, const CompilerType &rhs); bool operator!=(const CompilerType &lhs, const CompilerType &rhs);
struct CompilerType::IntegralTemplateArgument {
llvm::APSInt value;
CompilerType type;
};
} // namespace lldb_private } // namespace lldb_private
#endif // liblldb_CompilerType_h_ #endif // liblldb_CompilerType_h_

View File

@ -355,9 +355,8 @@ public:
GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx); GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx);
virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, virtual CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx); size_t idx);
virtual std::pair<llvm::APSInt, CompilerType> virtual llvm::Optional<CompilerType::IntegralTemplateArgument>
GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx);
size_t idx);
//---------------------------------------------------------------------- //----------------------------------------------------------------------
// Dumping types // Dumping types

View File

@ -426,7 +426,7 @@ lldb::SBType SBType::GetTemplateArgumentType(uint32_t idx) {
case eTemplateArgumentKindIntegral: case eTemplateArgumentKindIntegral:
type = m_opaque_sp->GetCompilerType(false) type = m_opaque_sp->GetCompilerType(false)
.GetIntegralTemplateArgument(idx) .GetIntegralTemplateArgument(idx)
.second; ->type;
break; break;
default: default:
break; break;

View File

@ -59,10 +59,8 @@ bool BitsetFrontEnd::Update() {
size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay(); size_t capping_size = target_sp->GetMaximumNumberOfChildrenToDisplay();
size_t size = 0; size_t size = 0;
auto value_and_type = if (auto arg = m_backend.GetCompilerType().GetIntegralTemplateArgument(0))
m_backend.GetCompilerType().GetIntegralTemplateArgument(0); size = arg->value.getLimitedValue(capping_size);
if (value_and_type.second)
size = value_and_type.first.getLimitedValue(capping_size);
m_elements.assign(size, ValueObjectSP()); m_elements.assign(size, ValueObjectSP());

View File

@ -7650,21 +7650,21 @@ ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
return CompilerType(getASTContext(), template_arg.getAsType()); return CompilerType(getASTContext(), template_arg.getAsType());
} }
std::pair<llvm::APSInt, CompilerType> llvm::Optional<CompilerType::IntegralTemplateArgument>
ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
size_t idx) { size_t idx) {
const clang::ClassTemplateSpecializationDecl *template_decl = const clang::ClassTemplateSpecializationDecl *template_decl =
GetAsTemplateSpecialization(type); GetAsTemplateSpecialization(type);
if (! template_decl || idx >= template_decl->getTemplateArgs().size()) if (! template_decl || idx >= template_decl->getTemplateArgs().size())
return {llvm::APSInt(0), CompilerType()}; return llvm::None;
const clang::TemplateArgument &template_arg = const clang::TemplateArgument &template_arg =
template_decl->getTemplateArgs()[idx]; template_decl->getTemplateArgs()[idx];
if (template_arg.getKind() != clang::TemplateArgument::Integral) if (template_arg.getKind() != clang::TemplateArgument::Integral)
return {llvm::APSInt(0), CompilerType()}; return llvm::None;
return {template_arg.getAsIntegral(), return {{template_arg.getAsIntegral(),
CompilerType(getASTContext(), template_arg.getIntegralType())}; CompilerType(getASTContext(), template_arg.getIntegralType())}};
} }
CompilerType ClangASTContext::GetTypeForFormatters(void *type) { CompilerType ClangASTContext::GetTypeForFormatters(void *type) {

View File

@ -703,12 +703,11 @@ CompilerType CompilerType::GetTypeTemplateArgument(size_t idx) const {
return CompilerType(); return CompilerType();
} }
std::pair<llvm::APSInt, CompilerType> llvm::Optional<CompilerType::IntegralTemplateArgument>
CompilerType::GetIntegralTemplateArgument(size_t idx) const CompilerType::GetIntegralTemplateArgument(size_t idx) const {
{
if (IsValid()) if (IsValid())
return m_type_system->GetIntegralTemplateArgument(m_type, idx); return m_type_system->GetIntegralTemplateArgument(m_type, idx);
return {llvm::APSInt(0), CompilerType()}; return llvm::None;
} }
CompilerType CompilerType::GetTypeForFormatters() const { CompilerType CompilerType::GetTypeForFormatters() const {

View File

@ -111,10 +111,10 @@ CompilerType TypeSystem::GetTypeTemplateArgument(opaque_compiler_type_t type,
return CompilerType(); return CompilerType();
} }
std::pair<llvm::APSInt, CompilerType> llvm::Optional<CompilerType::IntegralTemplateArgument>
TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type, TypeSystem::GetIntegralTemplateArgument(opaque_compiler_type_t type,
size_t idx) { size_t idx) {
return {llvm::APSInt(0), CompilerType()}; return llvm::None;
} }
LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) { LazyBool TypeSystem::ShouldPrintAsOneLiner(void *type, ValueObject *valobj) {

View File

@ -382,8 +382,8 @@ TEST_F(TestClangASTContext, TemplateArguments) {
infos.names.push_back("T"); infos.names.push_back("T");
infos.args.push_back(TemplateArgument(m_ast->getASTContext()->IntTy)); infos.args.push_back(TemplateArgument(m_ast->getASTContext()->IntTy));
infos.names.push_back("I"); infos.names.push_back("I");
infos.args.push_back(TemplateArgument(*m_ast->getASTContext(), llvm::APSInt arg(llvm::APInt(8, 47));
llvm::APSInt(47), infos.args.push_back(TemplateArgument(*m_ast->getASTContext(), arg,
m_ast->getASTContext()->IntTy)); m_ast->getASTContext()->IntTy));
// template<typename T, int I> struct foo; // template<typename T, int I> struct foo;
@ -419,15 +419,16 @@ TEST_F(TestClangASTContext, TemplateArguments) {
eTemplateArgumentKindType); eTemplateArgumentKindType);
EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0), EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 0),
int_type); int_type);
auto p = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0); EXPECT_EQ(llvm::None,
EXPECT_EQ(p.second, CompilerType()); m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 0));
EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1), EXPECT_EQ(m_ast->GetTemplateArgumentKind(t.GetOpaqueQualType(), 1),
eTemplateArgumentKindIntegral); eTemplateArgumentKindIntegral);
EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1), EXPECT_EQ(m_ast->GetTypeTemplateArgument(t.GetOpaqueQualType(), 1),
CompilerType()); CompilerType());
p = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1); auto result = m_ast->GetIntegralTemplateArgument(t.GetOpaqueQualType(), 1);
EXPECT_EQ(p.first, llvm::APSInt(47)); ASSERT_NE(llvm::None, result);
EXPECT_EQ(p.second, int_type); EXPECT_EQ(arg, result->value);
EXPECT_EQ(int_type, result->type);
} }
} }