llvm-project

Форк
0
726 строк · 22.5 Кб
1
//===- Module.cpp - Describe a module -------------------------------------===//
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
// This file defines the Module class, which describes a module in the source
10
// code.
11
//
12
//===----------------------------------------------------------------------===//
13

14
#include "clang/Basic/Module.h"
15
#include "clang/Basic/CharInfo.h"
16
#include "clang/Basic/FileManager.h"
17
#include "clang/Basic/LangOptions.h"
18
#include "clang/Basic/SourceLocation.h"
19
#include "clang/Basic/TargetInfo.h"
20
#include "llvm/ADT/ArrayRef.h"
21
#include "llvm/ADT/SmallVector.h"
22
#include "llvm/ADT/StringMap.h"
23
#include "llvm/ADT/StringRef.h"
24
#include "llvm/ADT/StringSwitch.h"
25
#include "llvm/Support/Compiler.h"
26
#include "llvm/Support/ErrorHandling.h"
27
#include "llvm/Support/raw_ostream.h"
28
#include <algorithm>
29
#include <cassert>
30
#include <functional>
31
#include <string>
32
#include <utility>
33
#include <vector>
34

35
using namespace clang;
36

37
Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
38
               bool IsFramework, bool IsExplicit, unsigned VisibilityID)
39
    : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
40
      VisibilityID(VisibilityID), IsUnimportable(false),
41
      HasIncompatibleModuleFile(false), IsAvailable(true),
42
      IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit),
43
      IsSystem(false), IsExternC(false), IsInferred(false),
44
      InferSubmodules(false), InferExplicitSubmodules(false),
45
      InferExportWildcard(false), ConfigMacrosExhaustive(false),
46
      NoUndeclaredIncludes(false), ModuleMapIsPrivate(false),
47
      NamedModuleHasInit(true), NameVisibility(Hidden) {
48
  if (Parent) {
49
    IsAvailable = Parent->isAvailable();
50
    IsUnimportable = Parent->isUnimportable();
51
    IsSystem = Parent->IsSystem;
52
    IsExternC = Parent->IsExternC;
53
    NoUndeclaredIncludes = Parent->NoUndeclaredIncludes;
54
    ModuleMapIsPrivate = Parent->ModuleMapIsPrivate;
55

56
    Parent->SubModuleIndex[Name] = Parent->SubModules.size();
57
    Parent->SubModules.push_back(this);
58
  }
59
}
60

61
Module::~Module() {
62
  for (auto *Submodule : SubModules) {
63
    delete Submodule;
64
  }
65
}
66

67
static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) {
68
  StringRef Platform = Target.getPlatformName();
69
  StringRef Env = Target.getTriple().getEnvironmentName();
70

71
  // Attempt to match platform and environment.
72
  if (Platform == Feature || Target.getTriple().getOSName() == Feature ||
73
      Env == Feature)
74
    return true;
75

76
  auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) {
77
    auto Pos = LHS.find('-');
78
    if (Pos == StringRef::npos)
79
      return false;
80
    SmallString<128> NewLHS = LHS.slice(0, Pos);
81
    NewLHS += LHS.slice(Pos+1, LHS.size());
82
    return NewLHS == RHS;
83
  };
84

85
  SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName();
86
  // Darwin has different but equivalent variants for simulators, example:
87
  //   1. x86_64-apple-ios-simulator
88
  //   2. x86_64-apple-iossimulator
89
  // where both are valid examples of the same platform+environment but in the
90
  // variant (2) the simulator is hardcoded as part of the platform name. Both
91
  // forms above should match for "iossimulator" requirement.
92
  if (Target.getTriple().isOSDarwin() && PlatformEnv.ends_with("simulator"))
93
    return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature);
94

95
  return PlatformEnv == Feature;
96
}
97

