aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h')
-rw-r--r--contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h399
1 files changed, 399 insertions, 0 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
new file mode 100644
index 000000000000..83c910477acc
--- /dev/null
+++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
@@ -0,0 +1,399 @@
+//===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
+#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H
+
+#include <set>
+
+#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"
+#include "Plugins/ExpressionParser/Clang/NameSearchContext.h"
+#include "lldb/Symbol/CompilerType.h"
+#include "lldb/Target/Target.h"
+#include "clang/AST/ExternalASTSource.h"
+#include "clang/Basic/IdentifierTable.h"
+
+#include "llvm/ADT/SmallSet.h"
+
+namespace lldb_private {
+
+/// \class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"
+/// Provider for named objects defined in the debug info for Clang
+///
+/// As Clang parses an expression, it may encounter names that are not defined
+/// inside the expression, including variables, functions, and types. Clang
+/// knows the name it is looking for, but nothing else. The ExternalSemaSource
+/// class provides Decls (VarDecl, FunDecl, TypeDecl) to Clang for these
+/// names, consulting the ClangExpressionDeclMap to do the actual lookups.
+class ClangASTSource : public clang::ExternalASTSource,
+ public ClangASTImporter::MapCompleter {
+public:
+ /// Constructor
+ ///
+ /// Initializes class variables.
+ ///
+ /// \param[in] target
+ /// A reference to the target containing debug information to use.
+ ///
+ /// \param[in] importer
+ /// The ClangASTImporter to use.
+ ClangASTSource(const lldb::TargetSP &target,
+ const std::shared_ptr<ClangASTImporter> &importer);
+
+ /// Destructor
+ ~ClangASTSource() override;
+
+ /// Interface stubs.
+ clang::Decl *GetExternalDecl(clang::GlobalDeclID) override { return nullptr; }
+ clang::Stmt *GetExternalDeclStmt(uint64_t) override { return nullptr; }
+ clang::Selector GetExternalSelector(uint32_t) override {
+ return clang::Selector();
+ }
+ uint32_t GetNumExternalSelectors() override { return 0; }
+ clang::CXXBaseSpecifier *
+ GetExternalCXXBaseSpecifiers(uint64_t Offset) override {
+ return nullptr;
+ }
+ void MaterializeVisibleDecls(const clang::DeclContext *DC) {}
+
+ void InstallASTContext(TypeSystemClang &ast_context);
+
+ //
+ // APIs for ExternalASTSource
+ //
+
+ /// Look up all Decls that match a particular name. Only handles
+ /// Identifiers and DeclContexts that are either NamespaceDecls or
+ /// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with the
+ /// result.
+ ///
+ /// The work for this function is done by
+ /// void FindExternalVisibleDecls (NameSearchContext &);
+ ///
+ /// \param[in] DC
+ /// The DeclContext to register the found Decls in.
+ ///
+ /// \param[in] Name
+ /// The name to find entries for.
+ ///
+ /// \return
+ /// Whatever SetExternalVisibleDeclsForName returns.
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
+ clang::DeclarationName Name) override;
+
+ /// Enumerate all Decls in a given lexical context.
+ ///
+ /// \param[in] DC
+ /// The DeclContext being searched.
+ ///
+ /// \param[in] IsKindWeWant
+ /// A callback function that returns true given the
+ /// DeclKinds of desired Decls, and false otherwise.
+ ///
+ /// \param[in] Decls
+ /// A vector that is filled in with matching Decls.
+ void FindExternalLexicalDecls(
+ const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Decls) override;
+
+ /// Specify the layout of the contents of a RecordDecl.
+ ///
+ /// \param[in] Record
+ /// The record (in the parser's AST context) that needs to be
+ /// laid out.
+ ///
+ /// \param[out] Size
+ /// The total size of the record in bits.
+ ///
+ /// \param[out] Alignment
+ /// The alignment of the record in bits.
+ ///
+ /// \param[in] FieldOffsets
+ /// A map that must be populated with pairs of the record's
+ /// fields (in the parser's AST context) and their offsets
+ /// (measured in bits).
+ ///
+ /// \param[in] BaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ concrete base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// \param[in] VirtualBaseOffsets
+ /// A map that must be populated with pairs of the record's
+ /// C++ virtual base classes (in the parser's AST context,
+ /// and only if the record is a CXXRecordDecl and has base
+ /// classes) and their offsets (measured in bytes).
+ ///
+ /// \return
+ /// True <=> the layout is valid.
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override;
+
+ /// Complete a TagDecl.
+ ///
+ /// \param[in] Tag
+ /// The Decl to be completed in place.
+ void CompleteType(clang::TagDecl *Tag) override;
+
+ /// Complete an ObjCInterfaceDecl.
+ ///
+ /// \param[in] Class
+ /// The Decl to be completed in place.
+ void CompleteType(clang::ObjCInterfaceDecl *Class) override;
+
+ /// Called on entering a translation unit. Tells Clang by calling
+ /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that
+ /// this object has something to say about undefined names.
+ ///
+ /// \param[in] Consumer
+ /// Unused.
+ void StartTranslationUnit(clang::ASTConsumer *Consumer) override;
+
+ //
+ // APIs for NamespaceMapCompleter
+ //
+
+ /// Look up the modules containing a given namespace and put the appropriate
+ /// entries in the namespace map.
+ ///
+ /// \param[in] namespace_map
+ /// The map to be completed.
+ ///
+ /// \param[in] name
+ /// The name of the namespace to be found.
+ ///
+ /// \param[in] parent_map
+ /// The map for the namespace's parent namespace, if there is
+ /// one.
+ void CompleteNamespaceMap(
+ ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
+ ClangASTImporter::NamespaceMapSP &parent_map) const override;
+
+ //
+ // Helper APIs
+ //
+
+ clang::NamespaceDecl *
+ AddNamespace(NameSearchContext &context,
+ ClangASTImporter::NamespaceMapSP &namespace_decls);
+
+ /// The worker function for FindExternalVisibleDeclsByName.
+ ///
+ /// \param[in] context
+ /// The NameSearchContext to use when filing results.
+ virtual void FindExternalVisibleDecls(NameSearchContext &context);
+
+ clang::Sema *getSema();
+
+ void SetLookupsEnabled(bool lookups_enabled) {
+ m_lookups_enabled = lookups_enabled;
+ }
+ bool GetLookupsEnabled() { return m_lookups_enabled; }
+
+ /// \class ClangASTSourceProxy ClangASTSource.h
+ /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource
+ ///
+ /// Clang AST contexts like to own their AST sources, so this is a state-
+ /// free proxy object.
+ class ClangASTSourceProxy : public clang::ExternalASTSource {
+ public:
+ ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}
+
+ bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
+ clang::DeclarationName Name) override {
+ return m_original.FindExternalVisibleDeclsByName(DC, Name);
+ }
+
+ void FindExternalLexicalDecls(
+ const clang::DeclContext *DC,
+ llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
+ llvm::SmallVectorImpl<clang::Decl *> &Decls) override {
+ return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);
+ }
+
+ void CompleteType(clang::TagDecl *Tag) override {
+ return m_original.CompleteType(Tag);
+ }
+
+ void CompleteType(clang::ObjCInterfaceDecl *Class) override {
+ return m_original.CompleteType(Class);
+ }
+
+ bool layoutRecordType(
+ const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
+ llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &BaseOffsets,
+ llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
+ &VirtualBaseOffsets) override {
+ return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,
+ BaseOffsets, VirtualBaseOffsets);
+ }
+
+ void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
+ return m_original.StartTranslationUnit(Consumer);
+ }
+
+ private:
+ ClangASTSource &m_original;
+ };
+
+ clang::ExternalASTSource *CreateProxy() {
+ return new ClangASTSourceProxy(*this);
+ }
+
+protected:
+ /// Look for the complete version of an Objective-C interface, and return it
+ /// if found.
+ ///
+ /// \param[in] interface_decl
+ /// An ObjCInterfaceDecl that may not be the complete one.
+ ///
+ /// \return
+ /// NULL if the complete interface couldn't be found;
+ /// the complete interface otherwise.
+ clang::ObjCInterfaceDecl *
+ GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);
+
+ /// Find all entities matching a given name in a given module, using a
+ /// NameSearchContext to make Decls for them.
+ ///
+ /// \param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ ///
+ /// \param[in] module
+ /// If non-NULL, the module to query.
+ ///
+ /// \param[in] namespace_decl
+ /// If valid and module is non-NULL, the parent namespace.
+ void FindExternalVisibleDecls(NameSearchContext &context,
+ lldb::ModuleSP module,
+ CompilerDeclContext &namespace_decl);
+
+ /// Find all Objective-C methods matching a given selector.
+ ///
+ /// \param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the selector and its m_decl_context
+ /// is the containing object.
+ void FindObjCMethodDecls(NameSearchContext &context);
+
+ /// Find all Objective-C properties and ivars with a given name.
+ ///
+ /// \param[in] context
+ /// The NameSearchContext that can construct Decls for this name.
+ /// Its m_decl_name contains the name and its m_decl_context
+ /// is the containing object.
+ void FindObjCPropertyAndIvarDecls(NameSearchContext &context);
+
+ /// Performs lookup into a namespace.
+ ///
+ /// \param context
+ /// The NameSearchContext for a lookup inside a namespace.
+ void LookupInNamespace(NameSearchContext &context);
+
+ /// A wrapper for TypeSystemClang::CopyType that sets a flag that
+ /// indicates that we should not respond to queries during import.
+ ///
+ /// \param[in] src_type
+ /// The source type.
+ ///
+ /// \return
+ /// The imported type.
+ CompilerType GuardedCopyType(const CompilerType &src_type);
+
+ std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();
+
+public:
+ /// Returns true if a name should be ignored by name lookup.
+ ///
+ /// \param[in] name
+ /// The name to be considered.
+ ///
+ /// \param[in] ignore_all_dollar_names
+ /// True if $-names of all sorts should be ignored.
+ ///
+ /// \return
+ /// True if the name is one of a class of names that are ignored by
+ /// global lookup for performance reasons.
+ bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);
+
+ /// Copies a single Decl into the parser's AST context.
+ ///
+ /// \param[in] src_decl
+ /// The Decl to copy.
+ ///
+ /// \return
+ /// A copy of the Decl in m_ast_context, or NULL if the copy failed.
+ clang::Decl *CopyDecl(clang::Decl *src_decl);
+
+ /// Determined the origin of a single Decl, if it can be found.
+ ///
+ /// \param[in] decl
+ /// The Decl whose origin is to be found.
+ ///
+ /// \return
+ /// True if lookup succeeded; false otherwise.
+ ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);
+
+ /// Returns the TypeSystem that uses this ClangASTSource instance as it's
+ /// ExternalASTSource.
+ TypeSystemClang *GetTypeSystem() const { return m_clang_ast_context; }
+
+private:
+ bool FindObjCPropertyAndIvarDeclsWithOrigin(
+ NameSearchContext &context,
+ DeclFromUser<const clang::ObjCInterfaceDecl> &origin_iface_decl);
+
+protected:
+ bool FindObjCMethodDeclsWithOrigin(
+ NameSearchContext &context,
+ clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);
+
+ void FindDeclInModules(NameSearchContext &context, ConstString name);
+ void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name);
+
+ /// Fills the namespace map of the given NameSearchContext.
+ ///
+ /// \param context The NameSearchContext with the namespace map to fill.
+ /// \param module_sp The module to search for namespaces or a nullptr if
+ /// the current target should be searched.
+ /// \param namespace_decl The DeclContext in which to search for namespaces.
+ void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,
+ const CompilerDeclContext &namespace_decl);
+
+ clang::TagDecl *FindCompleteType(const clang::TagDecl *decl);
+
+ friend struct NameSearchContext;
+
+ bool m_lookups_enabled;
+
+ /// The target to use in finding variables and types.
+ const lldb::TargetSP m_target;
+ /// The AST context requests are coming in for.
+ clang::ASTContext *m_ast_context;
+ /// The TypeSystemClang for m_ast_context.
+ TypeSystemClang *m_clang_ast_context;
+ /// The file manager paired with the AST context.
+ clang::FileManager *m_file_manager;
+ /// The target's AST importer.
+ std::shared_ptr<ClangASTImporter> m_ast_importer_sp;
+ std::set<const clang::Decl *> m_active_lexical_decls;
+ std::set<const char *> m_active_lookups;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H