Skip to content

[lldb] Introduce an ImportedDeclaration and [lldb] Handle @_originallyDefinedIn #9657

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

Closed
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
16 changes: 16 additions & 0 deletions lldb/include/lldb/Core/Module.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Symbol/ImportedDeclaration.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContextScope.h"
#include "lldb/Symbol/TypeSystem.h"
Expand Down Expand Up @@ -437,6 +438,21 @@ class Module : public std::enable_shared_from_this<Module>,
/// TypeMap::InsertUnique(...).
void FindTypes(const TypeQuery &query, TypeResults &results);

/// Finds imported declarations whose name match \p name.
///
/// \param[in] name
/// The name to search the imported declaration by.
///
/// \param[in] results
/// Any matching types will be populated into the \a results object.
///
/// \param[in] find_one
/// If set to true, the search will stop after the first imported
/// declaration is found.
void FindImportedDeclarations(ConstString name,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API should probably exist upstream, too.

std::vector<ImportedDeclaration> &results,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless you need to append to the same vector multiple times, it should probably be a return type.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You do append to the vector multiple times as part of the implementation (for example on SymbolFileDWARFDebugMap). This is also how all of the other query APIs in Module and SymbolFile do it, so I'd rather keep it this way to stay consistent.

bool find_one);

/// Get const accessor for the module architecture.
///
/// \return
Expand Down
20 changes: 20 additions & 0 deletions lldb/include/lldb/Core/ModuleList.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "lldb/Core/Address.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Symbol/ImportedDeclaration.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Iterable.h"
#include "lldb/Utility/Status.h"
Expand Down Expand Up @@ -397,6 +398,25 @@ class ModuleList {
void FindTypes(Module *search_first, const TypeQuery &query,
lldb_private::TypeResults &results) const;

/// Finds imported declarations whose name match \p name.
///
/// \param[in] search_first
/// If non-null, this module will be searched before any other
/// modules.
///
/// \param[in] name
/// The name to search the imported declaration by.
///
/// \param[in] results
/// Any matching types will be populated into the \a results object.
///
/// \param[in] find_one
/// If set to true, the search will stop after the first imported
/// declaration is found.
void FindImportedDeclarations(Module *search_first, ConstString name,
std::vector<ImportedDeclaration> &results,
bool find_one) const;

bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const;

/// Find addresses by file/line
Expand Down
34 changes: 34 additions & 0 deletions lldb/include/lldb/Symbol/ImportedDeclaration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//===-- ImportedDeclaration.h -----------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLDB_SYMBOL_IMPORTED_DECLARATION_H
#define LLDB_SYMBOL_IMPORTED_DECLARATION_H

#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/UserID.h"

namespace lldb_private {

struct ImportedDeclaration : public UserID {

ImportedDeclaration(lldb::user_id_t uid, ConstString name,
SymbolFile *symbol_file)
: UserID(uid), m_name(name), m_symbol_file(symbol_file) {}

ConstString GetName() const { return m_name; }

std::vector<lldb_private::CompilerContext> GetDeclContext() const;

private:
ConstString m_name;
SymbolFile *m_symbol_file = nullptr;
};

} // namespace lldb_private

#endif // LLDB_SYMBOL_IMPORTED_DECLARATION_H
17 changes: 17 additions & 0 deletions lldb/include/lldb/Symbol/SymbolFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SourceModule.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeList.h"
#include "lldb/Symbol/TypeSystem.h"
Expand Down Expand Up @@ -305,6 +307,21 @@ class SymbolFile : public PluginInterface {
bool include_inlines, SymbolContextList &sc_list);
virtual void FindFunctions(const RegularExpression &regex,
bool include_inlines, SymbolContextList &sc_list);
/// Finds imported declarations whose name match \p name.
///
/// \param[in] name
/// The name to search the imported declaration by.
///
/// \param[in] results
/// Any matching types will be populated into the \a results object.
///
/// \param[in] find_one
/// If set to true, the search will stop after the first imported
/// declaration is found.
virtual void
FindImportedDeclaration(ConstString name,
std::vector<ImportedDeclaration> &declarations,
bool find_one) {}

/// Find types using a type-matching object that contains all search
/// parameters.
Expand Down
6 changes: 6 additions & 0 deletions lldb/source/Core/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,12 @@ void Module::FindTypes(const TypeQuery &query, TypeResults &results) {
if (SymbolFile *symbols = GetSymbolFile())
symbols->FindTypes(query, results);
}
void Module::FindImportedDeclarations(ConstString name,
std::vector<ImportedDeclaration> &results,
bool find_one) {
if (SymbolFile *symbols = GetSymbolFile())
symbols->FindImportedDeclaration(name, results, find_one);
}

static Debugger::DebuggerList
DebuggersOwningModuleRequestingInterruption(Module &module) {
Expand Down
18 changes: 18 additions & 0 deletions lldb/source/Core/ModuleList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,24 @@ void ModuleList::FindTypes(Module *search_first, const TypeQuery &query,
}
}

void ModuleList::FindImportedDeclarations(
Module *search_first, ConstString name,
std::vector<ImportedDeclaration> &results, bool find_one) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
if (search_first) {
search_first->FindImportedDeclarations(name, results, find_one);
if (find_one && !results.empty())
return;
}
for (const auto &module_sp : m_modules) {
if (search_first != module_sp.get()) {
module_sp->FindImportedDeclarations(name, results, find_one);
}
if (find_one && !results.empty())
return;
}
}