98
/// Determine whether a translation unit built using the current
99
/// language options has the given feature.
100
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts,
101
                       const TargetInfo &Target) {
102
  bool HasFeature = llvm::StringSwitch<bool>(Feature)
103
                        .Case("altivec", LangOpts.AltiVec)
104
                        .Case("blocks", LangOpts.Blocks)
105
                        .Case("coroutines", LangOpts.Coroutines)
106
                        .Case("cplusplus", LangOpts.CPlusPlus)
107
                        .Case("cplusplus11", LangOpts.CPlusPlus11)
108
                        .Case("cplusplus14", LangOpts.CPlusPlus14)
109
                        .Case("cplusplus17", LangOpts.CPlusPlus17)
110
                        .Case("cplusplus20", LangOpts.CPlusPlus20)
111
                        .Case("cplusplus23", LangOpts.CPlusPlus23)
112
                        .Case("cplusplus26", LangOpts.CPlusPlus26)
113
                        .Case("c99", LangOpts.C99)
114
                        .Case("c11", LangOpts.C11)
115
                        .Case("c17", LangOpts.C17)
116
                        .Case("c23", LangOpts.C23)
117
                        .Case("freestanding", LangOpts.Freestanding)
118
                        .Case("gnuinlineasm", LangOpts.GNUAsm)
119
                        .Case("objc", LangOpts.ObjC)
120
                        .Case("objc_arc", LangOpts.ObjCAutoRefCount)
121
                        .Case("opencl", LangOpts.OpenCL)
122
                        .Case("tls", Target.isTLSSupported())
123
                        .Case("zvector", LangOpts.ZVector)
124
                        .Default(Target.hasFeature(Feature) ||
125
                                 isPlatformEnvironment(Target, Feature));
126
  if (!HasFeature)
127
    HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature);
128
  return HasFeature;
129
}
130

131
bool Module::isUnimportable(const LangOptions &LangOpts,
132
                            const TargetInfo &Target, Requirement &Req,
133
                            Module *&ShadowingModule) const {
134
  if (!IsUnimportable)
135
    return false;
136

137
  for (const Module *Current = this; Current; Current = Current->Parent) {
138
    if (Current->ShadowingModule) {
139
      ShadowingModule = Current->ShadowingModule;
140
      return true;
141
    }
142
    for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
143
      if (hasFeature(Current->Requirements[I].FeatureName, LangOpts, Target) !=
144
          Current->Requirements[I].RequiredState) {
145
        Req = Current->Requirements[I];
146
        return true;
147
      }
148
    }
149
  }
150

151
  llvm_unreachable("could not find a reason why module is unimportable");
152
}
153

154
// The -fmodule-name option tells the compiler to textually include headers in
155
// the specified module, meaning Clang won't build the specified module. This
156
// is useful in a number of situations, for instance, when building a library
157
// that vends a module map, one might want to avoid hitting intermediate build
158
// products containing the module map or avoid finding the system installed
159
// modulemap for that library.
160
bool Module::isForBuilding(const LangOptions &LangOpts) const {
161
  StringRef TopLevelName = getTopLevelModuleName();
162
  StringRef CurrentModule = LangOpts.CurrentModule;
163

164
  // When building the implementation of framework Foo, we want to make sure
165
  // that Foo *and* Foo_Private are textually included and no modules are built
166
  // for either.
167
  if (!LangOpts.isCompilingModule() && getTopLevelModule()->IsFramework &&
168
      CurrentModule == LangOpts.ModuleName &&
169
      !CurrentModule.ends_with("_Private") &&
170
      TopLevelName.ends_with("_Private"))
171
    TopLevelName = TopLevelName.drop_back(8);
172

173
  return TopLevelName == CurrentModule;
174
}
175

176
bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
177
                         Requirement &Req,
178
                         UnresolvedHeaderDirective &MissingHeader,
179
                         Module *&ShadowingModule) const {
180
  if (IsAvailable)
181
    return true;
182

183
  if (isUnimportable(LangOpts, Target, Req, ShadowingModule))
184
    return false;
185

186
  // FIXME: All missing headers are listed on the top-level module. Should we
187
  // just look there?
188
  for (const Module *Current = this; Current; Current = Current->Parent) {
189
    if (!Current->MissingHeaders.empty()) {
190
      MissingHeader = Current->MissingHeaders.front();
191
      return false;
192
    }
193
  }
194

195
  llvm_unreachable("could not find a reason why module is unavailable");
196
}
197

198
bool Module::isSubModuleOf(const Module *Other) const {
199
  for (auto *Parent = this; Parent; Parent = Parent->Parent) {
200
    if (Parent == Other)
201
      return true;
202
  }
203
  return false;
204
}
205

206
const Module *Module::getTopLevelModule() const {
207
  const Module *Result = this;
208
  while (Result->Parent)
209
    Result = Result->Parent;
210

211
  return Result;
212
}
213

214
static StringRef getModuleNameFromComponent(
215
    const std::pair<std::string, SourceLocation> &IdComponent) {
216
  return IdComponent.first;
217
}
218

