[Lldb-commits] [lldb] Make only one function that needs to be implemented when searching for types (PR #74786)

Will Hawkins via lldb-commits lldb-commits at lists.llvm.org
Fri Dec 8 23:20:04 PST 2023


================
@@ -45,6 +66,286 @@ 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 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. like "a::b::my_type".
----------------
hawkinsw wrote:

```suggestion
  ///   specified with the "::" string. For example, "a::b::my_type".
```

https://github.com/llvm/llvm-project/pull/74786


More information about the lldb-commits mailing list