mirror of
https://github.com/intel/llvm.git
synced 2026-01-22 07:01:03 +08:00
[lldb] Prevent false positives with simple template names in SymbolFileDWARF::FindTypes
The provided test case was crashing because of confusion attempting to find types for `ns::Foo` under -gsimple-template-names. (This looks broken normally because it's attempting to find `ns::Foo` rather than `ns::Foo<T>`) Looking up types can't give false positives, as opposed to looking up functions as mentioned in https://reviews.llvm.org/D137098. Reviewed By: Michael137 Differential Revision: https://reviews.llvm.org/D140240
This commit is contained in:
@@ -2501,6 +2501,11 @@ void SymbolFileDWARF::FindTypes(
|
||||
if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
|
||||
return;
|
||||
|
||||
// Unlike FindFunctions(), FindTypes() following cannot produce false
|
||||
// positives.
|
||||
|
||||
const llvm::StringRef name_ref = name.GetStringRef();
|
||||
auto name_bracket_index = name_ref.find('<');
|
||||
m_index->GetTypes(name, [&](DWARFDIE die) {
|
||||
if (!DIEInDeclContext(parent_decl_ctx, die))
|
||||
return true; // The containing decl contexts don't match
|
||||
@@ -2509,6 +2514,13 @@ void SymbolFileDWARF::FindTypes(
|
||||
if (!matching_type)
|
||||
return true;
|
||||
|
||||
// With -gsimple-template-names, a templated type's DW_AT_name will not
|
||||
// contain the template parameters. Make sure that if the original query
|
||||
// didn't contain a '<', we filter out entries with template parameters.
|
||||
if (name_bracket_index == llvm::StringRef::npos &&
|
||||
matching_type->IsTemplateType())
|
||||
return true;
|
||||
|
||||
// We found a type pointer, now find the shared pointer form our type
|
||||
// list
|
||||
types.InsertUnique(matching_type->shared_from_this());
|
||||
@@ -2519,11 +2531,11 @@ void SymbolFileDWARF::FindTypes(
|
||||
// contain the template parameters. Try again stripping '<' and anything
|
||||
// after, filtering out entries with template parameters that don't match.
|
||||
if (types.GetSize() < max_matches) {
|
||||
const llvm::StringRef name_ref = name.GetStringRef();
|
||||
auto it = name_ref.find('<');
|
||||
if (it != llvm::StringRef::npos) {
|
||||
const llvm::StringRef name_no_template_params = name_ref.slice(0, it);
|
||||
const llvm::StringRef template_params = name_ref.slice(it, name_ref.size());
|
||||
if (name_bracket_index != llvm::StringRef::npos) {
|
||||
const llvm::StringRef name_no_template_params =
|
||||
name_ref.slice(0, name_bracket_index);
|
||||
const llvm::StringRef template_params =
|
||||
name_ref.slice(name_bracket_index, name_ref.size());
|
||||
m_index->GetTypes(ConstString(name_no_template_params), [&](DWARFDIE die) {
|
||||
if (!DIEInDeclContext(parent_decl_ctx, die))
|
||||
return true; // The containing decl contexts don't match
|
||||
|
||||
@@ -7131,6 +7131,17 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
bool TypeSystemClang::IsTemplateType(lldb::opaque_compiler_type_t type) {
|
||||
if (!type)
|
||||
return false;
|
||||
CompilerType ct(weak_from_this(), type);
|
||||
const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr();
|
||||
if (auto *cxx_record_decl = dyn_cast<clang::TagType>(clang_type))
|
||||
return isa<clang::ClassTemplateSpecializationDecl>(
|
||||
cxx_record_decl->getDecl());
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t
|
||||
TypeSystemClang::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
|
||||
bool expand_pack) {
|
||||
|
||||
@@ -826,6 +826,8 @@ public:
|
||||
const char *name, bool omit_empty_base_classes,
|
||||
std::vector<uint32_t> &child_indexes) override;
|
||||
|
||||
bool IsTemplateType(lldb::opaque_compiler_type_t type) override;
|
||||
|
||||
size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
|
||||
bool expand_pack) override;
|
||||
|
||||
|
||||
@@ -260,6 +260,13 @@ bool CompilerType::IsScalarType() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompilerType::IsTemplateType() const {
|
||||
if (IsValid())
|
||||
if (auto type_system_sp = GetTypeSystem())
|
||||
return type_system_sp->IsTemplateType(m_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CompilerType::IsTypedefType() const {
|
||||
if (IsValid())
|
||||
if (auto type_system_sp = GetTypeSystem())
|
||||
|
||||
@@ -393,6 +393,10 @@ bool Type::IsAggregateType() {
|
||||
return GetForwardCompilerType().IsAggregateType();
|
||||
}
|
||||
|
||||
bool Type::IsTemplateType() {
|
||||
return GetForwardCompilerType().IsTemplateType();
|
||||
}
|
||||
|
||||
lldb::TypeSP Type::GetTypedefType() {
|
||||
lldb::TypeSP type_sp;
|
||||
if (IsTypedef()) {
|
||||
|
||||
@@ -116,6 +116,10 @@ CompilerType TypeSystem::GetTypeForFormatters(void *type) {
|
||||
return CompilerType(weak_from_this(), type);
|
||||
}
|
||||
|
||||
bool TypeSystem::IsTemplateType(lldb::opaque_compiler_type_t type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
|
||||
bool expand_pack) {
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user