219
static StringRef getModuleNameFromComponent(StringRef R) { return R; }
220

221
template<typename InputIter>
222
static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End,
223
                          bool AllowStringLiterals = true) {
224
  for (InputIter It = Begin; It != End; ++It) {
225
    if (It != Begin)
226
      OS << ".";
227

228
    StringRef Name = getModuleNameFromComponent(*It);
229
    if (!AllowStringLiterals || isValidAsciiIdentifier(Name))
230
      OS << Name;
231
    else {
232
      OS << '"';
233
      OS.write_escaped(Name);
234
      OS << '"';
235
    }
236
  }
237
}
238

239
template<typename Container>
240
static void printModuleId(raw_ostream &OS, const Container &C) {
241
  return printModuleId(OS, C.begin(), C.end());
242
}
243

244
std::string Module::getFullModuleName(bool AllowStringLiterals) const {
245
  SmallVector<StringRef, 2> Names;
246

247
  // Build up the set of module names (from innermost to outermost).
248
  for (const Module *M = this; M; M = M->Parent)
249
    Names.push_back(M->Name);
250

251
  std::string Result;
252

253
  llvm::raw_string_ostream Out(Result);
254
  printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals);
255
  Out.flush();
256

257
  return Result;
258
}
259

260
bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const {
261
  for (const Module *M = this; M; M = M->Parent) {
262
    if (nameParts.empty() || M->Name != nameParts.back())
263
      return false;
264
    nameParts = nameParts.drop_back();
265
  }
266
  return nameParts.empty();
267
}
268

269
OptionalDirectoryEntryRef Module::getEffectiveUmbrellaDir() const {
270
  if (const auto *Hdr = std::get_if<FileEntryRef>(&Umbrella))
271
    return Hdr->getDir();
272
  if (const auto *Dir = std::get_if<DirectoryEntryRef>(&Umbrella))
273
    return *Dir;
274
  return std::nullopt;
275
}
276

277
void Module::addTopHeader(FileEntryRef File) {
278
  assert(File);
279
  TopHeaders.insert(File);
280
}
281

282
ArrayRef<FileEntryRef> Module::getTopHeaders(FileManager &FileMgr) {
283
  if (!TopHeaderNames.empty()) {
284
    for (StringRef TopHeaderName : TopHeaderNames)
285
      if (auto FE = FileMgr.getOptionalFileRef(TopHeaderName))
286
        TopHeaders.insert(*FE);
287
    TopHeaderNames.clear();
288
  }
289

290
  return llvm::ArrayRef(TopHeaders.begin(), TopHeaders.end());
291
}
292

293
bool Module::directlyUses(const Module *Requested) {
294
  auto *Top = getTopLevelModule();
295

296
  // A top-level module implicitly uses itself.
297
  if (Requested->isSubModuleOf(Top))
298
    return true;
299

300
  for (auto *Use : Top->DirectUses)
301
    if (Requested->isSubModuleOf(Use))
302
      return true;
303

304
  // Anyone is allowed to use our builtin stddef.h and its accompanying modules.
305
  if (Requested->fullModuleNameIs({"_Builtin_stddef", "max_align_t"}) ||
306
      Requested->fullModuleNameIs({"_Builtin_stddef_wint_t"}))
307
    return true;
308
  // Darwin is allowed is to use our builtin 'ptrauth.h' and its accompanying
309
  // module.
310
  if (!Requested->Parent && Requested->Name == "ptrauth")
311
    return true;
312

313
  if (NoUndeclaredIncludes)
314
    UndeclaredUses.insert(Requested);
315

316
  return false;
317
}
318

319
void Module::addRequirement(StringRef Feature, bool RequiredState,
320
                            const LangOptions &LangOpts,
321
                            const TargetInfo &Target) {
322
  Requirements.push_back(Requirement{std::string(Feature), RequiredState});
323

324
  // If this feature is currently available, we're done.
325
  if (hasFeature(Feature, LangOpts, Target) == RequiredState)
326
    return;
327

328
  markUnavailable(/*Unimportable*/true);
329
}
330

