ModuleMap.h revision 392ed2b717d86ebdd202cb9bb58d18d8b3b4cd87
1179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===--- ModuleMap.h - Describe the layout of modules -----------*- C++ -*-===//
2179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
3179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//                     The LLVM Compiler Infrastructure
4179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
5179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// This file is distributed under the University of Illinois Open Source
6179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// License. See LICENSE.TXT for details.
7179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
8179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
9179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
10179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// This file defines the ModuleMap interface, which describes the layout of a
11179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org// module as it relates to headers.
12179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//
13179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org//===----------------------------------------------------------------------===//
14179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
15179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
16179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#ifndef LLVM_CLANG_LEX_MODULEMAP_H
17179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#define LLVM_CLANG_LEX_MODULEMAP_H
18179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
19179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "clang/Basic/LangOptions.h"
20179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "clang/Basic/SourceManager.h"
21179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/ADT/DenseMap.h"
22179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/ADT/IntrusiveRefCntPtr.h"
23179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/ADT/SmallVector.h"
24179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/ADT/StringRef.h"
25179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include "llvm/ADT/StringMap.h"
26179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org#include <string>
27179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
28179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgnamespace clang {
29179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
30179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass DirectoryEntry;
31179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass FileEntry;
32179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass FileManager;
33179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass DiagnosticConsumer;
34179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass DiagnosticsEngine;
35179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass ModuleMapParser;
36179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
37179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgclass ModuleMap {
38179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.orgpublic:
39179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  /// \brief Describes a module or submodule.
40179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  struct Module {
41179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief The name of this module.
42179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    std::string Name;
43179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
44179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief The location of the module definition.
45179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    SourceLocation DefinitionLoc;
46179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
47179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief The parent of this module. This will be NULL for the top-level
48179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// module.
49179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Module *Parent;
50179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
51179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief The umbrella header, if any.
52179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ///
53179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// Only the top-level module can have an umbrella header.
54179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    const FileEntry *UmbrellaHeader;
55179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
56179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief The submodules of this module, indexed by name.
57179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    llvm::StringMap<Module *> SubModules;
58179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
59179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief The headers that are part of this module.
60179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    llvm::SmallVector<const FileEntry *, 2> Headers;
61179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
62179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Whether this is a framework module.
63179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    bool IsFramework;
64179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
65179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Whether this is an explicit submodule.
66179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    bool IsExplicit;
67179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
68179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Construct a top-level module.
69179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    explicit Module(StringRef Name, SourceLocation DefinitionLoc,
70179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org                    bool IsFramework)
71179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), UmbrellaHeader(0),
72179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        IsFramework(IsFramework), IsExplicit(false) { }
73179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
74179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Construct  a new module or submodule.
75179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
76179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org           bool IsFramework, bool IsExplicit)
77179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
78179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        UmbrellaHeader(0), IsFramework(IsFramework), IsExplicit(IsExplicit) {
79179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
80179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
81179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ~Module();
82179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
83179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Determine whether this module is a submodule.
84179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    bool isSubModule() const { return Parent != 0; }
85179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
86179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Determine whether this module is a part of a framework,
87179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// either because it is a framework module or because it is a submodule
88179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// of a framework module.
89179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    bool isPartOfFramework() const {
90179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      for (const Module *Mod = this; Mod; Mod = Mod->Parent)
91179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org        if (Mod->IsFramework)
92179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org          return true;
93179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
94179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org      return false;
95179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    }
96179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
97179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Retrieve the full name of this module, including the path from
98179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// its top-level module.
99179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    std::string getFullModuleName() const;
100179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
101179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Retrieve the name of the top-level module.
102179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ///
103179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    StringRef getTopLevelModuleName() const;
104179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
105179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Print the module map for this module to the given stream.
106179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    ///
107179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    void print(llvm::raw_ostream &OS, unsigned Indent = 0) const;
10845b9940be332834440bd5299419f396e38085ebehans@chromium.org
109179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    /// \brief Dump the contents of this module to the given output stream.
110179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org    void dump() const;
111179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org  };
112179be588c25dccaa963df9c9c104fc6229435483jorlow@chromium.org
113private:
114  SourceManager *SourceMgr;
115  llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
116  LangOptions LangOpts;
117
118  /// \brief The top-level modules that are known.
119  llvm::StringMap<Module *> Modules;
120
121  /// \brief Mapping from each header to the module that owns the contents of the
122  /// that header.
123  llvm::DenseMap<const FileEntry *, Module *> Headers;
124
125  /// \brief Mapping from directories with umbrella headers to the module
126  /// that is generated from the umbrella header.
127  ///
128  /// This mapping is used to map headers that haven't explicitly been named
129  /// in the module map over to the module that includes them via its umbrella
130  /// header.
131  llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
132
133  friend class ModuleMapParser;
134
135public:
136  /// \brief Construct a new module map.
137  ///
138  /// \param FileMgr The file manager used to find module files and headers.
139  /// This file manager should be shared with the header-search mechanism, since
140  /// they will refer to the same headers.
141  ///
142  /// \param DC A diagnostic consumer that will be cloned for use in generating
143  /// diagnostics.
144  ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC);
145
146  /// \brief Destroy the module map.
147  ///
148  ~ModuleMap();
149
150  /// \brief Retrieve the module that owns the given header file, if any.
151  ///
152  /// \param File The header file that is likely to be included.
153  ///
154  /// \returns The module that owns the given header file, or null to indicate
155  /// that no module owns this header file.
156  Module *findModuleForHeader(const FileEntry *File);
157
158  /// \brief Retrieve a module with the given name.
159  ///
160  /// \param The name of the module to look up.
161  ///
162  /// \returns The named module, if known; otherwise, returns null.
163  Module *findModule(StringRef Name);
164
165  /// \brief Find a new module or submodule, or create it if it does not already
166  /// exist.
167  ///
168  /// \param Name The name of the module to find or create.
169  ///
170  /// \param Parent The module that will act as the parent of this submodule,
171  /// or NULL to indicate that this is a top-level module.
172  ///
173  /// \param IsFramework Whether this is a framework module.
174  ///
175  /// \param IsExplicit Whether this is an explicit submodule.
176  ///
177  /// \returns The found or newly-created module, along with a boolean value
178  /// that will be true if the module is newly-created.
179  std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,
180                                               bool IsFramework,
181                                               bool IsExplicit);
182
183  /// \brief Infer the contents of a framework module map from the given
184  /// framework directory.
185  Module *inferFrameworkModule(StringRef ModuleName,
186                               const DirectoryEntry *FrameworkDir);
187
188  /// \brief Retrieve the module map file containing the definition of the given
189  /// module.
190  ///
191  /// \param Module The module whose module map file will be returned, if known.
192  ///
193  /// \returns The file entry for the module map file containing the given
194  /// module, or NULL if the module definition was inferred.
195  const FileEntry *getContainingModuleMapFile(ModuleMap::Module *Module);
196
197  /// \brief Parse the given module map file, and record any modules we
198  /// encounter.
199  ///
200  /// \param File The file to be parsed.
201  ///
202  /// \returns true if an error occurred, false otherwise.
203  bool parseModuleMapFile(const FileEntry *File);
204
205  /// \brief Dump the contents of the module map, for debugging purposes.
206  void dump();
207};
208
209}
210#endif
211