File: | clang/lib/Sema/SemaModule.cpp |
Warning: | line 577, column 3 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===--- SemaModule.cpp - Semantic Analysis for Modules -------------------===// | |||
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 implements semantic analysis for modules (C++ modules syntax, | |||
10 | // Objective-C modules syntax, and Clang header modules). | |||
11 | // | |||
12 | //===----------------------------------------------------------------------===// | |||
13 | ||||
14 | #include "clang/AST/ASTConsumer.h" | |||
15 | #include "clang/Lex/HeaderSearch.h" | |||
16 | #include "clang/Lex/Preprocessor.h" | |||
17 | #include "clang/Sema/SemaInternal.h" | |||
18 | ||||
19 | using namespace clang; | |||
20 | using namespace sema; | |||
21 | ||||
22 | static void checkModuleImportContext(Sema &S, Module *M, | |||
23 | SourceLocation ImportLoc, DeclContext *DC, | |||
24 | bool FromInclude = false) { | |||
25 | SourceLocation ExternCLoc; | |||
26 | ||||
27 | if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) { | |||
28 | switch (LSD->getLanguage()) { | |||
29 | case LinkageSpecDecl::lang_c: | |||
30 | if (ExternCLoc.isInvalid()) | |||
31 | ExternCLoc = LSD->getBeginLoc(); | |||
32 | break; | |||
33 | case LinkageSpecDecl::lang_cxx: | |||
34 | break; | |||
35 | } | |||
36 | DC = LSD->getParent(); | |||
37 | } | |||
38 | ||||
39 | while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC)) | |||
40 | DC = DC->getParent(); | |||
41 | ||||
42 | if (!isa<TranslationUnitDecl>(DC)) { | |||
43 | S.Diag(ImportLoc, (FromInclude && S.isModuleVisible(M)) | |||
44 | ? diag::ext_module_import_not_at_top_level_noop | |||
45 | : diag::err_module_import_not_at_top_level_fatal) | |||
46 | << M->getFullModuleName() << DC; | |||
47 | S.Diag(cast<Decl>(DC)->getBeginLoc(), | |||
48 | diag::note_module_import_not_at_top_level) | |||
49 | << DC; | |||
50 | } else if (!M->IsExternC && ExternCLoc.isValid()) { | |||
51 | S.Diag(ImportLoc, diag::ext_module_import_in_extern_c) | |||
52 | << M->getFullModuleName(); | |||
53 | S.Diag(ExternCLoc, diag::note_extern_c_begins_here); | |||
54 | } | |||
55 | } | |||
56 | ||||
57 | Sema::DeclGroupPtrTy | |||
58 | Sema::ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc) { | |||
59 | if (!ModuleScopes.empty() && | |||
60 | ModuleScopes.back().Module->Kind == Module::GlobalModuleFragment) { | |||
61 | // Under -std=c++2a -fmodules-ts, we can find an explicit 'module;' after | |||
62 | // already implicitly entering the global module fragment. That's OK. | |||
63 | assert(getLangOpts().CPlusPlusModules && getLangOpts().ModulesTS &&(static_cast <bool> (getLangOpts().CPlusPlusModules && getLangOpts().ModulesTS && "unexpectedly encountered multiple global module fragment decls" ) ? void (0) : __assert_fail ("getLangOpts().CPlusPlusModules && getLangOpts().ModulesTS && \"unexpectedly encountered multiple global module fragment decls\"" , "clang/lib/Sema/SemaModule.cpp", 64, __extension__ __PRETTY_FUNCTION__ )) | |||
64 | "unexpectedly encountered multiple global module fragment decls")(static_cast <bool> (getLangOpts().CPlusPlusModules && getLangOpts().ModulesTS && "unexpectedly encountered multiple global module fragment decls" ) ? void (0) : __assert_fail ("getLangOpts().CPlusPlusModules && getLangOpts().ModulesTS && \"unexpectedly encountered multiple global module fragment decls\"" , "clang/lib/Sema/SemaModule.cpp", 64, __extension__ __PRETTY_FUNCTION__ )); | |||
65 | ModuleScopes.back().BeginLoc = ModuleLoc; | |||
66 | return nullptr; | |||
67 | } | |||
68 | ||||
69 | // We start in the global module; all those declarations are implicitly | |||
70 | // module-private (though they do not have module linkage). | |||
71 | Module *GlobalModule = | |||
72 | PushGlobalModuleFragment(ModuleLoc, /*IsImplicit=*/false); | |||
73 | ||||
74 | // All declarations created from now on are owned by the global module. | |||
75 | auto *TU = Context.getTranslationUnitDecl(); | |||
76 | TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::Visible); | |||
77 | TU->setLocalOwningModule(GlobalModule); | |||
78 | ||||
79 | // FIXME: Consider creating an explicit representation of this declaration. | |||
80 | return nullptr; | |||
81 | } | |||
82 | ||||
83 | Sema::DeclGroupPtrTy | |||
84 | Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, | |||
85 | ModuleDeclKind MDK, ModuleIdPath Path, bool IsFirstDecl) { | |||
86 | assert((getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) &&(static_cast <bool> ((getLangOpts().ModulesTS || getLangOpts ().CPlusPlusModules) && "should only have module decl in Modules TS or C++20" ) ? void (0) : __assert_fail ("(getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) && \"should only have module decl in Modules TS or C++20\"" , "clang/lib/Sema/SemaModule.cpp", 87, __extension__ __PRETTY_FUNCTION__ )) | |||
87 | "should only have module decl in Modules TS or C++20")(static_cast <bool> ((getLangOpts().ModulesTS || getLangOpts ().CPlusPlusModules) && "should only have module decl in Modules TS or C++20" ) ? void (0) : __assert_fail ("(getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) && \"should only have module decl in Modules TS or C++20\"" , "clang/lib/Sema/SemaModule.cpp", 87, __extension__ __PRETTY_FUNCTION__ )); | |||
88 | ||||
89 | // A module implementation unit requires that we are not compiling a module | |||
90 | // of any kind. A module interface unit requires that we are not compiling a | |||
91 | // module map. | |||
92 | switch (getLangOpts().getCompilingModule()) { | |||
93 | case LangOptions::CMK_None: | |||
94 | // It's OK to compile a module interface as a normal translation unit. | |||
95 | break; | |||
96 | ||||
97 | case LangOptions::CMK_ModuleInterface: | |||
98 | if (MDK != ModuleDeclKind::Implementation) | |||
99 | break; | |||
100 | ||||
101 | // We were asked to compile a module interface unit but this is a module | |||
102 | // implementation unit. That indicates the 'export' is missing. | |||
103 | Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch) | |||
104 | << FixItHint::CreateInsertion(ModuleLoc, "export "); | |||
105 | MDK = ModuleDeclKind::Interface; | |||
106 | break; | |||
107 | ||||
108 | case LangOptions::CMK_ModuleMap: | |||
109 | Diag(ModuleLoc, diag::err_module_decl_in_module_map_module); | |||
110 | return nullptr; | |||
111 | ||||
112 | case LangOptions::CMK_HeaderModule: | |||
113 | Diag(ModuleLoc, diag::err_module_decl_in_header_module); | |||
114 | return nullptr; | |||
115 | } | |||
116 | ||||
117 | assert(ModuleScopes.size() <= 1 && "expected to be at global module scope")(static_cast <bool> (ModuleScopes.size() <= 1 && "expected to be at global module scope") ? void (0) : __assert_fail ("ModuleScopes.size() <= 1 && \"expected to be at global module scope\"" , "clang/lib/Sema/SemaModule.cpp", 117, __extension__ __PRETTY_FUNCTION__ )); | |||
118 | ||||
119 | // FIXME: Most of this work should be done by the preprocessor rather than | |||
120 | // here, in order to support macro import. | |||
121 | ||||
122 | // Only one module-declaration is permitted per source file. | |||
123 | if (!ModuleScopes.empty() && | |||
124 | ModuleScopes.back().Module->isModulePurview()) { | |||
125 | Diag(ModuleLoc, diag::err_module_redeclaration); | |||
126 | Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module), | |||
127 | diag::note_prev_module_declaration); | |||
128 | return nullptr; | |||
129 | } | |||
130 | ||||
131 | // Find the global module fragment we're adopting into this module, if any. | |||
132 | Module *GlobalModuleFragment = nullptr; | |||
133 | if (!ModuleScopes.empty() && | |||
134 | ModuleScopes.back().Module->Kind == Module::GlobalModuleFragment) | |||
135 | GlobalModuleFragment = ModuleScopes.back().Module; | |||
136 | ||||
137 | // In C++20, the module-declaration must be the first declaration if there | |||
138 | // is no global module fragment. | |||
139 | if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !GlobalModuleFragment) { | |||
140 | Diag(ModuleLoc, diag::err_module_decl_not_at_start); | |||
141 | SourceLocation BeginLoc = | |||
142 | ModuleScopes.empty() | |||
143 | ? SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()) | |||
144 | : ModuleScopes.back().BeginLoc; | |||
145 | if (BeginLoc.isValid()) { | |||
146 | Diag(BeginLoc, diag::note_global_module_introducer_missing) | |||
147 | << FixItHint::CreateInsertion(BeginLoc, "module;\n"); | |||
148 | } | |||
149 | } | |||
150 | ||||
151 | // Flatten the dots in a module name. Unlike Clang's hierarchical module map | |||
152 | // modules, the dots here are just another character that can appear in a | |||
153 | // module name. | |||
154 | std::string ModuleName; | |||
155 | for (auto &Piece : Path) { | |||
156 | if (!ModuleName.empty()) | |||
157 | ModuleName += "."; | |||
158 | ModuleName += Piece.first->getName(); | |||
159 | } | |||
160 | ||||
161 | // If a module name was explicitly specified on the command line, it must be | |||
162 | // correct. | |||
163 | if (!getLangOpts().CurrentModule.empty() && | |||
164 | getLangOpts().CurrentModule != ModuleName) { | |||
165 | Diag(Path.front().second, diag::err_current_module_name_mismatch) | |||
166 | << SourceRange(Path.front().second, Path.back().second) | |||
167 | << getLangOpts().CurrentModule; | |||
168 | return nullptr; | |||
169 | } | |||
170 | const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName; | |||
171 | ||||
172 | auto &Map = PP.getHeaderSearchInfo().getModuleMap(); | |||
173 | Module *Mod; | |||
174 | ||||
175 | switch (MDK) { | |||
176 | case ModuleDeclKind::Interface: { | |||
177 | // We can't have parsed or imported a definition of this module or parsed a | |||
178 | // module map defining it already. | |||
179 | if (auto *M = Map.findModule(ModuleName)) { | |||
180 | Diag(Path[0].second, diag::err_module_redefinition) << ModuleName; | |||
181 | if (M->DefinitionLoc.isValid()) | |||
182 | Diag(M->DefinitionLoc, diag::note_prev_module_definition); | |||
183 | else if (Optional<FileEntryRef> FE = M->getASTFile()) | |||
184 | Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file) | |||
185 | << FE->getName(); | |||
186 | Mod = M; | |||
187 | break; | |||
188 | } | |||
189 | ||||
190 | // Create a Module for the module that we're defining. | |||
191 | Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName, | |||
192 | GlobalModuleFragment); | |||
193 | assert(Mod && "module creation should not fail")(static_cast <bool> (Mod && "module creation should not fail" ) ? void (0) : __assert_fail ("Mod && \"module creation should not fail\"" , "clang/lib/Sema/SemaModule.cpp", 193, __extension__ __PRETTY_FUNCTION__ )); | |||
194 | break; | |||
195 | } | |||
196 | ||||
197 | case ModuleDeclKind::Implementation: | |||
198 | std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc( | |||
199 | PP.getIdentifierInfo(ModuleName), Path[0].second); | |||
200 | Mod = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc}, | |||
201 | Module::AllVisible, | |||
202 | /*IsInclusionDirective=*/false); | |||
203 | if (!Mod) { | |||
204 | Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName; | |||
205 | // Create an empty module interface unit for error recovery. | |||
206 | Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName, | |||
207 | GlobalModuleFragment); | |||
208 | } | |||
209 | break; | |||
210 | } | |||
211 | ||||
212 | if (!GlobalModuleFragment) { | |||
213 | ModuleScopes.push_back({}); | |||
214 | if (getLangOpts().ModulesLocalVisibility) | |||
215 | ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules); | |||
216 | } else { | |||
217 | // We're done with the global module fragment now. | |||
218 | ActOnEndOfTranslationUnitFragment(TUFragmentKind::Global); | |||
219 | } | |||
220 | ||||
221 | // Switch from the global module fragment (if any) to the named module. | |||
222 | ModuleScopes.back().BeginLoc = StartLoc; | |||
223 | ModuleScopes.back().Module = Mod; | |||
224 | ModuleScopes.back().ModuleInterface = MDK != ModuleDeclKind::Implementation; | |||
225 | VisibleModules.setVisible(Mod, ModuleLoc); | |||
226 | ||||
227 | // From now on, we have an owning module for all declarations we see. | |||
228 | // However, those declarations are module-private unless explicitly | |||
229 | // exported. | |||
230 | auto *TU = Context.getTranslationUnitDecl(); | |||
231 | TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate); | |||
232 | TU->setLocalOwningModule(Mod); | |||
233 | ||||
234 | // FIXME: Create a ModuleDecl. | |||
235 | return nullptr; | |||
236 | } | |||
237 | ||||
238 | Sema::DeclGroupPtrTy | |||
239 | Sema::ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, | |||
240 | SourceLocation PrivateLoc) { | |||
241 | // C++20 [basic.link]/2: | |||
242 | // A private-module-fragment shall appear only in a primary module | |||
243 | // interface unit. | |||
244 | switch (ModuleScopes.empty() ? Module::GlobalModuleFragment | |||
245 | : ModuleScopes.back().Module->Kind) { | |||
246 | case Module::ModuleMapModule: | |||
247 | case Module::GlobalModuleFragment: | |||
248 | Diag(PrivateLoc, diag::err_private_module_fragment_not_module); | |||
249 | return nullptr; | |||
250 | ||||
251 | case Module::PrivateModuleFragment: | |||
252 | Diag(PrivateLoc, diag::err_private_module_fragment_redefined); | |||
253 | Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition); | |||
254 | return nullptr; | |||
255 | ||||
256 | case Module::ModuleInterfaceUnit: | |||
257 | break; | |||
258 | } | |||
259 | ||||
260 | if (!ModuleScopes.back().ModuleInterface) { | |||
261 | Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface); | |||
262 | Diag(ModuleScopes.back().BeginLoc, | |||
263 | diag::note_not_module_interface_add_export) | |||
264 | << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export "); | |||
265 | return nullptr; | |||
266 | } | |||
267 | ||||
268 | // FIXME: Check this isn't a module interface partition. | |||
269 | // FIXME: Check that this translation unit does not import any partitions; | |||
270 | // such imports would violate [basic.link]/2's "shall be the only module unit" | |||
271 | // restriction. | |||
272 | ||||
273 | // We've finished the public fragment of the translation unit. | |||
274 | ActOnEndOfTranslationUnitFragment(TUFragmentKind::Normal); | |||
275 | ||||
276 | auto &Map = PP.getHeaderSearchInfo().getModuleMap(); | |||
277 | Module *PrivateModuleFragment = | |||
278 | Map.createPrivateModuleFragmentForInterfaceUnit( | |||
279 | ModuleScopes.back().Module, PrivateLoc); | |||
280 | assert(PrivateModuleFragment && "module creation should not fail")(static_cast <bool> (PrivateModuleFragment && "module creation should not fail" ) ? void (0) : __assert_fail ("PrivateModuleFragment && \"module creation should not fail\"" , "clang/lib/Sema/SemaModule.cpp", 280, __extension__ __PRETTY_FUNCTION__ )); | |||
281 | ||||
282 | // Enter the scope of the private module fragment. | |||
283 | ModuleScopes.push_back({}); | |||
284 | ModuleScopes.back().BeginLoc = ModuleLoc; | |||
285 | ModuleScopes.back().Module = PrivateModuleFragment; | |||
286 | ModuleScopes.back().ModuleInterface = true; | |||
287 | VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc); | |||
288 | ||||
289 | // All declarations created from now on are scoped to the private module | |||
290 | // fragment (and are neither visible nor reachable in importers of the module | |||
291 | // interface). | |||
292 | auto *TU = Context.getTranslationUnitDecl(); | |||
293 | TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate); | |||
294 | TU->setLocalOwningModule(PrivateModuleFragment); | |||
295 | ||||
296 | // FIXME: Consider creating an explicit representation of this declaration. | |||
297 | return nullptr; | |||
298 | } | |||
299 | ||||
300 | DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, | |||
301 | SourceLocation ExportLoc, | |||
302 | SourceLocation ImportLoc, | |||
303 | ModuleIdPath Path) { | |||
304 | // Flatten the module path for a Modules TS module name. | |||
305 | std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc; | |||
306 | if (getLangOpts().ModulesTS) { | |||
307 | std::string ModuleName; | |||
308 | for (auto &Piece : Path) { | |||
309 | if (!ModuleName.empty()) | |||
310 | ModuleName += "."; | |||
311 | ModuleName += Piece.first->getName(); | |||
312 | } | |||
313 | ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second}; | |||
314 | Path = ModuleIdPath(ModuleNameLoc); | |||
315 | } | |||
316 | ||||
317 | Module *Mod = | |||
318 | getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible, | |||
319 | /*IsInclusionDirective=*/false); | |||
320 | if (!Mod) | |||
321 | return true; | |||
322 | ||||
323 | return ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Mod, Path); | |||
324 | } | |||
325 | ||||
326 | /// Determine whether \p D is lexically within an export-declaration. | |||
327 | static const ExportDecl *getEnclosingExportDecl(const Decl *D) { | |||
328 | for (auto *DC = D->getLexicalDeclContext(); DC; DC = DC->getLexicalParent()) | |||
329 | if (auto *ED = dyn_cast<ExportDecl>(DC)) | |||
330 | return ED; | |||
331 | return nullptr; | |||
332 | } | |||
333 | ||||
334 | DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, | |||
335 | SourceLocation ExportLoc, | |||
336 | SourceLocation ImportLoc, | |||
337 | Module *Mod, ModuleIdPath Path) { | |||
338 | VisibleModules.setVisible(Mod, ImportLoc); | |||
339 | ||||
340 | checkModuleImportContext(*this, Mod, ImportLoc, CurContext); | |||
341 | ||||
342 | // FIXME: we should support importing a submodule within a different submodule | |||
343 | // of the same top-level module. Until we do, make it an error rather than | |||
344 | // silently ignoring the import. | |||
345 | // Import-from-implementation is valid in the Modules TS. FIXME: Should we | |||
346 | // warn on a redundant import of the current module? | |||
347 | // FIXME: Import of a module from an implementation partition of the same | |||
348 | // module is permitted. | |||
349 | if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule && | |||
350 | (getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS)) { | |||
351 | Diag(ImportLoc, getLangOpts().isCompilingModule() | |||
352 | ? diag::err_module_self_import | |||
353 | : diag::err_module_import_in_implementation) | |||
354 | << Mod->getFullModuleName() << getLangOpts().CurrentModule; | |||
355 | } | |||
356 | ||||
357 | SmallVector<SourceLocation, 2> IdentifierLocs; | |||
358 | Module *ModCheck = Mod; | |||
359 | for (unsigned I = 0, N = Path.size(); I != N; ++I) { | |||
360 | // If we've run out of module parents, just drop the remaining identifiers. | |||
361 | // We need the length to be consistent. | |||
362 | if (!ModCheck) | |||
363 | break; | |||
364 | ModCheck = ModCheck->Parent; | |||
365 | ||||
366 | IdentifierLocs.push_back(Path[I].second); | |||
367 | } | |||
368 | ||||
369 | // If this was a header import, pad out with dummy locations. | |||
370 | // FIXME: Pass in and use the location of the header-name token in this case. | |||
371 | if (Path.empty()) { | |||
372 | for (; ModCheck; ModCheck = ModCheck->Parent) { | |||
373 | IdentifierLocs.push_back(SourceLocation()); | |||
374 | } | |||
375 | } | |||
376 | ||||
377 | ImportDecl *Import = ImportDecl::Create(Context, CurContext, StartLoc, | |||
378 | Mod, IdentifierLocs); | |||
379 | CurContext->addDecl(Import); | |||
380 | ||||
381 | // Sequence initialization of the imported module before that of the current | |||
382 | // module, if any. | |||
383 | if (!ModuleScopes.empty()) | |||
384 | Context.addModuleInitializer(ModuleScopes.back().Module, Import); | |||
385 | ||||
386 | if (!ModuleScopes.empty() && ModuleScopes.back().ModuleInterface) { | |||
387 | // Re-export the module if the imported module is exported. | |||
388 | // Note that we don't need to add re-exported module to Imports field | |||
389 | // since `Exports` implies the module is imported already. | |||
390 | if (ExportLoc.isValid() || getEnclosingExportDecl(Import)) | |||
391 | getCurrentModule()->Exports.emplace_back(Mod, false); | |||
392 | else | |||
393 | getCurrentModule()->Imports.insert(Mod); | |||
394 | } else if (ExportLoc.isValid()) { | |||
395 | // [module.interface]p1: | |||
396 | // An export-declaration shall inhabit a namespace scope and appear in the | |||
397 | // purview of a module interface unit. | |||
398 | Diag(ExportLoc, diag::err_export_not_in_module_interface); | |||
399 | } | |||
400 | ||||
401 | return Import; | |||
402 | } | |||
403 | ||||
404 | void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { | |||
405 | checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true); | |||
406 | BuildModuleInclude(DirectiveLoc, Mod); | |||
407 | } | |||
408 | ||||
409 | void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { | |||
410 | // Determine whether we're in the #include buffer for a module. The #includes | |||
411 | // in that buffer do not qualify as module imports; they're just an | |||
412 | // implementation detail of us building the module. | |||
413 | // | |||
414 | // FIXME: Should we even get ActOnModuleInclude calls for those? | |||
415 | bool IsInModuleIncludes = | |||
416 | TUKind == TU_Module && | |||
417 | getSourceManager().isWrittenInMainFile(DirectiveLoc); | |||
418 | ||||
419 | bool ShouldAddImport = !IsInModuleIncludes; | |||
420 | ||||
421 | // If this module import was due to an inclusion directive, create an | |||
422 | // implicit import declaration to capture it in the AST. | |||
423 | if (ShouldAddImport) { | |||
424 | TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); | |||
425 | ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, | |||
426 | DirectiveLoc, Mod, | |||
427 | DirectiveLoc); | |||
428 | if (!ModuleScopes.empty()) | |||
429 | Context.addModuleInitializer(ModuleScopes.back().Module, ImportD); | |||
430 | TU->addDecl(ImportD); | |||
431 | Consumer.HandleImplicitImportDecl(ImportD); | |||
432 | } | |||
433 | ||||
434 | getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc); | |||
435 | VisibleModules.setVisible(Mod, DirectiveLoc); | |||
436 | } | |||
437 | ||||
438 | void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { | |||
439 | checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true); | |||
440 | ||||
441 | ModuleScopes.push_back({}); | |||
442 | ModuleScopes.back().Module = Mod; | |||
443 | if (getLangOpts().ModulesLocalVisibility) | |||
444 | ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules); | |||
445 | ||||
446 | VisibleModules.setVisible(Mod, DirectiveLoc); | |||
447 | ||||
448 | // The enclosing context is now part of this module. | |||
449 | // FIXME: Consider creating a child DeclContext to hold the entities | |||
450 | // lexically within the module. | |||
451 | if (getLangOpts().trackLocalOwningModule()) { | |||
452 | for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) { | |||
453 | cast<Decl>(DC)->setModuleOwnershipKind( | |||
454 | getLangOpts().ModulesLocalVisibility | |||
455 | ? Decl::ModuleOwnershipKind::VisibleWhenImported | |||
456 | : Decl::ModuleOwnershipKind::Visible); | |||
457 | cast<Decl>(DC)->setLocalOwningModule(Mod); | |||
458 | } | |||
459 | } | |||
460 | } | |||
461 | ||||
462 | void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) { | |||
463 | if (getLangOpts().ModulesLocalVisibility) { | |||
464 | VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules); | |||
465 | // Leaving a module hides namespace names, so our visible namespace cache | |||
466 | // is now out of date. | |||
467 | VisibleNamespaceCache.clear(); | |||
468 | } | |||
469 | ||||
470 | assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&(static_cast <bool> (!ModuleScopes.empty() && ModuleScopes .back().Module == Mod && "left the wrong module scope" ) ? void (0) : __assert_fail ("!ModuleScopes.empty() && ModuleScopes.back().Module == Mod && \"left the wrong module scope\"" , "clang/lib/Sema/SemaModule.cpp", 471, __extension__ __PRETTY_FUNCTION__ )) | |||
471 | "left the wrong module scope")(static_cast <bool> (!ModuleScopes.empty() && ModuleScopes .back().Module == Mod && "left the wrong module scope" ) ? void (0) : __assert_fail ("!ModuleScopes.empty() && ModuleScopes.back().Module == Mod && \"left the wrong module scope\"" , "clang/lib/Sema/SemaModule.cpp", 471, __extension__ __PRETTY_FUNCTION__ )); | |||
472 | ModuleScopes.pop_back(); | |||
473 | ||||
474 | // We got to the end of processing a local module. Create an | |||
475 | // ImportDecl as we would for an imported module. | |||
476 | FileID File = getSourceManager().getFileID(EomLoc); | |||
477 | SourceLocation DirectiveLoc; | |||
478 | if (EomLoc == getSourceManager().getLocForEndOfFile(File)) { | |||
479 | // We reached the end of a #included module header. Use the #include loc. | |||
480 | assert(File != getSourceManager().getMainFileID() &&(static_cast <bool> (File != getSourceManager().getMainFileID () && "end of submodule in main source file") ? void ( 0) : __assert_fail ("File != getSourceManager().getMainFileID() && \"end of submodule in main source file\"" , "clang/lib/Sema/SemaModule.cpp", 481, __extension__ __PRETTY_FUNCTION__ )) | |||
481 | "end of submodule in main source file")(static_cast <bool> (File != getSourceManager().getMainFileID () && "end of submodule in main source file") ? void ( 0) : __assert_fail ("File != getSourceManager().getMainFileID() && \"end of submodule in main source file\"" , "clang/lib/Sema/SemaModule.cpp", 481, __extension__ __PRETTY_FUNCTION__ )); | |||
482 | DirectiveLoc = getSourceManager().getIncludeLoc(File); | |||
483 | } else { | |||
484 | // We reached an EOM pragma. Use the pragma location. | |||
485 | DirectiveLoc = EomLoc; | |||
486 | } | |||
487 | BuildModuleInclude(DirectiveLoc, Mod); | |||
488 | ||||
489 | // Any further declarations are in whatever module we returned to. | |||
490 | if (getLangOpts().trackLocalOwningModule()) { | |||
491 | // The parser guarantees that this is the same context that we entered | |||
492 | // the module within. | |||
493 | for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) { | |||
494 | cast<Decl>(DC)->setLocalOwningModule(getCurrentModule()); | |||
495 | if (!getCurrentModule()) | |||
496 | cast<Decl>(DC)->setModuleOwnershipKind( | |||
497 | Decl::ModuleOwnershipKind::Unowned); | |||
498 | } | |||
499 | } | |||
500 | } | |||
501 | ||||
502 | void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc, | |||
503 | Module *Mod) { | |||
504 | // Bail if we're not allowed to implicitly import a module here. | |||
505 | if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery || | |||
506 | VisibleModules.isVisible(Mod)) | |||
507 | return; | |||
508 | ||||
509 | // Create the implicit import declaration. | |||
510 | TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); | |||
511 | ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, | |||
512 | Loc, Mod, Loc); | |||
513 | TU->addDecl(ImportD); | |||
514 | Consumer.HandleImplicitImportDecl(ImportD); | |||
515 | ||||
516 | // Make the module visible. | |||
517 | getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc); | |||
518 | VisibleModules.setVisible(Mod, Loc); | |||
519 | } | |||
520 | ||||
521 | /// We have parsed the start of an export declaration, including the '{' | |||
522 | /// (if present). | |||
523 | Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, | |||
524 | SourceLocation LBraceLoc) { | |||
525 | ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc); | |||
526 | ||||
527 | // Set this temporarily so we know the export-declaration was braced. | |||
528 | D->setRBraceLoc(LBraceLoc); | |||
529 | ||||
530 | // C++2a [module.interface]p1: | |||
531 | // An export-declaration shall appear only [...] in the purview of a module | |||
532 | // interface unit. An export-declaration shall not appear directly or | |||
533 | // indirectly within [...] a private-module-fragment. | |||
534 | if (ModuleScopes.empty() || !ModuleScopes.back().Module->isModulePurview()) { | |||
| ||||
535 | Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0; | |||
536 | } else if (!ModuleScopes.back().ModuleInterface) { | |||
537 | Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1; | |||
538 | Diag(ModuleScopes.back().BeginLoc, | |||
539 | diag::note_not_module_interface_add_export) | |||
540 | << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export "); | |||
541 | } else if (ModuleScopes.back().Module->Kind == | |||
542 | Module::PrivateModuleFragment) { | |||
543 | Diag(ExportLoc, diag::err_export_in_private_module_fragment); | |||
544 | Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment); | |||
545 | } | |||
546 | ||||
547 | for (const DeclContext *DC = CurContext; DC; DC = DC->getLexicalParent()) { | |||
548 | if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) { | |||
549 | // An export-declaration shall not appear directly or indirectly within | |||
550 | // an unnamed namespace [...] | |||
551 | if (ND->isAnonymousNamespace()) { | |||
552 | Diag(ExportLoc, diag::err_export_within_anonymous_namespace); | |||
553 | Diag(ND->getLocation(), diag::note_anonymous_namespace); | |||
554 | // Don't diagnose internal-linkage declarations in this region. | |||
555 | D->setInvalidDecl(); | |||
556 | break; | |||
557 | } | |||
558 | ||||
559 | // A declaration is exported if it is [...] a namespace-definition | |||
560 | // that contains an exported declaration. | |||
561 | // | |||
562 | // Defer exporting the namespace until after we leave it, in order to | |||
563 | // avoid marking all subsequent declarations in the namespace as exported. | |||
564 | if (!DeferredExportedNamespaces.insert(ND).second) | |||
565 | break; | |||
566 | } | |||
567 | } | |||
568 | ||||
569 | // [...] its declaration or declaration-seq shall not contain an | |||
570 | // export-declaration. | |||
571 | if (auto *ED = getEnclosingExportDecl(D)) { | |||
572 | Diag(ExportLoc, diag::err_export_within_export); | |||
573 | if (ED->hasBraces()) | |||
574 | Diag(ED->getLocation(), diag::note_export); | |||
575 | } | |||
576 | ||||
577 | CurContext->addDecl(D); | |||
| ||||
578 | PushDeclContext(S, D); | |||
579 | D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported); | |||
580 | return D; | |||
581 | } | |||
582 | ||||
583 | static bool checkExportedDeclContext(Sema &S, DeclContext *DC, | |||
584 | SourceLocation BlockStart); | |||
585 | ||||
586 | namespace { | |||
587 | enum class UnnamedDeclKind { | |||
588 | Empty, | |||
589 | StaticAssert, | |||
590 | Asm, | |||
591 | UsingDirective, | |||
592 | Context | |||
593 | }; | |||
594 | } | |||
595 | ||||
596 | static llvm::Optional<UnnamedDeclKind> getUnnamedDeclKind(Decl *D) { | |||
597 | if (isa<EmptyDecl>(D)) | |||
598 | return UnnamedDeclKind::Empty; | |||
599 | if (isa<StaticAssertDecl>(D)) | |||
600 | return UnnamedDeclKind::StaticAssert; | |||
601 | if (isa<FileScopeAsmDecl>(D)) | |||
602 | return UnnamedDeclKind::Asm; | |||
603 | if (isa<UsingDirectiveDecl>(D)) | |||
604 | return UnnamedDeclKind::UsingDirective; | |||
605 | // Everything else either introduces one or more names or is ill-formed. | |||
606 | return llvm::None; | |||
607 | } | |||
608 | ||||
609 | unsigned getUnnamedDeclDiag(UnnamedDeclKind UDK, bool InBlock) { | |||
610 | switch (UDK) { | |||
611 | case UnnamedDeclKind::Empty: | |||
612 | case UnnamedDeclKind::StaticAssert: | |||
613 | // Allow empty-declarations and static_asserts in an export block as an | |||
614 | // extension. | |||
615 | return InBlock ? diag::ext_export_no_name_block : diag::err_export_no_name; | |||
616 | ||||
617 | case UnnamedDeclKind::UsingDirective: | |||
618 | // Allow exporting using-directives as an extension. | |||
619 | return diag::ext_export_using_directive; | |||
620 | ||||
621 | case UnnamedDeclKind::Context: | |||
622 | // Allow exporting DeclContexts that transitively contain no declarations | |||
623 | // as an extension. | |||
624 | return diag::ext_export_no_names; | |||
625 | ||||
626 | case UnnamedDeclKind::Asm: | |||
627 | return diag::err_export_no_name; | |||
628 | } | |||
629 | llvm_unreachable("unknown kind")::llvm::llvm_unreachable_internal("unknown kind", "clang/lib/Sema/SemaModule.cpp" , 629); | |||
630 | } | |||
631 | ||||
632 | static void diagExportedUnnamedDecl(Sema &S, UnnamedDeclKind UDK, Decl *D, | |||
633 | SourceLocation BlockStart) { | |||
634 | S.Diag(D->getLocation(), getUnnamedDeclDiag(UDK, BlockStart.isValid())) | |||
635 | << (unsigned)UDK; | |||
636 | if (BlockStart.isValid()) | |||
637 | S.Diag(BlockStart, diag::note_export); | |||
638 | } | |||
639 | ||||
640 | /// Check that it's valid to export \p D. | |||
641 | static bool checkExportedDecl(Sema &S, Decl *D, SourceLocation BlockStart) { | |||
642 | // C++2a [module.interface]p3: | |||
643 | // An exported declaration shall declare at least one name | |||
644 | if (auto UDK = getUnnamedDeclKind(D)) | |||
645 | diagExportedUnnamedDecl(S, *UDK, D, BlockStart); | |||
646 | ||||
647 | // [...] shall not declare a name with internal linkage. | |||
648 | if (auto *ND = dyn_cast<NamedDecl>(D)) { | |||
649 | // Don't diagnose anonymous union objects; we'll diagnose their members | |||
650 | // instead. | |||
651 | if (ND->getDeclName() && ND->getFormalLinkage() == InternalLinkage) { | |||
652 | S.Diag(ND->getLocation(), diag::err_export_internal) << ND; | |||
653 | if (BlockStart.isValid()) | |||
654 | S.Diag(BlockStart, diag::note_export); | |||
655 | } | |||
656 | } | |||
657 | ||||
658 | // C++2a [module.interface]p5: | |||
659 | // all entities to which all of the using-declarators ultimately refer | |||
660 | // shall have been introduced with a name having external linkage | |||
661 | if (auto *USD = dyn_cast<UsingShadowDecl>(D)) { | |||
662 | NamedDecl *Target = USD->getUnderlyingDecl(); | |||
663 | if (Target->getFormalLinkage() == InternalLinkage) { | |||
664 | S.Diag(USD->getLocation(), diag::err_export_using_internal) << Target; | |||
665 | S.Diag(Target->getLocation(), diag::note_using_decl_target); | |||
666 | if (BlockStart.isValid()) | |||
667 | S.Diag(BlockStart, diag::note_export); | |||
668 | } | |||
669 | } | |||
670 | ||||
671 | // Recurse into namespace-scope DeclContexts. (Only namespace-scope | |||
672 | // declarations are exported.) | |||
673 | if (auto *DC = dyn_cast<DeclContext>(D)) | |||
674 | if (DC->getRedeclContext()->isFileContext() && !isa<EnumDecl>(D)) | |||
675 | return checkExportedDeclContext(S, DC, BlockStart); | |||
676 | return false; | |||
677 | } | |||
678 | ||||
679 | /// Check that it's valid to export all the declarations in \p DC. | |||
680 | static bool checkExportedDeclContext(Sema &S, DeclContext *DC, | |||
681 | SourceLocation BlockStart) { | |||
682 | bool AllUnnamed = true; | |||
683 | for (auto *D : DC->decls()) | |||
684 | AllUnnamed &= checkExportedDecl(S, D, BlockStart); | |||
685 | return AllUnnamed; | |||
686 | } | |||
687 | ||||
688 | /// Complete the definition of an export declaration. | |||
689 | Decl *Sema::ActOnFinishExportDecl(Scope *S, Decl *D, SourceLocation RBraceLoc) { | |||
690 | auto *ED = cast<ExportDecl>(D); | |||
691 | if (RBraceLoc.isValid()) | |||
692 | ED->setRBraceLoc(RBraceLoc); | |||
693 | ||||
694 | PopDeclContext(); | |||
695 | ||||
696 | if (!D->isInvalidDecl()) { | |||
697 | SourceLocation BlockStart = | |||
698 | ED->hasBraces() ? ED->getBeginLoc() : SourceLocation(); | |||
699 | for (auto *Child : ED->decls()) { | |||
700 | if (checkExportedDecl(*this, Child, BlockStart)) { | |||
701 | // If a top-level child is a linkage-spec declaration, it might contain | |||
702 | // no declarations (transitively), in which case it's ill-formed. | |||
703 | diagExportedUnnamedDecl(*this, UnnamedDeclKind::Context, Child, | |||
704 | BlockStart); | |||
705 | } | |||
706 | } | |||
707 | } | |||
708 | ||||
709 | return D; | |||
710 | } | |||
711 | ||||
712 | Module *Sema::PushGlobalModuleFragment(SourceLocation BeginLoc, | |||
713 | bool IsImplicit) { | |||
714 | ModuleMap &Map = PP.getHeaderSearchInfo().getModuleMap(); | |||
715 | Module *GlobalModule = | |||
716 | Map.createGlobalModuleFragmentForModuleUnit(BeginLoc, getCurrentModule()); | |||
717 | assert(GlobalModule && "module creation should not fail")(static_cast <bool> (GlobalModule && "module creation should not fail" ) ? void (0) : __assert_fail ("GlobalModule && \"module creation should not fail\"" , "clang/lib/Sema/SemaModule.cpp", 717, __extension__ __PRETTY_FUNCTION__ )); | |||
718 | ||||
719 | // Enter the scope of the global module. | |||
720 | ModuleScopes.push_back({BeginLoc, GlobalModule, | |||
721 | /*ModuleInterface=*/false, | |||
722 | /*ImplicitGlobalModuleFragment=*/IsImplicit, | |||
723 | /*VisibleModuleSet*/{}}); | |||
724 | VisibleModules.setVisible(GlobalModule, BeginLoc); | |||
725 | ||||
726 | return GlobalModule; | |||
727 | } | |||
728 | ||||
729 | void Sema::PopGlobalModuleFragment() { | |||
730 | assert(!ModuleScopes.empty() && getCurrentModule()->isGlobalModule() &&(static_cast <bool> (!ModuleScopes.empty() && getCurrentModule ()->isGlobalModule() && "left the wrong module scope, which is not global module fragment" ) ? void (0) : __assert_fail ("!ModuleScopes.empty() && getCurrentModule()->isGlobalModule() && \"left the wrong module scope, which is not global module fragment\"" , "clang/lib/Sema/SemaModule.cpp", 731, __extension__ __PRETTY_FUNCTION__ )) | |||
731 | "left the wrong module scope, which is not global module fragment")(static_cast <bool> (!ModuleScopes.empty() && getCurrentModule ()->isGlobalModule() && "left the wrong module scope, which is not global module fragment" ) ? void (0) : __assert_fail ("!ModuleScopes.empty() && getCurrentModule()->isGlobalModule() && \"left the wrong module scope, which is not global module fragment\"" , "clang/lib/Sema/SemaModule.cpp", 731, __extension__ __PRETTY_FUNCTION__ )); | |||
732 | ModuleScopes.pop_back(); | |||
733 | } |