331
void Module::markUnavailable(bool Unimportable) {
332
  auto needUpdate = [Unimportable](Module *M) {
333
    return M->IsAvailable || (!M->IsUnimportable && Unimportable);
334
  };
335

336
  if (!needUpdate(this))
337
    return;
338

339
  SmallVector<Module *, 2> Stack;
340
  Stack.push_back(this);
341
  while (!Stack.empty()) {
342
    Module *Current = Stack.back();
343
    Stack.pop_back();
344

345
    if (!needUpdate(Current))
346
      continue;
347

348
    Current->IsAvailable = false;
349
    Current->IsUnimportable |= Unimportable;
350
    for (auto *Submodule : Current->submodules()) {
351
      if (needUpdate(Submodule))
352
        Stack.push_back(Submodule);
353
    }
354
  }
355
}
356

357
Module *Module::findSubmodule(StringRef Name) const {
358
  llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
359
  if (Pos == SubModuleIndex.end())
360
    return nullptr;
361

362
  return SubModules[Pos->getValue()];
363
}
364

365
Module *Module::findOrInferSubmodule(StringRef Name) {
366
  llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name);
367
  if (Pos != SubModuleIndex.end())
368
    return SubModules[Pos->getValue()];
369
  if (!InferSubmodules)
370
    return nullptr;
371
  Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0);
372
  Result->InferExplicitSubmodules = InferExplicitSubmodules;
373
  Result->InferSubmodules = InferSubmodules;
374
  Result->InferExportWildcard = InferExportWildcard;
375
  if (Result->InferExportWildcard)
376
    Result->Exports.push_back(Module::ExportDecl(nullptr, true));
377
  return Result;
378
}
379

380
Module *Module::getGlobalModuleFragment() const {
381
  assert(isNamedModuleUnit() && "We should only query the global module "
382
                                "fragment from the C++20 Named modules");
383

384
  for (auto *SubModule : SubModules)
385
    if (SubModule->isExplicitGlobalModule())
386
      return SubModule;
387

388
  return nullptr;
389
}
390

391
Module *Module::getPrivateModuleFragment() const {
392
  assert(isNamedModuleUnit() && "We should only query the private module "
393
                                "fragment from the C++20 Named modules");
394

395
  for (auto *SubModule : SubModules)
396
    if (SubModule->isPrivateModule())
397
      return SubModule;
398

399
  return nullptr;
400
}
401

402
void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const {
403
  // All non-explicit submodules are exported.
404
  for (std::vector<Module *>::const_iterator I = SubModules.begin(),
405
                                             E = SubModules.end();
406
       I != E; ++I) {
407
    Module *Mod = *I;
408
    if (!Mod->IsExplicit)
409
      Exported.push_back(Mod);
410
  }
411

412
  // Find re-exported modules by filtering the list of imported modules.
413
  bool AnyWildcard = false;
414
  bool UnrestrictedWildcard = false;
415
  SmallVector<Module *, 4> WildcardRestrictions;
416
  for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
417
    Module *Mod = Exports[I].getPointer();
418
    if (!Exports[I].getInt()) {
419
      // Export a named module directly; no wildcards involved.
420
      Exported.push_back(Mod);
421

422
      continue;
423
    }
424

425
    // Wildcard export: export all of the imported modules that match
426
    // the given pattern.
427
    AnyWildcard = true;
428
    if (UnrestrictedWildcard)
429
      continue;
430

431
    if (Module *Restriction = Exports[I].getPointer())
432
      WildcardRestrictions.push_back(Restriction);
433
    else {
434
      WildcardRestrictions.clear();
435
      UnrestrictedWildcard = true;
436
    }
437
  }
438

439
  // If there were any wildcards, push any imported modules that were
440
  // re-exported by the wildcard restriction.
441
  if (!AnyWildcard)
442
    return;
443

444
  for (unsigned I = 0, N = Imports.size(); I != N; ++I) {
445
    Module *Mod = Imports[I];
446
    bool Acceptable = UnrestrictedWildcard;
447
    if (!Acceptable) {
448
      // Check whether this module meets one of the restrictions.
449
      for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
450
        Module *Restriction = WildcardRestrictions[R];
451
        if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) {
452
          Acceptable = true;
453
          break;
454
        }
455
      }
456
    }
457

458
    if (!Acceptable)
459
      continue;
460

461
    Exported.push_back(Mod);
462
  }
463
}
464

465
void Module::buildVisibleModulesCache() const {
466
  assert(VisibleModulesCache.empty() && "cache does not need building");
467

468
  // This module is visible to itself.
469
  VisibleModulesCache.insert(this);
470

471
  // Every imported module is visible.
472
  SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end());
