1//===-- ClangModulesDeclVendor.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-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef liblldb_ClangModulesDeclVendor_h
10#define liblldb_ClangModulesDeclVendor_h
11
12#include "lldb/Core/ClangForward.h"
13#include "lldb/Symbol/SourceModule.h"
14#include "lldb/Target/Platform.h"
15
16#include "Plugins/ExpressionParser/Clang/ClangDeclVendor.h"
17
18#include <set>
19#include <vector>
20
21namespace lldb_private {
22
23class ClangModulesDeclVendor : public ClangDeclVendor {
24public:
25  // Constructors and Destructors
26  ClangModulesDeclVendor();
27
28  ~ClangModulesDeclVendor() override;
29
30  static bool classof(const DeclVendor *vendor) {
31    return vendor->GetKind() == eClangModuleDeclVendor;
32  }
33
34  static ClangModulesDeclVendor *Create(Target &target);
35
36  typedef std::vector<ConstString> ModulePath;
37  typedef uintptr_t ModuleID;
38  typedef std::vector<ModuleID> ModuleVector;
39
40  /// Add a module to the list of modules to search.
41  ///
42  /// \param[in] module
43  ///     The path to the exact module to be loaded.  E.g., if the desired
44  ///     module is std.io, then this should be { "std", "io" }.
45  ///
46  /// \param[in] exported_modules
47  ///     If non-NULL, a pointer to a vector to populate with the ID of every
48  ///     module that is re-exported by the specified module.
49  ///
50  /// \param[in] error_stream
51  ///     A stream to populate with the output of the Clang parser when
52  ///     it tries to load the module.
53  ///
54  /// \return
55  ///     True if the module could be loaded; false if not.  If the
56  ///     compiler encountered a fatal error during a previous module
57  ///     load, then this will always return false for this ModuleImporter.
58  virtual bool AddModule(const SourceModule &module,
59                         ModuleVector *exported_modules,
60                         Stream &error_stream) = 0;
61
62  /// Add all modules referred to in a given compilation unit to the list
63  /// of modules to search.
64  ///
65  /// \param[in] cu
66  ///     The compilation unit to scan for imported modules.
67  ///
68  /// \param[in] exported_modules
69  ///     A vector to populate with the ID of each module loaded (directly
70  ///     and via re-exports) in this way.
71  ///
72  /// \param[in] error_stream
73  ///     A stream to populate with the output of the Clang parser when
74  ///     it tries to load the modules.
75  ///
76  /// \return
77  ///     True if all modules referred to by the compilation unit could be
78  ///     loaded; false if one could not be loaded.  If the compiler
79  ///     encountered a fatal error during a previous module
80  ///     load, then this will always return false for this ModuleImporter.
81  virtual bool AddModulesForCompileUnit(CompileUnit &cu,
82                                        ModuleVector &exported_modules,
83                                        Stream &error_stream) = 0;
84
85  /// Enumerate all the macros that are defined by a given set of modules
86  /// that are already imported.
87  ///
88  /// \param[in] modules
89  ///     The unique IDs for all modules to query.  Later modules have higher
90  ///     priority, just as if you @imported them in that order.  This matters
91  ///     if module A #defines a macro and module B #undefs it.
92  ///
93  /// \param[in] handler
94  ///     A function to call with the text of each #define (including the
95  ///     #define directive).  #undef directives are not included; we simply
96  ///     elide any corresponding #define.  If this function returns true,
97  ///     we stop the iteration immediately.
98  virtual void
99  ForEachMacro(const ModuleVector &modules,
100               std::function<bool(const std::string &)> handler) = 0;
101
102  /// Query whether Clang supports modules for a particular language.
103  /// LLDB uses this to decide whether to try to find the modules loaded
104  /// by a given compile unit.
105  ///
106  /// \param[in] language
107  ///     The language to query for.
108  ///
109  /// \return
110  ///     True if Clang has modules for the given language.
111  static bool LanguageSupportsClangModules(lldb::LanguageType language);
112};
113
114} // namespace lldb_private
115
116#endif // liblldb_ClangModulesDeclVendor_h
117