clang  3.7.0
Basic/Module.cpp
Go to the documentation of this file.
1 //===--- Module.cpp - Describe a module -----------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the Module class, which describes a module in the source
11 // code.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/Basic/Module.h"
18 #include "clang/Basic/TargetInfo.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/Support/ErrorHandling.h"
23 #include "llvm/Support/raw_ostream.h"
24 
25 using namespace clang;
26 
27 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
28  bool IsFramework, bool IsExplicit, unsigned VisibilityID)
29  : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
30  Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID),
31  IsMissingRequirement(false), IsAvailable(true), IsFromModuleFile(false),
32  IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false),
33  IsExternC(false), IsInferred(false), InferSubmodules(false),
34  InferExplicitSubmodules(false), InferExportWildcard(false),
35  ConfigMacrosExhaustive(false), NameVisibility(Hidden) {
36  if (Parent) {
37  if (!Parent->isAvailable())
38  IsAvailable = false;
39  if (Parent->IsSystem)
40  IsSystem = true;
41  if (Parent->IsExternC)
42  IsExternC = true;
44 
45  Parent->SubModuleIndex[Name] = Parent->SubModules.size();
46  Parent->SubModules.push_back(this);
47  }
48 }
49 
52  I != IEnd; ++I) {
53  delete *I;
54  }
55 }
56 
57 /// \brief Determine whether a translation unit built using the current
58 /// language options has the given feature.
59 static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
60  const TargetInfo &Target) {
61  bool HasFeature = llvm::StringSwitch<bool>(Feature)
62  .Case("altivec", LangOpts.AltiVec)
63  .Case("blocks", LangOpts.Blocks)
64  .Case("cplusplus", LangOpts.CPlusPlus)
65  .Case("cplusplus11", LangOpts.CPlusPlus11)
66  .Case("objc", LangOpts.ObjC1)
67  .Case("objc_arc", LangOpts.ObjCAutoRefCount)
68  .Case("opencl", LangOpts.OpenCL)
69  .Case("tls", Target.isTLSSupported())
70  .Case("zvector", LangOpts.ZVector)
71  .Default(Target.hasFeature(Feature));
72  if (!HasFeature)
73  HasFeature = std::find(LangOpts.ModuleFeatures.begin(),
74  LangOpts.ModuleFeatures.end(),
75  Feature) != LangOpts.ModuleFeatures.end();
76  return HasFeature;
77 }
78 
79 bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
80  Requirement &Req,
81  UnresolvedHeaderDirective &MissingHeader) const {
82  if (IsAvailable)
83  return true;
84 
85  for (const Module *Current = this; Current; Current = Current->Parent) {
86  for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
87  if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
88  Current->Requirements[I].second) {
89  Req = Current->Requirements[I];
90  return false;
91  }
92  }
93  if (!Current->MissingHeaders.empty()) {
94  MissingHeader = Current->MissingHeaders.front();
95  return false;
96  }
97  }
98 
99  llvm_unreachable("could not find a reason why module is unavailable");
100 }
101 
102 bool Module::isSubModuleOf(const Module *Other) const {
103  const Module *This = this;
104  do {
105  if (This == Other)
106  return true;
107 
108  This = This->Parent;
109  } while (This);
110 
111  return false;
112 }
113 
115  const Module *Result = this;
116  while (Result->Parent)
117  Result = Result->Parent;
118 
119  return Result;
120 }
121 
122 std::string Module::getFullModuleName() const {
124 
125  // Build up the set of module names (from innermost to outermost).
126  for (const Module *M = this; M; M = M->Parent)
127  Names.push_back(M->Name);
128 
129  std::string Result;
130  for (SmallVectorImpl<StringRef>::reverse_iterator I = Names.rbegin(),
131  IEnd = Names.rend();
132  I != IEnd; ++I) {
133  if (!Result.empty())
134  Result += '.';
135 
136  Result += *I;
137  }
138 
139  return Result;
140 }
141 
143  if (Header U = getUmbrellaHeader())
144  return {"", U.Entry->getDir()};
145 
146  return {UmbrellaAsWritten, Umbrella.dyn_cast<const DirectoryEntry *>()};
147 }
148 
150  if (!TopHeaderNames.empty()) {
151  for (std::vector<std::string>::iterator
152  I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I) {
153  if (const FileEntry *FE = FileMgr.getFile(*I))
154  TopHeaders.insert(FE);
155  }
156  TopHeaderNames.clear();
157  }
158 
159  return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end());
160 }
161 
162 bool Module::directlyUses(const Module *Requested) const {
163  auto *Top = getTopLevelModule();
164 
165  // A top-level module implicitly uses itself.
166  if (Requested->isSubModuleOf(Top))
167  return true;
168 
169  for (auto *Use : Top->DirectUses)
170  if (Requested->isSubModuleOf(Use))
171  return true;
172  return false;
173 }
174 
175 void Module::addRequirement(StringRef Feature, bool RequiredState,
176  const LangOptions &LangOpts,
177  const TargetInfo &Target) {
178  Requirements.push_back(Requirement(Feature, RequiredState));
179 
180  // If this feature is currently available, we're done.
181  if (hasFeature(Feature, LangOpts, Target) == RequiredState)
182  return;
183 
184  markUnavailable(/*MissingRequirement*/true);
185 }
186 
187 void Module::markUnavailable(bool MissingRequirement) {
188  auto needUpdate = [MissingRequirement](Module *M) {
189  return M->IsAvailable || (!M->IsMissingRequirement && MissingRequirement);
190  };
191 
192  if (!needUpdate(this))
193  return;
194 
196  Stack.push_back(this);
197  while (!Stack.empty()) {
198  Module *Current = Stack.back();
199  Stack.pop_back();
200 
201  if (!needUpdate(Current))
202  continue;
203 
204  Current->IsAvailable = false;
205  Current->IsMissingRequirement |= MissingRequirement;
206  for (submodule_iterator Sub = Current->submodule_begin(),
207  SubEnd = Current->submodule_end();
208  Sub != SubEnd; ++Sub) {
209  if (needUpdate(*Sub))
210  Stack.push_back(*Sub);
211  }
212  }
213 }
214 
215 Module *Module::findSubmodule(StringRef Name) const {
216  llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
217  if (Pos == SubModuleIndex.end())
218  return nullptr;
219 
220  return SubModules[Pos->getValue()];
221 }
222 
223 static void printModuleId(raw_ostream &OS, const ModuleId &Id) {
224  for (unsigned I = 0, N = Id.size(); I != N; ++I) {
225  if (I)
226  OS << ".";
227  OS << Id[I].first;
228  }
229 }
230 
232  // All non-explicit submodules are exported.
233  for (std::vector<Module *>::const_iterator I = SubModules.begin(),
234  E = SubModules.end();
235  I != E; ++I) {
236  Module *Mod = *I;
237  if (!Mod->IsExplicit)
238  Exported.push_back(Mod);
239  }
240 
241  // Find re-exported modules by filtering the list of imported modules.
242  bool AnyWildcard = false;
243  bool UnrestrictedWildcard = false;
244  SmallVector<Module *, 4> WildcardRestrictions;
245  for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
246  Module *Mod = Exports[I].getPointer();
247  if (!Exports[I].getInt()) {
248  // Export a named module directly; no wildcards involved.
249  Exported.push_back(Mod);
250 
251  continue;
252  }
253 
254  // Wildcard export: export all of the imported modules that match
255  // the given pattern.
256  AnyWildcard = true;
257  if (UnrestrictedWildcard)
258  continue;
259 
260  if (Module *Restriction = Exports[I].getPointer())
261  WildcardRestrictions.push_back(Restriction);
262  else {
263  WildcardRestrictions.clear();
264  UnrestrictedWildcard = true;
265  }
266  }
267 
268  // If there were any wildcards, push any imported modules that were
269  // re-exported by the wildcard restriction.
270  if (!AnyWildcard)
271  return;
272 
273  for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
274  Module *Mod = Imports[I];
275  bool Acceptable = UnrestrictedWildcard;
276  if (!Acceptable) {
277  // Check whether this module meets one of the restrictions.
278  for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
279  Module *Restriction = WildcardRestrictions[R];
280  if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
281  Acceptable = true;
282  break;
283  }
284  }
285  }
286 
287  if (!Acceptable)
288  continue;
289 
290  Exported.push_back(Mod);
291  }
292 }
293 
294 void Module::buildVisibleModulesCache() const {
295  assert(VisibleModulesCache.empty() && "cache does not need building");
296 
297  // This module is visible to itself.
298  VisibleModulesCache.insert(this);
299 
300  // Every imported module is visible.
302  while (!Stack.empty()) {
303  Module *CurrModule = Stack.pop_back_val();
304 
305  // Every module transitively exported by an imported module is visible.
306  if (VisibleModulesCache.insert(CurrModule).second)
307  CurrModule->getExportedModules(Stack);
308  }
309 }
310 
311 void Module::print(raw_ostream &OS, unsigned Indent) const {
312  OS.indent(Indent);
313  if (IsFramework)
314  OS << "framework ";
315  if (IsExplicit)
316  OS << "explicit ";
317  OS << "module " << Name;
318 
319  if (IsSystem || IsExternC) {
320  OS.indent(Indent + 2);
321  if (IsSystem)
322  OS << " [system]";
323  if (IsExternC)
324  OS << " [extern_c]";
325  }
326 
327  OS << " {\n";
328 
329  if (!Requirements.empty()) {
330  OS.indent(Indent + 2);
331  OS << "requires ";
332  for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
333  if (I)
334  OS << ", ";
335  if (!Requirements[I].second)
336  OS << "!";
337  OS << Requirements[I].first;
338  }
339  OS << "\n";
340  }
341 
342  if (Header H = getUmbrellaHeader()) {
343  OS.indent(Indent + 2);
344  OS << "umbrella header \"";
345  OS.write_escaped(H.NameAsWritten);
346  OS << "\"\n";
347  } else if (DirectoryName D = getUmbrellaDir()) {
348  OS.indent(Indent + 2);
349  OS << "umbrella \"";
350  OS.write_escaped(D.NameAsWritten);
351  OS << "\"\n";
352  }
353 
354  if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
355  OS.indent(Indent + 2);
356  OS << "config_macros ";
358  OS << "[exhaustive]";
359  for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
360  if (I)
361  OS << ", ";
362  OS << ConfigMacros[I];
363  }
364  OS << "\n";
365  }
366 
367  struct {
368  StringRef Prefix;
370  } Kinds[] = {{"", HK_Normal},
371  {"textual ", HK_Textual},
372  {"private ", HK_Private},
373  {"private textual ", HK_PrivateTextual},
374  {"exclude ", HK_Excluded}};
375 
376  for (auto &K : Kinds) {
377  for (auto &H : Headers[K.Kind]) {
378  OS.indent(Indent + 2);
379  OS << K.Prefix << "header \"";
380  OS.write_escaped(H.NameAsWritten);
381  OS << "\"\n";
382  }
383  }
384 
386  MI != MIEnd; ++MI)
387  // Print inferred subframework modules so that we don't need to re-infer
388  // them (requires expensive directory iteration + stat calls) when we build
389  // the module. Regular inferred submodules are OK, as we need to look at all
390  // those header files anyway.
391  if (!(*MI)->IsInferred || (*MI)->IsFramework)
392  (*MI)->print(OS, Indent + 2);
393 
394  for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
395  OS.indent(Indent + 2);
396  OS << "export ";
397  if (Module *Restriction = Exports[I].getPointer()) {
398  OS << Restriction->getFullModuleName();
399  if (Exports[I].getInt())
400  OS << ".*";
401  } else {
402  OS << "*";
403  }
404  OS << "\n";
405  }
406 
407  for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
408  OS.indent(Indent + 2);
409  OS << "export ";
410  printModuleId(OS, UnresolvedExports[I].Id);
411  if (UnresolvedExports[I].Wildcard) {
412  if (UnresolvedExports[I].Id.empty())
413  OS << "*";
414  else
415  OS << ".*";
416  }
417  OS << "\n";
418  }
419 
420  for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
421  OS.indent(Indent + 2);
422  OS << "use ";
423  OS << DirectUses[I]->getFullModuleName();
424  OS << "\n";
425  }
426 
427  for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
428  OS.indent(Indent + 2);
429  OS << "use ";
431  OS << "\n";
432  }
433 
434  for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
435  OS.indent(Indent + 2);
436  OS << "link ";
437  if (LinkLibraries[I].IsFramework)
438  OS << "framework ";
439  OS << "\"";
440  OS.write_escaped(LinkLibraries[I].Library);
441  OS << "\"";
442  }
443 
444  for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
445  OS.indent(Indent + 2);
446  OS << "conflict ";
448  OS << ", \"";
449  OS.write_escaped(UnresolvedConflicts[I].Message);
450  OS << "\"\n";
451  }
452 
453  for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
454  OS.indent(Indent + 2);
455  OS << "conflict ";
456  OS << Conflicts[I].Other->getFullModuleName();
457  OS << ", \"";
458  OS.write_escaped(Conflicts[I].Message);
459  OS << "\"\n";
460  }
461 
462  if (InferSubmodules) {
463  OS.indent(Indent + 2);
465  OS << "explicit ";
466  OS << "module * {\n";
467  if (InferExportWildcard) {
468  OS.indent(Indent + 4);
469  OS << "export *\n";
470  }
471  OS.indent(Indent + 2);
472  OS << "}\n";
473  }
474 
475  OS.indent(Indent);
476  OS << "}\n";
477 }
478 
479 void Module::dump() const {
480  print(llvm::errs());
481 }
482 
485  if (isVisible(M))
486  return;
487 
488  ++Generation;
489 
490  struct Visiting {
491  Module *M;
492  Visiting *ExportedBy;
493  };
494 
495  std::function<void(Visiting)> VisitModule = [&](Visiting V) {
496  // Modules that aren't available cannot be made visible.
497  if (!V.M->isAvailable())
498  return;
499 
500  // Nothing to do for a module that's already visible.
501  unsigned ID = V.M->getVisibilityID();
502  if (ImportLocs.size() <= ID)
503  ImportLocs.resize(ID + 1);
504  else if (ImportLocs[ID].isValid())
505  return;
506 
507  ImportLocs[ID] = Loc;
508  Vis(M);
509 
510  // Make any exported modules visible.
512  V.M->getExportedModules(Exports);
513  for (Module *E : Exports)
514  VisitModule({E, &V});
515 
516  for (auto &C : V.M->Conflicts) {
517  if (isVisible(C.Other)) {
519  for (Visiting *I = &V; I; I = I->ExportedBy)
520  Path.push_back(I->M);
521  Cb(Path, C.Other, C.Message);
522  }
523  }
524  };
525  VisitModule({M, nullptr});
526 }
unsigned IsAvailable
Whether this module is available in the current translation unit.
Definition: Basic/Module.h:159
SmallVector< UnresolvedExportDecl, 2 > UnresolvedExports
The set of export declarations that have yet to be resolved.
Definition: Basic/Module.h:247
std::string Name
The name of this module.
Definition: Basic/Module.h:52
Header getUmbrellaHeader() const
Retrieve the header that serves as the umbrella header for this module.
Definition: Basic/Module.h:394
Implements support for file system lookup, file system caching, and directory search management...
Definition: FileManager.h:115
Defines the clang::FileManager interface and associated types.
submodule_iterator submodule_begin()
Definition: Basic/Module.h:467
unsigned IsExternC
Whether this is an 'extern "C"' module (which implicitly puts all headers in it within an 'extern "...
Definition: Basic/Module.h:177
std::vector< UnresolvedConflict > UnresolvedConflicts
The list of conflicts for which the module-id has not yet been resolved.
Definition: Basic/Module.h:291
Module * getTopLevelModule()
Retrieve the top-level module for this (sub)module, which may be this module.
Definition: Basic/Module.h:361
Defines the clang::Module class, which describes a module in the source code.
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target)
Determine whether a translation unit built using the current language options has the given feature...
unsigned IsFramework
Whether this is a framework module.
Definition: Basic/Module.h:165
void addRequirement(StringRef Feature, bool RequiredState, const LangOptions &LangOpts, const TargetInfo &Target)
Add the given feature requirement to the list of features required by this module.
void getExportedModules(SmallVectorImpl< Module * > &Exported) const
Appends this module's list of exported modules to Exported.
llvm::function_ref< void(Module *M)> VisibleCallback
A callback to call when a module is made visible (directly or indirectly) by a call to setVisible...
Definition: Basic/Module.h:531
void markUnavailable(bool MissingRequirement=false)
Mark this module and all of its submodules as unavailable.
std::string getFullModuleName() const
Retrieve the full name of this module, including the path from its top-level module.
SmallVector< Requirement, 2 > Requirements
The set of language features required to use this module.
Definition: Basic/Module.h:150
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
Describes a module or submodule.
Definition: Basic/Module.h:49
bool directlyUses(const Module *Requested) const
Determine whether this module has declared its intention to directly use another module.
unsigned InferExportWildcard
Whether, when inferring submodules, the inferr submodules should export all modules they import (e...
Definition: Basic/Module.h:194
bool isAvailable() const
Determine whether this module is available for use within the current translation unit...
Definition: Basic/Module.h:313
Module * Parent
The parent of this module. This will be NULL for the top-level module.
Definition: Basic/Module.h:59
submodule_iterator submodule_end()
Definition: Basic/Module.h:469
std::vector< Module * >::iterator submodule_iterator
Definition: Basic/Module.h:464
std::vector< std::string > ModuleFeatures
The names of any features to enable in module 'requires' decls in addition to the hard-coded list in ...
Definition: LangOptions.h:107
unsigned IsSystem
Whether this is a "system" module (which assumes that all headers in it are system headers)...
Definition: Basic/Module.h:172
const FileEntry * getFile(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Lookup, cache, and verify the specified file (real or virtual).
Module * findSubmodule(StringRef Name) const
Find the submodule with the given name.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
Definition: Basic/Module.h:220
static void printModuleId(raw_ostream &OS, const ModuleId &Id)
std::vector< bool > & Stack
ID
Defines the set of possible language-specific address spaces.
Definition: AddressSpaces.h:27
const DirectoryEntry * Entry
Definition: Basic/Module.h:122
void setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis=[](Module *){}, ConflictCallback Cb=[](ArrayRef< Module * >, Module *, StringRef){})
Make a specific module visible.
void dump() const
Dump the contents of this module to the given output stream.
Exposes information about the current target.
Defines the clang::LangOptions interface.
SmallVector< ModuleId, 2 > UnresolvedDirectUses
The set of use declarations that have yet to be resolved.
Definition: Basic/Module.h:253
unsigned ConfigMacrosExhaustive
Whether the set of configuration macros is exhaustive.
Definition: Basic/Module.h:201
ArrayRef< const FileEntry * > getTopHeaders(FileManager &FileMgr)
The top-level headers associated with this module.
llvm::SmallVector< LinkLibrary, 2 > LinkLibraries
The set of libraries or frameworks to link against when an entity from this module is used...
Definition: Basic/Module.h:274
Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID)
Construct a new module or submodule.
SmallVector< std::pair< std::string, SourceLocation >, 2 > ModuleId
Describes the name of a module.
Definition: Basic/Module.h:43
bool isSubModuleOf(const Module *Other) const
Determine whether this module is a submodule of the given other module.
std::vector< Module * >::const_iterator submodule_const_iterator
Definition: Basic/Module.h:465
static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II)
DirectoryName getUmbrellaDir() const
Retrieve the directory for which this module serves as the umbrella.
Information about a header directive as found in the module map file.
Definition: Basic/Module.h:111
The result type of a method or function.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
Definition: Basic/Module.h:229
#define false
Definition: stdbool.h:33
Kind
void print(raw_ostream &OS, unsigned Indent=0) const
Print the module map for this module to the given stream.
Encodes a location in the source. The SourceManager can decode this to get at the full include stack...
Information about a directory name as found in the module map file.
Definition: Basic/Module.h:120
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:53
SmallVector< Header, 2 > Headers[5]
The headers that are part of this module.
Definition: Basic/Module.h:128
unsigned IsMissingRequirement
Whether this module is missing a feature from Requirements.
Definition: Basic/Module.h:153
Stored information about a header directive that was found in the module map file but has not been re...
Definition: Basic/Module.h:132
llvm::PointerUnion< const DirectoryEntry *, const FileEntry * > Umbrella
The umbrella header or directory.
Definition: Basic/Module.h:67
llvm::function_ref< void(ArrayRef< Module * > Path, Module *Conflict, StringRef Message)> ConflictCallback
A callback to call when a module conflict is found. Path consists of a sequence of modules from the c...
Definition: Basic/Module.h:537
std::vector< Conflict > Conflicts
The list of conflicts.
Definition: Basic/Module.h:303
SmallVector< Module *, 2 > DirectUses
The directly used modules.
Definition: Basic/Module.h:250
std::pair< std::string, bool > Requirement
An individual requirement: a feature name and a flag indicating the required state of that feature...
Definition: Basic/Module.h:144
Cached information about one directory (either on disk or in the virtual file system).
Definition: FileManager.h:40
bool isTLSSupported() const
Whether the target supports thread-local storage.
FormatToken * Current
unsigned InferSubmodules
Whether we should infer submodules for this module based on the headers.
Definition: Basic/Module.h:186
Defines the clang::TargetInfo interface.
std::vector< std::string > ConfigMacros
The set of "configuration macros", which are macros that (intentionally) change how this module is bu...
Definition: Basic/Module.h:278
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
std::string UmbrellaAsWritten
The name of the umbrella entry, as written in the module map.
Definition: Basic/Module.h:73
#define true
Definition: stdbool.h:32
unsigned IsExplicit
Whether this is an explicit submodule.
Definition: Basic/Module.h:168
unsigned InferExplicitSubmodules
Whether, when inferring submodules, the inferred submodules should be explicit.
Definition: Basic/Module.h:190
unsigned Indent
The current line's indent.