aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2023-12-12 17:07:42 -0800
committerVitaly Buka <vitalybuka@google.com>2023-12-12 17:07:42 -0800
commit79b7f3fd24ab19e9272eddd8d0f2b39d893222c9 (patch)
tree22871065c49d77394007a1999e8855e49783716b
parent2dad66c39ce65a06df39cd761362624b355951e3 (diff)
parentdd9587795811ba21e6ca6ad52b4531e17e6babd6 (diff)
downloadllvm-79b7f3fd24ab19e9272eddd8d0f2b39d893222c9.zip
llvm-79b7f3fd24ab19e9272eddd8d0f2b39d893222c9.tar.gz
llvm-79b7f3fd24ab19e9272eddd8d0f2b39d893222c9.tar.bz2
[𝘀𝗽𝗿] changes introduced through rebase
Created using spr 1.3.4 [skip ci]
-rw-r--r--compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp4
-rw-r--r--lldb/include/lldb/Core/Module.h77
-rw-r--r--lldb/include/lldb/Core/ModuleList.h24
-rw-r--r--lldb/include/lldb/Symbol/CompilerDecl.h7
-rw-r--r--lldb/include/lldb/Symbol/CompilerDeclContext.h8
-rw-r--r--lldb/include/lldb/Symbol/SymbolFile.h29
-rw-r--r--lldb/include/lldb/Symbol/SymbolFileOnDemand.h13
-rw-r--r--lldb/include/lldb/Symbol/Type.h305
-rw-r--r--lldb/include/lldb/Symbol/TypeMap.h6
-rw-r--r--lldb/include/lldb/Symbol/TypeSystem.h24
-rw-r--r--lldb/include/lldb/lldb-forward.h2
-rw-r--r--lldb/include/lldb/lldb-private-enumerations.h5
-rw-r--r--lldb/source/API/SBModule.cpp54
-rw-r--r--lldb/source/API/SBTarget.cpp38
-rw-r--r--lldb/source/Commands/CommandObjectMemory.cpp23
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp51
-rw-r--r--lldb/source/Core/Module.cpp94
-rw-r--r--lldb/source/Core/ModuleList.cpp37
-rw-r--r--lldb/source/DataFormatters/TypeFormat.cpp11
-rw-r--r--lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp97
-rw-r--r--lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp30
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp15
-rw-r--r--lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp9
-rw-r--r--lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h9
-rw-r--r--lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp23
-rw-r--r--lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h8
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp32
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp48
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h15
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp270
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h10
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp23
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h9
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp37
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h10
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp59
-rw-r--r--lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h15
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp151
-rw-r--r--lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h8
-rw-r--r--lldb/source/Symbol/CompilerDecl.cpp5
-rw-r--r--lldb/source/Symbol/CompilerDeclContext.cpp7
-rw-r--r--lldb/source/Symbol/SymbolFile.cpp11
-rw-r--r--lldb/source/Symbol/SymbolFileOnDemand.cpp23
-rw-r--r--lldb/source/Symbol/Type.cpp146
-rw-r--r--lldb/source/Symbol/TypeMap.cpp14
-rw-r--r--lldb/source/Symbol/TypeSystem.cpp10
-rw-r--r--lldb/source/Target/Language.cpp10
-rw-r--r--lldb/test/API/functionalities/type_find_first/Makefile2
-rw-r--r--lldb/test/API/functionalities/type_find_first/TestFindFirstType.py38
-rw-r--r--lldb/test/API/functionalities/type_find_first/main.cpp17
-rw-r--r--lldb/test/API/lang/cpp/unique-types4/TestUniqueTypes4.py21
-rw-r--r--lldb/test/API/lang/cpp/unique-types4/main.cpp4
-rw-r--r--lldb/tools/lldb-test/lldb-test.cpp48
-rw-r--r--llvm/include/llvm/CodeGen/CodeGenPassBuilder.h1
-rw-r--r--llvm/include/llvm/CodeGen/MachinePassRegistry.def3
-rw-r--r--llvm/include/llvm/Transforms/CFGuard.h13
-rw-r--r--llvm/lib/Passes/CMakeLists.txt1
-rw-r--r--llvm/lib/Passes/PassBuilder.cpp21
-rw-r--r--llvm/lib/Passes/PassRegistry.def4
-rw-r--r--llvm/lib/Target/TargetMachine.cpp4
-rw-r--r--llvm/lib/Transforms/CFGuard/CFGuard.cpp85
-rw-r--r--llvm/test/CodeGen/X86/code-model-elf-sections.ll16
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/CMakeLists.txt12
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/SparseBufferRewriting.cpp2
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/SparseGPUCodegen.cpp4
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp4
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/SparseStorageSpecifierToLLVM.cpp2
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp4
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorConversion.cpp2
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp4
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/SparseVectorization.cpp4
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp6
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenEnv.cpp (renamed from mlir/lib/Dialect/SparseTensor/Transforms/CodegenEnv.cpp)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenEnv.h (renamed from mlir/lib/Dialect/SparseTensor/Transforms/CodegenEnv.h)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenUtils.cpp (renamed from mlir/lib/Dialect/SparseTensor/Transforms/CodegenUtils.cpp)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenUtils.h (renamed from mlir/lib/Dialect/SparseTensor/Transforms/CodegenUtils.h)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp (renamed from mlir/lib/Dialect/SparseTensor/Transforms/IterationGraphSorter.cpp)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h (renamed from mlir/lib/Dialect/SparseTensor/Transforms/IterationGraphSorter.h)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.cpp (renamed from mlir/lib/Dialect/SparseTensor/Transforms/LoopEmitter.cpp)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.h (renamed from mlir/lib/Dialect/SparseTensor/Transforms/LoopEmitter.h)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.cpp (renamed from mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorDescriptor.cpp)0
-rw-r--r--mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.h (renamed from mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorDescriptor.h)0
-rw-r--r--mlir/tools/mlir-opt/CMakeLists.txt4
-rw-r--r--mlir/tools/mlir-opt/mlir-opt.cpp4
-rw-r--r--utils/bazel/llvm-project-overlay/mlir/BUILD.bazel117
85 files changed, 1320 insertions, 1043 deletions
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
index 2264c55..0526384 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.cpp
@@ -18,10 +18,10 @@
static const size_t kBufferSize = 1 << 20;
-static void *background(void *arg) { return nullptr; }
-
pthread_barrier_t bar;
+// Without appropriate workarounds this code can cause the forked process to
+// start with locked internal mutexes.
void CanDeadLock() {
// Don't bother with leaks, we try to trigger allocator or lsan deadlock.
__lsan::ScopedDisabler disable;
diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 2973ee0..f4973cd 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -415,70 +415,19 @@ public:
void FindGlobalVariables(const RegularExpression &regex, size_t max_matches,
VariableList &variable_list);
- /// Find types by name.
- ///
- /// Type lookups in modules go through the SymbolFile. The SymbolFile needs to
- /// be able to lookup types by basename and not the fully qualified typename.
- /// This allows the type accelerator tables to stay small, even with heavily
- /// templatized C++. The type search will then narrow down the search
- /// results. If "exact_match" is true, then the type search will only match
- /// exact type name matches. If "exact_match" is false, the type will match
- /// as long as the base typename matches and as long as any immediate
- /// containing namespaces/class scopes that are specified match. So to
- /// search for a type "d" in "b::c", the name "b::c::d" can be specified and
- /// it will match any class/namespace "b" which contains a class/namespace
- /// "c" which contains type "d". We do this to allow users to not always
- /// have to specify complete scoping on all expressions, but it also allows
- /// for exact matching when required.
- ///
- /// \param[in] type_name
- /// The name of the type we are looking for that is a fully
- /// or partially qualified type name.
- ///
- /// \param[in] exact_match
- /// If \b true, \a type_name is fully qualified and must match
- /// exactly. If \b false, \a type_name is a partially qualified
- /// name where the leading namespaces or classes can be
- /// omitted to make finding types that a user may type
- /// easier.
- ///
- /// \param[out] types
- /// A type list gets populated with any matches.
+ /// Find types using a type-matching object that contains all search
+ /// parameters.
///
- void
- FindTypes(ConstString type_name, bool exact_match, size_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeList &types);
-
- /// Find types by name.
- ///
- /// This behaves like the other FindTypes method but allows to
- /// specify a DeclContext and a language for the type being searched
- /// for.
- ///
- /// \param searched_symbol_files
- /// Prevents one file from being visited multiple times.
- void
- FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types);
-
- lldb::TypeSP FindFirstType(const SymbolContext &sc, ConstString type_name,
- bool exact_match);
-
- /// Find types by name that are in a namespace. This function is used by the
- /// expression parser when searches need to happen in an exact namespace
- /// scope.
+ /// \see lldb_private::TypeQuery
///
- /// \param[in] type_name
- /// The name of a type within a namespace that should not include
- /// any qualifying namespaces (just a type basename).
+ /// \param[in] query
+ /// A type matching object that contains all of the details of the type
+ /// search.
///
- /// \param[out] type_list
- /// A type list gets populated with any matches.
- void FindTypesInNamespace(ConstString type_name,
- const CompilerDeclContext &parent_decl_ctx,
- size_t max_matches, TypeList &type_list);
+ /// \param[in] results
+ /// Any matching types will be populated into the \a results object using
+ /// TypeMap::InsertUnique(...).
+ void FindTypes(const TypeQuery &query, TypeResults &results);
/// Get const accessor for the module architecture.
///
@@ -1122,12 +1071,6 @@ protected:
private:
Module(); // Only used internally by CreateJITModule ()
- void FindTypes_Impl(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- size_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types);
-
Module(const Module &) = delete;
const Module &operator=(const Module &) = delete;
diff --git a/lldb/include/lldb/Core/ModuleList.h b/lldb/include/lldb/Core/ModuleList.h
index 9826dd0..d78f7c5 100644
--- a/lldb/include/lldb/Core/ModuleList.h
+++ b/lldb/include/lldb/Core/ModuleList.h
@@ -340,26 +340,22 @@ public:
lldb::SymbolType symbol_type,
SymbolContextList &sc_list) const;
- /// Find types by name.
+ /// Find types using a type-matching object that contains all search
+ /// parameters.
///
/// \param[in] search_first
/// If non-null, this module will be searched before any other
/// modules.
///
- /// \param[in] name
- /// The name of the type we are looking for.
- ///
- /// \param[in] max_matches
- /// Allow the number of matches to be limited to \a
- /// max_matches. Specify UINT32_MAX to get all possible matches.
- ///
- /// \param[out] types
- /// A type list gets populated with any matches.
+ /// \param[in] query
+ /// A type matching object that contains all of the details of the type
+ /// search.
///
- void FindTypes(Module *search_first, ConstString name,
- bool name_is_fully_qualified, size_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeList &types) const;
+ /// \param[in] results
+ /// Any matching types will be populated into the \a results object using
+ /// TypeMap::InsertUnique(...).
+ void FindTypes(Module *search_first, const TypeQuery &query,
+ lldb_private::TypeResults &results) const;
bool FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const;
diff --git a/lldb/include/lldb/Symbol/CompilerDecl.h b/lldb/include/lldb/Symbol/CompilerDecl.h
index 67290b9..825a4f1 100644
--- a/lldb/include/lldb/Symbol/CompilerDecl.h
+++ b/lldb/include/lldb/Symbol/CompilerDecl.h
@@ -84,6 +84,13 @@ public:
// based argument index
CompilerType GetFunctionArgumentType(size_t arg_idx) const;
+ /// Populate a valid compiler context from the current declaration.
+ ///
+ /// \returns A valid vector of CompilerContext entries that describes
+ /// this declaration. The first entry in the vector is the parent of
+ /// the subsequent entry, so the topmost entry is the global namespace.
+ std::vector<lldb_private::CompilerContext> GetCompilerContext() const;
+
private:
TypeSystem *m_type_system = nullptr;
void *m_opaque_decl = nullptr;
diff --git a/lldb/include/lldb/Symbol/CompilerDeclContext.h b/lldb/include/lldb/Symbol/CompilerDeclContext.h
index 61a9c9c..89b4a97 100644
--- a/lldb/include/lldb/Symbol/CompilerDeclContext.h
+++ b/lldb/include/lldb/Symbol/CompilerDeclContext.h
@@ -11,6 +11,7 @@
#include <vector>
+#include "lldb/Symbol/Type.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-private.h"
@@ -56,6 +57,13 @@ public:
return m_type_system != nullptr && m_opaque_decl_ctx != nullptr;
}
+ /// Populate a valid compiler context from the current decl context.
+ ///
+ /// \returns A valid vector of CompilerContext entries that describes
+ /// this declaration context. The first entry in the vector is the parent of
+ /// the subsequent entry, so the topmost entry is the global namespace.
+ std::vector<lldb_private::CompilerContext> GetCompilerContext() const;
+
std::vector<CompilerDecl> FindDeclByName(ConstString name,
const bool ignore_using_decls);
diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index a546b05..c9a2a64 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -301,21 +301,20 @@ public:
bool include_inlines, SymbolContextList &sc_list);
virtual void FindFunctions(const RegularExpression &regex,
bool include_inlines, SymbolContextList &sc_list);
- virtual void
- FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types);
-
- /// Find types specified by a CompilerContextPattern.
- /// \param languages
- /// Only return results in these languages.
- /// \param searched_symbol_files
- /// Prevents one file from being visited multiple times.
- virtual void
- FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types);
+
+ /// Find types using a type-matching object that contains all search
+ /// parameters.
+ ///
+ /// \see lldb_private::TypeQuery
+ ///
+ /// \param[in] query
+ /// A type matching object that contains all of the details of the type
+ /// search.
+ ///
+ /// \param[in] results
+ /// Any matching types will be populated into the \a results object using
+ /// TypeMap::InsertUnique(...).
+ virtual void FindTypes(const TypeQuery &query, TypeResults &results) {}
virtual void
GetMangledNamesForFunction(const std::string &scope_qualified_name,
diff --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
index 9cbcef2..cde9f3c 100644
--- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -152,17 +152,8 @@ public:
const std::string &scope_qualified_name,
std::vector<lldb_private::ConstString> &mangled_names) override;
- void
- FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
-
- void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
- lldb_private::LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
+ void FindTypes(const lldb_private::TypeQuery &query,
+ lldb_private::TypeResults &results) override;
void GetTypes(lldb_private::SymbolContextScope *sc_scope,
lldb::TypeClass type_mask,
diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index 15edbea..307be6c 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -12,11 +12,15 @@
#include "lldb/Core/Declaration.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Symbol/TypeList.h"
+#include "lldb/Symbol/TypeMap.h"
+#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/UserID.h"
#include "lldb/lldb-private.h"
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseSet.h"
#include <optional>
#include <set>
@@ -24,6 +28,23 @@
namespace lldb_private {
class SymbolFileCommon;
+/// A SmallBitVector that represents a set of source languages (\p
+/// lldb::LanguageType). Each lldb::LanguageType is represented by
+/// the bit with the position of its enumerator. The largest
+/// LanguageType is < 64, so this is space-efficient and on 64-bit
+/// architectures a LanguageSet can be completely stack-allocated.
+struct LanguageSet {
+ llvm::SmallBitVector bitvector;
+ LanguageSet();
+
+ /// If the set contains a single language only, return it.
+ std::optional<lldb::LanguageType> GetSingularLanguage();
+ void Insert(lldb::LanguageType language);
+ bool Empty() const;
+ size_t Size() const;
+ bool operator[](unsigned i) const;
+};
+
/// CompilerContext allows an array of these items to be passed to perform
/// detailed lookups in SymbolVendor and SymbolFile functions.
struct CompilerContext {
@@ -45,6 +66,290 @@ struct CompilerContext {
bool contextMatches(llvm::ArrayRef<CompilerContext> context_chain,
llvm::ArrayRef<CompilerContext> pattern);
+FLAGS_ENUM(TypeQueryOptions){
+ e_none = 0u,
+ /// If set, TypeQuery::m_context contains an exact context that must match
+ /// the full context. If not set, TypeQuery::m_context can contain a partial
+ /// type match where the full context isn't fully specified.
+ e_exact_match = (1u << 0),
+ /// If set, TypeQuery::m_context is a clang module compiler context. If not
+ /// set TypeQuery::m_context is normal type lookup context.
+ e_module_search = (1u << 1),
+ /// When true, the find types call should stop the query as soon as a single
+ /// matching type is found. When false, the type query should find all
+ /// matching types.
+ e_find_one = (1u << 2),
+};
+LLDB_MARK_AS_BITMASK_ENUM(TypeQueryOptions)
+
+/// A class that contains all state required for type lookups.
+///
+/// Using a TypeQuery class for matching types simplifies the internal APIs we
+/// need to implement type lookups in LLDB. Type lookups can fully specify the
+/// exact typename by filling out a complete or partial CompilerContext array.
+/// This technique allows for powerful searches and also allows the SymbolFile
+/// classes to use the m_context array to lookup types by basename, then
+/// eliminate potential matches without having to resolve types into each
+/// TypeSystem. This makes type lookups vastly more efficient and allows the
+/// SymbolFile objects to stop looking up types when the type matching is
+/// complete, like if we are looking for only a single type in our search.
+class TypeQuery {
+public:
+ TypeQuery() = delete;
+
+ /// Construct a type match object using a fully- or partially-qualified name.
+ ///
+ /// The specified \a type_name will be chopped up and the m_context will be
+ /// populated by separating the string by looking for "::". We do this because
+ /// symbol files have indexes that contain only the type's basename. This also
+ /// allows symbol files to efficiently not realize types that don't match the
+ /// specified context. Example of \a type_name values that can be specified
+ /// include:
+ /// "foo": Look for any type whose basename matches "foo".
+ /// If \a exact_match is true, then the type can't be contained in any
+ /// declaration context like a namespace, class, or other containing
+ /// scope.
+ /// If \a exact match is false, then we will find all matches including
+ /// ones that are contained in other declaration contexts, including top
+ /// level types.
+ /// "foo::bar": Look for any type whose basename matches "bar" but make sure
+ /// its parent declaration context is any named declaration context
+ /// (namespace, class, struct, etc) whose name matches "foo".
+ /// If \a exact_match is true, then the "foo" declaration context must
+ /// appear at the source file level or inside of a function.
+ /// If \a exact match is false, then the "foo" declaration context can
+ /// be contained in any other declaration contexts.
+ /// "class foo": Only match types that are classes whose basename matches
+ /// "foo".
+ /// "struct foo": Only match types that are structures whose basename
+ /// matches "foo".
+ /// "class foo::bar": Only match types that are classes whose basename
+ /// matches "bar" and that are contained in any named declaration context
+ /// named "foo".
+ ///
+ /// \param[in] type_name
+ /// A fully- or partially-qualified type name. This name will be parsed and
+ /// broken up and the m_context will be populated with the various parts of
+ /// the name. This typename can be prefixed with "struct ", "class ",
+ /// "union", "enum " or "typedef " before the actual type name to limit the
+ /// results of the types that match. The declaration context can be
+ /// specified with the "::" string. For example, "a::b::my_type".
+ ///
+ /// \param[in] options A set of boolean enumeration flags from the
+ /// TypeQueryOptions enumerations. \see TypeQueryOptions.
+ TypeQuery(llvm::StringRef name, TypeQueryOptions options = e_none);
+
+ /// Construct a type-match object that matches a type basename that exists
+ /// in the specified declaration context.
+ ///
+ /// This allows the m_context to be first populated using a declaration
+ /// context to exactly identify the containing declaration context of a type.
+ /// This can be used when you have a forward declaration to a type and you
+ /// need to search for its complete type.
+ ///
+ /// \param[in] decl_ctx
+ /// A declaration context object that comes from a TypeSystem plug-in. This
+ /// object will be asked to populate the array of CompilerContext objects
+ /// by adding the top most declaration context first into the array and then
+ /// adding any containing declaration contexts.
+ ///
+ /// \param[in] type_basename
+ /// The basename of the type to lookup in the specified declaration context.
+ ///
+ /// \param[in] options A set of boolean enumeration flags from the
+ /// TypeQueryOptions enumerations. \see TypeQueryOptions.
+ TypeQuery(const CompilerDeclContext &decl_ctx, ConstString type_basename,
+ TypeQueryOptions options = e_none);
+ /// Construct a type-match object using a compiler declaration that specifies
+ /// a typename and a declaration context to use when doing exact type lookups.
+ ///
+ /// This allows the m_context to be first populated using a type declaration.
+ /// The type declaration might have a declaration context and each TypeSystem
+ /// plug-in can populate the declaration context needed to perform an exact
+ /// lookup for a type.
+ /// This can be used when you have a forward declaration to a type and you
+ /// need to search for its complete type.
+ ///
+ /// \param[in] decl
+ /// A type declaration context object that comes from a TypeSystem plug-in.
+ /// This object will be asked to full the array of CompilerContext objects
+ /// by adding the top most declaration context first into the array and then
+ /// adding any containing declaration contexts, and ending with the exact
+ /// typename and the kind of type it is (class, struct, union, enum, etc).
+ ///
+ /// \param[in] options A set of boolean enumeration flags from the
+ /// TypeQueryOptions enumerations. \see TypeQueryOptions.
+ TypeQuery(const CompilerDecl &decl, TypeQueryOptions options = e_none);
+
+ /// Construct a type-match object using a CompilerContext array.
+ ///
+ /// Clients can manually create compiler contexts and use these to find
+ /// matches when searching for types. There are two types of contexts that
+ /// are supported when doing type searchs: type contexts and clang module
+ /// contexts. Type contexts have contexts that specify the type and its
+ /// containing declaration context like namespaces and classes. Clang module
+ /// contexts specify contexts more completely to find exact matches within
+ /// clang module debug information. They will include the modules that the
+ /// type is included in and any functions that the type might be defined in.
+ /// This allows very fine-grained type resolution.
+ ///
+ /// \param[in] context The compiler context to use when doing the search.
+ ///
+ /// \param[in] options A set of boolean enumeration flags from the
+ /// TypeQueryOptions enumerations. \see TypeQueryOptions.
+ TypeQuery(const llvm::ArrayRef<lldb_private::CompilerContext> &context,
+ TypeQueryOptions options = e_none);
+
+ /// Construct a type-match object that duplicates all matching criterea,
+ /// but not any searched symbol files or the type map for matches. This allows
+ /// the m_context to be modified prior to performing another search.
+ TypeQuery(const TypeQuery &rhs) = default;
+ /// Assign a type-match object that duplicates all matching criterea,
+ /// but not any searched symbol files or the type map for matches. This allows
+ /// the m_context to be modified prior to performing another search.
+ TypeQuery &operator=(const TypeQuery &rhs) = default;
+
+ /// Check of a CompilerContext array from matching type from a symbol file
+ /// matches the \a m_context.
+ ///
+ /// \param[in] context
+ /// A fully qualified CompilerContext array for a potential match that is
+ /// created by the symbol file prior to trying to actually resolve a type.
+ ///
+ /// \returns
+ /// True if the context matches, false if it doesn't. If e_exact_match
+ /// is set in m_options, then \a context must exactly match \a m_context. If
+ /// e_exact_match is not set, then the bottom m_context.size() objects in
+ /// \a context must match. This allows SymbolFile objects the fill in a
+ /// potential type basename match from the index into \a context, and see if
+ /// it matches prior to having to resolve a lldb_private::Type object for
+ /// the type from the index. This allows type parsing to be as efficient as
+ /// possible and only realize the types that match the query.
+ bool
+ ContextMatches(llvm::ArrayRef<lldb_private::CompilerContext> context) const;
+
+ /// Get the type basename to use when searching the type indexes in each
+ /// SymbolFile object.
+ ///
+ /// Debug information indexes often contain indexes that track the basename
+ /// of types only, not a fully qualified path. This allows the indexes to be
+ /// smaller and allows for efficient lookups.
+ ///
+ /// \returns
+ /// The type basename to use when doing lookups as a constant string.
+ ConstString GetTypeBasename() const;
+
+ /// Returns true if any matching languages have been specified in this type
+ /// matching object.
+ bool HasLanguage() const { return m_languages.has_value(); }
+
+ /// Add a language family to the list of languages that should produce a
+ /// match.
+ void AddLanguage(lldb::LanguageType language);
+
+ /// Check if the language matches any languages that have been added to this
+ /// match object.
+ ///
+ /// \returns
+ /// True if no language have been specified, or if some language have been
+ /// added using AddLanguage(...) and they match. False otherwise.
+ bool LanguageMatches(lldb::LanguageType language) const;
+
+ bool GetExactMatch() const { return (m_options & e_exact_match) != 0; }
+ /// The \a m_context can be used in two ways: normal types searching with
+ /// the context containing a stanadard declaration context for a type, or
+ /// with the context being more complete for exact matches in clang modules.
+ /// Set this to true if you wish to search for a type in clang module.
+ bool GetModuleSearch() const { return (m_options & e_module_search) != 0; }
+
+ /// Returns true if the type query is supposed to find only a single matching
+ /// type. Returns false if the type query should find all matches.
+ bool GetFindOne() const { return (m_options & e_find_one) != 0; }
+ void SetFindOne(bool b) {
+ if (b)
+ m_options |= e_find_one;
+ else
+ m_options &= (e_exact_match | e_find_one);
+ }
+
+ /// Access the internal compiler context array.
+ ///
+ /// Clients can use this to populate the context manually.
+ std::vector<lldb_private::CompilerContext> &GetContextRef() {
+ return m_context;
+ }
+
+protected:
+ /// A full or partial compiler context array where the parent declaration
+ /// contexts appear at the top of the array starting at index zero and the
+ /// last entry contains the type and name of the type we are looking for.
+ std::vector<lldb_private::CompilerContext> m_context;
+ /// An options bitmask that contains enabled options for the type query.
+ /// \see TypeQueryOptions.
+ TypeQueryOptions m_options;
+ /// If this variable has a value, then the language family must match at least
+ /// one of the specified languages. If this variable has no value, then the
+ /// language of the type doesn't need to match any types that are searched.
+ std::optional<LanguageSet> m_languages;
+};
+
+/// This class tracks the state and results of a \ref TypeQuery.
+///
+/// Any mutable state required for type lookups and the results are tracked in
+/// this object.
+class TypeResults {
+public:
+ /// Construct a type results object
+ TypeResults() = default;
+
+ /// When types that match a TypeQuery are found, this API is used to insert
+ /// the matching types.
+ ///
+ /// \return
+ /// True if the type was added, false if the \a type_sp was already in the
+ /// results.
+ bool InsertUnique(const lldb::TypeSP &type_sp);
+
+ /// Check if the type matching has found all of the matches that it needs.
+ bool Done(const TypeQuery &query) const;
+
+ /// Check if a SymbolFile object has already been searched by this type match
+ /// object.
+ ///
+ /// This function will add \a sym_file to the set of SymbolFile objects if it
+ /// isn't already in the set and return \a false. Returns true if \a sym_file
+ /// was already in the set and doesn't need to be searched.
+ ///
+ /// Any clients that search for types should first check that the symbol file
+ /// has not already been searched. If this function returns true, the type
+ /// search function should early return to avoid duplicating type searchihng
+ /// efforts.
+ ///
+ /// \param[in] sym_file
+ /// A SymbolFile pointer that will be used to track which symbol files have
+ /// already been searched.
+ ///
+ /// \returns
+ /// True if the symbol file has been search already, false otherwise.
+ bool AlreadySearched(lldb_private::SymbolFile *sym_file);
+
+ /// Access the set of searched symbol files.
+ llvm::DenseSet<lldb_private::SymbolFile *> &GetSearchedSymbolFiles() {
+ return m_searched_symbol_files;
+ }
+
+ lldb::TypeSP GetFirstType() const { return m_type_map.FirstType(); }
+ TypeMap &GetTypeMap() { return m_type_map; }
+ const TypeMap &GetTypeMap() const { return m_type_map; }
+
+private:
+ /// Matching types get added to this map as type search continues.
+ TypeMap m_type_map;
+ /// This set is used to track and make sure we only perform lookups in a
+ /// symbol file one time.
+ llvm::DenseSet<lldb_private::SymbolFile *> m_searched_symbol_files;
+};
+
class SymbolFileType : public std::enable_shared_from_this<SymbolFileType>,
public UserID {
public:
diff --git a/lldb/include/lldb/Symbol/TypeMap.h b/lldb/include/lldb/Symbol/TypeMap.h
index c200ccb..4337118 100644
--- a/lldb/include/lldb/Symbol/TypeMap.h
+++ b/lldb/include/lldb/Symbol/TypeMap.h
@@ -27,7 +27,7 @@ public:
void Clear();
void Dump(Stream *s, bool show_context,
- lldb::DescriptionLevel level = lldb::eDescriptionLevelFull);
+ lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) const;
TypeMap FindTypes(ConstString name);
@@ -41,10 +41,12 @@ public:
lldb::TypeSP GetTypeAtIndex(uint32_t idx);
+ lldb::TypeSP FirstType() const;
+
typedef std::multimap<lldb::user_id_t, lldb::TypeSP> collection;
typedef AdaptedIterable<collection, lldb::TypeSP, map_adapter> TypeIterable;
- TypeIterable Types() { return TypeIterable(m_types); }
+ TypeIterable Types() const { return TypeIterable(m_types); }
void ForEach(
std::function<bool(const lldb::TypeSP &type_sp)> const &callback) const;
diff --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index cd5004a..6382913 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -26,6 +26,7 @@
#include "lldb/Expression/Expression.h"
#include "lldb/Symbol/CompilerDecl.h"
#include "lldb/Symbol/CompilerDeclContext.h"
+#include "lldb/Symbol/Type.h"
#include "lldb/lldb-private.h"
class PDBASTParser;
@@ -43,23 +44,6 @@ namespace npdb {
class PdbAstBuilder;
} // namespace npdb
-/// A SmallBitVector that represents a set of source languages (\p
-/// lldb::LanguageType). Each lldb::LanguageType is represented by
-/// the bit with the position of its enumerator. The largest
-/// LanguageType is < 64, so this is space-efficient and on 64-bit
-/// architectures a LanguageSet can be completely stack-allocated.
-struct LanguageSet {
- llvm::SmallBitVector bitvector;
- LanguageSet();
-
- /// If the set contains a single language only, return it.
- std::optional<lldb::LanguageType> GetSingularLanguage();
- void Insert(lldb::LanguageType language);
- bool Empty() const;
- size_t Size() const;
- bool operator[](unsigned i) const;
-};
-
/// Interface for representing a type system.
///
/// Implemented by language plugins to define the type system for a given
@@ -122,6 +106,9 @@ public:
virtual CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
size_t arg_idx);
+ virtual std::vector<lldb_private::CompilerContext>
+ DeclGetCompilerContext(void *opaque_decl);
+
virtual CompilerType GetTypeForDecl(void *opaque_decl) = 0;
// CompilerDeclContext functions
@@ -146,6 +133,9 @@ public:
virtual CompilerDeclContext
GetCompilerDeclContextForType(const CompilerType &type);
+ virtual std::vector<lldb_private::CompilerContext>
+ DeclContextGetCompilerContext(void *opaque_decl_ctx);
+
// Tests
#ifndef NDEBUG
/// Verify the integrity of the type to catch CompilerTypes that mix
diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 068fce4..4e0c62f 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -258,9 +258,11 @@ class TypeImpl;
class TypeList;
class TypeListImpl;
class TypeMap;
+class TypeQuery;
class TypeMemberFunctionImpl;
class TypeMemberImpl;
class TypeNameSpecifierImpl;
+class TypeResults;
class TypeSummaryImpl;
class TypeSummaryOptions;
class TypeSystem;
diff --git a/lldb/include/lldb/lldb-private-enumerations.h b/lldb/include/lldb/lldb-private-enumerations.h
index 7f98220..5f15972 100644
--- a/lldb/include/lldb/lldb-private-enumerations.h
+++ b/lldb/include/lldb/lldb-private-enumerations.h
@@ -198,12 +198,15 @@ enum class CompilerContextKind : uint16_t {
Variable = 1 << 7,
Enum = 1 << 8,
Typedef = 1 << 9,
+ Builtin = 1 << 10,
Any = 1 << 15,
/// Match 0..n nested modules.
AnyModule = Any | Module,
/// Match any type.
- AnyType = Any | Class | Struct | Union | Enum | Typedef
+ AnyType = Any | Class | Struct | Union | Enum | Typedef | Builtin,
+ /// Math any declaration context.
+ AnyDeclContext = Any | Namespace | Class | Struct | Union | Enum | Function
};
// Enumerations that can be used to specify the kind of metric we're looking at
diff --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp
index b865502..262e26c 100644
--- a/lldb/source/API/SBModule.cpp
+++ b/lldb/source/API/SBModule.cpp
@@ -437,26 +437,25 @@ lldb::SBType SBModule::FindFirstType(const char *name_cstr) {
LLDB_INSTRUMENT_VA(this, name_cstr);
ModuleSP module_sp(GetSP());
- if (!name_cstr || !module_sp)
- return {};
- SymbolContext sc;
- const bool exact_match = false;
- ConstString name(name_cstr);
+ if (name_cstr && module_sp) {
+ ConstString name(name_cstr);
+ TypeQuery query(name.GetStringRef(), TypeQueryOptions::e_find_one);
+ TypeResults results;
+ module_sp->FindTypes(query, results);
+ TypeSP type_sp = results.GetFirstType();
+ if (type_sp)
+ return SBType(type_sp);
- SBType sb_type = SBType(module_sp->FindFirstType(sc, name, exact_match));
-
- if (sb_type.IsValid())
- return sb_type;
+ auto type_system_or_err =
+ module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
+ if (auto err = type_system_or_err.takeError()) {
+ llvm::consumeError(std::move(err));
+ return {};
+ }
- auto type_system_or_err = module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
- if (auto err = type_system_or_err.takeError()) {
- llvm::consumeError(std::move(err));
- return {};
+ if (auto ts = *type_system_or_err)
+ return SBType(ts->GetBuiltinTypeByName(name));
}
-
- if (auto ts = *type_system_or_err)
- return SBType(ts->GetBuiltinTypeByName(name));
-
return {};
}
@@ -471,7 +470,7 @@ lldb::SBType SBModule::GetBasicType(lldb::BasicType type) {
llvm::consumeError(std::move(err));
} else {
if (auto ts = *type_system_or_err)
- return SBType(ts->GetBasicTypeFromAST(type));
+ return SBType(ts->GetBasicTypeFromAST(type));
}
}
return SBType();
@@ -485,13 +484,11 @@ lldb::SBTypeList SBModule::FindTypes(const char *type) {
ModuleSP module_sp(GetSP());
if (type && module_sp) {
TypeList type_list;
- const bool exact_match = false;
- ConstString name(type);
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_sp->FindTypes(name, exact_match, UINT32_MAX, searched_symbol_files,
- type_list);
-
- if (type_list.Empty()) {
+ TypeQuery query(type);
+ TypeResults results;
+ module_sp->FindTypes(query, results);
+ if (results.GetTypeMap().Empty()) {
+ ConstString name(type);
auto type_system_or_err =
module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
if (auto err = type_system_or_err.takeError()) {
@@ -502,11 +499,8 @@ lldb::SBTypeList SBModule::FindTypes(const char *type) {
retval.Append(SBType(compiler_type));
}
} else {
- for (size_t idx = 0; idx < type_list.GetSize(); idx++) {
- TypeSP type_sp(type_list.GetTypeAtIndex(idx));
- if (type_sp)
- retval.Append(SBType(type_sp));
- }
+ for (const TypeSP &type_sp : results.GetTypeMap().Types())
+ retval.Append(SBType(type_sp));
}
}
return retval;
diff --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index 2d02955..8e616af 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -1804,21 +1804,13 @@ lldb::SBType SBTarget::FindFirstType(const char *typename_cstr) {
TargetSP target_sp(GetSP());
if (typename_cstr && typename_cstr[0] && target_sp) {
ConstString const_typename(typename_cstr);
- SymbolContext sc;
- const bool exact_match = false;
-
- const ModuleList &module_list = target_sp->GetImages();
- size_t count = module_list.GetSize();
- for (size_t idx = 0; idx < count; idx++) {
- ModuleSP module_sp(module_list.GetModuleAtIndex(idx));
- if (module_sp) {
- TypeSP type_sp(
- module_sp->FindFirstType(sc, const_typename, exact_match));
- if (type_sp)
- return SBType(type_sp);
- }
- }
-
+ TypeQuery query(const_typename.GetStringRef(),
+ TypeQueryOptions::e_find_one);
+ TypeResults results;
+ target_sp->GetImages().FindTypes(/*search_first=*/nullptr, query, results);
+ TypeSP type_sp = results.GetFirstType();
+ if (type_sp)
+ return SBType(type_sp);
// Didn't find the type in the symbols; Try the loaded language runtimes.
if (auto process_sp = target_sp->GetProcessSP()) {
for (auto *runtime : process_sp->GetLanguageRuntimes()) {
@@ -1859,17 +1851,11 @@ lldb::SBTypeList SBTarget::FindTypes(const char *typename_cstr) {
if (typename_cstr && typename_cstr[0] && target_sp) {
ModuleList &images = target_sp->GetImages();
ConstString const_typename(typename_cstr);
- bool exact_match = false;
- TypeList type_list;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- images.FindTypes(nullptr, const_typename, exact_match, UINT32_MAX,
- searched_symbol_files, type_list);
-
- for (size_t idx = 0; idx < type_list.GetSize(); idx++) {
- TypeSP type_sp(type_list.GetTypeAtIndex(idx));
- if (type_sp)
- sb_type_list.Append(SBType(type_sp));
- }
+ TypeQuery query(typename_cstr);
+ TypeResults results;
+ images.FindTypes(nullptr, query, results);
+ for (const TypeSP &type_sp : results.GetTypeMap().Types())
+ sb_type_list.Append(SBType(type_sp));
// Try the loaded language runtimes
if (auto process_sp = target_sp->GetProcessSP()) {
diff --git a/lldb/source/Commands/CommandObjectMemory.cpp b/lldb/source/Commands/CommandObjectMemory.cpp
index b02b7de..4ecac73 100644
--- a/lldb/source/Commands/CommandObjectMemory.cpp
+++ b/lldb/source/Commands/CommandObjectMemory.cpp
@@ -372,8 +372,6 @@ protected:
if (view_as_type_cstr && view_as_type_cstr[0]) {
// We are viewing memory as a type
- const bool exact_match = false;
- TypeList type_list;
uint32_t reference_count = 0;
uint32_t pointer_count = 0;
size_t idx;
@@ -452,18 +450,18 @@ protected:
}
}
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
ConstString lookup_type_name(type_str.c_str());
StackFrame *frame = m_exe_ctx.GetFramePtr();
ModuleSP search_first;
- if (frame) {
+ if (frame)
search_first = frame->GetSymbolContext(eSymbolContextModule).module_sp;
- }
- target->GetImages().FindTypes(search_first.get(), lookup_type_name,
- exact_match, 1, searched_symbol_files,
- type_list);
+ TypeQuery query(lookup_type_name.GetStringRef(),
+ TypeQueryOptions::e_find_one);
+ TypeResults results;
+ target->GetImages().FindTypes(search_first.get(), query, results);
+ TypeSP type_sp = results.GetFirstType();
- if (type_list.GetSize() == 0 && lookup_type_name.GetCString()) {
+ if (!type_sp && lookup_type_name.GetCString()) {
LanguageType language_for_type =
m_memory_options.m_language_for_type.GetCurrentValue();
std::set<LanguageType> languages_to_check;
@@ -499,15 +497,14 @@ protected:
}
if (!compiler_type.IsValid()) {
- if (type_list.GetSize() == 0) {
+ if (type_sp) {
+ compiler_type = type_sp->GetFullCompilerType();
+ } else {
result.AppendErrorWithFormat("unable to find any types that match "
"the raw type '%s' for full type '%s'\n",
lookup_type_name.GetCString(),
view_as_type_cstr);
return;
- } else {
- TypeSP type_sp(type_list.GetTypeAtIndex(0));
- compiler_type = type_sp->GetFullCompilerType();
}
}
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 63232c2..bc8bc51 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1706,16 +1706,18 @@ static size_t LookupTypeInModule(Target *target,
CommandInterpreter &interpreter, Stream &strm,
Module *module, const char *name_cstr,
bool name_is_regex) {
- TypeList type_list;
if (module && name_cstr && name_cstr[0]) {
- const uint32_t max_num_matches = UINT32_MAX;
- bool name_is_fully_qualified = false;
-
- ConstString name(name_cstr);
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- module->FindTypes(name, name_is_fully_qualified, max_num_matches,
- searched_symbol_files, type_list);
+ TypeQuery query(name_cstr);
+ TypeResults results;
+ module->FindTypes(query, results);
+ TypeList type_list;
+ SymbolContext sc;
+ if (module)
+ sc.module_sp = module->shared_from_this();
+ // Sort the type results and put the results that matched in \a module
+ // first if \a module was specified.
+ sc.SortTypeList(results.GetTypeMap(), type_list);
if (type_list.Empty())
return 0;
@@ -1748,22 +1750,21 @@ static size_t LookupTypeInModule(Target *target,
}
strm.EOL();
}
+ return type_list.GetSize();
}
- return type_list.GetSize();
+ return 0;
}
static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
Stream &strm, Module &module,
const char *name_cstr, bool name_is_regex) {
+ TypeQuery query(name_cstr);
+ TypeResults results;
+ module.FindTypes(query, results);
TypeList type_list;
- const uint32_t max_num_matches = UINT32_MAX;
- bool name_is_fully_qualified = false;
-
- ConstString name(name_cstr);
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module.FindTypes(name, name_is_fully_qualified, max_num_matches,
- searched_symbol_files, type_list);
-
+ SymbolContext sc;
+ sc.module_sp = module.shared_from_this();
+ sc.SortTypeList(results.GetTypeMap(), type_list);
if (type_list.Empty())
return 0;
@@ -2082,7 +2083,7 @@ protected:
result.GetOutputStream().EOL();
result.GetOutputStream().EOL();
}
- if (INTERRUPT_REQUESTED(GetDebugger(),
+ if (INTERRUPT_REQUESTED(GetDebugger(),
"Interrupted in dump all symtabs with {0} "
"of {1} dumped.", num_dumped, num_modules))
break;
@@ -2112,8 +2113,8 @@ protected:
result.GetOutputStream().EOL();
result.GetOutputStream().EOL();
}
- if (INTERRUPT_REQUESTED(GetDebugger(),
- "Interrupted in dump symtab list with {0} of {1} dumped.",
+ if (INTERRUPT_REQUESTED(GetDebugger(),
+ "Interrupted in dump symtab list with {0} of {1} dumped.",
num_dumped, num_matches))
break;
@@ -2175,7 +2176,7 @@ protected:
result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
num_modules);
for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
- if (INTERRUPT_REQUESTED(GetDebugger(),
+ if (INTERRUPT_REQUESTED(GetDebugger(),
"Interrupted in dump all sections with {0} of {1} dumped",
image_idx, num_modules))
break;
@@ -2196,7 +2197,7 @@ protected:
FindModulesByName(target, arg_cstr, module_list, true);
if (num_matches > 0) {
for (size_t i = 0; i < num_matches; ++i) {
- if (INTERRUPT_REQUESTED(GetDebugger(),
+ if (INTERRUPT_REQUESTED(GetDebugger(),
"Interrupted in dump section list with {0} of {1} dumped.",
i, num_matches))
break;
@@ -2338,7 +2339,7 @@ protected:
}
for (size_t i = 0; i < num_matches; ++i) {
- if (INTERRUPT_REQUESTED(GetDebugger(),
+ if (INTERRUPT_REQUESTED(GetDebugger(),
"Interrupted in dump clang ast list with {0} of {1} dumped.",
i, num_matches))
break;
@@ -2477,9 +2478,9 @@ protected:
if (num_modules > 0) {
uint32_t num_dumped = 0;
for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
- if (INTERRUPT_REQUESTED(GetDebugger(),
+ if (INTERRUPT_REQUESTED(GetDebugger(),
"Interrupted in dump all line tables with "
- "{0} of {1} dumped", num_dumped,
+ "{0} of {1} dumped", num_dumped,
num_modules))
break;
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index e6279a0..65a65c4 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -949,99 +949,9 @@ void Module::FindAddressesForLine(const lldb::TargetSP target_sp,
}
}
-void Module::FindTypes_Impl(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- size_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
+void Module::FindTypes(const TypeQuery &query, TypeResults &results) {
if (SymbolFile *symbols = GetSymbolFile())
- symbols->FindTypes(name, parent_decl_ctx, max_matches,
- searched_symbol_files, types);
-}
-
-void Module::FindTypesInNamespace(ConstString type_name,
- const CompilerDeclContext &parent_decl_ctx,
- size_t max_matches, TypeList &type_list) {
- TypeMap types_map;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- FindTypes_Impl(type_name, parent_decl_ctx, max_matches, searched_symbol_files,
- types_map);
- if (types_map.GetSize()) {
- SymbolContext sc;
- sc.module_sp = shared_from_this();
- sc.SortTypeList(types_map, type_list);
- }
-}
-
-lldb::TypeSP Module::FindFirstType(const SymbolContext &sc, ConstString name,
- bool exact_match) {
- TypeList type_list;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- FindTypes(name, exact_match, 1, searched_symbol_files, type_list);
- if (type_list.GetSize())
- return type_list.GetTypeAtIndex(0);
- return TypeSP();
-}
-
-void Module::FindTypes(
- ConstString name, bool exact_match, size_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeList &types) {
- const char *type_name_cstr = name.GetCString();
- llvm::StringRef type_scope;
- llvm::StringRef type_basename;
- TypeClass type_class = eTypeClassAny;
- TypeMap typesmap;
-
- if (Type::GetTypeScopeAndBasename(type_name_cstr, type_scope, type_basename,
- type_class)) {
- // Check if "name" starts with "::" which means the qualified type starts
- // from the root namespace and implies and exact match. The typenames we
- // get back from clang do not start with "::" so we need to strip this off
- // in order to get the qualified names to match
- exact_match = type_scope.consume_front("::");
-
- ConstString type_basename_const_str(type_basename);
- FindTypes_Impl(type_basename_const_str, CompilerDeclContext(), max_matches,
- searched_symbol_files, typesmap);
- if (typesmap.GetSize())
- typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
- exact_match);
- } else {
- // The type is not in a namespace/class scope, just search for it by
- // basename
- if (type_class != eTypeClassAny && !type_basename.empty()) {
- // The "type_name_cstr" will have been modified if we have a valid type
- // class prefix (like "struct", "class", "union", "typedef" etc).
- FindTypes_Impl(ConstString(type_basename), CompilerDeclContext(),
- UINT_MAX, searched_symbol_files, typesmap);
- typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class,
- exact_match);
- } else {
- FindTypes_Impl(name, CompilerDeclContext(), UINT_MAX,
- searched_symbol_files, typesmap);
- if (exact_match) {
- typesmap.RemoveMismatchedTypes(type_scope, name, type_class,
- exact_match);
- }
- }
- }
- if (typesmap.GetSize()) {
- SymbolContext sc;
- sc.module_sp = shared_from_this();
- sc.SortTypeList(typesmap, types);
- }
-}
-
-void Module::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- // If a scoped timer is needed, place it in a SymbolFile::FindTypes override.
- // A timer here is too high volume for some cases, for example when calling
- // FindTypes on each object file.
- if (SymbolFile *symbols = GetSymbolFile())
- symbols->FindTypes(pattern, languages, searched_symbol_files, types);
+ symbols->FindTypes(query, results);
}
static Debugger::DebuggerList
diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp
index 04a9df7d..aa89c93 100644
--- a/lldb/source/Core/ModuleList.cpp
+++ b/lldb/source/Core/ModuleList.cpp
@@ -557,36 +557,21 @@ ModuleSP ModuleList::FindModule(const UUID &uuid) const {
return module_sp;
}
-void ModuleList::FindTypes(Module *search_first, ConstString name,
- bool name_is_fully_qualified, size_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeList &types) const {
+void ModuleList::FindTypes(Module *search_first, const TypeQuery &query,
+ TypeResults &results) const {
std::lock_guard<std::recursive_mutex> guard(m_modules_mutex);
-
- collection::const_iterator pos, end = m_modules.end();
if (search_first) {
- for (pos = m_modules.begin(); pos != end; ++pos) {
- if (search_first == pos->get()) {
- search_first->FindTypes(name, name_is_fully_qualified, max_matches,
- searched_symbol_files, types);
-
- if (types.GetSize() >= max_matches)
- return;
- }
- }
- }
-
- for (pos = m_modules.begin(); pos != end; ++pos) {
- // Search the module if the module is not equal to the one in the symbol
- // context "sc". If "sc" contains a empty module shared pointer, then the
- // comparison will always be true (valid_module_ptr != nullptr).
- if (search_first != pos->get())
- (*pos)->FindTypes(name, name_is_fully_qualified, max_matches,
- searched_symbol_files, types);
-
- if (types.GetSize() >= max_matches)
+ search_first->FindTypes(query, results);
+ if (results.Done(query))
return;
}
+ for (const auto &module_sp : m_modules) {
+ if (search_first != module_sp.get()) {
+ module_sp->FindTypes(query, results);
+ if (results.Done(query))
+ return;
+ }
+ }
}
bool ModuleList::FindSourceFile(const FileSpec &orig_spec,
diff --git a/lldb/source/DataFormatters/TypeFormat.cpp b/lldb/source/DataFormatters/TypeFormat.cpp
index 126240a..409c452 100644
--- a/lldb/source/DataFormatters/TypeFormat.cpp
+++ b/lldb/source/DataFormatters/TypeFormat.cpp
@@ -161,13 +161,12 @@ bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj,
if (!target_sp)
return false;
const ModuleList &images(target_sp->GetImages());
- TypeList types;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- images.FindTypes(nullptr, m_enum_type, false, UINT32_MAX,
- searched_symbol_files, types);
- if (types.Empty())
+ TypeQuery query(m_enum_type.GetStringRef());
+ TypeResults results;
+ images.FindTypes(nullptr, query, results);
+ if (results.GetTypeMap().Empty())
return false;
- for (lldb::TypeSP type_sp : types.Types()) {
+ for (lldb::TypeSP type_sp : results.GetTypeMap().Types()) {
if (!type_sp)
continue;
if ((type_sp->GetForwardCompilerType().GetTypeInfo() &
diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 5d7e125..00ab6a0 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -201,19 +201,17 @@ TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
LLDB_LOG(log, " CTD Searching namespace {0} in module {1}",
item.second.GetName(), item.first->GetFileSpec().GetFilename());
- TypeList types;
-
ConstString name(decl->getName());
- item.first->FindTypesInNamespace(name, item.second, UINT32_MAX, types);
-
- for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
-
- if (!type)
- continue;
+ // Create a type matcher using the CompilerDeclContext for the namespace
+ // as the context (item.second) and search for the name inside of this
+ // context.
+ TypeQuery query(item.second, name);
+ TypeResults results;
+ item.first->FindTypes(query, results);
- CompilerType clang_type(type->GetFullCompilerType());
+ for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types()) {
+ CompilerType clang_type(type_sp->GetFullCompilerType());
if (!ClangUtil::IsClangType(clang_type))
continue;
@@ -233,24 +231,15 @@ TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
}
}
} else {
- TypeList types;
-
- ConstString name(decl->getName());
-
const ModuleList &module_list = m_target->GetImages();
+ // Create a type matcher using a CompilerDecl. Each TypeSystem class knows
+ // how to fill out a CompilerContext array using a CompilerDecl.
+ TypeQuery query(CompilerDecl(m_clang_ast_context, (void *)decl));
+ TypeResults results;
+ module_list.FindTypes(nullptr, query, results);
+ for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types()) {
- bool exact_match = false;
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX,
- searched_symbol_files, types);
-
- for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
- lldb::TypeSP type = types.GetTypeAtIndex(ti);
-
- if (!type)
- continue;
-
- CompilerType clang_type(type->GetFullCompilerType());
+ CompilerType clang_type(type_sp->GetFullCompilerType());
if (!ClangUtil::IsClangType(clang_type))
continue;
@@ -263,13 +252,6 @@ TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
TagDecl *candidate_tag_decl = const_cast<TagDecl *>(tag_type->getDecl());
- // We have found a type by basename and we need to make sure the decl
- // contexts are the same before we can try to complete this type with
- // another
- if (!TypeSystemClang::DeclsAreEquivalent(const_cast<TagDecl *>(decl),
- candidate_tag_decl))
- continue;
-
if (TypeSystemClang::GetCompleteDecl(&candidate_tag_decl->getASTContext(),
candidate_tag_decl))
return candidate_tag_decl;
@@ -614,41 +596,40 @@ void ClangASTSource::FindExternalVisibleDecls(
if (context.m_found_type)
return;
- TypeList types;
- const bool exact_match = true;
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- if (module_sp && namespace_decl)
- module_sp->FindTypesInNamespace(name, namespace_decl, 1, types);
- else {
- m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
- searched_symbol_files, types);
+ lldb::TypeSP type_sp;
+ TypeResults results;
+ if (module_sp && namespace_decl) {
+ // Match the name in the specified decl context.
+ TypeQuery query(namespace_decl, name, TypeQueryOptions::e_find_one);
+ module_sp->FindTypes(query, results);
+ type_sp = results.GetFirstType();
+ } else {
+ // Match the exact name of the type at the root level.
+ TypeQuery query(name.GetStringRef(), TypeQueryOptions::e_exact_match |
+ TypeQueryOptions::e_find_one);
+ m_target->GetImages().FindTypes(nullptr, query, results);
+ type_sp = results.GetFirstType();
}
- if (size_t num_types = types.GetSize()) {
- for (size_t ti = 0; ti < num_types; ++ti) {
- lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
-
- if (log) {
- const char *name_string = type_sp->GetName().GetCString();
-
- LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\": {1}", name,
- (name_string ? name_string : "<anonymous>"));
- }
+ if (type_sp) {
+ if (log) {
+ const char *name_string = type_sp->GetName().GetCString();
- CompilerType full_type = type_sp->GetFullCompilerType();
+ LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\": {1}", name,
+ (name_string ? name_string : "<anonymous>"));
+ }
- CompilerType copied_clang_type(GuardedCopyType(full_type));
+ CompilerType full_type = type_sp->GetFullCompilerType();
- if (!copied_clang_type) {
- LLDB_LOG(log, " CAS::FEVD - Couldn't export a type");
+ CompilerType copied_clang_type(GuardedCopyType(full_type));
- continue;
- }
+ if (!copied_clang_type) {
+ LLDB_LOG(log, " CAS::FEVD - Couldn't export a type");
+ } else {
context.AddTypeDecl(copied_clang_type);
context.m_found_type = true;
- break;
}
}
diff --git a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
index a5c9ead..0ea9201 100644
--- a/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
@@ -82,24 +82,30 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfo(
lookup_name.append(class_name.data(), class_name.size());
type_info.SetName(class_name);
- const bool exact_match = true;
+ ConstString const_lookup_name(lookup_name);
TypeList class_types;
-
+ ModuleSP module_sp = vtable_info.symbol->CalculateSymbolContextModule();
// First look in the module that the vtable symbol came from and
// look for a single exact match.
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- ModuleSP module_sp = vtable_info.symbol->CalculateSymbolContextModule();
- if (module_sp)
- module_sp->FindTypes(ConstString(lookup_name), exact_match, 1,
- searched_symbol_files, class_types);
+ TypeResults results;
+ TypeQuery query(const_lookup_name.GetStringRef(),
+ TypeQueryOptions::e_exact_match |
+ TypeQueryOptions::e_find_one);
+ if (module_sp) {
+ module_sp->FindTypes(query, results);
+ TypeSP type_sp = results.GetFirstType();
+ if (type_sp)
+ class_types.Insert(type_sp);
+ }
// If we didn't find a symbol, then move on to the entire module
// list in the target and get as many unique matches as possible
- Target &target = m_process->GetTarget();
- if (class_types.Empty())
- target.GetImages().FindTypes(nullptr, ConstString(lookup_name),
- exact_match, UINT32_MAX,
- searched_symbol_files, class_types);
+ if (class_types.Empty()) {
+ query.SetFindOne(false);
+ m_process->GetTarget().GetImages().FindTypes(nullptr, query, results);
+ for (const auto &type_sp : results.GetTypeMap().Types())
+ class_types.Insert(type_sp);
+ }
lldb::TypeSP type_sp;
if (class_types.Empty()) {
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
index 289288a..ba52444 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -139,17 +139,10 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) {
if (!module_sp)
return TypeSP();
- const bool exact_match = true;
- const uint32_t max_matches = UINT32_MAX;
- TypeList types;
-
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- module_sp->FindTypes(name, exact_match, max_matches, searched_symbol_files,
- types);
-
- for (uint32_t i = 0; i < types.GetSize(); ++i) {
- TypeSP type_sp(types.GetTypeAtIndex(i));
-
+ TypeQuery query(name.GetStringRef(), TypeQueryOptions::e_exact_match);
+ TypeResults results;
+ module_sp->FindTypes(query, results);
+ for (const TypeSP &type_sp : results.GetTypeMap().Types()) {
if (TypeSystemClang::IsObjCObjectOrInterfaceType(
type_sp->GetForwardCompilerType())) {
if (TypePayloadClang(type_sp->GetPayload()).IsCompleteObjCClass()) {
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index cd52233..729d6af 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -448,15 +448,6 @@ void SymbolFileBreakpad::FindFunctions(const RegularExpression &regex,
// TODO
}
-void SymbolFileBreakpad::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) {}
-
-void SymbolFileBreakpad::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {}
-
void SymbolFileBreakpad::AddSymbols(Symtab &symtab) {
Log *log = GetLog(LLDBLog::Symbols);
Module &module = *m_objfile_sp->GetModule();
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 4a01a64..214fbdd 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -118,15 +118,6 @@ public:
void FindFunctions(const RegularExpression &regex, bool include_inlines,
SymbolContextList &sc_list) override;
- void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
-
- void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
-
llvm::Expected<lldb::TypeSystemSP>
GetTypeSystemForLanguage(lldb::LanguageType language) override {
return llvm::make_error<llvm::StringError>(
diff --git a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
index 7a2b4c0..d192944 100644
--- a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
+++ b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp
@@ -1020,23 +1020,18 @@ lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
return type_sp.get();
}
-void SymbolFileCTF::FindTypes(
- lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) {
-
- searched_symbol_files.clear();
- searched_symbol_files.insert(this);
+void SymbolFileCTF::FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) {
+ // Make sure we haven't already searched this SymbolFile before.
+ if (results.AlreadySearched(this))
+ return;
- size_t matches = 0;
+ ConstString name = match.GetTypeBasename();
for (TypeSP type_sp : GetTypeList().Types()) {
- if (matches == max_matches)
- break;
if (type_sp && type_sp->GetName() == name) {
- types.Insert(type_sp);
- matches++;
+ results.InsertUnique(type_sp);
+ if (results.Done(match))
+ return;
}
}
}
diff --git a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
index 787dc18..f111937 100644
--- a/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
+++ b/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h
@@ -105,12 +105,8 @@ public:
lldb::TypeClass type_mask,
lldb_private::TypeList &type_list) override {}
- void
- FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
void FindTypesByRegex(const lldb_private::RegularExpression &regex,
uint32_t max_matches, lldb_private::TypeMap &types);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index e3c6464..3348766 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -152,16 +152,16 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
// If this type comes from a Clang module, recursively look in the
// DWARF section of the .pcm file in the module cache. Clang
// generates DWO skeleton units as breadcrumbs to find them.
- std::vector<CompilerContext> decl_context = die.GetDeclContext();
- TypeMap pcm_types;
+ std::vector<lldb_private::CompilerContext> die_context = die.GetDeclContext();
+ TypeQuery query(die_context, TypeQueryOptions::e_module_search |
+ TypeQueryOptions::e_find_one);
+ TypeResults results;
// The type in the Clang module must have the same language as the current CU.
- LanguageSet languages;
- languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));
- llvm::DenseSet<SymbolFile *> searched_symbol_files;
- clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages,
- searched_symbol_files, pcm_types);
- if (pcm_types.Empty()) {
+ query.AddLanguage(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));
+ clang_module_sp->FindTypes(query, results);
+ TypeSP pcm_type_sp = results.GetTypeMap().FirstType();
+ if (!pcm_type_sp) {
// Since this type is defined in one of the Clang modules imported
// by this symbol file, search all of them. Instead of calling
// sym_file->FindTypes(), which would return this again, go straight
@@ -170,24 +170,20 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
// Well-formed clang modules never form cycles; guard against corrupted
// ones by inserting the current file.
- searched_symbol_files.insert(&sym_file);
+ results.AlreadySearched(&sym_file);
sym_file.ForEachExternalModule(
- *sc.comp_unit, searched_symbol_files, [&](Module &module) {
- module.GetSymbolFile()->FindTypes(decl_context, languages,
- searched_symbol_files, pcm_types);
- return pcm_types.GetSize();
+ *sc.comp_unit, results.GetSearchedSymbolFiles(), [&](Module &module) {
+ module.FindTypes(query, results);
+ pcm_type_sp = results.GetTypeMap().FirstType();
+ return !pcm_type_sp;
});
}
- if (!pcm_types.GetSize())
+ if (!pcm_type_sp)
return TypeSP();
// We found a real definition for this type in the Clang module, so lets use
// it and cache the fact that we found a complete type for this die.
- TypeSP pcm_type_sp = pcm_types.GetTypeAtIndex(0);
- if (!pcm_type_sp)
- return TypeSP();
-
lldb_private::CompilerType pcm_type = pcm_type_sp->GetForwardCompilerType();
lldb_private::CompilerType type =
GetClangASTImporter().CopyType(m_ast, pcm_type);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
index 1f9524f..bed68f4 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -418,6 +418,54 @@ std::vector<lldb_private::CompilerContext> DWARFDIE::GetDeclContext() const {
return context;
}
+std::vector<lldb_private::CompilerContext>
+DWARFDIE::GetTypeLookupContext() const {
+ std::vector<lldb_private::CompilerContext> context;
+ // If there is no name, then there is no need to look anything up for this
+ // DIE.
+ const char *name = GetName();
+ if (!name || !name[0])
+ return context;
+ const dw_tag_t tag = Tag();
+ if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit)
+ return context;
+ DWARFDIE parent = GetParent();
+ if (parent)
+ context = parent.GetTypeLookupContext();
+ auto push_ctx = [&](CompilerContextKind kind, llvm::StringRef name) {
+ context.push_back({kind, ConstString(name)});
+ };
+ switch (tag) {
+ case DW_TAG_namespace:
+ push_ctx(CompilerContextKind::Namespace, name);
+ break;
+ case DW_TAG_structure_type:
+ push_ctx(CompilerContextKind::Struct, name);
+ break;
+ case DW_TAG_union_type:
+ push_ctx(CompilerContextKind::Union, name);
+ break;
+ case DW_TAG_class_type:
+ push_ctx(CompilerContextKind::Class, name);
+ break;
+ case DW_TAG_enumeration_type:
+ push_ctx(CompilerContextKind::Enum, name);
+ break;
+ case DW_TAG_variable:
+ push_ctx(CompilerContextKind::Variable, GetPubname());
+ break;
+ case DW_TAG_typedef:
+ push_ctx(CompilerContextKind::Typedef, name);
+ break;
+ case DW_TAG_base_type:
+ push_ctx(CompilerContextKind::Builtin, name);
+ break;
+ default:
+ break;
+ }
+ return context;
+}
+
DWARFDIE
DWARFDIE::GetParentDeclContextDIE() const {
if (IsValid())
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
index a68af62c..511ca62 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -73,9 +73,22 @@ public:
std::vector<DWARFDIE> GetDeclContextDIEs() const;
/// Return this DIE's decl context as it is needed to look up types
- /// in Clang's -gmodules debug info format.
+ /// in Clang modules. This context will include any modules or functions that
+ /// the type is declared in so an exact module match can be efficiently made.
std::vector<CompilerContext> GetDeclContext() const;
+ /// Get a context to a type so it can be looked up.
+ ///
+ /// This function uses the current DIE to fill in a CompilerContext array
+ /// that is suitable for type lookup for comparison to a TypeQuery's compiler
+ /// context (TypeQuery::GetContextRef()). If this DIE represents a named type,
+ /// it should fill out the compiler context with the type itself as the last
+ /// entry. The declaration context should be above the type and stop at an
+ /// appropriate time, like either the translation unit or at a function
+ /// context. This is designed to allow users to efficiently look for types
+ /// using a full or partial CompilerContext array.
+ std::vector<CompilerContext> GetTypeLookupContext() const;
+
// Getting attribute values from the DIE.
//
// GetAttributeValueAsXXX() functions should only be used if you are
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index d4c573e..7eddc50 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2596,177 +2596,157 @@ void SymbolFileDWARF::GetMangledNamesForFunction(
}
}
-void SymbolFileDWARF::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- // Make sure we haven't already searched this SymbolFile before.
- if (!searched_symbol_files.insert(this).second)
- return;
-
- Log *log = GetLog(DWARFLog::Lookups);
+/// Split a name up into a basename and template parameters.
+static bool SplitTemplateParams(llvm::StringRef fullname,
+ llvm::StringRef &basename,
+ llvm::StringRef &template_params) {
+ auto it = fullname.find('<');
+ if (it == llvm::StringRef::npos) {
+ basename = fullname;
+ template_params = llvm::StringRef();
+ return false;
+ }
+ basename = fullname.slice(0, it);
+ template_params = fullname.slice(it, fullname.size());
+ return true;
+}
- if (log) {
- if (parent_decl_ctx)
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx = "
- "{1:p} (\"{2}\"), max_matches={3}, type_list)",
- name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
- parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches);
- else
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx = "
- "NULL, max_matches={1}, type_list)",
- name.GetCString(), max_matches);
+static bool UpdateCompilerContextForSimpleTemplateNames(TypeQuery &match) {
+ // We need to find any names in the context that have template parameters
+ // and strip them so the context can be matched when -gsimple-template-names
+ // is being used. Returns true if any of the context items were updated.
+ bool any_context_updated = false;
+ for (auto &context : match.GetContextRef()) {
+ llvm::StringRef basename, params;
+ if (SplitTemplateParams(context.name.GetStringRef(), basename, params)) {
+ context.name = ConstString(basename);
+ any_context_updated = true;
+ }
}
+ return any_context_updated;
+}
+void SymbolFileDWARF::FindTypes(const TypeQuery &query, TypeResults &results) {
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
+ // Make sure we haven't already searched this SymbolFile before.
+ if (results.AlreadySearched(this))
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
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- Type *matching_type = ResolveType(die, true, true);
- if (!matching_type)
- return true;
+ bool have_index_match = false;
+ m_index->GetTypes(query.GetTypeBasename(), [&](DWARFDIE die) {
+ // Check the language, but only if we have a language filter.
+ if (query.HasLanguage()) {
+ if (!query.LanguageMatches(GetLanguageFamily(*die.GetCU())))
+ return true; // Keep iterating over index types, language mismatch.
+ }
- // 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;
+ // Check the context matches
+ std::vector<lldb_private::CompilerContext> die_context;
+ if (query.GetModuleSearch())
+ die_context = die.GetDeclContext();
+ else
+ die_context = die.GetTypeLookupContext();
+ assert(!die_context.empty());
+ if (!query.ContextMatches(die_context))
+ return true; // Keep iterating over index types, context mismatch.
- // We found a type pointer, now find the shared pointer form our type
- // list
- types.InsertUnique(matching_type->shared_from_this());
- return types.GetSize() < max_matches;
+ // Try to resolve the type.
+ if (Type *matching_type = ResolveType(die, true, true)) {
+ if (matching_type->IsTemplateType()) {
+ // We have to watch out for case where we lookup a type by basename and
+ // it matches a template with simple template names. Like looking up
+ // "Foo" and if we have simple template names then we will match
+ // "Foo<int>" and "Foo<double>" because all the DWARF has is "Foo" in
+ // the accelerator tables. The main case we see this in is when the
+ // expression parser is trying to parse "Foo<int>" and it will first do
+ // a lookup on just "Foo". We verify the type basename matches before
+ // inserting the type in the results.
+ auto CompilerTypeBasename =
+ matching_type->GetForwardCompilerType().GetTypeName(true);
+ if (CompilerTypeBasename != query.GetTypeBasename())
+ return true; // Keep iterating over index types, basename mismatch.
+ }
+ have_index_match = true;
+ results.InsertUnique(matching_type->shared_from_this());
+ }
+ return !results.Done(query); // Keep iterating if we aren't done.
});
+ if (results.Done(query))
+ return;
+
// With -gsimple-template-names, a templated type's DW_AT_name will not
// 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) {
- 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
-
- const llvm::StringRef base_name = GetTypeForDIE(die)->GetBaseName().AsCString();
- auto it = base_name.find('<');
- // If the candidate qualified name doesn't have '<', it doesn't have
- // template params to compare.
- if (it == llvm::StringRef::npos)
- return true;
-
- // Filter out non-matching instantiations by comparing template params.
- const llvm::StringRef base_name_template_params =
- base_name.slice(it, base_name.size());
-
- if (template_params != base_name_template_params)
- return true;
-
- Type *matching_type = ResolveType(die, true, true);
- if (!matching_type)
- return true;
+ if (!have_index_match) {
+ // Create a type matcher with a compiler context that is tuned for
+ // -gsimple-template-names. We will use this for the index lookup and the
+ // context matching, but will use the original "match" to insert matches
+ // into if things match. The "match_simple" has a compiler context with
+ // all template parameters removed to allow the names and context to match.
+ // The UpdateCompilerContextForSimpleTemplateNames(...) will return true if
+ // it trims any context items down by removing template parameter names.
+ TypeQuery query_simple(query);
+ if (UpdateCompilerContextForSimpleTemplateNames(query_simple)) {
+
+ // Copy our match's context and update the basename we are looking for
+ // so we can use this only to compare the context correctly.
+ m_index->GetTypes(query_simple.GetTypeBasename(), [&](DWARFDIE die) {
+ // Check the language, but only if we have a language filter.
+ if (query.HasLanguage()) {
+ if (!query.LanguageMatches(GetLanguageFamily(*die.GetCU())))
+ return true; // Keep iterating over index types, language mismatch.
+ }
- // We found a type pointer, now find the shared pointer form our type
- // list.
- types.InsertUnique(matching_type->shared_from_this());
- return types.GetSize() < max_matches;
+ // Check the context matches
+ std::vector<lldb_private::CompilerContext> die_context;
+ if (query.GetModuleSearch())
+ die_context = die.GetDeclContext();
+ else
+ die_context = die.GetTypeLookupContext();
+ assert(!die_context.empty());
+ if (!query_simple.ContextMatches(die_context))
+ return true; // Keep iterating over index types, context mismatch.
+
+ // Try to resolve the type.
+ if (Type *matching_type = ResolveType(die, true, true)) {
+ ConstString name = matching_type->GetQualifiedName();
+ // We have found a type that still might not match due to template
+ // parameters. If we create a new TypeQuery that uses the new type's
+ // fully qualified name, we can find out if this type matches at all
+ // context levels. We can't use just the "match_simple" context
+ // because all template parameters were stripped off. The fully
+ // qualified name of the type will have the template parameters and
+ // will allow us to make sure it matches correctly.
+ TypeQuery die_query(name.GetStringRef(),
+ TypeQueryOptions::e_exact_match);
+ if (!query.ContextMatches(die_query.GetContextRef()))
+ return true; // Keep iterating over index types, context mismatch.
+
+ results.InsertUnique(matching_type->shared_from_this());
+ }
+ return !results.Done(query); // Keep iterating if we aren't done.
});
+ if (results.Done(query))
+ return;
}
}
// Next search through the reachable Clang modules. This only applies for
// DWARF objects compiled with -gmodules that haven't been processed by
// dsymutil.
- if (types.GetSize() < max_matches) {
- UpdateExternalModuleListIfNeeded();
-
- for (const auto &pair : m_external_type_modules)
- if (ModuleSP external_module_sp = pair.second)
- if (SymbolFile *sym_file = external_module_sp->GetSymbolFile())
- sym_file->FindTypes(name, parent_decl_ctx, max_matches,
- searched_symbol_files, types);
- }
+ UpdateExternalModuleListIfNeeded();
- if (log && types.GetSize()) {
- if (parent_decl_ctx) {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx "
- "= {1:p} (\"{2}\"), max_matches={3}, type_list) => {4}",
- name.GetCString(), static_cast<const void *>(&parent_decl_ctx),
- parent_decl_ctx.GetName().AsCString("<NULL>"), max_matches,
- types.GetSize());
- } else {
- GetObjectFile()->GetModule()->LogMessage(
- log,
- "SymbolFileDWARF::FindTypes (sc, name=\"{0}\", parent_decl_ctx "
- "= NULL, max_matches={1}, type_list) => {2}",
- name.GetCString(), max_matches, types.GetSize());
+ for (const auto &pair : m_external_type_modules) {
+ if (ModuleSP external_module_sp = pair.second) {
+ external_module_sp->FindTypes(query, results);
+ if (results.Done(query))
+ return;
}
}
}
-void SymbolFileDWARF::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
- // Make sure we haven't already searched this SymbolFile before.
- if (!searched_symbol_files.insert(this).second)
- return;
-
- std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- if (pattern.empty())
- return;
-
- ConstString name = pattern.back().name;
-
- if (!name)
- return;
-
- m_index->GetTypes(name, [&](DWARFDIE die) {
- if (!languages[GetLanguageFamily(*die.GetCU())])
- return true;
-
- std::vector<CompilerContext> die_context = die.GetDeclContext();
- if (!contextMatches(die_context, pattern))
- return true;
-
- if (Type *matching_type = ResolveType(die, true, true)) {
- // We found a type pointer, now find the shared pointer form our type
- // list.
- types.InsertUnique(matching_type->shared_from_this());
- }
- return true;
- });
-
- // Next search through the reachable Clang modules. This only applies for
- // DWARF objects compiled with -gmodules that haven't been processed by
- // dsymutil.
- UpdateExternalModuleListIfNeeded();
-
- for (const auto &pair : m_external_type_modules)
- if (ModuleSP external_module_sp = pair.second)
- external_module_sp->FindTypes(pattern, languages, searched_symbol_files,
- types);
-}
-
CompilerDeclContext
SymbolFileDWARF::FindNamespace(ConstString name,
const CompilerDeclContext &parent_decl_ctx,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index e6efbba..78819ed 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -186,14 +186,8 @@ public:
GetMangledNamesForFunction(const std::string &scope_qualified_name,
std::vector<ConstString> &mangled_names) override;
- void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
-
- void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
void GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask,
TypeList &type_list) override;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index 263ada9..e5b59460 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -1227,27 +1227,12 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE(
return TypeSP();
}
-void SymbolFileDWARFDebugMap::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
+void SymbolFileDWARFDebugMap::FindTypes(const TypeQuery &query,
+ TypeResults &results) {
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes(name, parent_decl_ctx, max_matches,
- searched_symbol_files, types);
- return types.GetSize() >= max_matches;
- });
-}
-
-void SymbolFileDWARFDebugMap::FindTypes(
- llvm::ArrayRef<CompilerContext> context, LanguageSet languages,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- LLDB_SCOPED_TIMER();
- ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool {
- oso_dwarf->FindTypes(context, languages, searched_symbol_files, types);
- return false;
+ oso_dwarf->FindTypes(query, results);
+ return !results.Done(query); // Keep iterating if we aren't done.
});
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
index 13f94f6..cd0a4bb 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
@@ -118,13 +118,8 @@ public:
bool include_inlines, SymbolContextList &sc_list) override;
void FindFunctions(const RegularExpression &regex, bool include_inlines,
SymbolContextList &sc_list) override;
- void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
- void FindTypes(llvm::ArrayRef<CompilerContext> context, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
CompilerDeclContext FindNamespace(ConstString name,
const CompilerDeclContext &parent_decl_ctx,
bool only_root_namespaces) override;
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index eaca476..35c2575 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1717,24 +1717,33 @@ void SymbolFileNativePDB::FindFunctions(const RegularExpression &regex,
bool include_inlines,
SymbolContextList &sc_list) {}
-void SymbolFileNativePDB::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches, llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- if (!name)
+void SymbolFileNativePDB::FindTypes(const lldb_private::TypeQuery &query,
+ lldb_private::TypeResults &results) {
+
+ // Make sure we haven't already searched this SymbolFile before.
+ if (results.AlreadySearched(this))
return;
- searched_symbol_files.clear();
- searched_symbol_files.insert(this);
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- // There is an assumption 'name' is not a regex
- FindTypesByName(name.GetStringRef(), max_matches, types);
-}
+ std::vector<TypeIndex> matches =
+ m_index->tpi().findRecordsByName(query.GetTypeBasename().GetStringRef());
-void SymbolFileNativePDB::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {}
+ for (TypeIndex type_idx : matches) {
+ TypeSP type_sp = GetOrCreateType(type_idx);
+ if (!type_sp)
+ continue;
+
+ // We resolved a type. Get the fully qualified name to ensure it matches.
+ ConstString name = type_sp->GetQualifiedName();
+ TypeQuery type_match(name.GetStringRef(), TypeQueryOptions::e_exact_match);
+ if (query.ContextMatches(type_match.GetContextRef())) {
+ results.InsertUnique(type_sp);
+ if (results.Done(query))
+ return;
+ }
+ }
+}
void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name,
uint32_t max_matches,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index bf64cd33..9d0458c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -140,14 +140,8 @@ public:
std::optional<PdbCompilandSymId> FindSymbolScope(PdbCompilandSymId id);
- void FindTypes(ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
-
- void FindTypes(llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) override;
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
llvm::Expected<lldb::TypeSystemSP>
GetTypeSystemForLanguage(lldb::LanguageType language) override;
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 78eabc3..96036de 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1446,24 +1446,6 @@ void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) {
symtab.Finalize();
}
-void SymbolFilePDB::FindTypes(
- lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) {
- std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- if (!name)
- return;
- if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
- return;
-
- searched_symbol_files.clear();
- searched_symbol_files.insert(this);
-
- // There is an assumption 'name' is not a regex
- FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types);
-}
-
void SymbolFilePDB::DumpClangAST(Stream &s) {
auto type_system_or_err =
GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
@@ -1536,25 +1518,27 @@ void SymbolFilePDB::FindTypesByRegex(
}
}
-void SymbolFilePDB::FindTypesByName(
- llvm::StringRef name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches, lldb_private::TypeMap &types) {
+void SymbolFilePDB::FindTypes(const lldb_private::TypeQuery &query,
+ lldb_private::TypeResults &type_results) {
+
+ // Make sure we haven't already searched this SymbolFile before.
+ if (type_results.AlreadySearched(this))
+ return;
+
+ std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
+
std::unique_ptr<IPDBEnumSymbols> results;
- if (name.empty())
+ llvm::StringRef basename = query.GetTypeBasename().GetStringRef();
+ if (basename.empty())
return;
results = m_global_scope_up->findAllChildren(PDB_SymType::None);
if (!results)
return;
- uint32_t matches = 0;
-
while (auto result = results->getNext()) {
- if (max_matches > 0 && matches >= max_matches)
- break;
if (MSVCUndecoratedNameParser::DropScope(
- result->getRawSymbol().getName()) != name)
+ result->getRawSymbol().getName()) != basename)
continue;
switch (result->getSymTag()) {
@@ -1573,23 +1557,20 @@ void SymbolFilePDB::FindTypesByName(
if (!ResolveTypeUID(result->getSymIndexId()))
continue;
- if (parent_decl_ctx.IsValid() &&
- GetDeclContextContainingUID(result->getSymIndexId()) != parent_decl_ctx)
- continue;
-
auto iter = m_types.find(result->getSymIndexId());
if (iter == m_types.end())
continue;
- types.Insert(iter->second);
- ++matches;
+ // We resolved a type. Get the fully qualified name to ensure it matches.
+ ConstString name = iter->second->GetQualifiedName();
+ TypeQuery type_match(name.GetStringRef(), TypeQueryOptions::e_exact_match);
+ if (query.ContextMatches(type_match.GetContextRef())) {
+ type_results.InsertUnique(iter->second);
+ if (type_results.Done(query))
+ return;
+ }
}
}
-void SymbolFilePDB::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) {}
-
void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol,
uint32_t type_mask,
TypeCollection &type_collection) {
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index 5b98c6e..01851f1 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -134,19 +134,8 @@ public:
std::vector<lldb_private::ConstString> &mangled_names) override;
void AddSymbols(lldb_private::Symtab &symtab) override;
-
- void
- FindTypes(lldb_private::ConstString name,
- const lldb_private::CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
-
- void FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> pattern,
- lldb_private::LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- lldb_private::TypeMap &types) override;
-
+ void FindTypes(const lldb_private::TypeQuery &match,
+ lldb_private::TypeResults &results) override;
void FindTypesByRegex(const lldb_private::RegularExpression &regex,
uint32_t max_matches, lldb_private::TypeMap &types);
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 7c28935..47024cd 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -2461,89 +2461,6 @@ void TypeSystemClang::DumpDeclHiearchy(clang::Decl *decl) {
}
}
-bool TypeSystemClang::DeclsAreEquivalent(clang::Decl *lhs_decl,
- clang::Decl *rhs_decl) {
- if (lhs_decl && rhs_decl) {
- // Make sure the decl kinds match first
- const clang::Decl::Kind lhs_decl_kind = lhs_decl->getKind();
- const clang::Decl::Kind rhs_decl_kind = rhs_decl->getKind();
-
- if (lhs_decl_kind == rhs_decl_kind) {
- // Now check that the decl contexts kinds are all equivalent before we
- // have to check any names of the decl contexts...
- clang::DeclContext *lhs_decl_ctx = lhs_decl->getDeclContext();
- clang::DeclContext *rhs_decl_ctx = rhs_decl->getDeclContext();
- if (lhs_decl_ctx && rhs_decl_ctx) {
- while (true) {
- if (lhs_decl_ctx && rhs_decl_ctx) {
- const clang::Decl::Kind lhs_decl_ctx_kind =
- lhs_decl_ctx->getDeclKind();
- const clang::Decl::Kind rhs_decl_ctx_kind =
- rhs_decl_ctx->getDeclKind();
- if (lhs_decl_ctx_kind == rhs_decl_ctx_kind) {
- lhs_decl_ctx = lhs_decl_ctx->getParent();
- rhs_decl_ctx = rhs_decl_ctx->getParent();
-
- if (lhs_decl_ctx == nullptr && rhs_decl_ctx == nullptr)
- break;
- } else
- return false;
- } else
- return false;
- }
-
- // Now make sure the name of the decls match
- clang::NamedDecl *lhs_named_decl =
- llvm::dyn_cast<clang::NamedDecl>(lhs_decl);
- clang::NamedDecl *rhs_named_decl =
- llvm::dyn_cast<clang::NamedDecl>(rhs_decl);
- if (lhs_named_decl && rhs_named_decl) {
- clang::DeclarationName lhs_decl_name = lhs_named_decl->getDeclName();
- clang::DeclarationName rhs_decl_name = rhs_named_decl->getDeclName();
- if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
- if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
- return false;
- } else
- return false;
- } else
- return false;
-
- // We know that the decl context kinds all match, so now we need to
- // make sure the names match as well
- lhs_decl_ctx = lhs_decl->getDeclContext();
- rhs_decl_ctx = rhs_decl->getDeclContext();
- while (true) {
- switch (lhs_decl_ctx->getDeclKind()) {
- case clang::Decl::TranslationUnit:
- // We don't care about the translation unit names
- return true;
- default: {
- clang::NamedDecl *lhs_named_decl =
- llvm::dyn_cast<clang::NamedDecl>(lhs_decl_ctx);
- clang::NamedDecl *rhs_named_decl =
- llvm::dyn_cast<clang::NamedDecl>(rhs_decl_ctx);
- if (lhs_named_decl && rhs_named_decl) {
- clang::DeclarationName lhs_decl_name =
- lhs_named_decl->getDeclName();
- clang::DeclarationName rhs_decl_name =
- rhs_named_decl->getDeclName();
- if (lhs_decl_name.getNameKind() == rhs_decl_name.getNameKind()) {
- if (lhs_decl_name.getAsString() != rhs_decl_name.getAsString())
- return false;
- } else
- return false;
- } else
- return false;
- } break;
- }
- lhs_decl_ctx = lhs_decl_ctx->getParent();
- rhs_decl_ctx = rhs_decl_ctx->getParent();
- }
- }
- }
- }
- return false;
-}
bool TypeSystemClang::GetCompleteDecl(clang::ASTContext *ast,
clang::Decl *decl) {
if (!decl)
@@ -9070,6 +8987,66 @@ size_t TypeSystemClang::DeclGetFunctionNumArguments(void *opaque_decl) {
return 0;
}
+static CompilerContextKind GetCompilerKind(clang::Decl::Kind clang_kind,
+ clang::DeclContext const *decl_ctx) {
+ switch (clang_kind) {
+ case Decl::TranslationUnit:
+ return CompilerContextKind::TranslationUnit;
+ case Decl::Namespace:
+ return CompilerContextKind::Namespace;
+ case Decl::Var:
+ return CompilerContextKind::Variable;
+ case Decl::Enum:
+ return CompilerContextKind::Enum;
+ case Decl::Typedef:
+ return CompilerContextKind::Typedef;
+ default:
+ // Many other kinds have multiple values
+ if (decl_ctx) {
+ if (decl_ctx->isFunctionOrMethod())
+ return CompilerContextKind::Function;
+ else if (decl_ctx->isRecord())
+ return (CompilerContextKind)((uint16_t)CompilerContextKind::Class |
+ (uint16_t)CompilerContextKind::Struct |
+ (uint16_t)CompilerContextKind::Union);
+ }
+ break;
+ }
+ return CompilerContextKind::Any;
+}
+
+static void
+InsertCompilerContext(TypeSystemClang *ts, clang::DeclContext *decl_ctx,
+ std::vector<lldb_private::CompilerContext> &context) {
+ if (decl_ctx == nullptr)
+ return;
+ InsertCompilerContext(ts, decl_ctx->getParent(), context);
+ clang::Decl::Kind clang_kind = decl_ctx->getDeclKind();
+ if (clang_kind == Decl::TranslationUnit)
+ return; // Stop at the translation unit.
+ const CompilerContextKind compiler_kind =
+ GetCompilerKind(clang_kind, decl_ctx);
+ ConstString decl_ctx_name = ts->DeclContextGetName(decl_ctx);
+ context.push_back({compiler_kind, decl_ctx_name});
+}
+
+std::vector<lldb_private::CompilerContext>
+TypeSystemClang::DeclGetCompilerContext(void *opaque_decl) {
+ std::vector<lldb_private::CompilerContext> context;
+ ConstString decl_name = DeclGetName(opaque_decl);
+ if (decl_name) {
+ clang::Decl *decl = (clang::Decl *)opaque_decl;
+ // Add the entire decl context first
+ clang::DeclContext *decl_ctx = decl->getDeclContext();
+ InsertCompilerContext(this, decl_ctx, context);
+ // Now add the decl information
+ auto compiler_kind =
+ GetCompilerKind(decl->getKind(), dyn_cast<DeclContext>(decl));
+ context.push_back({compiler_kind, decl_name});
+ }
+ return context;
+}
+
CompilerType TypeSystemClang::DeclGetFunctionArgumentType(void *opaque_decl,
size_t idx) {
if (clang::FunctionDecl *func_decl =
@@ -9308,6 +9285,14 @@ bool TypeSystemClang::DeclContextIsClassMethod(void *opaque_decl_ctx) {
return false;
}
+std::vector<lldb_private::CompilerContext>
+TypeSystemClang::DeclContextGetCompilerContext(void *opaque_decl_ctx) {
+ auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
+ std::vector<lldb_private::CompilerContext> context;
+ InsertCompilerContext(this, decl_ctx, context);
+ return context;
+}
+
bool TypeSystemClang::DeclContextIsContainedInLookup(
void *opaque_decl_ctx, void *other_opaque_decl_ctx) {
auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx;
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 19f2673..a731648 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -183,8 +183,6 @@ public:
static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx);
- static bool DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl);
-
static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl);
void SetMetadataAsUserID(const clang::Decl *decl, lldb::user_id_t user_id);
@@ -558,6 +556,9 @@ public:
CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
size_t arg_idx) override;
+ std::vector<lldb_private::CompilerContext>
+ DeclGetCompilerContext(void *opaque_decl) override;
+
CompilerType GetTypeForDecl(void *opaque_decl) override;
// CompilerDeclContext override functions
@@ -587,6 +588,9 @@ public:
lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) override;
+ std::vector<lldb_private::CompilerContext>
+ DeclContextGetCompilerContext(void *opaque_decl_ctx) override;
+
// Clang specific clang::DeclContext functions
static clang::DeclContext *
diff --git a/lldb/source/Symbol/CompilerDecl.cpp b/lldb/source/Symbol/CompilerDecl.cpp
index 3cafa95..0eb630e 100644
--- a/lldb/source/Symbol/CompilerDecl.cpp
+++ b/lldb/source/Symbol/CompilerDecl.cpp
@@ -47,3 +47,8 @@ bool lldb_private::operator!=(const lldb_private::CompilerDecl &lhs,
return lhs.GetTypeSystem() != rhs.GetTypeSystem() ||
lhs.GetOpaqueDecl() != rhs.GetOpaqueDecl();
}
+
+std::vector<lldb_private::CompilerContext>
+CompilerDecl::GetCompilerContext() const {
+ return m_type_system->DeclGetCompilerContext(m_opaque_decl);
+}
diff --git a/lldb/source/Symbol/CompilerDeclContext.cpp b/lldb/source/Symbol/CompilerDeclContext.cpp
index a188e60..b40a08e 100644
--- a/lldb/source/Symbol/CompilerDeclContext.cpp
+++ b/lldb/source/Symbol/CompilerDeclContext.cpp
@@ -59,6 +59,13 @@ bool CompilerDeclContext::IsContainedInLookup(CompilerDeclContext other) const {
other.m_opaque_decl_ctx);
}
+std::vector<lldb_private::CompilerContext>
+CompilerDeclContext::GetCompilerContext() const {
+ if (IsValid())
+ return m_type_system->DeclContextGetCompilerContext(m_opaque_decl_ctx);
+ return {};
+}
+
bool lldb_private::operator==(const lldb_private::CompilerDeclContext &lhs,
const lldb_private::CompilerDeclContext &rhs) {
return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&
diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp
index 4b9c386..e318e2be 100644
--- a/lldb/source/Symbol/SymbolFile.cpp
+++ b/lldb/source/Symbol/SymbolFile.cpp
@@ -134,17 +134,6 @@ void SymbolFile::GetMangledNamesForFunction(
const std::string &scope_qualified_name,
std::vector<ConstString> &mangled_names) {}
-void SymbolFile::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {}
-
-void SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
- LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files,
- TypeMap &types) {}
-
void SymbolFile::AssertModuleLock() {
// The code below is too expensive to leave enabled in release builds. It's
// enabled in debug builds or when the correct macro is set.
diff --git a/lldb/source/Symbol/SymbolFileOnDemand.cpp b/lldb/source/Symbol/SymbolFileOnDemand.cpp
index 19b519c..3399525 100644
--- a/lldb/source/Symbol/SymbolFileOnDemand.cpp
+++ b/lldb/source/Symbol/SymbolFileOnDemand.cpp
@@ -431,31 +431,14 @@ void SymbolFileOnDemand::GetMangledNamesForFunction(
mangled_names);
}
-void SymbolFileOnDemand::FindTypes(
- ConstString name, const CompilerDeclContext &parent_decl_ctx,
- uint32_t max_matches,
- llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
- TypeMap &types) {
- if (!m_debug_info_enabled) {
- Log *log = GetLog();
- LLDB_LOG(log, "[{0}] {1}({2}) is skipped", GetSymbolFileName(),
- __FUNCTION__, name);
- return;
- }
- return m_sym_file_impl->FindTypes(name, parent_decl_ctx, max_matches,
- searched_symbol_files, types);
-}
-
-void SymbolFileOnDemand::FindTypes(
- llvm::ArrayRef<CompilerContext> pattern, LanguageSet languages,
- llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {
+void SymbolFileOnDemand::FindTypes(const TypeQuery &match,
+ TypeResults &results) {
if (!m_debug_info_enabled) {
LLDB_LOG(GetLog(), "[{0}] {1} is skipped", GetSymbolFileName(),
__FUNCTION__);
return;
}
- return m_sym_file_impl->FindTypes(pattern, languages, searched_symbol_files,
- types);
+ return m_sym_file_impl->FindTypes(match, results);
}
void SymbolFileOnDemand::GetTypes(SymbolContextScope *sc_scope,
diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 54eeace..293fe1b 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -64,6 +64,127 @@ bool lldb_private::contextMatches(llvm::ArrayRef<CompilerContext> context_chain,
return true;
}
+static CompilerContextKind ConvertTypeClass(lldb::TypeClass type_class) {
+ if (type_class == eTypeClassAny)
+ return CompilerContextKind::AnyType;
+ uint16_t result = 0;
+ if (type_class & lldb::eTypeClassClass)
+ result |= (uint16_t)CompilerContextKind::Class;
+ if (type_class & lldb::eTypeClassStruct)
+ result |= (uint16_t)CompilerContextKind::Struct;
+ if (type_class & lldb::eTypeClassUnion)
+ result |= (uint16_t)CompilerContextKind::Union;
+ if (type_class & lldb::eTypeClassEnumeration)
+ result |= (uint16_t)CompilerContextKind::Enum;
+ if (type_class & lldb::eTypeClassFunction)
+ result |= (uint16_t)CompilerContextKind::Function;
+ if (type_class & lldb::eTypeClassTypedef)
+ result |= (uint16_t)CompilerContextKind::Typedef;
+ return (CompilerContextKind)result;
+}
+
+TypeQuery::TypeQuery(llvm::StringRef name, TypeQueryOptions options)
+ : m_options(options) {
+ llvm::StringRef scope, basename;
+ lldb::TypeClass type_class = lldb::eTypeClassAny;
+ if (Type::GetTypeScopeAndBasename(name, scope, basename, type_class)) {
+ if (scope.consume_front("::"))
+ m_options |= e_exact_match;
+ if (!scope.empty()) {
+ std::pair<llvm::StringRef, llvm::StringRef> scope_pair =
+ scope.split("::");
+ while (!scope_pair.second.empty()) {
+ m_context.push_back({CompilerContextKind::AnyDeclContext,
+ ConstString(scope_pair.first.str())});
+ scope_pair = scope_pair.second.split("::");
+ }
+ m_context.push_back({CompilerContextKind::AnyDeclContext,
+ ConstString(scope_pair.first.str())});
+ }
+ m_context.push_back(
+ {ConvertTypeClass(type_class), ConstString(basename.str())});
+ } else {
+ m_context.push_back(
+ {CompilerContextKind::AnyType, ConstString(name.str())});
+ }
+}
+
+TypeQuery::TypeQuery(const CompilerDeclContext &decl_ctx,
+ ConstString type_basename, TypeQueryOptions options)
+ : m_options(options) {
+ // Always use an exact match if we are looking for a type in compiler context.
+ m_options |= e_exact_match;
+ m_context = decl_ctx.GetCompilerContext();
+ m_context.push_back({CompilerContextKind::AnyType, type_basename});
+}
+
+TypeQuery::TypeQuery(
+ const llvm::ArrayRef<lldb_private::CompilerContext> &context,
+ TypeQueryOptions options)
+ : m_context(context), m_options(options) {
+ // Always use an exact match if we are looking for a type in compiler context.
+ m_options |= e_exact_match;
+}
+
+TypeQuery::TypeQuery(const CompilerDecl &decl, TypeQueryOptions options)
+ : m_options(options) {
+ // Always for an exact match if we are looking for a type using a declaration.
+ m_options |= e_exact_match;
+ m_context = decl.GetCompilerContext();
+}
+
+ConstString TypeQuery::GetTypeBasename() const {
+ if (m_context.empty())
+ return ConstString();
+ return m_context.back().name;
+}
+
+void TypeQuery::AddLanguage(LanguageType language) {
+ if (!m_languages)
+ m_languages = LanguageSet();
+ m_languages->Insert(language);
+}
+
+bool TypeQuery::ContextMatches(
+ llvm::ArrayRef<CompilerContext> context_chain) const {
+ if (GetExactMatch() || context_chain.size() == m_context.size())
+ return ::contextMatches(context_chain, m_context);
+
+ // We don't have an exact match, we need to bottom m_context.size() items to
+ // match for a successful lookup.
+ if (context_chain.size() < m_context.size())
+ return false; // Not enough items in context_chain to allow for a match.
+
+ size_t compare_count = context_chain.size() - m_context.size();
+ return ::contextMatches(
+ llvm::ArrayRef<CompilerContext>(context_chain.data() + compare_count,
+ m_context.size()),
+ m_context);
+}
+
+bool TypeQuery::LanguageMatches(lldb::LanguageType language) const {
+ // If we have no language filterm language always matches.
+ if (!m_languages.has_value())
+ return true;
+ return (*m_languages)[language];
+}
+
+bool TypeResults::AlreadySearched(lldb_private::SymbolFile *sym_file) {
+ return !m_searched_symbol_files.insert(sym_file).second;
+}
+
+bool TypeResults::InsertUnique(const lldb::TypeSP &type_sp) {
+ if (type_sp)
+ return m_type_map.InsertUnique(type_sp);
+ return false;
+}
+
+bool TypeResults::Done(const TypeQuery &query) const {
+ if (query.GetFindOne())
+ return !m_type_map.Empty();
+ return false;
+}
+
void CompilerContext::Dump(Stream &s) const {
switch (kind) {
default:
@@ -641,6 +762,8 @@ bool Type::GetTypeScopeAndBasename(llvm::StringRef name,
if (name.empty())
return false;
+ // Clear the scope in case we have just a type class and a basename.
+ scope = llvm::StringRef();
basename = name;
if (basename.consume_front("struct "))
type_class = eTypeClassStruct;
@@ -654,8 +777,10 @@ bool Type::GetTypeScopeAndBasename(llvm::StringRef name,
type_class = eTypeClassTypedef;
size_t namespace_separator = basename.find("::");
- if (namespace_separator == llvm::StringRef::npos)
- return false;
+ if (namespace_separator == llvm::StringRef::npos) {
+ // If "name" started a type class we need to return true with no scope.
+ return type_class != eTypeClassAny;
+ }
size_t template_begin = basename.find('<');
while (namespace_separator != llvm::StringRef::npos) {
@@ -1049,16 +1174,19 @@ CompilerType TypeImpl::FindDirectNestedType(llvm::StringRef name) {
return CompilerType();
auto type_system = GetTypeSystem(/*prefer_dynamic*/ false);
auto *symbol_file = type_system->GetSymbolFile();
+ if (!symbol_file)
+ return CompilerType();
auto decl_context = type_system->GetCompilerDeclContextForType(m_static_type);
if (!decl_context.IsValid())
return CompilerType();
- llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
- TypeMap search_result;
- symbol_file->FindTypes(ConstString(name), decl_context, /*max_matches*/ 1,
- searched_symbol_files, search_result);
- if (search_result.Empty())
- return CompilerType();
- return search_result.GetTypeAtIndex(0)->GetFullCompilerType();
+ TypeQuery query(decl_context, ConstString(name),
+ TypeQueryOptions::e_find_one);
+ TypeResults results;
+ symbol_file->FindTypes(query, results);
+ TypeSP type_sp = results.GetFirstType();
+ if (type_sp)
+ return type_sp->GetFullCompilerType();
+ return CompilerType();
}
bool TypeMemberFunctionImpl::IsValid() {
diff --git a/lldb/source/Symbol/TypeMap.cpp b/lldb/source/Symbol/TypeMap.cpp
index 0d5f6d5..8933de5 100644
--- a/lldb/source/Symbol/TypeMap.cpp
+++ b/lldb/source/Symbol/TypeMap.cpp
@@ -91,6 +91,12 @@ TypeSP TypeMap::GetTypeAtIndex(uint32_t idx) {
return TypeSP();
}
+lldb::TypeSP TypeMap::FirstType() const {
+ if (m_types.empty())
+ return TypeSP();
+ return m_types.begin()->second;
+}
+
void TypeMap::ForEach(
std::function<bool(const lldb::TypeSP &type_sp)> const &callback) const {
for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) {
@@ -121,10 +127,10 @@ bool TypeMap::Remove(const lldb::TypeSP &type_sp) {
return false;
}
-void TypeMap::Dump(Stream *s, bool show_context, lldb::DescriptionLevel level) {
- for (iterator pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) {
- pos->second->Dump(s, show_context, level);
- }
+void TypeMap::Dump(Stream *s, bool show_context,
+ lldb::DescriptionLevel level) const {
+ for (const auto &pair : m_types)
+ pair.second->Dump(s, show_context, level);
}
void TypeMap::RemoveMismatchedTypes(llvm::StringRef type_scope,
diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index 874f125..59b1b39 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -171,6 +171,16 @@ CompilerType TypeSystem::DeclGetFunctionArgumentType(void *opaque_decl,
return CompilerType();
}
+std::vector<lldb_private::CompilerContext>
+TypeSystem::DeclGetCompilerContext(void *opaque_decl) {
+ return {};
+}
+
+std::vector<lldb_private::CompilerContext>
+TypeSystem::DeclContextGetCompilerContext(void *opaque_decl_ctx) {
+ return {};
+}
+
std::vector<CompilerDecl>
TypeSystem::DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
bool ignore_imported_decls) {
diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp
index 42c3350..caf3e66 100644
--- a/lldb/source/Target/Language.cpp
+++ b/lldb/source/Target/Language.cpp
@@ -434,12 +434,10 @@ bool Language::ImageListTypeScavenger::Find_Impl(
Target *target = exe_scope->CalculateTarget().get();
if (target) {
const auto &images(target->GetImages());
- ConstString cs_key(key);
- llvm::DenseSet<SymbolFile *> searched_sym_files;
- TypeList matches;
- images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files,
- matches);
- for (const auto &match : matches.Types()) {
+ TypeQuery query(key);
+ TypeResults type_results;
+ images.FindTypes(nullptr, query, type_results);
+ for (const auto &match : type_results.GetTypeMap().Types()) {
if (match) {
CompilerType compiler_type(match->GetFullCompilerType());
compiler_type = AdjustForInclusion(compiler_type);
diff --git a/lldb/test/API/functionalities/type_find_first/Makefile b/lldb/test/API/functionalities/type_find_first/Makefile
new file mode 100644
index 0000000..3d0b98f
--- /dev/null
+++ b/lldb/test/API/functionalities/type_find_first/Makefile
@@ -0,0 +1,2 @@
+CXX_SOURCES := main.cpp
+include Makefile.rules
diff --git a/lldb/test/API/functionalities/type_find_first/TestFindFirstType.py b/lldb/test/API/functionalities/type_find_first/TestFindFirstType.py
new file mode 100644
index 0000000..432708d
--- /dev/null
+++ b/lldb/test/API/functionalities/type_find_first/TestFindFirstType.py
@@ -0,0 +1,38 @@
+"""
+Test the SBModule and SBTarget type lookup APIs.
+"""
+
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+
+class TypeFindFirstTestCase(TestBase):
+
+ NO_DEBUG_INFO_TESTCASE = True
+
+ def test_find_first_type(self):
+ """
+ Test SBTarget::FindFirstType() and SBModule::FindFirstType() APIs.
+
+ This function had regressed after some past modification of the type
+ lookup internal code where if we had multiple types with the same
+ basename, FindFirstType() could end up failing depending on which
+ type was found first in the debug info indexes. This test will
+ ensure this doesn't regress in the future.
+ """
+ self.build()
+ target = self.createTestTarget()
+ # Test the SBTarget APIs for FindFirstType
+ integer_type = target.FindFirstType("Integer::Point")
+ self.assertTrue(integer_type.IsValid())
+ float_type = target.FindFirstType("Float::Point")
+ self.assertTrue(float_type.IsValid())
+
+ # Test the SBModule APIs for FindFirstType
+ exe_module = target.GetModuleAtIndex(0)
+ self.assertTrue(exe_module.IsValid())
+ integer_type = exe_module.FindFirstType("Integer::Point")
+ self.assertTrue(integer_type.IsValid())
+ float_type = exe_module.FindFirstType("Float::Point")
+ self.assertTrue(float_type.IsValid())
diff --git a/lldb/test/API/functionalities/type_find_first/main.cpp b/lldb/test/API/functionalities/type_find_first/main.cpp
new file mode 100644
index 0000000..f4e4672
--- /dev/null
+++ b/lldb/test/API/functionalities/type_find_first/main.cpp
@@ -0,0 +1,17 @@
+namespace Integer {
+struct Point {
+ int x, y;
+};
+} // namespace Integer
+
+namespace Float {
+struct Point {
+ float x, y;
+};
+} // namespace Float
+
+int main(int argc, char const *argv[]) {
+ Integer::Point ip = {2, 3};
+ Float::Point fp = {2.0, 3.0};
+ return 0;
+}
diff --git a/lldb/test/API/lang/cpp/unique-types4/TestUniqueTypes4.py b/lldb/test/API/lang/cpp/unique-types4/TestUniqueTypes4.py
index d9ac07f..3fa694f 100644
--- a/lldb/test/API/lang/cpp/unique-types4/TestUniqueTypes4.py
+++ b/lldb/test/API/lang/cpp/unique-types4/TestUniqueTypes4.py
@@ -17,27 +17,20 @@ class UniqueTypesTestCase4(TestBase):
)
# FIXME: these should successfully print the values
self.expect(
- "expression ns::Foo<double>::value", substrs=["no member named"], error=True
+ "expression ns::Foo<double>::value", substrs=["'Foo' in namespace 'ns'"], error=True
)
self.expect(
- "expression ns::Foo<int>::value", substrs=["no member named"], error=True
+ "expression ns::Foo<int>::value", substrs=["'Foo' in namespace 'ns'"], error=True
)
self.expect(
- "expression ns::Bar<double>::value", substrs=["no member named"], error=True
+ "expression ns::Bar<double>::value", substrs=["'Bar' in namespace 'ns'"], error=True
)
self.expect(
- "expression ns::Bar<int>::value", substrs=["no member named"], error=True
- )
- self.expect(
- "expression ns::FooDouble::value",
- substrs=["Couldn't look up symbols"],
- error=True,
- )
- self.expect(
- "expression ns::FooInt::value",
- substrs=["Couldn't look up symbols"],
- error=True,
+ "expression ns::Bar<int>::value", substrs=["'Bar' in namespace 'ns'"], error=True
)
+ self.expect_expr("ns::FooDouble::value", result_type="double", result_value="0")
+ self.expect_expr("ns::FooInt::value", result_type="int", result_value="0")
+
@skipIf(compiler=no_match("clang"))
@skipIf(compiler_version=["<", "15.0"])
diff --git a/lldb/test/API/lang/cpp/unique-types4/main.cpp b/lldb/test/API/lang/cpp/unique-types4/main.cpp
index 8306352..815b4f9 100644
--- a/lldb/test/API/lang/cpp/unique-types4/main.cpp
+++ b/lldb/test/API/lang/cpp/unique-types4/main.cpp
@@ -4,6 +4,8 @@ template <typename T> struct Foo {
static T value;
};
+template <class T> T Foo<T>::value = 0;
+
template <typename T> using Bar = Foo<T>;
using FooInt = Foo<int>;
@@ -20,4 +22,6 @@ ns::FooDouble f;
int main() {
// Set breakpoint here
+ return (int)a.value + b.value + (int)c.value + d.value + e.value +
+ (int)f.value;
}
diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index 45911b9..e326a84 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/tools/lldb-test/lldb-test.cpp
@@ -290,8 +290,8 @@ int lldb_assert(Debugger &Dbg);
} // namespace assert
} // namespace opts
-std::vector<CompilerContext> parseCompilerContext() {
- std::vector<CompilerContext> result;
+llvm::SmallVector<CompilerContext, 4> parseCompilerContext() {
+ llvm::SmallVector<CompilerContext, 4> result;
if (opts::symbols::CompilerContext.empty())
return result;
@@ -577,29 +577,33 @@ Error opts::symbols::findTypes(lldb_private::Module &Module) {
Expected<CompilerDeclContext> ContextOr = getDeclContext(Symfile);
if (!ContextOr)
return ContextOr.takeError();
- const CompilerDeclContext &ContextPtr =
- ContextOr->IsValid() ? *ContextOr : CompilerDeclContext();
-
- LanguageSet languages;
- if (!Language.empty())
- languages.Insert(Language::GetLanguageTypeFromString(Language));
-
- DenseSet<SymbolFile *> SearchedFiles;
- TypeMap Map;
- if (!Name.empty())
- Symfile.FindTypes(ConstString(Name), ContextPtr, UINT32_MAX, SearchedFiles,
- Map);
- else
- Module.FindTypes(parseCompilerContext(), languages, SearchedFiles, Map);
- outs() << formatv("Found {0} types:\n", Map.GetSize());
+ TypeResults results;
+ if (!Name.empty()) {
+ if (ContextOr->IsValid()) {
+ TypeQuery query(*ContextOr, ConstString(Name),
+ TypeQueryOptions::e_module_search);
+ if (!Language.empty())
+ query.AddLanguage(Language::GetLanguageTypeFromString(Language));
+ Symfile.FindTypes(query, results);
+ } else {
+ TypeQuery query(Name);
+ if (!Language.empty())
+ query.AddLanguage(Language::GetLanguageTypeFromString(Language));
+ Symfile.FindTypes(query, results);
+ }
+ } else {
+ TypeQuery query(parseCompilerContext(), TypeQueryOptions::e_module_search);
+ if (!Language.empty())
+ query.AddLanguage(Language::GetLanguageTypeFromString(Language));
+ Symfile.FindTypes(query, results);
+ }
+ outs() << formatv("Found {0} types:\n", results.GetTypeMap().GetSize());
StreamString Stream;
// Resolve types to force-materialize typedef types.
- Map.ForEach([&](TypeSP &type) {
- type->GetFullCompilerType();
- return false;
- });
- Map.Dump(&Stream, false, GetDescriptionLevel());
+ for (const auto &type_sp : results.GetTypeMap().Types())
+ type_sp->GetFullCompilerType();
+ results.GetTypeMap().Dump(&Stream, false, GetDescriptionLevel());
outs() << Stream.GetData() << "\n";
return Error::success();
}
diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
index 92bfef2..fe60481 100644
--- a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h
@@ -48,6 +48,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/CGPassBuilderOption.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/CFGuard.h"
#include "llvm/Transforms/Scalar/ConstantHoisting.h"
#include "llvm/Transforms/Scalar/LoopPassManager.h"
#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"
diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
index 9ebf33b..283fb14 100644
--- a/llvm/include/llvm/CodeGen/MachinePassRegistry.def
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def
@@ -38,6 +38,7 @@ FUNCTION_ANALYSIS("targetir", TargetIRAnalysis,
#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
#endif
FUNCTION_PASS("callbrprepare", CallBrPreparePass, ())
+FUNCTION_PASS("cfguard", CFGuardPass, ())
FUNCTION_PASS("consthoist", ConstantHoistingPass, ())
FUNCTION_PASS("dwarf-eh-prepare", DwarfEHPreparePass, (TM))
FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass, (false))
@@ -124,8 +125,6 @@ MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis,
#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)
#endif
DUMMY_FUNCTION_PASS("atomic-expand", AtomicExpandPass, ())
-DUMMY_FUNCTION_PASS("cfguard-check", CFGuardCheckPass, ())
-DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ())
DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())
DUMMY_FUNCTION_PASS("expandmemcmp", ExpandMemCmpPass, ())
DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())
diff --git a/llvm/include/llvm/Transforms/CFGuard.h b/llvm/include/llvm/Transforms/CFGuard.h
index 86fcbc3..caf822a2 100644
--- a/llvm/include/llvm/Transforms/CFGuard.h
+++ b/llvm/include/llvm/Transforms/CFGuard.h
@@ -11,10 +11,23 @@
#ifndef LLVM_TRANSFORMS_CFGUARD_H
#define LLVM_TRANSFORMS_CFGUARD_H
+#include "llvm/IR/PassManager.h"
+
namespace llvm {
class FunctionPass;
+class CFGuardPass : public PassInfoMixin<CFGuardPass> {
+public:
+ enum class Mechanism { Check, Dispatch };
+
+ CFGuardPass(Mechanism M = Mechanism::Check) : GuardMechanism(M) {}
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM);
+
+private:
+ Mechanism GuardMechanism;
+};
+
/// Insert Control FLow Guard checks on indirect function calls.
FunctionPass *createCFGuardCheckPass();
diff --git a/llvm/lib/Passes/CMakeLists.txt b/llvm/lib/Passes/CMakeLists.txt
index e42edfe..98d2de7 100644
--- a/llvm/lib/Passes/CMakeLists.txt
+++ b/llvm/lib/Passes/CMakeLists.txt
@@ -16,6 +16,7 @@ add_llvm_component_library(LLVMPasses
LINK_COMPONENTS
AggressiveInstCombine
Analysis
+ CFGuard
CodeGen
Core
Coroutines
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index c48e591..f0417d6 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -100,6 +100,7 @@
#include "llvm/Support/Regex.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"
+#include "llvm/Transforms/CFGuard.h"
#include "llvm/Transforms/Coroutines/CoroCleanup.h"
#include "llvm/Transforms/Coroutines/CoroConditionalWrapper.h"
#include "llvm/Transforms/Coroutines/CoroEarly.h"
@@ -738,6 +739,26 @@ Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
"PostOrderFunctionAttrs");
}
+Expected<CFGuardPass::Mechanism> parseCFGuardPassOptions(StringRef Params) {
+ if (Params.empty())
+ return CFGuardPass::Mechanism::Check;
+
+ auto [Param, RHS] = Params.split(';');
+ if (!RHS.empty())
+ return make_error<StringError>(
+ formatv("too many CFGuardPass parameters '{0}' ", Params).str(),
+ inconvertibleErrorCode());
+
+ if (Param == "check")
+ return CFGuardPass::Mechanism::Check;
+ if (Param == "dispatch")
+ return CFGuardPass::Mechanism::Dispatch;
+
+ return make_error<StringError>(
+ formatv("invalid CFGuardPass mechanism: '{0}' ", Param).str(),
+ inconvertibleErrorCode());
+}
+
Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
return parseSinglePassOption(Params, "memssa", "EarlyCSE");
}
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 6afc8b4..1a9a348 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -434,6 +434,10 @@ FUNCTION_PASS("wasm-eh-prepare", WasmEHPreparePass())
#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS)
#endif
FUNCTION_PASS_WITH_PARAMS(
+ "cfguard", "CFGuardPass",
+ [](CFGuardPass::Mechanism M) { return CFGuardPass(M); },
+ parseCFGuardPassOptions, "check;dispatch")
+FUNCTION_PASS_WITH_PARAMS(
"early-cse", "EarlyCSEPass",
[](bool UseMemorySSA) { return EarlyCSEPass(UseMemorySSA); },
parseEarlyCSEPassOptions, "memssa")
diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp
index 246f6b4..5428e14 100644
--- a/llvm/lib/Target/TargetMachine.cpp
+++ b/llvm/lib/Target/TargetMachine.cpp
@@ -55,6 +55,8 @@ bool TargetMachine::isLargeGlobalObject(const GlobalObject *GO) const {
// We should properly mark well-known section name prefixes as small/large,
// because otherwise the output section may have the wrong section flags and
// the linker will lay it out in an unexpected way.
+ // TODO: bring back lbss/ldata/lrodata checks after fixing accesses to large
+ // globals in the small code model.
StringRef Name = GV->getSection();
if (!Name.empty()) {
auto IsPrefix = [&](StringRef Prefix) {
@@ -63,8 +65,6 @@ bool TargetMachine::isLargeGlobalObject(const GlobalObject *GO) const {
};
if (IsPrefix(".bss") || IsPrefix(".data") || IsPrefix(".rodata"))
return false;
- if (IsPrefix(".lbss") || IsPrefix(".ldata") || IsPrefix(".lrodata"))
- return true;
}
// For x86-64, we treat an explicit GlobalVariable small code model to mean
diff --git a/llvm/lib/Transforms/CFGuard/CFGuard.cpp b/llvm/lib/Transforms/CFGuard/CFGuard.cpp
index 3877343..4d43065 100644
--- a/llvm/lib/Transforms/CFGuard/CFGuard.cpp
+++ b/llvm/lib/Transforms/CFGuard/CFGuard.cpp
@@ -34,25 +34,22 @@ namespace {
/// Adds Control Flow Guard (CFG) checks on indirect function calls/invokes.
/// These checks ensure that the target address corresponds to the start of an
-/// address-taken function. X86_64 targets use the CF_Dispatch mechanism. X86,
-/// ARM, and AArch64 targets use the CF_Check machanism.
-class CFGuard : public FunctionPass {
+/// address-taken function. X86_64 targets use the Mechanism::Dispatch
+/// mechanism. X86, ARM, and AArch64 targets use the Mechanism::Check machanism.
+class CFGuardImpl {
public:
- static char ID;
-
- enum Mechanism { CF_Check, CF_Dispatch };
-
- // Default constructor required for the INITIALIZE_PASS macro.
- CFGuard() : FunctionPass(ID) {
- initializeCFGuardPass(*PassRegistry::getPassRegistry());
- // By default, use the guard check mechanism.
- GuardMechanism = CF_Check;
- }
-
- // Recommended constructor used to specify the type of guard mechanism.
- CFGuard(Mechanism Var) : FunctionPass(ID) {
- initializeCFGuardPass(*PassRegistry::getPassRegistry());
- GuardMechanism = Var;
+ using Mechanism = CFGuardPass::Mechanism;
+
+ CFGuardImpl(Mechanism M) : GuardMechanism(M) {
+ // Get or insert the guard check or dispatch global symbols.
+ switch (GuardMechanism) {
+ case Mechanism::Check:
+ GuardFnName = "__guard_check_icall_fptr";
+ break;
+ case Mechanism::Dispatch:
+ GuardFnName = "__guard_dispatch_icall_fptr";
+ break;
+ }
}
/// Inserts a Control Flow Guard (CFG) check on an indirect call using the CFG
@@ -141,21 +138,37 @@ public:
/// \param CB indirect call to instrument.
void insertCFGuardDispatch(CallBase *CB);
- bool doInitialization(Module &M) override;
- bool runOnFunction(Function &F) override;
+ bool doInitialization(Module &M);
+ bool runOnFunction(Function &F);
private:
// Only add checks if the module has the cfguard=2 flag.
int cfguard_module_flag = 0;
- Mechanism GuardMechanism = CF_Check;
+ StringRef GuardFnName;
+ Mechanism GuardMechanism = Mechanism::Check;
FunctionType *GuardFnType = nullptr;
PointerType *GuardFnPtrType = nullptr;
Constant *GuardFnGlobal = nullptr;
};
+class CFGuard : public FunctionPass {
+ CFGuardImpl Impl;
+
+public:
+ static char ID;
+
+ // Default constructor required for the INITIALIZE_PASS macro.
+ CFGuard(CFGuardImpl::Mechanism M) : FunctionPass(ID), Impl(M) {
+ initializeCFGuardPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool doInitialization(Module &M) override { return Impl.doInitialization(M); }
+ bool runOnFunction(Function &F) override { return Impl.runOnFunction(F); }
+};
+
} // end anonymous namespace
-void CFGuard::insertCFGuardCheck(CallBase *CB) {
+void CFGuardImpl::insertCFGuardCheck(CallBase *CB) {
assert(Triple(CB->getModule()->getTargetTriple()).isOSWindows() &&
"Only applicable for Windows targets");
@@ -184,7 +197,7 @@ void CFGuard::insertCFGuardCheck(CallBase *CB) {
GuardCheck->setCallingConv(CallingConv::CFGuard_Check);
}
-void CFGuard::insertCFGuardDispatch(CallBase *CB) {
+void CFGuardImpl::insertCFGuardDispatch(CallBase *CB) {
assert(Triple(CB->getModule()->getTargetTriple()).isOSWindows() &&
"Only applicable for Windows targets");
@@ -218,7 +231,7 @@ void CFGuard::insertCFGuardDispatch(CallBase *CB) {
CB->eraseFromParent();
}
-bool CFGuard::doInitialization(Module &M) {
+bool CFGuardImpl::doInitialization(Module &M) {
// Check if this module has the cfguard flag and read its value.
if (auto *MD =
@@ -235,15 +248,6 @@ bool CFGuard::doInitialization(Module &M) {
{PointerType::getUnqual(M.getContext())}, false);
GuardFnPtrType = PointerType::get(GuardFnType, 0);
- // Get or insert the guard check or dispatch global symbols.
- llvm::StringRef GuardFnName;
- if (GuardMechanism == CF_Check) {
- GuardFnName = "__guard_check_icall_fptr";
- } else if (GuardMechanism == CF_Dispatch) {
- GuardFnName = "__guard_dispatch_icall_fptr";
- } else {
- assert(false && "Invalid CFGuard mechanism");
- }
GuardFnGlobal = M.getOrInsertGlobal(GuardFnName, GuardFnPtrType, [&] {
auto *Var = new GlobalVariable(M, GuardFnPtrType, false,
GlobalVariable::ExternalLinkage, nullptr,
@@ -255,7 +259,7 @@ bool CFGuard::doInitialization(Module &M) {
return true;
}
-bool CFGuard::runOnFunction(Function &F) {
+bool CFGuardImpl::runOnFunction(Function &F) {
// Skip modules for which CFGuard checks have been disabled.
if (cfguard_module_flag != 2)
@@ -283,7 +287,7 @@ bool CFGuard::runOnFunction(Function &F) {
}
// For each indirect call/invoke, add the appropriate dispatch or check.
- if (GuardMechanism == CF_Dispatch) {
+ if (GuardMechanism == Mechanism::Dispatch) {
for (CallBase *CB : IndirectCalls) {
insertCFGuardDispatch(CB);
}
@@ -296,13 +300,20 @@ bool CFGuard::runOnFunction(Function &F) {
return true;
}
+PreservedAnalyses CFGuardPass::run(Function &F, FunctionAnalysisManager &FAM) {
+ CFGuardImpl Impl(GuardMechanism);
+ bool Changed = Impl.doInitialization(*F.getParent());
+ Changed |= Impl.runOnFunction(F);
+ return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
+}
+
char CFGuard::ID = 0;
INITIALIZE_PASS(CFGuard, "CFGuard", "CFGuard", false, false)
FunctionPass *llvm::createCFGuardCheckPass() {
- return new CFGuard(CFGuard::CF_Check);
+ return new CFGuard(CFGuardPass::Mechanism::Check);
}
FunctionPass *llvm::createCFGuardDispatchPass() {
- return new CFGuard(CFGuard::CF_Dispatch);
+ return new CFGuard(CFGuardPass::Mechanism::Dispatch);
}
diff --git a/llvm/test/CodeGen/X86/code-model-elf-sections.ll b/llvm/test/CodeGen/X86/code-model-elf-sections.ll
index 749d5b6b..cb19f0d 100644
--- a/llvm/test/CodeGen/X86/code-model-elf-sections.ll
+++ b/llvm/test/CodeGen/X86/code-model-elf-sections.ll
@@ -21,16 +21,16 @@
; SMALL: .data {{.*}} WA {{.*}}
; SMALL: .data.x {{.*}} WA {{.*}}
; SMALL: .data0 {{.*}} WA {{.*}}
-; SMALL: .ldata {{.*}} WAl {{.*}}
-; SMALL: .ldata.x {{.*}} WAl {{.*}}
+; SMALL: .ldata {{.*}} WA {{.*}}
+; SMALL: .ldata.x {{.*}} WA {{.*}}
; SMALL: .ldata0 {{.*}} WA {{.*}}
; SMALL: force_small {{.*}} WA {{.*}}
; SMALL: force_large {{.*}} WAl {{.*}}
; SMALL: foo {{.*}} WA {{.*}}
; SMALL: .bss {{.*}} WA {{.*}}
-; SMALL: .lbss {{.*}} WAl {{.*}}
+; SMALL: .lbss {{.*}} WA {{.*}}
; SMALL: .rodata {{.*}} A {{.*}}
-; SMALL: .lrodata {{.*}} Al {{.*}}
+; SMALL: .lrodata {{.*}} A {{.*}}
; SMALL: .data.rel.ro {{.*}} WA {{.*}}
; SMALL: .tbss {{.*}} WAT {{.*}}
; SMALL: .tdata {{.*}} WAT {{.*}}
@@ -38,16 +38,16 @@
; SMALL-DS: .data {{.*}} WA {{.*}}
; SMALL-DS: .data.x {{.*}} WA {{.*}}
; SMALL-DS: .data0 {{.*}} WA {{.*}}
-; SMALL-DS: .ldata {{.*}} WAl {{.*}}
-; SMALL-DS: .ldata.x {{.*}} WAl {{.*}}
+; SMALL-DS: .ldata {{.*}} WA {{.*}}
+; SMALL-DS: .ldata.x {{.*}} WA {{.*}}
; SMALL-DS: .ldata0 {{.*}} WA {{.*}}
; SMALL-DS: .data.data {{.*}} WA {{.*}}
; SMALL-DS: force_small {{.*}} WA {{.*}}
; SMALL-DS: force_large {{.*}} WAl {{.*}}
; SMALL-DS: foo {{.*}} WA {{.*}}
-; SMALL-DS: .lbss {{.*}} WAl {{.*}}
+; SMALL-DS: .lbss {{.*}} WA {{.*}}
; SMALL-DS: .bss.bss {{.*}} WA {{.*}}
-; SMALL-DS: .lrodata {{.*}} Al {{.*}}
+; SMALL-DS: .lrodata {{.*}} A {{.*}}
; SMALL-DS: .rodata.rodata {{.*}} A {{.*}}
; SMALL-DS: .data.rel.ro.relro {{.*}} WA {{.*}}
; SMALL-DS: .tbss.tbss {{.*}} WAT {{.*}}
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/CMakeLists.txt b/mlir/lib/Dialect/SparseTensor/Transforms/CMakeLists.txt
index 8459e46..ad8b0d0 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/CMakeLists.txt
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/CMakeLists.txt
@@ -1,9 +1,6 @@
add_mlir_dialect_library(MLIRSparseTensorTransforms
+ # Rewriting.
BufferizableOpInterfaceImpl.cpp
- CodegenEnv.cpp
- CodegenUtils.cpp
- IterationGraphSorter.cpp
- LoopEmitter.cpp
SparseBufferRewriting.cpp
SparseGPUCodegen.cpp
SparseReinterpretMap.cpp
@@ -12,11 +9,16 @@ add_mlir_dialect_library(MLIRSparseTensorTransforms
SparseTensorConversion.cpp
SparseTensorPasses.cpp
SparseTensorRewriting.cpp
- SparseTensorDescriptor.cpp
SparseVectorization.cpp
Sparsification.cpp
SparsificationAndBufferizationPass.cpp
StageSparseOperations.cpp
+ # Utilities.
+ Utils/CodegenEnv.cpp
+ Utils/CodegenUtils.cpp
+ Utils/IterationGraphSorter.cpp
+ Utils/LoopEmitter.cpp
+ Utils/SparseTensorDescriptor.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/SparseTensor
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseBufferRewriting.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseBufferRewriting.cpp
index cdbf4f0..248e941 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseBufferRewriting.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseBufferRewriting.cpp
@@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenUtils.h"
+#include "Utils/CodegenUtils.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseGPUCodegen.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseGPUCodegen.cpp
index 5155cab..477ff2e 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseGPUCodegen.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseGPUCodegen.cpp
@@ -13,8 +13,8 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenUtils.h"
-#include "LoopEmitter.h"
+#include "Utils/CodegenUtils.h"
+#include "Utils/LoopEmitter.h"
#include "mlir/Dialect/Bufferization/IR/Bufferization.h"
#include "mlir/Dialect/GPU/IR/GPUDialect.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
index 488079c..f2e1b0b 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseReinterpretMap.cpp
@@ -6,8 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenUtils.h"
-#include "IterationGraphSorter.h"
+#include "Utils/CodegenUtils.h"
+#include "Utils/IterationGraphSorter.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Bufferization/IR/Bufferization.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseStorageSpecifierToLLVM.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseStorageSpecifierToLLVM.cpp
index a6f4dd3..91dad05 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseStorageSpecifierToLLVM.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseStorageSpecifierToLLVM.cpp
@@ -6,7 +6,7 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenUtils.h"
+#include "Utils/CodegenUtils.h"
#include "mlir/Conversion/LLVMCommon/StructBuilder.h"
#include "mlir/Dialect/SparseTensor/IR/SparseTensorStorageLayout.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
index 18b2bb0..491501a 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorCodegen.cpp
@@ -15,8 +15,8 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenUtils.h"
-#include "SparseTensorDescriptor.h"
+#include "Utils/CodegenUtils.h"
+#include "Utils/SparseTensorDescriptor.h"
#include "mlir/Dialect/Arith/Utils/Utils.h"
#include "mlir/Dialect/Bufferization/IR/Bufferization.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorConversion.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorConversion.cpp
index e6052f2..b0447b2 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorConversion.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorConversion.cpp
@@ -16,7 +16,7 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenUtils.h"
+#include "Utils/CodegenUtils.h"
#include "mlir/Dialect/Bufferization/IR/BufferizableOpInterface.h"
#include "mlir/Dialect/Bufferization/IR/Bufferization.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp
index 4fc692f..3b9685b 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorRewriting.cpp
@@ -10,8 +10,8 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenUtils.h"
-#include "LoopEmitter.h"
+#include "Utils/CodegenUtils.h"
+#include "Utils/LoopEmitter.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseVectorization.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseVectorization.cpp
index 561c4e2..7710a44 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseVectorization.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseVectorization.cpp
@@ -16,8 +16,8 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenUtils.h"
-#include "LoopEmitter.h"
+#include "Utils/CodegenUtils.h"
+#include "Utils/LoopEmitter.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp
index 2367d3b..934e1e5 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Sparsification.cpp
@@ -10,9 +10,9 @@
//
//===----------------------------------------------------------------------===//
-#include "CodegenEnv.h"
-#include "CodegenUtils.h"
-#include "LoopEmitter.h"
+#include "Utils/CodegenEnv.h"
+#include "Utils/CodegenUtils.h"
+#include "Utils/LoopEmitter.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/CodegenEnv.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenEnv.cpp
index 4bd3af2..4bd3af2 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/CodegenEnv.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenEnv.cpp
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/CodegenEnv.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenEnv.h
index cd626041..cd626041 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/CodegenEnv.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenEnv.h
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/CodegenUtils.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenUtils.cpp
index 33d449a..33d449a 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/CodegenUtils.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenUtils.cpp
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/CodegenUtils.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenUtils.h
index 57de437..57de437 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/CodegenUtils.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/CodegenUtils.h
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/IterationGraphSorter.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
index b601172..b601172 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/IterationGraphSorter.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.cpp
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/IterationGraphSorter.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
index 52ee117..52ee117 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/IterationGraphSorter.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/IterationGraphSorter.h
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/LoopEmitter.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.cpp
index 08d37b6..08d37b6 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/LoopEmitter.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.cpp
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/LoopEmitter.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.h
index fa8b007..fa8b007 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/LoopEmitter.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/LoopEmitter.h
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorDescriptor.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.cpp
index 3ab4157..3ab4157 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorDescriptor.cpp
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.cpp
diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorDescriptor.h b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.h
index 5c7d8aa..5c7d8aa 100644
--- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseTensorDescriptor.h
+++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.h
diff --git a/mlir/tools/mlir-opt/CMakeLists.txt b/mlir/tools/mlir-opt/CMakeLists.txt
index bc8eed1..b6ada66 100644
--- a/mlir/tools/mlir-opt/CMakeLists.txt
+++ b/mlir/tools/mlir-opt/CMakeLists.txt
@@ -67,6 +67,10 @@ set(LIBS
MLIRTransformUtils
MLIRSupport
MLIRIR
+
+ # TODO: Remove when registerAllGPUToLLVMIRTranslations is no longer
+ # registered directly in mlir-opt.cpp.
+ MLIRToLLVMIRTranslationRegistration
)
# Exclude from libMLIR.so because this has static options intended for
diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp
index c7cf1e5..b7c69ea 100644
--- a/mlir/tools/mlir-opt/mlir-opt.cpp
+++ b/mlir/tools/mlir-opt/mlir-opt.cpp
@@ -276,6 +276,10 @@ int main(int argc, char **argv) {
DialectRegistry registry;
registerAllDialects(registry);
registerAllExtensions(registry);
+
+ // TODO: Remove this and the corresponding MLIRToLLVMIRTranslationRegistration
+ // cmake dependency when a safe dialect interface registration mechanism is
+ // implemented, see D157703 (and corresponding note on the declaration).
registerAllGPUToLLVMIRTranslations(registry);
#ifdef MLIR_INCLUDE_TESTS
diff --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
index 2e3bb8a..200998a 100644
--- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
@@ -2773,13 +2773,9 @@ cc_library(
td_library(
name = "SparseTensorTdFiles",
- srcs = [
- "include/mlir/Dialect/SparseTensor/IR/SparseTensorAttrDefs.td",
- "include/mlir/Dialect/SparseTensor/IR/SparseTensorBase.td",
- "include/mlir/Dialect/SparseTensor/IR/SparseTensorInterfaces.td",
- "include/mlir/Dialect/SparseTensor/IR/SparseTensorOps.td",
- "include/mlir/Dialect/SparseTensor/IR/SparseTensorTypes.td",
- ],
+ srcs = glob([
+ "include/mlir/Dialect/SparseTensor/IR/*.td",
+ ]),
includes = ["include"],
deps = [
":InferTypeOpInterfaceTdFiles",
@@ -2788,15 +2784,6 @@ td_library(
],
)
-td_library(
- name = "SparseTensorInterfacesTdFiles",
- srcs = [
- "include/mlir/Dialect/SparseTensor/IR/SparseTensorInterfaces.td",
- ],
- includes = ["include"],
- deps = [":OpBaseTdFiles"],
-)
-
gentbl_cc_library(
name = "SparseTensorAttrDefsIncGen",
tbl_outs = [
@@ -2918,7 +2905,37 @@ gentbl_cc_library(
],
tblgen = ":mlir-tblgen",
td_file = "include/mlir/Dialect/SparseTensor/IR/SparseTensorInterfaces.td",
- deps = [":SparseTensorInterfacesTdFiles"],
+ deps = [":SparseTensorTdFiles"],
+)
+
+td_library(
+ name = "SparseTensorTransformOpsTdFiles",
+ srcs = glob([
+ "include/mlir/Dialect/SparseTensor/TransformOps/*.td",
+ ]),
+ includes = ["include"],
+ deps = [
+ ":TransformDialectTdFiles",
+ ],
+)
+
+gentbl_cc_library(
+ name = "SparseTensorTransformOpsIncGen",
+ tbl_outs = [
+ (
+ ["-gen-op-decls"],
+ "include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.h.inc",
+ ),
+ (
+ ["-gen-op-defs"],
+ "include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.cpp.inc",
+ ),
+ ],
+ tblgen = ":mlir-tblgen",
+ td_file = "include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.td",
+ deps = [
+ ":SparseTensorTransformOpsTdFiles",
+ ],
)
# This library is shared by both SparseTensorDialect and
@@ -2932,19 +2949,11 @@ cc_library(
cc_library(
name = "SparseTensorDialect",
- srcs = [
- "lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.cpp",
- "lib/Dialect/SparseTensor/IR/Detail/DimLvlMap.h",
- "lib/Dialect/SparseTensor/IR/Detail/DimLvlMapParser.cpp",
- "lib/Dialect/SparseTensor/IR/Detail/DimLvlMapParser.h",
- "lib/Dialect/SparseTensor/IR/Detail/LvlTypeParser.cpp",
- "lib/Dialect/SparseTensor/IR/Detail/LvlTypeParser.h",
- "lib/Dialect/SparseTensor/IR/Detail/TemplateExtras.h",
- "lib/Dialect/SparseTensor/IR/Detail/Var.cpp",
- "lib/Dialect/SparseTensor/IR/Detail/Var.h",
- "lib/Dialect/SparseTensor/IR/SparseTensorDialect.cpp",
- "lib/Dialect/SparseTensor/IR/SparseTensorInterfaces.cpp",
- ],
+ srcs = glob([
+ "lib/Dialect/SparseTensor/IR/*.cpp",
+ "lib/Dialect/SparseTensor/IR/Detail/*.cpp",
+ "lib/Dialect/SparseTensor/IR/Detail/*.h",
+ ]),
hdrs = [
"include/mlir/Dialect/SparseTensor/IR/SparseTensor.h",
"include/mlir/Dialect/SparseTensor/IR/SparseTensorInterfaces.h",
@@ -2987,40 +2996,14 @@ cc_library(
],
)
-td_library(
- name = "SparseTensorTransformOpsTdFiles",
- srcs = glob([
- "include/mlir/Dialect/SparseTensor/TransformOps/*.td",
- ]),
- includes = ["include"],
- deps = [
- ":TransformDialectTdFiles",
- ],
-)
-
-gentbl_cc_library(
- name = "SparseTensorTransformOpsIncGen",
- tbl_outs = [
- (
- ["-gen-op-decls"],
- "include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.h.inc",
- ),
- (
- ["-gen-op-defs"],
- "include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.cpp.inc",
- ),
- ],
- tblgen = ":mlir-tblgen",
- td_file = "include/mlir/Dialect/SparseTensor/TransformOps/SparseTensorTransformOps.td",
- deps = [
- ":SparseTensorTransformOpsTdFiles",
- ],
-)
-
cc_library(
name = "SparseTensorUtils",
- srcs = glob(["lib/Dialect/SparseTensor/Utils/*.cpp"]),
- hdrs = glob(["include/mlir/Dialect/SparseTensor/Utils/*.h"]),
+ srcs = glob([
+ "lib/Dialect/SparseTensor/Utils/*.cpp",
+ ]),
+ hdrs = glob([
+ "include/mlir/Dialect/SparseTensor/Utils/*.h",
+ ]),
includes = ["include"],
deps = [
":ArithDialect",
@@ -3039,6 +3022,8 @@ cc_library(
srcs = glob([
"lib/Dialect/SparseTensor/Transforms/*.cpp",
"lib/Dialect/SparseTensor/Transforms/*.h",
+ "lib/Dialect/SparseTensor/Transforms/Utils/*.cpp",
+ "lib/Dialect/SparseTensor/Transforms/Utils/*.h",
]),
hdrs = [
"include/mlir/Dialect/SparseTensor/Transforms/BufferizableOpInterfaceImpl.h",
@@ -3081,8 +3066,12 @@ cc_library(
cc_library(
name = "SparseTensorPipelines",
- srcs = glob(["lib/Dialect/SparseTensor/Pipelines/*.cpp"]),
- hdrs = ["include/mlir/Dialect/SparseTensor/Pipelines/Passes.h"],
+ srcs = glob([
+ "lib/Dialect/SparseTensor/Pipelines/*.cpp",
+ ]),
+ hdrs = [
+ "include/mlir/Dialect/SparseTensor/Pipelines/Passes.h",
+ ],
includes = ["include"],
local_defines = if_cuda_available(["MLIR_GPU_TO_CUBIN_PASS_ENABLE"]),
deps = [