473
  while (!Stack.empty()) {
474
    Module *CurrModule = Stack.pop_back_val();
475

476
    // Every module transitively exported by an imported module is visible.
477
    if (VisibleModulesCache.insert(CurrModule).second)
478
      CurrModule->getExportedModules(Stack);
479
  }
480
}
481

482
void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const {
483
  OS.indent(Indent);
484
  if (IsFramework)
485
    OS << "framework ";
486
  if (IsExplicit)
487
    OS << "explicit ";
488
  OS << "module ";
489
  printModuleId(OS, &Name, &Name + 1);
490

491
  if (IsSystem || IsExternC) {
492
    OS.indent(Indent + 2);
493
    if (IsSystem)
494
      OS << " [system]";
495
    if (IsExternC)
496
      OS << " [extern_c]";
497
  }
498

499
  OS << " {\n";
500

501
  if (!Requirements.empty()) {
502
    OS.indent(Indent + 2);
503
    OS << "requires ";
504
    for (unsigned I = 0, N = Requirements.size(); I != N; ++I) {
505
      if (I)
506
        OS << ", ";
507
      if (!Requirements[I].RequiredState)
508
        OS << "!";
509
      OS << Requirements[I].FeatureName;
510
    }
511
    OS << "\n";
512
  }
513

514
  if (std::optional<Header> H = getUmbrellaHeaderAsWritten()) {
515
    OS.indent(Indent + 2);
516
    OS << "umbrella header \"";
517
    OS.write_escaped(H->NameAsWritten);
518
    OS << "\"\n";
519
  } else if (std::optional<DirectoryName> D = getUmbrellaDirAsWritten()) {
520
    OS.indent(Indent + 2);
521
    OS << "umbrella \"";
522
    OS.write_escaped(D->NameAsWritten);
523
    OS << "\"\n";
524
  }
525

526
  if (!ConfigMacros.empty() || ConfigMacrosExhaustive) {
527
    OS.indent(Indent + 2);
528
    OS << "config_macros ";
529
    if (ConfigMacrosExhaustive)
530
      OS << "[exhaustive]";
531
    for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) {
532
      if (I)
533
        OS << ", ";
534
      OS << ConfigMacros[I];
535
    }
536
    OS << "\n";
537
  }
538

539
  struct {
540
    StringRef Prefix;
541
    HeaderKind Kind;
542
  } Kinds[] = {{"", HK_Normal},
543
               {"textual ", HK_Textual},
544
               {"private ", HK_Private},
545
               {"private textual ", HK_PrivateTextual},
546
               {"exclude ", HK_Excluded}};
547

548
  for (auto &K : Kinds) {
549
    assert(&K == &Kinds[K.Kind] && "kinds in wrong order");
550
    for (auto &H : Headers[K.Kind]) {
551
      OS.indent(Indent + 2);
552
      OS << K.Prefix << "header \"";
553
      OS.write_escaped(H.NameAsWritten);
554
      OS << "\" { size " << H.Entry.getSize()
555
         << " mtime " << H.Entry.getModificationTime() << " }\n";
556
    }
557
  }
558
  for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) {
559
    for (auto &U : *Unresolved) {
560
      OS.indent(Indent + 2);
561
      OS << Kinds[U.Kind].Prefix << "header \"";
562
      OS.write_escaped(U.FileName);
563
      OS << "\"";
564
      if (U.Size || U.ModTime) {
565
        OS << " {";
566
        if (U.Size)
567
          OS << " size " << *U.Size;
568
        if (U.ModTime)
569
          OS << " mtime " << *U.ModTime;
570
        OS << " }";
571
      }
572
      OS << "\n";
573
    }
574
  }
575

576
  if (!ExportAsModule.empty()) {
577
    OS.indent(Indent + 2);
578
    OS << "export_as" << ExportAsModule << "\n";
579
  }
580

581
  for (auto *Submodule : submodules())
582
    // Print inferred subframework modules so that we don't need to re-infer
583
    // them (requires expensive directory iteration + stat calls) when we build
584
    // the module. Regular inferred submodules are OK, as we need to look at all
585
    // those header files anyway.
586
    if (!Submodule->IsInferred || Submodule->IsFramework)
587
      Submodule->print(OS, Indent + 2, Dump);
588

589
  for (unsigned I = 0, N = Exports.size(); I != N; ++I) {
590
    OS.indent(Indent + 2);
591
    OS << "export ";
592
    if (Module *Restriction = Exports[I].getPointer()) {
593
      OS << Restriction->getFullModuleName(true);
594
      if (Exports[I].getInt())
595
        OS << ".*";
596
    } else {
597
      OS << "*";
598
    }
599
    OS << "\n";
600
  }
