1292932Sdim//===-- ClangModulesDeclVendor.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_ClangModulesDeclVendor_h
10292932Sdim#define liblldb_ClangModulesDeclVendor_h
11292932Sdim
12292932Sdim#include "lldb/Core/ClangForward.h"
13353358Sdim#include "lldb/Symbol/SourceModule.h"
14292932Sdim#include "lldb/Target/Platform.h"
15292932Sdim
16360784Sdim#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
17360784Sdim
18292932Sdim#include <set>
19292932Sdim#include <vector>
20292932Sdim
21314564Sdimnamespace lldb_private {
22314564Sdim
23360784Sdimclass ClangModulesDeclVendor : public ClangDeclVendor {
24292932Sdimpublic:
25314564Sdim  // Constructors and Destructors
26314564Sdim  ClangModulesDeclVendor();
27292932Sdim
28314564Sdim  ~ClangModulesDeclVendor() override;
29314564Sdim
30360784Sdim  static bool classof(const DeclVendor *vendor) {
31360784Sdim    return vendor->GetKind() == eClangModuleDeclVendor;
32360784Sdim  }
33360784Sdim
34314564Sdim  static ClangModulesDeclVendor *Create(Target &target);
35314564Sdim
36314564Sdim  typedef std::vector<ConstString> ModulePath;
37314564Sdim  typedef uintptr_t ModuleID;
38314564Sdim  typedef std::vector<ModuleID> ModuleVector;
39314564Sdim
40314564Sdim  /// Add a module to the list of modules to search.
41314564Sdim  ///
42353358Sdim  /// \param[in] module
43314564Sdim  ///     The path to the exact module to be loaded.  E.g., if the desired
44314564Sdim  ///     module is std.io, then this should be { "std", "io" }.
45314564Sdim  ///
46353358Sdim  /// \param[in] exported_modules
47314564Sdim  ///     If non-NULL, a pointer to a vector to populate with the ID of every
48314564Sdim  ///     module that is re-exported by the specified module.
49314564Sdim  ///
50353358Sdim  /// \param[in] error_stream
51314564Sdim  ///     A stream to populate with the output of the Clang parser when
52314564Sdim  ///     it tries to load the module.
53314564Sdim  ///
54353358Sdim  /// \return
55314564Sdim  ///     True if the module could be loaded; false if not.  If the
56314564Sdim  ///     compiler encountered a fatal error during a previous module
57314564Sdim  ///     load, then this will always return false for this ModuleImporter.
58353358Sdim  virtual bool AddModule(const SourceModule &module,
59353358Sdim                         ModuleVector *exported_modules,
60314564Sdim                         Stream &error_stream) = 0;
61314564Sdim
62314564Sdim  /// Add all modules referred to in a given compilation unit to the list
63314564Sdim  /// of modules to search.
64314564Sdim  ///
65353358Sdim  /// \param[in] cu
66314564Sdim  ///     The compilation unit to scan for imported modules.
67314564Sdim  ///
68353358Sdim  /// \param[in] exported_modules
69314564Sdim  ///     A vector to populate with the ID of each module loaded (directly
70314564Sdim  ///     and via re-exports) in this way.
71314564Sdim  ///
72353358Sdim  /// \param[in] error_stream
73314564Sdim  ///     A stream to populate with the output of the Clang parser when
74314564Sdim  ///     it tries to load the modules.
75314564Sdim  ///
76353358Sdim  /// \return
77314564Sdim  ///     True if all modules referred to by the compilation unit could be
78314564Sdim  ///     loaded; false if one could not be loaded.  If the compiler
79314564Sdim  ///     encountered a fatal error during a previous module
80314564Sdim  ///     load, then this will always return false for this ModuleImporter.
81314564Sdim  virtual bool AddModulesForCompileUnit(CompileUnit &cu,
82314564Sdim                                        ModuleVector &exported_modules,
83314564Sdim                                        Stream &error_stream) = 0;
84314564Sdim
85314564Sdim  /// Enumerate all the macros that are defined by a given set of modules
86314564Sdim  /// that are already imported.
87314564Sdim  ///
88353358Sdim  /// \param[in] modules
89314564Sdim  ///     The unique IDs for all modules to query.  Later modules have higher
90314564Sdim  ///     priority, just as if you @imported them in that order.  This matters
91314564Sdim  ///     if module A #defines a macro and module B #undefs it.
92314564Sdim  ///
93353358Sdim  /// \param[in] handler
94314564Sdim  ///     A function to call with the text of each #define (including the
95314564Sdim  ///     #define directive).  #undef directives are not included; we simply
96314564Sdim  ///     elide any corresponding #define.  If this function returns true,
97314564Sdim  ///     we stop the iteration immediately.
98314564Sdim  virtual void
99314564Sdim  ForEachMacro(const ModuleVector &modules,
100314564Sdim               std::function<bool(const std::string &)> handler) = 0;
101314564Sdim
102314564Sdim  /// Query whether Clang supports modules for a particular language.
103314564Sdim  /// LLDB uses this to decide whether to try to find the modules loaded
104353358Sdim  /// by a given compile unit.
105314564Sdim  ///
106353358Sdim  /// \param[in] language
107314564Sdim  ///     The language to query for.
108314564Sdim  ///
109353358Sdim  /// \return
110314564Sdim  ///     True if Clang has modules for the given language.
111314564Sdim  static bool LanguageSupportsClangModules(lldb::LanguageType language);
112292932Sdim};
113314564Sdim
114292932Sdim} // namespace lldb_private
115292932Sdim
116292932Sdim#endif // liblldb_ClangModulesDeclVendor_h
117