brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.1 KiB · 2450635 Raw
403 lines · c
1//===-- ClangASTSource.h ----------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H10#define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H11 12#include <set>13 14#include "Plugins/ExpressionParser/Clang/ClangASTImporter.h"15#include "Plugins/ExpressionParser/Clang/NameSearchContext.h"16#include "lldb/Symbol/CompilerType.h"17#include "lldb/Target/Target.h"18#include "clang/AST/ExternalASTSource.h"19#include "clang/Basic/IdentifierTable.h"20 21#include "llvm/ADT/SmallSet.h"22 23namespace lldb_private {24 25/// \class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h"26/// Provider for named objects defined in the debug info for Clang27///28/// As Clang parses an expression, it may encounter names that are not defined29/// inside the expression, including variables, functions, and types.  Clang30/// knows the name it is looking for, but nothing else. The ExternalSemaSource31/// class provides Decls (VarDecl, FunDecl, TypeDecl) to Clang for these32/// names, consulting the ClangExpressionDeclMap to do the actual lookups.33class ClangASTSource : public clang::ExternalASTSource,34                       public ClangASTImporter::MapCompleter {35public:36  /// Constructor37  ///38  /// Initializes class variables.39  ///40  /// \param[in] target41  ///     A reference to the target containing debug information to use.42  ///43  /// \param[in] importer44  ///     The ClangASTImporter to use.45  ClangASTSource(const lldb::TargetSP &target,46                 const std::shared_ptr<ClangASTImporter> &importer);47 48  /// Destructor49  ~ClangASTSource() override;50 51  /// Interface stubs.52  clang::Decl *GetExternalDecl(clang::GlobalDeclID) override { return nullptr; }53  clang::Stmt *GetExternalDeclStmt(uint64_t) override { return nullptr; }54  clang::Selector GetExternalSelector(uint32_t) override {55    return clang::Selector();56  }57  uint32_t GetNumExternalSelectors() override { return 0; }58  clang::CXXBaseSpecifier *59  GetExternalCXXBaseSpecifiers(uint64_t Offset) override {60    return nullptr;61  }62  void MaterializeVisibleDecls(const clang::DeclContext *DC) {}63 64  void InstallASTContext(TypeSystemClang &ast_context);65 66  //67  // APIs for ExternalASTSource68  //69 70  /// Look up all Decls that match a particular name.  Only handles71  /// Identifiers and DeclContexts that are either NamespaceDecls or72  /// TranslationUnitDecls.  Calls SetExternalVisibleDeclsForName with the73  /// result.74  ///75  /// The work for this function is done by76  /// void FindExternalVisibleDecls (NameSearchContext &);77  ///78  /// \param[in] DC79  ///     The DeclContext to register the found Decls in.80  ///81  /// \param[in] Name82  ///     The name to find entries for.83  ///84  /// \return85  ///     Whatever SetExternalVisibleDeclsForName returns.86  bool87  FindExternalVisibleDeclsByName(const clang::DeclContext *DC,88                                 clang::DeclarationName Name,89                                 const clang::DeclContext *OriginalDC) override;90 91  /// Enumerate all Decls in a given lexical context.92  ///93  /// \param[in] DC94  ///     The DeclContext being searched.95  ///96  /// \param[in] IsKindWeWant97  ///     A callback function that returns true given the98  ///     DeclKinds of desired Decls, and false otherwise.99  ///100  /// \param[in] Decls101  ///     A vector that is filled in with matching Decls.102  void FindExternalLexicalDecls(103      const clang::DeclContext *DC,104      llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,105      llvm::SmallVectorImpl<clang::Decl *> &Decls) override;106 107  /// Specify the layout of the contents of a RecordDecl.108  ///109  /// \param[in] Record110  ///     The record (in the parser's AST context) that needs to be111  ///     laid out.112  ///113  /// \param[out] Size114  ///     The total size of the record in bits.115  ///116  /// \param[out] Alignment117  ///     The alignment of the record in bits.118  ///119  /// \param[in] FieldOffsets120  ///     A map that must be populated with pairs of the record's121  ///     fields (in the parser's AST context) and their offsets122  ///     (measured in bits).123  ///124  /// \param[in] BaseOffsets125  ///     A map that must be populated with pairs of the record's126  ///     C++ concrete base classes (in the parser's AST context,127  ///     and only if the record is a CXXRecordDecl and has base128  ///     classes) and their offsets (measured in bytes).129  ///130  /// \param[in] VirtualBaseOffsets131  ///     A map that must be populated with pairs of the record's132  ///     C++ virtual base classes (in the parser's AST context,133  ///     and only if the record is a CXXRecordDecl and has base134  ///     classes) and their offsets (measured in bytes).135  ///136  /// \return137  ///     True <=> the layout is valid.138  bool layoutRecordType(139      const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,140      llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,141      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>142          &BaseOffsets,143      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>144          &VirtualBaseOffsets) override;145 146  /// Complete a TagDecl.147  ///148  /// \param[in] Tag149  ///     The Decl to be completed in place.150  void CompleteType(clang::TagDecl *Tag) override;151 152  /// Complete an ObjCInterfaceDecl.153  ///154  /// \param[in] Class155  ///     The Decl to be completed in place.156  void CompleteType(clang::ObjCInterfaceDecl *Class) override;157 158  /// Called on entering a translation unit.  Tells Clang by calling159  /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() that160  /// this object has something to say about undefined names.161  ///162  /// \param[in] Consumer163  ///     Unused.164  void StartTranslationUnit(clang::ASTConsumer *Consumer) override;165 166  //167  // APIs for NamespaceMapCompleter168  //169 170  /// Look up the modules containing a given namespace and put the appropriate171  /// entries in the namespace map.172  ///173  /// \param[in] namespace_map174  ///     The map to be completed.175  ///176  /// \param[in] name177  ///     The name of the namespace to be found.178  ///179  /// \param[in] parent_map180  ///     The map for the namespace's parent namespace, if there is181  ///     one.182  void CompleteNamespaceMap(183      ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,184      ClangASTImporter::NamespaceMapSP &parent_map) const override;185 186  //187  // Helper APIs188  //189 190  clang::NamespaceDecl *191  AddNamespace(NameSearchContext &context,192               ClangASTImporter::NamespaceMapSP &namespace_decls);193 194  /// The worker function for FindExternalVisibleDeclsByName.195  ///196  /// \param[in] context197  ///     The NameSearchContext to use when filing results.198  virtual void FindExternalVisibleDecls(NameSearchContext &context);199 200  clang::Sema *getSema();201 202  void SetLookupsEnabled(bool lookups_enabled) {203    m_lookups_enabled = lookups_enabled;204  }205  bool GetLookupsEnabled() { return m_lookups_enabled; }206 207  /// \class ClangASTSourceProxy ClangASTSource.h208  /// "lldb/Expression/ClangASTSource.h" Proxy for ClangASTSource209  ///210  /// Clang AST contexts like to own their AST sources, so this is a state-211  /// free proxy object.212  class ClangASTSourceProxy : public clang::ExternalASTSource {213  public:214    ClangASTSourceProxy(ClangASTSource &original) : m_original(original) {}215 216    bool FindExternalVisibleDeclsByName(217        const clang::DeclContext *DC, clang::DeclarationName Name,218        const clang::DeclContext *OriginalDC) override {219      return m_original.FindExternalVisibleDeclsByName(DC, Name, OriginalDC);220    }221 222    void FindExternalLexicalDecls(223        const clang::DeclContext *DC,224        llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,225        llvm::SmallVectorImpl<clang::Decl *> &Decls) override {226      return m_original.FindExternalLexicalDecls(DC, IsKindWeWant, Decls);227    }228 229    void CompleteType(clang::TagDecl *Tag) override {230      return m_original.CompleteType(Tag);231    }232 233    void CompleteType(clang::ObjCInterfaceDecl *Class) override {234      return m_original.CompleteType(Class);235    }236 237    bool layoutRecordType(238        const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,239        llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,240        llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>241            &BaseOffsets,242        llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>243            &VirtualBaseOffsets) override {244      return m_original.layoutRecordType(Record, Size, Alignment, FieldOffsets,245                                         BaseOffsets, VirtualBaseOffsets);246    }247 248    void StartTranslationUnit(clang::ASTConsumer *Consumer) override {249      return m_original.StartTranslationUnit(Consumer);250    }251 252  private:253    ClangASTSource &m_original;254  };255 256  llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> CreateProxy() {257    return llvm::makeIntrusiveRefCnt<ClangASTSourceProxy>(*this);258  }259 260protected:261  /// Look for the complete version of an Objective-C interface, and return it262  /// if found.263  ///264  /// \param[in] interface_decl265  ///     An ObjCInterfaceDecl that may not be the complete one.266  ///267  /// \return268  ///     NULL if the complete interface couldn't be found;269  ///     the complete interface otherwise.270  clang::ObjCInterfaceDecl *271  GetCompleteObjCInterface(const clang::ObjCInterfaceDecl *interface_decl);272 273  /// Find all entities matching a given name in a given module, using a274  /// NameSearchContext to make Decls for them.275  ///276  /// \param[in] context277  ///     The NameSearchContext that can construct Decls for this name.278  ///279  /// \param[in] module280  ///     If non-NULL, the module to query.281  ///282  /// \param[in] namespace_decl283  ///     If valid and module is non-NULL, the parent namespace.284  void FindExternalVisibleDecls(NameSearchContext &context,285                                lldb::ModuleSP module,286                                CompilerDeclContext &namespace_decl);287 288  /// Find all Objective-C methods matching a given selector.289  ///290  /// \param[in] context291  ///     The NameSearchContext that can construct Decls for this name.292  ///     Its m_decl_name contains the selector and its m_decl_context293  ///     is the containing object.294  void FindObjCMethodDecls(NameSearchContext &context);295 296  /// Find all Objective-C properties and ivars with a given name.297  ///298  /// \param[in] context299  ///     The NameSearchContext that can construct Decls for this name.300  ///     Its m_decl_name contains the name and its m_decl_context301  ///     is the containing object.302  void FindObjCPropertyAndIvarDecls(NameSearchContext &context);303 304  /// Performs lookup into a namespace.305  ///306  /// \param context307  ///     The NameSearchContext for a lookup inside a namespace.308  void LookupInNamespace(NameSearchContext &context);309 310  /// A wrapper for TypeSystemClang::CopyType that sets a flag that311  /// indicates that we should not respond to queries during import.312  ///313  /// \param[in] src_type314  ///     The source type.315  ///316  /// \return317  ///     The imported type.318  CompilerType GuardedCopyType(const CompilerType &src_type);319 320  std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor();321 322public:323  /// Returns true if a name should be ignored by name lookup.324  ///325  /// \param[in] name326  ///     The name to be considered.327  ///328  /// \param[in] ignore_all_dollar_names329  ///     True if $-names of all sorts should be ignored.330  ///331  /// \return332  ///     True if the name is one of a class of names that are ignored by333  ///     global lookup for performance reasons.334  bool IgnoreName(const ConstString name, bool ignore_all_dollar_names);335 336  /// Copies a single Decl into the parser's AST context.337  ///338  /// \param[in] src_decl339  ///     The Decl to copy.340  ///341  /// \return342  ///     A copy of the Decl in m_ast_context, or NULL if the copy failed.343  clang::Decl *CopyDecl(clang::Decl *src_decl);344 345  /// Determined the origin of a single Decl, if it can be found.346  ///347  /// \param[in] decl348  ///     The Decl whose origin is to be found.349  ///350  /// \return351  ///     True if lookup succeeded; false otherwise.352  ClangASTImporter::DeclOrigin GetDeclOrigin(const clang::Decl *decl);353 354  /// Returns the TypeSystem that uses this ClangASTSource instance as it's355  /// ExternalASTSource.356  TypeSystemClang *GetTypeSystem() const { return m_clang_ast_context; }357 358private:359  bool FindObjCPropertyAndIvarDeclsWithOrigin(360      NameSearchContext &context,361      DeclFromUser<const clang::ObjCInterfaceDecl> &origin_iface_decl);362 363protected:364  bool FindObjCMethodDeclsWithOrigin(365      NameSearchContext &context,366      clang::ObjCInterfaceDecl *original_interface_decl, const char *log_info);367 368  void FindDeclInModules(NameSearchContext &context, ConstString name);369  void FindDeclInObjCRuntime(NameSearchContext &context, ConstString name);370 371  /// Fills the namespace map of the given NameSearchContext.372  ///373  /// \param context The NameSearchContext with the namespace map to fill.374  /// \param module_sp The module to search for namespaces or a nullptr if375  ///                  the current target should be searched.376  /// \param namespace_decl The DeclContext in which to search for namespaces.377  void FillNamespaceMap(NameSearchContext &context, lldb::ModuleSP module_sp,378                        const CompilerDeclContext &namespace_decl);379 380  clang::TagDecl *FindCompleteType(const clang::TagDecl *decl);381 382  friend struct NameSearchContext;383 384  bool m_lookups_enabled;385 386  /// The target to use in finding variables and types.387  const lldb::TargetSP m_target;388  /// The AST context requests are coming in for.389  clang::ASTContext *m_ast_context;390  /// The TypeSystemClang for m_ast_context.391  TypeSystemClang *m_clang_ast_context;392  /// The file manager paired with the AST context.393  clang::FileManager *m_file_manager;394  /// The target's AST importer.395  std::shared_ptr<ClangASTImporter> m_ast_importer_sp;396  std::set<const clang::Decl *> m_active_lexical_decls;397  std::set<const char *> m_active_lookups;398};399 400} // namespace lldb_private401 402#endif // LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CLANGASTSOURCE_H403