601

602
  for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I) {
603
    OS.indent(Indent + 2);
604
    OS << "export ";
605
    printModuleId(OS, UnresolvedExports[I].Id);
606
    if (UnresolvedExports[I].Wildcard)
607
      OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*");
608
    OS << "\n";
609
  }
610

611
  if (Dump) {
612
    for (Module *M : Imports) {
613
      OS.indent(Indent + 2);
614
      llvm::errs() << "import " << M->getFullModuleName() << "\n";
615
    }
616
  }
617

618
  for (unsigned I = 0, N = DirectUses.size(); I != N; ++I) {
619
    OS.indent(Indent + 2);
620
    OS << "use ";
621
    OS << DirectUses[I]->getFullModuleName(true);
622
    OS << "\n";
623
  }
624

625
  for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I) {
626
    OS.indent(Indent + 2);
627
    OS << "use ";
628
    printModuleId(OS, UnresolvedDirectUses[I]);
629
    OS << "\n";
630
  }
631

632
  for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I) {
633
    OS.indent(Indent + 2);
634
    OS << "link ";
635
    if (LinkLibraries[I].IsFramework)
636
      OS << "framework ";
637
    OS << "\"";
638
    OS.write_escaped(LinkLibraries[I].Library);
639
    OS << "\"";
640
  }
641

642
  for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I) {
643
    OS.indent(Indent + 2);
644
    OS << "conflict ";
645
    printModuleId(OS, UnresolvedConflicts[I].Id);
646
    OS << ", \"";
647
    OS.write_escaped(UnresolvedConflicts[I].Message);
648
    OS << "\"\n";
649
  }
650

651
  for (unsigned I = 0, N = Conflicts.size(); I != N; ++I) {
652
    OS.indent(Indent + 2);
653
    OS << "conflict ";
654
    OS << Conflicts[I].Other->getFullModuleName(true);
655
    OS << ", \"";
656
    OS.write_escaped(Conflicts[I].Message);
657
    OS << "\"\n";
658
  }
659

660
  if (InferSubmodules) {
661
    OS.indent(Indent + 2);
662
    if (InferExplicitSubmodules)
663
      OS << "explicit ";
664
    OS << "module * {\n";
665
    if (InferExportWildcard) {
666
      OS.indent(Indent + 4);
667
      OS << "export *\n";
668
    }
669
    OS.indent(Indent + 2);
670
    OS << "}\n";
671
  }
672

673
  OS.indent(Indent);
674
  OS << "}\n";
675
}
676

677
LLVM_DUMP_METHOD void Module::dump() const {
678
  print(llvm::errs(), 0, true);
679
}
680

681
void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc,
682
                                  VisibleCallback Vis, ConflictCallback Cb) {
683
  // We can't import a global module fragment so the location can be invalid.
684
  assert((M->isGlobalModule() || Loc.isValid()) &&
685
         "setVisible expects a valid import location");
686
  if (isVisible(M))
687
    return;
688

689
  ++Generation;
690

691
  struct Visiting {
692
    Module *M;
693
    Visiting *ExportedBy;
694
  };
695

696
  std::function<void(Visiting)> VisitModule = [&](Visiting V) {
697
    // Nothing to do for a module that's already visible.
698
    unsigned ID = V.M->getVisibilityID();
699
    if (ImportLocs.size() <= ID)
700
      ImportLocs.resize(ID + 1);
701
    else if (ImportLocs[ID].isValid())
702
      return;
703

704
    ImportLocs[ID] = Loc;
705
    Vis(V.M);
706

707
    // Make any exported modules visible.
708
    SmallVector<Module *, 16> Exports;
709
    V.M->getExportedModules(Exports);
710
    for (Module *E : Exports) {
711
      // Don't import non-importable modules.
712
      if (!E->isUnimportable())
713
        VisitModule({E, &V});
714
    }
715

716
    for (auto &C : V.M->Conflicts) {
717
      if (isVisible(C.Other)) {
718
        llvm::SmallVector<Module*, 8> Path;
719
        for (Visiting *I = &V; I; I = I->ExportedBy)
720
          Path.push_back(I->M);
721
        Cb(Path, C.Other, C.Message);
722
      }
723
    }
724
  };
725
  VisitModule({M, nullptr});
726
}
727

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.