bool ModuleList::FindSourceFile(const FileSpec &orig_spec,
FileSpec &new_spec) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
Expand Down
16 changes: 16 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2677,6 +2677,22 @@ void SymbolFileDWARF::FindFunctions(const RegularExpression &regex,
});
}

void SymbolFileDWARF::FindImportedDeclaration(
ConstString name, std::vector<ImportedDeclaration> &sc_list,
bool find_one) {
llvm::DenseSet<const DWARFDebugInfoEntry *> resolved_dies;
m_index->GetNamespaces(name, [&](DWARFDIE die) {
if (die.Tag() != llvm::dwarf::DW_TAG_imported_declaration)
return true;

if (name != die.GetName())
return true;

sc_list.emplace_back(die.GetID(), name, this);
return !find_one;
});
}

void SymbolFileDWARF::GetMangledNamesForFunction(
const std::string &scope_qualified_name,
std::vector<ConstString> &mangled_names) {
Expand Down
4 changes: 4 additions & 0 deletions lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ class SymbolFileDWARF : public SymbolFileCommon {
void FindFunctions(const RegularExpression &regex, bool include_inlines,
SymbolContextList &sc_list) override;

void FindImportedDeclaration(ConstString name,
std::vector<ImportedDeclaration> &sc_list,
bool find_one) override;

void
GetMangledNamesForFunction(const std::string &scope_qualified_name,
std::vector<ConstString> &mangled_names) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1122,6 +1122,17 @@ void SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression &regex,
});
}

void SymbolFileDWARFDebugMap::FindImportedDeclaration(
ConstString name, std::vector<ImportedDeclaration> &declarations,
bool find_one) {
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) {
oso_dwarf->FindImportedDeclaration(name, declarations, find_one);
if (find_one && !declarations.empty())
return IterationAction::Stop;
return IterationAction::Continue;
});
}

void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope,
lldb::TypeClass type_mask,
TypeList &type_list) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ class SymbolFileDWARFDebugMap : public SymbolFileCommon {
bool include_inlines, SymbolContextList &sc_list) override;
void FindFunctions(const RegularExpression &regex, bool include_inlines,
SymbolContextList &sc_list) override;
void FindImportedDeclaration(ConstString name,
std::vector<ImportedDeclaration> &declarations,
bool find_one) override;
void FindTypes(const lldb_private::TypeQuery &match,
lldb_private::TypeResults &results) override;
CompilerDeclContext FindNamespace(ConstString name,
Expand Down
10 changes: 10 additions & 0 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4720,6 +4720,16 @@ SwiftASTContext::ReconstructType(ConstString mangled_typename) {
.getPointer();
assert(!found_type || &found_type->getASTContext() == *ast_ctx);

// This type might have been been found in reflection and annotated with
// @_originallyDefinedIn. The compiler emits a typelias for these type
// pointing them back to the types with the real module name.
if (!found_type) {
auto adjusted =
GetTypeSystemSwiftTypeRef().AdjustTypeForOriginallyDefinedInModule(
mangled_typename);
found_type =
swift::Demangle::getTypeForMangling(**ast_ctx, adjusted).getPointer();
}
// Objective-C classes sometimes have private subclasses that are invisible
// to the Swift compiler because they are declared and defined in a .m file.
// If we can't reconstruct an ObjC type, walk up the type hierarchy until we
Expand Down
20 changes: 18 additions & 2 deletions lldb/source/Plugins/TypeSystem/Swift/SwiftDemangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,23 @@ NodeAtPath(swift::Demangle::NodePointer root,
return ChildAtPath(root, kind_path.drop_front());
}

/// \return the child of the \p Type node.
static swift::Demangle::NodePointer GetType(swift::Demangle::NodePointer n) {
/// \return the child of the TypeMangling node.
static swift::Demangle::NodePointer
GetTypeMangling(swift::Demangle::NodePointer n) {
using namespace swift::Demangle;
if (!n || n->getKind() != Node::Kind::Global)
return nullptr;
n = n->getFirstChild();
if (!n || n->getKind() != Node::Kind::TypeMangling || !n->hasChildren())
return nullptr;
n = n->getFirstChild();
return n;
}

/// \return the child of the \p Type node.
static swift::Demangle::NodePointer GetType(swift::Demangle::NodePointer n) {
using namespace swift::Demangle;
n = GetTypeMangling(n);
if (!n || n->getKind() != Node::Kind::Type || !n->hasChildren())
return nullptr;
n = n->getFirstChild();
Expand All @@ -80,6 +88,14 @@ GetDemangledType(swift::Demangle::Demangler &dem, llvm::StringRef name) {
return GetType(dem.demangleSymbol(name));
}

/// Demangle a mangled type name and return the child of the \p TypeMangling
/// node.
inline swift::Demangle::NodePointer
GetDemangledTypeMangling(swift::Demangle::Demangler &dem,
llvm::StringRef name) {
return GetTypeMangling(dem.demangleSymbol(name));
}

/// Wrap node in Global/TypeMangling/Type.
static swift::Demangle::NodePointer
mangleType(swift::Demangle::Demangler &dem,
Expand Down
Loading