/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Module.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 2.15M | NameVisibility(Hidden) { |
48 | 2.15M | if (Parent) { |
49 | 2.03M | IsAvailable = Parent->isAvailable(); |
50 | 2.03M | IsUnimportable = Parent->isUnimportable(); |
51 | 2.03M | IsSystem = Parent->IsSystem; |
52 | 2.03M | IsExternC = Parent->IsExternC; |
53 | 2.03M | NoUndeclaredIncludes = Parent->NoUndeclaredIncludes; |
54 | 2.03M | ModuleMapIsPrivate = Parent->ModuleMapIsPrivate; |
55 | | |
56 | 2.03M | Parent->SubModuleIndex[Name] = Parent->SubModules.size(); |
57 | 2.03M | Parent->SubModules.push_back(this); |
58 | 2.03M | } |
59 | 2.15M | } |
60 | | |
61 | 1.52M | Module::~Module() { |
62 | 1.52M | for (submodule_iterator I = submodule_begin(), IEnd = submodule_end(); |
63 | 2.93M | I != IEnd; ++I1.41M ) { |
64 | 1.41M | delete *I; |
65 | 1.41M | } |
66 | 1.52M | } |
67 | | |
68 | 56.8k | static bool isPlatformEnvironment(const TargetInfo &Target, StringRef Feature) { |
69 | 56.8k | StringRef Platform = Target.getPlatformName(); |
70 | 56.8k | StringRef Env = Target.getTriple().getEnvironmentName(); |
71 | | |
72 | | // Attempt to match platform and environment. |
73 | 56.8k | if (Platform == Feature || Target.getTriple().getOSName() == Feature56.8k || |
74 | 56.8k | Env == Feature56.8k ) |
75 | 58 | return true; |
76 | | |
77 | 56.8k | auto CmpPlatformEnv = [](StringRef LHS, StringRef RHS) { |
78 | 3 | auto Pos = LHS.find('-'); |
79 | 3 | if (Pos == StringRef::npos) |
80 | 0 | return false; |
81 | 3 | SmallString<128> NewLHS = LHS.slice(0, Pos); |
82 | 3 | NewLHS += LHS.slice(Pos+1, LHS.size()); |
83 | 3 | return NewLHS == RHS; |
84 | 3 | }; |
85 | | |
86 | 56.8k | SmallString<128> PlatformEnv = Target.getTriple().getOSAndEnvironmentName(); |
87 | | // Darwin has different but equivalent variants for simulators, example: |
88 | | // 1. x86_64-apple-ios-simulator |
89 | | // 2. x86_64-apple-iossimulator |
90 | | // where both are valid examples of the same platform+environment but in the |
91 | | // variant (2) the simulator is hardcoded as part of the platform name. Both |
92 | | // forms above should match for "iossimulator" requirement. |
93 | 56.8k | if (Target.getTriple().isOSDarwin() && PlatformEnv.endswith("simulator")56.1k ) |
94 | 3 | return PlatformEnv == Feature || CmpPlatformEnv(PlatformEnv, Feature); |
95 | | |
96 | 56.7k | return PlatformEnv == Feature; |
97 | 56.8k | } |
98 | | |
99 | | /// Determine whether a translation unit built using the current |
100 | | /// language options has the given feature. |
101 | | static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, |
102 | 60.1k | const TargetInfo &Target) { |
103 | 60.1k | bool HasFeature = llvm::StringSwitch<bool>(Feature) |
104 | 60.1k | .Case("altivec", LangOpts.AltiVec) |
105 | 60.1k | .Case("blocks", LangOpts.Blocks) |
106 | 60.1k | .Case("coroutines", LangOpts.Coroutines) |
107 | 60.1k | .Case("cplusplus", LangOpts.CPlusPlus) |
108 | 60.1k | .Case("cplusplus11", LangOpts.CPlusPlus11) |
109 | 60.1k | .Case("cplusplus14", LangOpts.CPlusPlus14) |
110 | 60.1k | .Case("cplusplus17", LangOpts.CPlusPlus17) |
111 | 60.1k | .Case("c99", LangOpts.C99) |
112 | 60.1k | .Case("c11", LangOpts.C11) |
113 | 60.1k | .Case("c17", LangOpts.C17) |
114 | 60.1k | .Case("freestanding", LangOpts.Freestanding) |
115 | 60.1k | .Case("gnuinlineasm", LangOpts.GNUAsm) |
116 | 60.1k | .Case("objc", LangOpts.ObjC) |
117 | 60.1k | .Case("objc_arc", LangOpts.ObjCAutoRefCount) |
118 | 60.1k | .Case("opencl", LangOpts.OpenCL) |
119 | 60.1k | .Case("tls", Target.isTLSSupported()) |
120 | 60.1k | .Case("zvector", LangOpts.ZVector) |
121 | 60.1k | .Default(Target.hasFeature(Feature) || |
122 | 60.1k | isPlatformEnvironment(Target, Feature)56.8k ); |
123 | 60.1k | if (!HasFeature) |
124 | 41.2k | HasFeature = llvm::is_contained(LangOpts.ModuleFeatures, Feature); |
125 | 60.1k | return HasFeature; |
126 | 60.1k | } |
127 | | |
128 | | bool Module::isUnimportable(const LangOptions &LangOpts, |
129 | | const TargetInfo &Target, Requirement &Req, |
130 | 23 | Module *&ShadowingModule) const { |
131 | 23 | if (!IsUnimportable) |
132 | 2 | return false; |
133 | | |
134 | 21 | for (const Module *Current = this; Current; Current = Current->Parent0 ) { |
135 | 21 | if (Current->ShadowingModule) { |
136 | 1 | ShadowingModule = Current->ShadowingModule; |
137 | 1 | return true; |
138 | 1 | } |
139 | 20 | for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I0 ) { |
140 | 20 | if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != |
141 | 20 | Current->Requirements[I].second) { |
142 | 20 | Req = Current->Requirements[I]; |
143 | 20 | return true; |
144 | 20 | } |
145 | 20 | } |
146 | 20 | } |
147 | | |
148 | 0 | llvm_unreachable("could not find a reason why module is unimportable"); |
149 | 0 | } |
150 | | |
151 | | bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target, |
152 | | Requirement &Req, |
153 | | UnresolvedHeaderDirective &MissingHeader, |
154 | 39.6k | Module *&ShadowingModule) const { |
155 | 39.6k | if (IsAvailable) |
156 | 39.6k | return true; |
157 | | |
158 | 23 | if (isUnimportable(LangOpts, Target, Req, ShadowingModule)) |
159 | 21 | return false; |
160 | | |
161 | | // FIXME: All missing headers are listed on the top-level module. Should we |
162 | | // just look there? |
163 | 3 | for (const Module *Current = this; 2 Current; Current = Current->Parent1 ) { |
164 | 3 | if (!Current->MissingHeaders.empty()) { |
165 | 2 | MissingHeader = Current->MissingHeaders.front(); |
166 | 2 | return false; |
167 | 2 | } |
168 | 3 | } |
169 | | |
170 | 0 | llvm_unreachable("could not find a reason why module is unavailable"); |
171 | 0 | } |
172 | | |
173 | 48.1k | bool Module::isSubModuleOf(const Module *Other) const { |
174 | 161k | for (auto *Parent = this; Parent; Parent = Parent->Parent113k ) { |
175 | 161k | if (Parent == Other) |
176 | 47.6k | return true; |
177 | 161k | } |
178 | 457 | return false; |
179 | 48.1k | } |
180 | | |
181 | 7.23M | const Module *Module::getTopLevelModule() const { |
182 | 7.23M | const Module *Result = this; |
183 | 19.5M | while (Result->Parent) |
184 | 12.2M | Result = Result->Parent; |
185 | | |
186 | 7.23M | return Result; |
187 | 7.23M | } |
188 | | |
189 | | static StringRef getModuleNameFromComponent( |
190 | 3 | const std::pair<std::string, SourceLocation> &IdComponent) { |
191 | 3 | return IdComponent.first; |
192 | 3 | } |
193 | | |
194 | 9.23k | static StringRef getModuleNameFromComponent(StringRef R) { return R; } |
195 | | |
196 | | template<typename InputIter> |
197 | | static void printModuleId(raw_ostream &OS, InputIter Begin, InputIter End, |
198 | 4.74k | bool AllowStringLiterals = true) { |
199 | 13.9k | for (InputIter It = Begin; It != End; ++It9.23k ) { |
200 | 9.23k | if (It != Begin) |
201 | 4.50k | OS << "."; |
202 | | |
203 | 9.23k | StringRef Name = getModuleNameFromComponent(*It); |
204 | 9.23k | if (!AllowStringLiterals || isValidAsciiIdentifier(Name)510 ) |
205 | 9.22k | OS << Name; |
206 | 11 | else { |
207 | 11 | OS << '"'; |
208 | 11 | OS.write_escaped(Name); |
209 | 11 | OS << '"'; |
210 | 11 | } |
211 | 9.23k | } |
212 | 4.74k | } Module.cpp:void printModuleId<std::__1::reverse_iterator<llvm::StringRef*> >(llvm::raw_ostream&, std::__1::reverse_iterator<llvm::StringRef*>, std::__1::reverse_iterator<llvm::StringRef*>, bool) Line | Count | Source | 198 | 4.48k | bool AllowStringLiterals = true) { | 199 | 13.4k | for (InputIter It = Begin; It != End; ++It8.99k ) { | 200 | 8.99k | if (It != Begin) | 201 | 4.50k | OS << "."; | 202 | | | 203 | 8.99k | StringRef Name = getModuleNameFromComponent(*It); | 204 | 8.99k | if (!AllowStringLiterals || isValidAsciiIdentifier(Name)265 ) | 205 | 8.98k | OS << Name; | 206 | 9 | else { | 207 | 9 | OS << '"'; | 208 | 9 | OS.write_escaped(Name); | 209 | 9 | OS << '"'; | 210 | 9 | } | 211 | 8.99k | } | 212 | 4.48k | } |
Module.cpp:void printModuleId<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*>(llvm::raw_ostream&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const*, bool) Line | Count | Source | 198 | 242 | bool AllowStringLiterals = true) { | 199 | 484 | for (InputIter It = Begin; It != End; ++It242 ) { | 200 | 242 | if (It != Begin) | 201 | 0 | OS << "."; | 202 | | | 203 | 242 | StringRef Name = getModuleNameFromComponent(*It); | 204 | 242 | if (!AllowStringLiterals || isValidAsciiIdentifier(Name)) | 205 | 240 | OS << Name; | 206 | 2 | else { | 207 | 2 | OS << '"'; | 208 | 2 | OS.write_escaped(Name); | 209 | 2 | OS << '"'; | 210 | 2 | } | 211 | 242 | } | 212 | 242 | } |
Module.cpp:void printModuleId<std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, clang::SourceLocation> const*>(llvm::raw_ostream&, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, clang::SourceLocation> const*, std::__1::pair<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, clang::SourceLocation> const*, bool) Line | Count | Source | 198 | 14 | bool AllowStringLiterals = true) { | 199 | 17 | for (InputIter It = Begin; It != End; ++It3 ) { | 200 | 3 | if (It != Begin) | 201 | 0 | OS << "."; | 202 | | | 203 | 3 | StringRef Name = getModuleNameFromComponent(*It); | 204 | 3 | if (!AllowStringLiterals || isValidAsciiIdentifier(Name)) | 205 | 3 | OS << Name; | 206 | 0 | else { | 207 | 0 | OS << '"'; | 208 | 0 | OS.write_escaped(Name); | 209 | 0 | OS << '"'; | 210 | 0 | } | 211 | 3 | } | 212 | 14 | } |
|
213 | | |
214 | | template<typename Container> |
215 | 14 | static void printModuleId(raw_ostream &OS, const Container &C) { |
216 | 14 | return printModuleId(OS, C.begin(), C.end()); |
217 | 14 | } |
218 | | |
219 | 4.48k | std::string Module::getFullModuleName(bool AllowStringLiterals) const { |
220 | 4.48k | SmallVector<StringRef, 2> Names; |
221 | | |
222 | | // Build up the set of module names (from innermost to outermost). |
223 | 13.4k | for (const Module *M = this; M; M = M->Parent8.98k ) |
224 | 8.98k | Names.push_back(M->Name); |
225 | | |
226 | 4.48k | std::string Result; |
227 | | |
228 | 4.48k | llvm::raw_string_ostream Out(Result); |
229 | 4.48k | printModuleId(Out, Names.rbegin(), Names.rend(), AllowStringLiterals); |
230 | 4.48k | Out.flush(); |
231 | | |
232 | 4.48k | return Result; |
233 | 4.48k | } |
234 | | |
235 | 9.37k | bool Module::fullModuleNameIs(ArrayRef<StringRef> nameParts) const { |
236 | 9.69k | for (const Module *M = this; M; M = M->Parent322 ) { |
237 | 9.55k | if (nameParts.empty() || M->Name != nameParts.back()) |
238 | 9.23k | return false; |
239 | 322 | nameParts = nameParts.drop_back(); |
240 | 322 | } |
241 | 138 | return nameParts.empty(); |
242 | 9.37k | } |
243 | | |
244 | 94.9k | Module::DirectoryName Module::getUmbrellaDir() const { |
245 | 94.9k | if (Header U = getUmbrellaHeader()) |
246 | 12.0k | return {"", "", U.Entry->getDir()}; |
247 | | |
248 | 82.9k | return {UmbrellaAsWritten, UmbrellaRelativeToRootModuleDirectory, |
249 | 82.9k | Umbrella.dyn_cast<const DirectoryEntry *>()}; |
250 | 94.9k | } |
251 | | |
252 | 30.7k | void Module::addTopHeader(const FileEntry *File) { |
253 | 30.7k | assert(File); |
254 | 0 | TopHeaders.insert(File); |
255 | 30.7k | } |
256 | | |
257 | 28.5k | ArrayRef<const FileEntry *> Module::getTopHeaders(FileManager &FileMgr) { |
258 | 28.5k | if (!TopHeaderNames.empty()) { |
259 | 1 | for (std::vector<std::string>::iterator |
260 | 3 | I = TopHeaderNames.begin(), E = TopHeaderNames.end(); I != E; ++I2 ) { |
261 | 2 | if (auto FE = FileMgr.getFile(*I)) |
262 | 2 | TopHeaders.insert(*FE); |
263 | 2 | } |
264 | 1 | TopHeaderNames.clear(); |
265 | 1 | } |
266 | | |
267 | 28.5k | return llvm::makeArrayRef(TopHeaders.begin(), TopHeaders.end()); |
268 | 28.5k | } |
269 | | |
270 | 47.9k | bool Module::directlyUses(const Module *Requested) { |
271 | 47.9k | auto *Top = getTopLevelModule(); |
272 | | |
273 | | // A top-level module implicitly uses itself. |
274 | 47.9k | if (Requested->isSubModuleOf(Top)) |
275 | 47.5k | return true; |
276 | | |
277 | 393 | for (auto *Use : Top->DirectUses) |
278 | 86 | if (Requested->isSubModuleOf(Use)) |
279 | 26 | return true; |
280 | | |
281 | | // Anyone is allowed to use our builtin stddef.h and its accompanying module. |
282 | 367 | if (!Requested->Parent && Requested->Name == "_Builtin_stddef_max_align_t"179 ) |
283 | 162 | return true; |
284 | | |
285 | 205 | if (NoUndeclaredIncludes) |
286 | 193 | UndeclaredUses.insert(Requested); |
287 | | |
288 | 205 | return false; |
289 | 367 | } |
290 | | |
291 | | void Module::addRequirement(StringRef Feature, bool RequiredState, |
292 | | const LangOptions &LangOpts, |
293 | 60.0k | const TargetInfo &Target) { |
294 | 60.0k | Requirements.push_back(Requirement(std::string(Feature), RequiredState)); |
295 | | |
296 | | // If this feature is currently available, we're done. |
297 | 60.0k | if (hasFeature(Feature, LangOpts, Target) == RequiredState) |
298 | 22.9k | return; |
299 | | |
300 | 37.1k | markUnavailable(/*Unimportable*/true); |
301 | 37.1k | } |
302 | | |
303 | 40.7k | void Module::markUnavailable(bool Unimportable) { |
304 | 68.4k | auto needUpdate = [Unimportable](Module *M) { |
305 | 68.4k | return M->IsAvailable || (18.9k !M->IsUnimportable18.9k && Unimportable3.25k ); |
306 | 68.4k | }; |
307 | | |
308 | 40.7k | if (!needUpdate(this)) |
309 | 15.4k | return; |
310 | | |
311 | 25.2k | SmallVector<Module *, 2> Stack; |
312 | 25.2k | Stack.push_back(this); |
313 | 50.5k | while (!Stack.empty()) { |
314 | 25.3k | Module *Current = Stack.back(); |
315 | 25.3k | Stack.pop_back(); |
316 | | |
317 | 25.3k | if (!needUpdate(Current)) |
318 | 0 | continue; |
319 | | |
320 | 25.3k | Current->IsAvailable = false; |
321 | 25.3k | Current->IsUnimportable |= Unimportable; |
322 | 25.3k | for (submodule_iterator Sub = Current->submodule_begin(), |
323 | 25.3k | SubEnd = Current->submodule_end(); |
324 | 27.7k | Sub != SubEnd; ++Sub2.36k ) { |
325 | 2.36k | if (needUpdate(*Sub)) |
326 | 128 | Stack.push_back(*Sub); |
327 | 2.36k | } |
328 | 25.3k | } |
329 | 25.2k | } |
330 | | |
331 | 5.09M | Module *Module::findSubmodule(StringRef Name) const { |
332 | 5.09M | llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); |
333 | 5.09M | if (Pos == SubModuleIndex.end()) |
334 | 3.73M | return nullptr; |
335 | | |
336 | 1.36M | return SubModules[Pos->getValue()]; |
337 | 5.09M | } |
338 | | |
339 | 47 | Module *Module::findOrInferSubmodule(StringRef Name) { |
340 | 47 | llvm::StringMap<unsigned>::const_iterator Pos = SubModuleIndex.find(Name); |
341 | 47 | if (Pos != SubModuleIndex.end()) |
342 | 46 | return SubModules[Pos->getValue()]; |
343 | 1 | if (!InferSubmodules) |
344 | 0 | return nullptr; |
345 | 1 | Module *Result = new Module(Name, SourceLocation(), this, false, InferExplicitSubmodules, 0); |
346 | 1 | Result->InferExplicitSubmodules = InferExplicitSubmodules; |
347 | 1 | Result->InferSubmodules = InferSubmodules; |
348 | 1 | Result->InferExportWildcard = InferExportWildcard; |
349 | 1 | if (Result->InferExportWildcard) |
350 | 1 | Result->Exports.push_back(Module::ExportDecl(nullptr, true)); |
351 | 1 | return Result; |
352 | 1 | } |
353 | | |
354 | 3.87M | void Module::getExportedModules(SmallVectorImpl<Module *> &Exported) const { |
355 | | // All non-explicit submodules are exported. |
356 | 3.87M | for (std::vector<Module *>::const_iterator I = SubModules.begin(), |
357 | 3.87M | E = SubModules.end(); |
358 | 7.25M | I != E; ++I3.38M ) { |
359 | 3.38M | Module *Mod = *I; |
360 | 3.38M | if (!Mod->IsExplicit) |
361 | 3.34M | Exported.push_back(Mod); |
362 | 3.38M | } |
363 | | |
364 | | // Find re-exported modules by filtering the list of imported modules. |
365 | 3.87M | bool AnyWildcard = false; |
366 | 3.87M | bool UnrestrictedWildcard = false; |
367 | 3.87M | SmallVector<Module *, 4> WildcardRestrictions; |
368 | 6.11M | for (unsigned I = 0, N = Exports.size(); I != N; ++I2.24M ) { |
369 | 2.24M | Module *Mod = Exports[I].getPointer(); |
370 | 2.24M | if (!Exports[I].getInt()) { |
371 | | // Export a named module directly; no wildcards involved. |
372 | 155k | Exported.push_back(Mod); |
373 | | |
374 | 155k | continue; |
375 | 155k | } |
376 | | |
377 | | // Wildcard export: export all of the imported modules that match |
378 | | // the given pattern. |
379 | 2.08M | AnyWildcard = true; |
380 | 2.08M | if (UnrestrictedWildcard) |
381 | 7.47k | continue; |
382 | | |
383 | 2.08M | if (Module *Restriction = Exports[I].getPointer()) |
384 | 3 | WildcardRestrictions.push_back(Restriction); |
385 | 2.08M | else { |
386 | 2.08M | WildcardRestrictions.clear(); |
387 | 2.08M | UnrestrictedWildcard = true; |
388 | 2.08M | } |
389 | 2.08M | } |
390 | | |
391 | | // If there were any wildcards, push any imported modules that were |
392 | | // re-exported by the wildcard restriction. |
393 | 3.87M | if (!AnyWildcard) |
394 | 1.79M | return; |
395 | | |
396 | 11.4M | for (unsigned I = 0, N = Imports.size(); 2.08M I != N; ++I9.33M ) { |
397 | 9.33M | Module *Mod = Imports[I]; |
398 | 9.33M | bool Acceptable = UnrestrictedWildcard; |
399 | 9.33M | if (!Acceptable) { |
400 | | // Check whether this module meets one of the restrictions. |
401 | 9 | for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R3 ) { |
402 | 6 | Module *Restriction = WildcardRestrictions[R]; |
403 | 6 | if (Mod == Restriction || Mod->isSubModuleOf(Restriction)) { |
404 | 3 | Acceptable = true; |
405 | 3 | break; |
406 | 3 | } |
407 | 6 | } |
408 | 6 | } |
409 | | |
410 | 9.33M | if (!Acceptable) |
411 | 3 | continue; |
412 | | |
413 | 9.33M | Exported.push_back(Mod); |
414 | 9.33M | } |
415 | 2.08M | } |
416 | | |
417 | 281 | void Module::buildVisibleModulesCache() const { |
418 | 281 | assert(VisibleModulesCache.empty() && "cache does not need building"); |
419 | | |
420 | | // This module is visible to itself. |
421 | 0 | VisibleModulesCache.insert(this); |
422 | | |
423 | | // Every imported module is visible. |
424 | 281 | SmallVector<Module *, 16> Stack(Imports.begin(), Imports.end()); |
425 | 194k | while (!Stack.empty()) { |
426 | 194k | Module *CurrModule = Stack.pop_back_val(); |
427 | | |
428 | | // Every module transitively exported by an imported module is visible. |
429 | 194k | if (VisibleModulesCache.insert(CurrModule).second) |
430 | 82.9k | CurrModule->getExportedModules(Stack); |
431 | 194k | } |
432 | 281 | } |
433 | | |
434 | 242 | void Module::print(raw_ostream &OS, unsigned Indent, bool Dump) const { |
435 | 242 | OS.indent(Indent); |
436 | 242 | if (IsFramework) |
437 | 217 | OS << "framework "; |
438 | 242 | if (IsExplicit) |
439 | 0 | OS << "explicit "; |
440 | 242 | OS << "module "; |
441 | 242 | printModuleId(OS, &Name, &Name + 1); |
442 | | |
443 | 242 | if (IsSystem || IsExternC180 ) { |
444 | 67 | OS.indent(Indent + 2); |
445 | 67 | if (IsSystem) |
446 | 62 | OS << " [system]"; |
447 | 67 | if (IsExternC) |
448 | 65 | OS << " [extern_c]"; |
449 | 67 | } |
450 | | |
451 | 242 | OS << " {\n"; |
452 | | |
453 | 242 | if (!Requirements.empty()) { |
454 | 0 | OS.indent(Indent + 2); |
455 | 0 | OS << "requires "; |
456 | 0 | for (unsigned I = 0, N = Requirements.size(); I != N; ++I) { |
457 | 0 | if (I) |
458 | 0 | OS << ", "; |
459 | 0 | if (!Requirements[I].second) |
460 | 0 | OS << "!"; |
461 | 0 | OS << Requirements[I].first; |
462 | 0 | } |
463 | 0 | OS << "\n"; |
464 | 0 | } |
465 | | |
466 | 242 | if (Header H = getUmbrellaHeader()) { |
467 | 217 | OS.indent(Indent + 2); |
468 | 217 | OS << "umbrella header \""; |
469 | 217 | OS.write_escaped(H.NameAsWritten); |
470 | 217 | OS << "\"\n"; |
471 | 217 | } else if (DirectoryName 25 D25 = getUmbrellaDir()) { |
472 | 0 | OS.indent(Indent + 2); |
473 | 0 | OS << "umbrella \""; |
474 | 0 | OS.write_escaped(D.NameAsWritten); |
475 | 0 | OS << "\"\n"; |
476 | 0 | } |
477 | | |
478 | 242 | if (!ConfigMacros.empty() || ConfigMacrosExhaustive) { |
479 | 0 | OS.indent(Indent + 2); |
480 | 0 | OS << "config_macros "; |
481 | 0 | if (ConfigMacrosExhaustive) |
482 | 0 | OS << "[exhaustive]"; |
483 | 0 | for (unsigned I = 0, N = ConfigMacros.size(); I != N; ++I) { |
484 | 0 | if (I) |
485 | 0 | OS << ", "; |
486 | 0 | OS << ConfigMacros[I]; |
487 | 0 | } |
488 | 0 | OS << "\n"; |
489 | 0 | } |
490 | | |
491 | 242 | struct { |
492 | 242 | StringRef Prefix; |
493 | 242 | HeaderKind Kind; |
494 | 242 | } Kinds[] = {{"", HK_Normal}, |
495 | 242 | {"textual ", HK_Textual}, |
496 | 242 | {"private ", HK_Private}, |
497 | 242 | {"private textual ", HK_PrivateTextual}, |
498 | 242 | {"exclude ", HK_Excluded}}; |
499 | | |
500 | 1.21k | for (auto &K : Kinds) { |
501 | 1.21k | assert(&K == &Kinds[K.Kind] && "kinds in wrong order"); |
502 | 41 | for (auto &H : Headers[K.Kind]) { |
503 | 41 | OS.indent(Indent + 2); |
504 | 41 | OS << K.Prefix << "header \""; |
505 | 41 | OS.write_escaped(H.NameAsWritten); |
506 | 41 | OS << "\" { size " << H.Entry->getSize() |
507 | 41 | << " mtime " << H.Entry->getModificationTime() << " }\n"; |
508 | 41 | } |
509 | 1.21k | } |
510 | 484 | for (auto *Unresolved : {&UnresolvedHeaders, &MissingHeaders}) { |
511 | 484 | for (auto &U : *Unresolved) { |
512 | 0 | OS.indent(Indent + 2); |
513 | 0 | OS << Kinds[U.Kind].Prefix << "header \""; |
514 | 0 | OS.write_escaped(U.FileName); |
515 | 0 | OS << "\""; |
516 | 0 | if (U.Size || U.ModTime) { |
517 | 0 | OS << " {"; |
518 | 0 | if (U.Size) |
519 | 0 | OS << " size " << *U.Size; |
520 | 0 | if (U.ModTime) |
521 | 0 | OS << " mtime " << *U.ModTime; |
522 | 0 | OS << " }"; |
523 | 0 | } |
524 | 0 | OS << "\n"; |
525 | 0 | } |
526 | 484 | } |
527 | | |
528 | 242 | if (!ExportAsModule.empty()) { |
529 | 0 | OS.indent(Indent + 2); |
530 | 0 | OS << "export_as" << ExportAsModule << "\n"; |
531 | 0 | } |
532 | | |
533 | 242 | for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end(); |
534 | 367 | MI != MIEnd; ++MI125 ) |
535 | | // Print inferred subframework modules so that we don't need to re-infer |
536 | | // them (requires expensive directory iteration + stat calls) when we build |
537 | | // the module. Regular inferred submodules are OK, as we need to look at all |
538 | | // those header files anyway. |
539 | 125 | if (!(*MI)->IsInferred || (*MI)->IsFramework119 ) |
540 | 124 | (*MI)->print(OS, Indent + 2, Dump); |
541 | | |
542 | 459 | for (unsigned I = 0, N = Exports.size(); I != N; ++I217 ) { |
543 | 217 | OS.indent(Indent + 2); |
544 | 217 | OS << "export "; |
545 | 217 | if (Module *Restriction = Exports[I].getPointer()) { |
546 | 0 | OS << Restriction->getFullModuleName(true); |
547 | 0 | if (Exports[I].getInt()) |
548 | 0 | OS << ".*"; |
549 | 217 | } else { |
550 | 217 | OS << "*"; |
551 | 217 | } |
552 | 217 | OS << "\n"; |
553 | 217 | } |
554 | | |
555 | 255 | for (unsigned I = 0, N = UnresolvedExports.size(); I != N; ++I13 ) { |
556 | 13 | OS.indent(Indent + 2); |
557 | 13 | OS << "export "; |
558 | 13 | printModuleId(OS, UnresolvedExports[I].Id); |
559 | 13 | if (UnresolvedExports[I].Wildcard) |
560 | 11 | OS << (UnresolvedExports[I].Id.empty() ? "*" : ".*"0 ); |
561 | 13 | OS << "\n"; |
562 | 13 | } |
563 | | |
564 | 242 | if (Dump) { |
565 | 0 | for (Module *M : Imports) { |
566 | 0 | OS.indent(Indent + 2); |
567 | 0 | llvm::errs() << "import " << M->getFullModuleName() << "\n"; |
568 | 0 | } |
569 | 0 | } |
570 | | |
571 | 242 | for (unsigned I = 0, N = DirectUses.size(); I != N; ++I0 ) { |
572 | 0 | OS.indent(Indent + 2); |
573 | 0 | OS << "use "; |
574 | 0 | OS << DirectUses[I]->getFullModuleName(true); |
575 | 0 | OS << "\n"; |
576 | 0 | } |
577 | | |
578 | 243 | for (unsigned I = 0, N = UnresolvedDirectUses.size(); I != N; ++I1 ) { |
579 | 1 | OS.indent(Indent + 2); |
580 | 1 | OS << "use "; |
581 | 1 | printModuleId(OS, UnresolvedDirectUses[I]); |
582 | 1 | OS << "\n"; |
583 | 1 | } |
584 | | |
585 | 312 | for (unsigned I = 0, N = LinkLibraries.size(); I != N; ++I70 ) { |
586 | 70 | OS.indent(Indent + 2); |
587 | 70 | OS << "link "; |
588 | 70 | if (LinkLibraries[I].IsFramework) |
589 | 70 | OS << "framework "; |
590 | 70 | OS << "\""; |
591 | 70 | OS.write_escaped(LinkLibraries[I].Library); |
592 | 70 | OS << "\""; |
593 | 70 | } |
594 | | |
595 | 242 | for (unsigned I = 0, N = UnresolvedConflicts.size(); I != N; ++I0 ) { |
596 | 0 | OS.indent(Indent + 2); |
597 | 0 | OS << "conflict "; |
598 | 0 | printModuleId(OS, UnresolvedConflicts[I].Id); |
599 | 0 | OS << ", \""; |
600 | 0 | OS.write_escaped(UnresolvedConflicts[I].Message); |
601 | 0 | OS << "\"\n"; |
602 | 0 | } |
603 | | |
604 | 242 | for (unsigned I = 0, N = Conflicts.size(); I != N; ++I0 ) { |
605 | 0 | OS.indent(Indent + 2); |
606 | 0 | OS << "conflict "; |
607 | 0 | OS << Conflicts[I].Other->getFullModuleName(true); |
608 | 0 | OS << ", \""; |
609 | 0 | OS.write_escaped(Conflicts[I].Message); |
610 | 0 | OS << "\"\n"; |
611 | 0 | } |
612 | | |
613 | 242 | if (InferSubmodules) { |
614 | 217 | OS.indent(Indent + 2); |
615 | 217 | if (InferExplicitSubmodules) |
616 | 0 | OS << "explicit "; |
617 | 217 | OS << "module * {\n"; |
618 | 217 | if (InferExportWildcard) { |
619 | 217 | OS.indent(Indent + 4); |
620 | 217 | OS << "export *\n"; |
621 | 217 | } |
622 | 217 | OS.indent(Indent + 2); |
623 | 217 | OS << "}\n"; |
624 | 217 | } |
625 | | |
626 | 242 | OS.indent(Indent); |
627 | 242 | OS << "}\n"; |
628 | 242 | } |
629 | | |
630 | 0 | LLVM_DUMP_METHOD void Module::dump() const { |
631 | 0 | print(llvm::errs(), 0, true); |
632 | 0 | } |
633 | | |
634 | | void VisibleModuleSet::setVisible(Module *M, SourceLocation Loc, |
635 | 398k | VisibleCallback Vis, ConflictCallback Cb) { |
636 | 398k | assert(Loc.isValid() && "setVisible expects a valid import location"); |
637 | 398k | if (isVisible(M)) |
638 | 330k | return; |
639 | | |
640 | 68.0k | ++Generation; |
641 | | |
642 | 68.0k | struct Visiting { |
643 | 68.0k | Module *M; |
644 | 68.0k | Visiting *ExportedBy; |
645 | 68.0k | }; |
646 | | |
647 | 7.10M | std::function<void(Visiting)> VisitModule = [&](Visiting V) { |
648 | | // Nothing to do for a module that's already visible. |
649 | 7.10M | unsigned ID = V.M->getVisibilityID(); |
650 | 7.10M | if (ImportLocs.size() <= ID) |
651 | 391k | ImportLocs.resize(ID + 1); |
652 | 6.70M | else if (ImportLocs[ID].isValid()) |
653 | 4.85M | return; |
654 | | |
655 | 2.24M | ImportLocs[ID] = Loc; |
656 | 2.24M | Vis(M); |
657 | | |
658 | | // Make any exported modules visible. |
659 | 2.24M | SmallVector<Module *, 16> Exports; |
660 | 2.24M | V.M->getExportedModules(Exports); |
661 | 7.03M | for (Module *E : Exports) { |
662 | | // Don't import non-importable modules. |
663 | 7.03M | if (!E->isUnimportable()) |
664 | 7.03M | VisitModule({E, &V}); |
665 | 7.03M | } |
666 | | |
667 | 2.24M | for (auto &C : V.M->Conflicts) { |
668 | 2 | if (isVisible(C.Other)) { |
669 | 2 | llvm::SmallVector<Module*, 8> Path; |
670 | 4 | for (Visiting *I = &V; I; I = I->ExportedBy2 ) |
671 | 2 | Path.push_back(I->M); |
672 | 2 | Cb(Path, C.Other, C.Message); |
673 | 2 | } |
674 | 2 | } |
675 | 2.24M | }; |
676 | 68.0k | VisitModule({M, nullptr}); |
677 | 68.0k | } |
678 | | |
679 | | ASTSourceDescriptor::ASTSourceDescriptor(Module &M) |
680 | 746k | : Signature(M.Signature), ClangModule(&M) { |
681 | 746k | if (M.Directory) |
682 | 561k | Path = M.Directory->getName(); |
683 | 746k | if (auto File = M.getASTFile()) |
684 | 45.2k | ASTFile = File->getName(); |
685 | 746k | } |
686 | | |
687 | 32.7k | std::string ASTSourceDescriptor::getModuleName() const { |
688 | 32.7k | if (ClangModule) |
689 | 32.6k | return ClangModule->Name; |
690 | 123 | else |
691 | 123 | return std::string(PCHModuleName); |
692 | 32.7k | } |