Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.h
39653 views
//===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H9#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H1011#include <set>1213#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"14#include "Plugins/ExpressionParser/Clang/NameSearchContext.h"15#include "lldb/Symbol/CompilerType.h"16#include "lldb/Target/Target.h"17#include "clang/AST/ExternalASTSource.h"18#include "clang/Basic/IdentifierTable.h"1920#include "llvm/ADT/SmallSet.h"2122namespace lldb_private {2324/// \class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"25/// Provider for named objects defined in the debug info for Clang26///27/// As Clang parses an expression, it may encounter names that are not defined28/// inside the expression, including variables, functions, and types. Clang29/// knows the name it is looking for, but nothing else. The ExternalSemaSource30/// class provides Decls (VarDecl, FunDecl, TypeDecl) to Clang for these31/// names, consulting the ClangExpressionDeclMap to do the actual lookups.32class ClangASTSource : public clang::ExternalASTSource,33public ClangASTImporter::MapCompleter {34public:35/// Constructor36///37/// Initializes class variables.38///39/// \param[in] target40/// A reference to the target containing debug information to use.41///42/// \param[in] importer43/// The ClangASTImporter to use.44ClangASTSource(const lldb::TargetSP &target,45const std::shared_ptr<ClangASTImporter> &importer);4647/// Destructor48~ClangASTSource() override;4950/// Interface stubs.51clang::Decl *GetExternalDecl(clang::GlobalDeclID) override { return nullptr; }52clang::Stmt *GetExternalDeclStmt(uint64_t) override { return nullptr; }53clang::Selector GetExternalSelector(uint32_t) override {54return clang::Selector();55}56uint32_t GetNumExternalSelectors() override { return 0; }57clang::CXXBaseSpecifier *58GetExternalCXXBaseSpecifiers(uint64_t Offset) override {59return nullptr;60}61void MaterializeVisibleDecls(const clang::DeclContext *DC) {}6263void InstallASTContext(TypeSystemClang &ast_context);6465//66// APIs for ExternalASTSource67//6869/// Look up all Decls that match a particular name. Only handles70/// Identifiers and DeclContexts that are either NamespaceDecls or71/// TranslationUnitDecls. Calls SetExternalVisibleDeclsForName with the72/// result.73///74/// The work for this function is done by75/// void FindExternalVisibleDecls (NameSearchContext &);76///77/// \param[in] DC78/// The DeclContext to register the found Decls in.79///80/// \param[in] Name81/// The name to find entries for.82///83/// \return84/// Whatever SetExternalVisibleDeclsForName returns.85bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,86clang::DeclarationName Name) override;8788/// Enumerate all Decls in a given lexical context.89///90/// \param[in] DC91/// The DeclContext being searched.92///93/// \param[in] IsKindWeWant94/// A callback function that returns true given the95/// DeclKinds of desired Decls, and false otherwise.96///97/// \param[in] Decls98/// A vector that is filled in with matching Decls.99void FindExternalLexicalDecls(100const clang::DeclContext *DC,101llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,102llvm::SmallVectorImpl<clang::Decl *> &Decls) override;103104/// Specify the layout of the contents of a RecordDecl.105///106/// \param[in] Record107/// The record (in the parser's AST context) that needs to be108/// laid out.109///110/// \param[out] Size111/// The total size of the record in bits.112///113/// \param[out] Alignment114/// The alignment of the record in bits.115///116/// \param[in] FieldOffsets117/// A map that must be populated with pairs of the record's118/// fields (in the parser's AST context) and their offsets119/// (measured in bits).120///121/// \param[in] BaseOffsets122/// A map that must be populated with pairs of the record's123/// C++ concrete base classes (in the parser's AST context,124/// and only if the record is a CXXRecordDecl and has base125/// classes) and their offsets (measured in bytes).126///127/// \param[in] VirtualBaseOffsets128/// A map that must be populated with pairs of the record's129/// C++ virtual base classes (in the parser's AST context,130/// and only if the record is a CXXRecordDecl and has base131/// classes) and their offsets (measured in bytes).132///133/// \return134/// True <=> the layout is valid.135bool layoutRecordType(136const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,137llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,138llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>139&BaseOffsets,140llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>141&VirtualBaseOffsets) override;142143/// Complete a TagDecl.144///145/// \param[in] Tag146/// The Decl to be completed in place.147void CompleteType(clang::TagDecl *Tag) override;148149/// Complete an ObjCInterfaceDecl.150///151/// \param[in] Class152/// The Decl to be completed in place.153void CompleteType(clang::ObjCInterfaceDecl *Class) override;154155/// Called on entering a translation unit. Tells Clang by calling156/// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that157/// this object has something to say about undefined names.158///159/// \param[in] Consumer160/// Unused.161void StartTranslationUnit(clang::ASTConsumer *Consumer) override;162163//164// APIs for NamespaceMapCompleter165//166167/// Look up the modules containing a given namespace and put the appropriate168/// entries in the namespace map.169///170/// \param[in] namespace_map171/// The map to be completed.172///173/// \param[in] name174/// The name of the namespace to be found.175///176/// \param[in] parent_map177/// The map for the namespace's parent namespace, if there is178/// one.179void CompleteNamespaceMap(180ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,181ClangASTImporter::NamespaceMapSP &parent_map) const override;182183//184// Helper APIs185//186187clang::NamespaceDecl *188AddNamespace(NameSearchContext &context,189ClangASTImporter::NamespaceMapSP &namespace_decls);190191/// The worker function for FindExternalVisibleDeclsByName.192///193/// \param[in] context194/// The NameSearchContext to use when filing results.195virtual void FindExternalVisibleDecls(NameSearchContext &context);196197clang::Sema *getSema();198199void SetLookupsEnabled(bool lookups_enabled) {200m_lookups_enabled = lookups_enabled;201}202bool GetLookupsEnabled() { return m_lookups_enabled; }203204/// \class ClangASTSourceProxy ClangASTSource.h205/// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource206///207/// Clang AST contexts like to own their AST sources, so this is a state-208/// free proxy object.209class ClangASTSourceProxy : public clang::ExternalASTSource {210public:211ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}212213bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,214clang::DeclarationName Name) override {215return m_original.FindExternalVisibleDeclsByName(DC, Name);216}217218void FindExternalLexicalDecls(219const clang::DeclContext *DC,220llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,221llvm::SmallVectorImpl<clang::Decl *> &Decls) override {222return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);223}224225void CompleteType(clang::TagDecl *Tag) override {226return m_original.CompleteType(Tag);227}228229void CompleteType(clang::ObjCInterfaceDecl *Class) override {230return m_original.CompleteType(Class);231}232233bool layoutRecordType(234const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,235llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,236llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>237&BaseOffsets,238llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>239&VirtualBaseOffsets) override {240return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,241BaseOffsets, VirtualBaseOffsets);242}243244void StartTranslationUnit(clang::ASTConsumer *Consumer) override {245return m_original.StartTranslationUnit(Consumer);246}247248private:249ClangASTSource &m_original;250};251252clang::ExternalASTSource *CreateProxy() {253return new ClangASTSourceProxy(*this);254}255256protected:257/// Look for the complete version of an Objective-C interface, and return it258/// if found.259///260/// \param[in] interface_decl261/// An ObjCInterfaceDecl that may not be the complete one.262///263/// \return264/// NULL if the complete interface couldn't be found;265/// the complete interface otherwise.266clang::ObjCInterfaceDecl *267GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);268269/// Find all entities matching a given name in a given module, using a270/// NameSearchContext to make Decls for them.271///272/// \param[in] context273/// The NameSearchContext that can construct Decls for this name.274///275/// \param[in] module276/// If non-NULL, the module to query.277///278/// \param[in] namespace_decl279/// If valid and module is non-NULL, the parent namespace.280void FindExternalVisibleDecls(NameSearchContext &context,281lldb::ModuleSP module,282CompilerDeclContext &namespace_decl);283284/// Find all Objective-C methods matching a given selector.285///286/// \param[in] context287/// The NameSearchContext that can construct Decls for this name.288/// Its m_decl_name contains the selector and its m_decl_context289/// is the containing object.290void FindObjCMethodDecls(NameSearchContext &context);291292/// Find all Objective-C properties and ivars with a given name.293///294/// \param[in] context295/// The NameSearchContext that can construct Decls for this name.296/// Its m_decl_name contains the name and its m_decl_context297/// is the containing object.298void FindObjCPropertyAndIvarDecls(NameSearchContext &context);299300/// Performs lookup into a namespace.301///302/// \param context303/// The NameSearchContext for a lookup inside a namespace.304void LookupInNamespace(NameSearchContext &context);305306/// A wrapper for TypeSystemClang::CopyType that sets a flag that307/// indicates that we should not respond to queries during import.308///309/// \param[in] src_type310/// The source type.311///312/// \return313/// The imported type.314CompilerType GuardedCopyType(const CompilerType &src_type);315316std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();317318public:319/// Returns true if a name should be ignored by name lookup.320///321/// \param[in] name322/// The name to be considered.323///324/// \param[in] ignore_all_dollar_names325/// True if $-names of all sorts should be ignored.326///327/// \return328/// True if the name is one of a class of names that are ignored by329/// global lookup for performance reasons.330bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);331332/// Copies a single Decl into the parser's AST context.333///334/// \param[in] src_decl335/// The Decl to copy.336///337/// \return338/// A copy of the Decl in m_ast_context, or NULL if the copy failed.339clang::Decl *CopyDecl(clang::Decl *src_decl);340341/// Determined the origin of a single Decl, if it can be found.342///343/// \param[in] decl344/// The Decl whose origin is to be found.345///346/// \return347/// True if lookup succeeded; false otherwise.348ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);349350/// Returns the TypeSystem that uses this ClangASTSource instance as it's351/// ExternalASTSource.352TypeSystemClang *GetTypeSystem() const { return m_clang_ast_context; }353354private:355bool FindObjCPropertyAndIvarDeclsWithOrigin(356NameSearchContext &context,357DeclFromUser<const clang::ObjCInterfaceDecl> &origin_iface_decl);358359protected:360bool FindObjCMethodDeclsWithOrigin(361NameSearchContext &context,362clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);363364void FindDeclInModules(NameSearchContext &context, ConstString name);365void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name);366367/// Fills the namespace map of the given NameSearchContext.368///369/// \param context The NameSearchContext with the namespace map to fill.370/// \param module_sp The module to search for namespaces or a nullptr if371/// the current target should be searched.372/// \param namespace_decl The DeclContext in which to search for namespaces.373void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,374const CompilerDeclContext &namespace_decl);375376clang::TagDecl *FindCompleteType(const clang::TagDecl *decl);377378friend struct NameSearchContext;379380bool m_lookups_enabled;381382/// The target to use in finding variables and types.383const lldb::TargetSP m_target;384/// The AST context requests are coming in for.385clang::ASTContext *m_ast_context;386/// The TypeSystemClang for m_ast_context.387TypeSystemClang *m_clang_ast_context;388/// The file manager paired with the AST context.389clang::FileManager *m_file_manager;390/// The target's AST importer.391std::shared_ptr<ClangASTImporter> m_ast_importer_sp;392std::set<const clang::Decl *> m_active_lexical_decls;393std::set<const char *> m_active_lookups;394};395396} // namespace lldb_private397398#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H399400401