1292932Sdim//===-- CompilerDeclContext.h -----------------------------------*- C++ -*-===//
2292932Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6292932Sdim//
7292932Sdim//===----------------------------------------------------------------------===//
8292932Sdim
9292932Sdim#ifndef liblldb_CompilerDeclContext_h_
10292932Sdim#define liblldb_CompilerDeclContext_h_
11292932Sdim
12292932Sdim#include <vector>
13292932Sdim
14321369Sdim#include "lldb/Utility/ConstString.h"
15292932Sdim#include "lldb/lldb-private.h"
16292932Sdim
17292932Sdimnamespace lldb_private {
18292932Sdim
19360784Sdim/// Represents a generic declaration context in a program. A declaration context
20360784Sdim/// is data structure that contains declarations (e.g. namespaces).
21360784Sdim///
22360784Sdim/// This class serves as an abstraction for a declaration context inside one of
23360784Sdim/// the TypeSystems implemented by the language plugins. It does not have any
24360784Sdim/// actual logic in it but only stores an opaque pointer and a pointer to the
25360784Sdim/// TypeSystem that gives meaning to this opaque pointer. All methods of this
26360784Sdim/// class should call their respective method in the TypeSystem interface and
27360784Sdim/// pass the opaque pointer along.
28360784Sdim///
29360784Sdim/// \see lldb_private::TypeSystem
30314564Sdimclass CompilerDeclContext {
31292932Sdimpublic:
32360784Sdim  /// Constructs an invalid CompilerDeclContext.
33360784Sdim  CompilerDeclContext() = default;
34292932Sdim
35360784Sdim  /// Constructs a CompilerDeclContext with the given opaque decl context
36360784Sdim  /// and its respective TypeSystem instance.
37360784Sdim  ///
38360784Sdim  /// This constructor should only be called from the respective TypeSystem
39360784Sdim  /// implementation.
40360784Sdim  ///
41360784Sdim  /// \see lldb_private::ClangASTContext::CreateDeclContext(clang::DeclContext*)
42314564Sdim  CompilerDeclContext(TypeSystem *type_system, void *decl_ctx)
43314564Sdim      : m_type_system(type_system), m_opaque_decl_ctx(decl_ctx) {}
44292932Sdim
45314564Sdim  // Tests
46292932Sdim
47314564Sdim  explicit operator bool() const { return IsValid(); }
48292932Sdim
49314564Sdim  bool operator<(const CompilerDeclContext &rhs) const {
50314564Sdim    if (m_type_system == rhs.m_type_system)
51314564Sdim      return m_opaque_decl_ctx < rhs.m_opaque_decl_ctx;
52314564Sdim    return m_type_system < rhs.m_type_system;
53314564Sdim  }
54292932Sdim
55314564Sdim  bool IsValid() const {
56314564Sdim    return m_type_system != nullptr && m_opaque_decl_ctx != nullptr;
57314564Sdim  }
58292932Sdim
59314564Sdim  std::vector<CompilerDecl> FindDeclByName(ConstString name,
60314564Sdim                                           const bool ignore_using_decls);
61292932Sdim
62314564Sdim  /// Checks if this decl context represents a method of a class.
63314564Sdim  ///
64353358Sdim  /// \param[out] language_ptr
65314564Sdim  ///     If non NULL and \b true is returned from this function,
66314564Sdim  ///     this will indicate if the language that respresents the method.
67314564Sdim  ///
68353358Sdim  /// \param[out] is_instance_method_ptr
69314564Sdim  ///     If non NULL and \b true is returned from this function,
70314564Sdim  ///     this will indicate if the method is an instance function (true)
71314564Sdim  ///     or a class method (false indicating the function is static, or
72314564Sdim  ///     doesn't require an instance of the class to be called).
73314564Sdim  ///
74353358Sdim  /// \param[out] language_object_name_ptr
75314564Sdim  ///     If non NULL and \b true is returned from this function,
76314564Sdim  ///     this will indicate if implicit object name for the language
77314564Sdim  ///     like "this" for C++, and "self" for Objective C.
78314564Sdim  ///
79353358Sdim  /// \return
80314564Sdim  ///     Returns true if this is a decl context that represents a method
81314564Sdim  ///     in a struct, union or class.
82314564Sdim  bool IsClassMethod(lldb::LanguageType *language_ptr,
83314564Sdim                     bool *is_instance_method_ptr,
84314564Sdim                     ConstString *language_object_name_ptr);
85292932Sdim
86353358Sdim  /// Check if the given other decl context is contained in the lookup
87353358Sdim  /// of this decl context (for example because the other context is a nested
88353358Sdim  /// inline namespace).
89353358Sdim  ///
90353358Sdim  /// @param[in] other
91353358Sdim  ///     The other decl context for which we should check if it is contained
92353358Sdim  ///     in the lookoup of this context.
93353358Sdim  ///
94353358Sdim  /// @return
95353358Sdim  ///     Returns true iff the other decl context is contained in the lookup
96353358Sdim  ///     of this decl context.
97353358Sdim  bool IsContainedInLookup(CompilerDeclContext other) const;
98353358Sdim
99314564Sdim  // Accessors
100292932Sdim
101314564Sdim  TypeSystem *GetTypeSystem() const { return m_type_system; }
102292932Sdim
103314564Sdim  void *GetOpaqueDeclContext() const { return m_opaque_decl_ctx; }
104292932Sdim
105314564Sdim  void SetDeclContext(TypeSystem *type_system, void *decl_ctx) {
106314564Sdim    m_type_system = type_system;
107314564Sdim    m_opaque_decl_ctx = decl_ctx;
108314564Sdim  }
109294024Sdim
110314564Sdim  void Clear() {
111314564Sdim    m_type_system = nullptr;
112314564Sdim    m_opaque_decl_ctx = nullptr;
113314564Sdim  }
114292932Sdim
115314564Sdim  ConstString GetName() const;
116314564Sdim
117314564Sdim  ConstString GetScopeQualifiedName() const;
118314564Sdim
119292932Sdimprivate:
120360784Sdim  TypeSystem *m_type_system = nullptr;
121360784Sdim  void *m_opaque_decl_ctx = nullptr;
122292932Sdim};
123292932Sdim
124314564Sdimbool operator==(const CompilerDeclContext &lhs, const CompilerDeclContext &rhs);
125314564Sdimbool operator!=(const CompilerDeclContext &lhs, const CompilerDeclContext &rhs);
126314564Sdim
127292932Sdim} // namespace lldb_private
128292932Sdim
129292932Sdim#endif // #ifndef liblldb_CompilerDeclContext_h_
130