1b7bdb8cfSRichard Smith //===--- SemaModule.cpp - Semantic Analysis for Modules -------------------===//
2b7bdb8cfSRichard Smith //
3b7bdb8cfSRichard Smith // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4b7bdb8cfSRichard Smith // See https://llvm.org/LICENSE.txt for license information.
5b7bdb8cfSRichard Smith // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6b7bdb8cfSRichard Smith //
7b7bdb8cfSRichard Smith //===----------------------------------------------------------------------===//
8b7bdb8cfSRichard Smith //
9b7bdb8cfSRichard Smith //  This file implements semantic analysis for modules (C++ modules syntax,
10b7bdb8cfSRichard Smith //  Objective-C modules syntax, and Clang header modules).
11b7bdb8cfSRichard Smith //
12b7bdb8cfSRichard Smith //===----------------------------------------------------------------------===//
13b7bdb8cfSRichard Smith 
14b7bdb8cfSRichard Smith #include "clang/AST/ASTConsumer.h"
15b7bdb8cfSRichard Smith #include "clang/Lex/HeaderSearch.h"
16b7bdb8cfSRichard Smith #include "clang/Lex/Preprocessor.h"
17b7bdb8cfSRichard Smith #include "clang/Sema/SemaInternal.h"
18b7bdb8cfSRichard Smith 
19b7bdb8cfSRichard Smith using namespace clang;
20b7bdb8cfSRichard Smith using namespace sema;
21b7bdb8cfSRichard Smith 
22b7bdb8cfSRichard Smith static void checkModuleImportContext(Sema &S, Module *M,
23b7bdb8cfSRichard Smith                                      SourceLocation ImportLoc, DeclContext *DC,
24b7bdb8cfSRichard Smith                                      bool FromInclude = false) {
25b7bdb8cfSRichard Smith   SourceLocation ExternCLoc;
26b7bdb8cfSRichard Smith 
27b7bdb8cfSRichard Smith   if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) {
28b7bdb8cfSRichard Smith     switch (LSD->getLanguage()) {
29b7bdb8cfSRichard Smith     case LinkageSpecDecl::lang_c:
30b7bdb8cfSRichard Smith       if (ExternCLoc.isInvalid())
31b7bdb8cfSRichard Smith         ExternCLoc = LSD->getBeginLoc();
32b7bdb8cfSRichard Smith       break;
33b7bdb8cfSRichard Smith     case LinkageSpecDecl::lang_cxx:
34b7bdb8cfSRichard Smith       break;
35b7bdb8cfSRichard Smith     }
36b7bdb8cfSRichard Smith     DC = LSD->getParent();
37b7bdb8cfSRichard Smith   }
38b7bdb8cfSRichard Smith 
39b7bdb8cfSRichard Smith   while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC))
40b7bdb8cfSRichard Smith     DC = DC->getParent();
41b7bdb8cfSRichard Smith 
42b7bdb8cfSRichard Smith   if (!isa<TranslationUnitDecl>(DC)) {
43b7bdb8cfSRichard Smith     S.Diag(ImportLoc, (FromInclude && S.isModuleVisible(M))
44b7bdb8cfSRichard Smith                           ? diag::ext_module_import_not_at_top_level_noop
45b7bdb8cfSRichard Smith                           : diag::err_module_import_not_at_top_level_fatal)
46b7bdb8cfSRichard Smith         << M->getFullModuleName() << DC;
47b7bdb8cfSRichard Smith     S.Diag(cast<Decl>(DC)->getBeginLoc(),
48b7bdb8cfSRichard Smith            diag::note_module_import_not_at_top_level)
49b7bdb8cfSRichard Smith         << DC;
50b7bdb8cfSRichard Smith   } else if (!M->IsExternC && ExternCLoc.isValid()) {
51b7bdb8cfSRichard Smith     S.Diag(ImportLoc, diag::ext_module_import_in_extern_c)
52b7bdb8cfSRichard Smith       << M->getFullModuleName();
53b7bdb8cfSRichard Smith     S.Diag(ExternCLoc, diag::note_extern_c_begins_here);
54b7bdb8cfSRichard Smith   }
55b7bdb8cfSRichard Smith }
56b7bdb8cfSRichard Smith 
57b7bdb8cfSRichard Smith Sema::DeclGroupPtrTy
58b7bdb8cfSRichard Smith Sema::ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc) {
59b7bdb8cfSRichard Smith   if (!ModuleScopes.empty() &&
60b7bdb8cfSRichard Smith       ModuleScopes.back().Module->Kind == Module::GlobalModuleFragment) {
61b7bdb8cfSRichard Smith     // Under -std=c++2a -fmodules-ts, we can find an explicit 'module;' after
62b7bdb8cfSRichard Smith     // already implicitly entering the global module fragment. That's OK.
63b7bdb8cfSRichard Smith     assert(getLangOpts().CPlusPlusModules && getLangOpts().ModulesTS &&
64b7bdb8cfSRichard Smith            "unexpectedly encountered multiple global module fragment decls");
65b7bdb8cfSRichard Smith     ModuleScopes.back().BeginLoc = ModuleLoc;
66b7bdb8cfSRichard Smith     return nullptr;
67b7bdb8cfSRichard Smith   }
68b7bdb8cfSRichard Smith 
69b7bdb8cfSRichard Smith   // We start in the global module; all those declarations are implicitly
70b7bdb8cfSRichard Smith   // module-private (though they do not have module linkage).
71b7bdb8cfSRichard Smith   auto &Map = PP.getHeaderSearchInfo().getModuleMap();
72*a5bbbfefSRichard Smith   auto *GlobalModule = Map.createGlobalModuleFragmentForModuleUnit(ModuleLoc);
73b7bdb8cfSRichard Smith   assert(GlobalModule && "module creation should not fail");
74b7bdb8cfSRichard Smith 
75b7bdb8cfSRichard Smith   // Enter the scope of the global module.
76b7bdb8cfSRichard Smith   ModuleScopes.push_back({});
77b7bdb8cfSRichard Smith   ModuleScopes.back().BeginLoc = ModuleLoc;
78b7bdb8cfSRichard Smith   ModuleScopes.back().Module = GlobalModule;
79b7bdb8cfSRichard Smith   VisibleModules.setVisible(GlobalModule, ModuleLoc);
80b7bdb8cfSRichard Smith 
81b7bdb8cfSRichard Smith   // All declarations created from now on are owned by the global module.
82b7bdb8cfSRichard Smith   auto *TU = Context.getTranslationUnitDecl();
83b7bdb8cfSRichard Smith   TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::Visible);
84b7bdb8cfSRichard Smith   TU->setLocalOwningModule(GlobalModule);
85b7bdb8cfSRichard Smith 
86b7bdb8cfSRichard Smith   // FIXME: Consider creating an explicit representation of this declaration.
87b7bdb8cfSRichard Smith   return nullptr;
88b7bdb8cfSRichard Smith }
89b7bdb8cfSRichard Smith 
90b7bdb8cfSRichard Smith Sema::DeclGroupPtrTy
91b7bdb8cfSRichard Smith Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc,
92b7bdb8cfSRichard Smith                       ModuleDeclKind MDK, ModuleIdPath Path, bool IsFirstDecl) {
93b7bdb8cfSRichard Smith   assert((getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) &&
94b7bdb8cfSRichard Smith          "should only have module decl in Modules TS or C++20");
95b7bdb8cfSRichard Smith 
96b7bdb8cfSRichard Smith   // A module implementation unit requires that we are not compiling a module
97b7bdb8cfSRichard Smith   // of any kind. A module interface unit requires that we are not compiling a
98b7bdb8cfSRichard Smith   // module map.
99b7bdb8cfSRichard Smith   switch (getLangOpts().getCompilingModule()) {
100b7bdb8cfSRichard Smith   case LangOptions::CMK_None:
101b7bdb8cfSRichard Smith     // It's OK to compile a module interface as a normal translation unit.
102b7bdb8cfSRichard Smith     break;
103b7bdb8cfSRichard Smith 
104b7bdb8cfSRichard Smith   case LangOptions::CMK_ModuleInterface:
105b7bdb8cfSRichard Smith     if (MDK != ModuleDeclKind::Implementation)
106b7bdb8cfSRichard Smith       break;
107b7bdb8cfSRichard Smith 
108b7bdb8cfSRichard Smith     // We were asked to compile a module interface unit but this is a module
109b7bdb8cfSRichard Smith     // implementation unit. That indicates the 'export' is missing.
110b7bdb8cfSRichard Smith     Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch)
111b7bdb8cfSRichard Smith       << FixItHint::CreateInsertion(ModuleLoc, "export ");
112b7bdb8cfSRichard Smith     MDK = ModuleDeclKind::Interface;
113b7bdb8cfSRichard Smith     break;
114b7bdb8cfSRichard Smith 
115b7bdb8cfSRichard Smith   case LangOptions::CMK_ModuleMap:
116b7bdb8cfSRichard Smith     Diag(ModuleLoc, diag::err_module_decl_in_module_map_module);
117b7bdb8cfSRichard Smith     return nullptr;
118b7bdb8cfSRichard Smith 
119b7bdb8cfSRichard Smith   case LangOptions::CMK_HeaderModule:
120b7bdb8cfSRichard Smith     Diag(ModuleLoc, diag::err_module_decl_in_header_module);
121b7bdb8cfSRichard Smith     return nullptr;
122b7bdb8cfSRichard Smith   }
123b7bdb8cfSRichard Smith 
124b7bdb8cfSRichard Smith   assert(ModuleScopes.size() <= 1 && "expected to be at global module scope");
125b7bdb8cfSRichard Smith 
126b7bdb8cfSRichard Smith   // FIXME: Most of this work should be done by the preprocessor rather than
127b7bdb8cfSRichard Smith   // here, in order to support macro import.
128b7bdb8cfSRichard Smith 
129b7bdb8cfSRichard Smith   // Only one module-declaration is permitted per source file.
130b7bdb8cfSRichard Smith   if (!ModuleScopes.empty() &&
131*a5bbbfefSRichard Smith       ModuleScopes.back().Module->isModulePurview()) {
132b7bdb8cfSRichard Smith     Diag(ModuleLoc, diag::err_module_redeclaration);
133b7bdb8cfSRichard Smith     Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module),
134b7bdb8cfSRichard Smith          diag::note_prev_module_declaration);
135b7bdb8cfSRichard Smith     return nullptr;
136b7bdb8cfSRichard Smith   }
137b7bdb8cfSRichard Smith 
138b7bdb8cfSRichard Smith   // Find the global module fragment we're adopting into this module, if any.
139b7bdb8cfSRichard Smith   Module *GlobalModuleFragment = nullptr;
140b7bdb8cfSRichard Smith   if (!ModuleScopes.empty() &&
141b7bdb8cfSRichard Smith       ModuleScopes.back().Module->Kind == Module::GlobalModuleFragment)
142b7bdb8cfSRichard Smith     GlobalModuleFragment = ModuleScopes.back().Module;
143b7bdb8cfSRichard Smith 
144b7bdb8cfSRichard Smith   // In C++20, the module-declaration must be the first declaration if there
145b7bdb8cfSRichard Smith   // is no global module fragment.
146b7bdb8cfSRichard Smith   if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !GlobalModuleFragment) {
147b7bdb8cfSRichard Smith     Diag(ModuleLoc, diag::err_module_decl_not_at_start);
148b7bdb8cfSRichard Smith     SourceLocation BeginLoc =
149b7bdb8cfSRichard Smith         ModuleScopes.empty()
150b7bdb8cfSRichard Smith             ? SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID())
151b7bdb8cfSRichard Smith             : ModuleScopes.back().BeginLoc;
152b7bdb8cfSRichard Smith     if (BeginLoc.isValid()) {
153b7bdb8cfSRichard Smith       Diag(BeginLoc, diag::note_global_module_introducer_missing)
154b7bdb8cfSRichard Smith           << FixItHint::CreateInsertion(BeginLoc, "module;\n");
155b7bdb8cfSRichard Smith     }
156b7bdb8cfSRichard Smith   }
157b7bdb8cfSRichard Smith 
158b7bdb8cfSRichard Smith   // Flatten the dots in a module name. Unlike Clang's hierarchical module map
159b7bdb8cfSRichard Smith   // modules, the dots here are just another character that can appear in a
160b7bdb8cfSRichard Smith   // module name.
161b7bdb8cfSRichard Smith   std::string ModuleName;
162b7bdb8cfSRichard Smith   for (auto &Piece : Path) {
163b7bdb8cfSRichard Smith     if (!ModuleName.empty())
164b7bdb8cfSRichard Smith       ModuleName += ".";
165b7bdb8cfSRichard Smith     ModuleName += Piece.first->getName();
166b7bdb8cfSRichard Smith   }
167b7bdb8cfSRichard Smith 
168b7bdb8cfSRichard Smith   // If a module name was explicitly specified on the command line, it must be
169b7bdb8cfSRichard Smith   // correct.
170b7bdb8cfSRichard Smith   if (!getLangOpts().CurrentModule.empty() &&
171b7bdb8cfSRichard Smith       getLangOpts().CurrentModule != ModuleName) {
172b7bdb8cfSRichard Smith     Diag(Path.front().second, diag::err_current_module_name_mismatch)
173b7bdb8cfSRichard Smith         << SourceRange(Path.front().second, Path.back().second)
174b7bdb8cfSRichard Smith         << getLangOpts().CurrentModule;
175b7bdb8cfSRichard Smith     return nullptr;
176b7bdb8cfSRichard Smith   }
177b7bdb8cfSRichard Smith   const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName;
178b7bdb8cfSRichard Smith 
179b7bdb8cfSRichard Smith   auto &Map = PP.getHeaderSearchInfo().getModuleMap();
180b7bdb8cfSRichard Smith   Module *Mod;
181b7bdb8cfSRichard Smith 
182b7bdb8cfSRichard Smith   switch (MDK) {
183b7bdb8cfSRichard Smith   case ModuleDeclKind::Interface: {
184b7bdb8cfSRichard Smith     // We can't have parsed or imported a definition of this module or parsed a
185b7bdb8cfSRichard Smith     // module map defining it already.
186b7bdb8cfSRichard Smith     if (auto *M = Map.findModule(ModuleName)) {
187b7bdb8cfSRichard Smith       Diag(Path[0].second, diag::err_module_redefinition) << ModuleName;
188b7bdb8cfSRichard Smith       if (M->DefinitionLoc.isValid())
189b7bdb8cfSRichard Smith         Diag(M->DefinitionLoc, diag::note_prev_module_definition);
190b7bdb8cfSRichard Smith       else if (const auto *FE = M->getASTFile())
191b7bdb8cfSRichard Smith         Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file)
192b7bdb8cfSRichard Smith             << FE->getName();
193b7bdb8cfSRichard Smith       Mod = M;
194b7bdb8cfSRichard Smith       break;
195b7bdb8cfSRichard Smith     }
196b7bdb8cfSRichard Smith 
197b7bdb8cfSRichard Smith     // Create a Module for the module that we're defining.
198b7bdb8cfSRichard Smith     Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
199b7bdb8cfSRichard Smith                                            GlobalModuleFragment);
200b7bdb8cfSRichard Smith     assert(Mod && "module creation should not fail");
201b7bdb8cfSRichard Smith     break;
202b7bdb8cfSRichard Smith   }
203b7bdb8cfSRichard Smith 
204b7bdb8cfSRichard Smith   case ModuleDeclKind::Implementation:
205b7bdb8cfSRichard Smith     std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc(
206b7bdb8cfSRichard Smith         PP.getIdentifierInfo(ModuleName), Path[0].second);
207b7bdb8cfSRichard Smith     Mod = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc},
208b7bdb8cfSRichard Smith                                        Module::AllVisible,
209b7bdb8cfSRichard Smith                                        /*IsIncludeDirective=*/false);
210b7bdb8cfSRichard Smith     if (!Mod) {
211b7bdb8cfSRichard Smith       Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName;
212b7bdb8cfSRichard Smith       // Create an empty module interface unit for error recovery.
213b7bdb8cfSRichard Smith       Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName,
214b7bdb8cfSRichard Smith                                              GlobalModuleFragment);
215b7bdb8cfSRichard Smith     }
216b7bdb8cfSRichard Smith     break;
217b7bdb8cfSRichard Smith   }
218b7bdb8cfSRichard Smith 
219b7bdb8cfSRichard Smith   if (!GlobalModuleFragment) {
220b7bdb8cfSRichard Smith     ModuleScopes.push_back({});
221b7bdb8cfSRichard Smith     if (getLangOpts().ModulesLocalVisibility)
222b7bdb8cfSRichard Smith       ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
223*a5bbbfefSRichard Smith   } else {
224*a5bbbfefSRichard Smith     // We're done with the global module fragment now.
225*a5bbbfefSRichard Smith     ActOnEndOfTranslationUnitFragment(TUFragmentKind::Global);
226b7bdb8cfSRichard Smith   }
227b7bdb8cfSRichard Smith 
228b7bdb8cfSRichard Smith   // Switch from the global module fragment (if any) to the named module.
229b7bdb8cfSRichard Smith   ModuleScopes.back().BeginLoc = StartLoc;
230b7bdb8cfSRichard Smith   ModuleScopes.back().Module = Mod;
231b7bdb8cfSRichard Smith   ModuleScopes.back().ModuleInterface = MDK != ModuleDeclKind::Implementation;
232b7bdb8cfSRichard Smith   VisibleModules.setVisible(Mod, ModuleLoc);
233b7bdb8cfSRichard Smith 
234b7bdb8cfSRichard Smith   // From now on, we have an owning module for all declarations we see.
235b7bdb8cfSRichard Smith   // However, those declarations are module-private unless explicitly
236b7bdb8cfSRichard Smith   // exported.
237b7bdb8cfSRichard Smith   auto *TU = Context.getTranslationUnitDecl();
238b7bdb8cfSRichard Smith   TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
239b7bdb8cfSRichard Smith   TU->setLocalOwningModule(Mod);
240b7bdb8cfSRichard Smith 
241b7bdb8cfSRichard Smith   // FIXME: Create a ModuleDecl.
242b7bdb8cfSRichard Smith   return nullptr;
243b7bdb8cfSRichard Smith }
244b7bdb8cfSRichard Smith 
245*a5bbbfefSRichard Smith Sema::DeclGroupPtrTy
246*a5bbbfefSRichard Smith Sema::ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc,
247*a5bbbfefSRichard Smith                                      SourceLocation PrivateLoc) {
248*a5bbbfefSRichard Smith   // C++20 [basic.link]/2:
249*a5bbbfefSRichard Smith   //   A private-module-fragment shall appear only in a primary module
250*a5bbbfefSRichard Smith   //   interface unit.
251*a5bbbfefSRichard Smith   switch (ModuleScopes.empty() ? Module::GlobalModuleFragment
252*a5bbbfefSRichard Smith                                : ModuleScopes.back().Module->Kind) {
253*a5bbbfefSRichard Smith   case Module::ModuleMapModule:
254*a5bbbfefSRichard Smith   case Module::GlobalModuleFragment:
255*a5bbbfefSRichard Smith     Diag(PrivateLoc, diag::err_private_module_fragment_not_module);
256*a5bbbfefSRichard Smith     return nullptr;
257*a5bbbfefSRichard Smith 
258*a5bbbfefSRichard Smith   case Module::PrivateModuleFragment:
259*a5bbbfefSRichard Smith     Diag(PrivateLoc, diag::err_private_module_fragment_redefined);
260*a5bbbfefSRichard Smith     Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition);
261*a5bbbfefSRichard Smith     return nullptr;
262*a5bbbfefSRichard Smith 
263*a5bbbfefSRichard Smith   case Module::ModuleInterfaceUnit:
264*a5bbbfefSRichard Smith     break;
265*a5bbbfefSRichard Smith   }
266*a5bbbfefSRichard Smith 
267*a5bbbfefSRichard Smith   if (!ModuleScopes.back().ModuleInterface) {
268*a5bbbfefSRichard Smith     Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface);
269*a5bbbfefSRichard Smith     Diag(ModuleScopes.back().BeginLoc,
270*a5bbbfefSRichard Smith          diag::note_not_module_interface_add_export)
271*a5bbbfefSRichard Smith         << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export ");
272*a5bbbfefSRichard Smith     return nullptr;
273*a5bbbfefSRichard Smith   }
274*a5bbbfefSRichard Smith 
275*a5bbbfefSRichard Smith   // FIXME: Check this isn't a module interface partition.
276*a5bbbfefSRichard Smith   // FIXME: Check that this translation unit does not import any partitions;
277*a5bbbfefSRichard Smith   // such imports would violate [basic.link]/2's "shall be the only module unit"
278*a5bbbfefSRichard Smith   // restriction.
279*a5bbbfefSRichard Smith 
280*a5bbbfefSRichard Smith   // We've finished the public fragment of the translation unit.
281*a5bbbfefSRichard Smith   ActOnEndOfTranslationUnitFragment(TUFragmentKind::Normal);
282*a5bbbfefSRichard Smith 
283*a5bbbfefSRichard Smith   auto &Map = PP.getHeaderSearchInfo().getModuleMap();
284*a5bbbfefSRichard Smith   Module *PrivateModuleFragment =
285*a5bbbfefSRichard Smith       Map.createPrivateModuleFragmentForInterfaceUnit(
286*a5bbbfefSRichard Smith           ModuleScopes.back().Module, PrivateLoc);
287*a5bbbfefSRichard Smith   assert(PrivateModuleFragment && "module creation should not fail");
288*a5bbbfefSRichard Smith 
289*a5bbbfefSRichard Smith   // Enter the scope of the private module fragment.
290*a5bbbfefSRichard Smith   ModuleScopes.push_back({});
291*a5bbbfefSRichard Smith   ModuleScopes.back().BeginLoc = ModuleLoc;
292*a5bbbfefSRichard Smith   ModuleScopes.back().Module = PrivateModuleFragment;
293*a5bbbfefSRichard Smith   ModuleScopes.back().ModuleInterface = true;
294*a5bbbfefSRichard Smith   VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc);
295*a5bbbfefSRichard Smith 
296*a5bbbfefSRichard Smith   // All declarations created from now on are scoped to the private module
297*a5bbbfefSRichard Smith   // fragment (and are neither visible nor reachable in importers of the module
298*a5bbbfefSRichard Smith   // interface).
299*a5bbbfefSRichard Smith   auto *TU = Context.getTranslationUnitDecl();
300*a5bbbfefSRichard Smith   TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
301*a5bbbfefSRichard Smith   TU->setLocalOwningModule(PrivateModuleFragment);
302*a5bbbfefSRichard Smith 
303*a5bbbfefSRichard Smith   // FIXME: Consider creating an explicit representation of this declaration.
304*a5bbbfefSRichard Smith   return nullptr;
305*a5bbbfefSRichard Smith }
306*a5bbbfefSRichard Smith 
307b7bdb8cfSRichard Smith DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
308b7bdb8cfSRichard Smith                                    SourceLocation ExportLoc,
309b7bdb8cfSRichard Smith                                    SourceLocation ImportLoc,
310b7bdb8cfSRichard Smith                                    ModuleIdPath Path) {
311b7bdb8cfSRichard Smith   // Flatten the module path for a Modules TS module name.
312b7bdb8cfSRichard Smith   std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
313b7bdb8cfSRichard Smith   if (getLangOpts().ModulesTS) {
314b7bdb8cfSRichard Smith     std::string ModuleName;
315b7bdb8cfSRichard Smith     for (auto &Piece : Path) {
316b7bdb8cfSRichard Smith       if (!ModuleName.empty())
317b7bdb8cfSRichard Smith         ModuleName += ".";
318b7bdb8cfSRichard Smith       ModuleName += Piece.first->getName();
319b7bdb8cfSRichard Smith     }
320b7bdb8cfSRichard Smith     ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second};
321b7bdb8cfSRichard Smith     Path = ModuleIdPath(ModuleNameLoc);
322b7bdb8cfSRichard Smith   }
323b7bdb8cfSRichard Smith 
324b7bdb8cfSRichard Smith   Module *Mod =
325b7bdb8cfSRichard Smith       getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible,
326b7bdb8cfSRichard Smith                                    /*IsIncludeDirective=*/false);
327b7bdb8cfSRichard Smith   if (!Mod)
328b7bdb8cfSRichard Smith     return true;
329b7bdb8cfSRichard Smith 
330b7bdb8cfSRichard Smith   return ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Mod, Path);
331b7bdb8cfSRichard Smith }
332b7bdb8cfSRichard Smith 
333b7bdb8cfSRichard Smith DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
334b7bdb8cfSRichard Smith                                    SourceLocation ExportLoc,
335b7bdb8cfSRichard Smith                                    SourceLocation ImportLoc,
336b7bdb8cfSRichard Smith                                    Module *Mod, ModuleIdPath Path) {
337b7bdb8cfSRichard Smith   VisibleModules.setVisible(Mod, ImportLoc);
338b7bdb8cfSRichard Smith 
339b7bdb8cfSRichard Smith   checkModuleImportContext(*this, Mod, ImportLoc, CurContext);
340b7bdb8cfSRichard Smith 
341b7bdb8cfSRichard Smith   // FIXME: we should support importing a submodule within a different submodule
342b7bdb8cfSRichard Smith   // of the same top-level module. Until we do, make it an error rather than
343b7bdb8cfSRichard Smith   // silently ignoring the import.
344b7bdb8cfSRichard Smith   // Import-from-implementation is valid in the Modules TS. FIXME: Should we
345b7bdb8cfSRichard Smith   // warn on a redundant import of the current module?
346b7bdb8cfSRichard Smith   // FIXME: Import of a module from an implementation partition of the same
347b7bdb8cfSRichard Smith   // module is permitted.
348b7bdb8cfSRichard Smith   if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
349b7bdb8cfSRichard Smith       (getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS)) {
350b7bdb8cfSRichard Smith     Diag(ImportLoc, getLangOpts().isCompilingModule()
351b7bdb8cfSRichard Smith                         ? diag::err_module_self_import
352b7bdb8cfSRichard Smith                         : diag::err_module_import_in_implementation)
353b7bdb8cfSRichard Smith         << Mod->getFullModuleName() << getLangOpts().CurrentModule;
354b7bdb8cfSRichard Smith   }
355b7bdb8cfSRichard Smith 
356b7bdb8cfSRichard Smith   SmallVector<SourceLocation, 2> IdentifierLocs;
357b7bdb8cfSRichard Smith   Module *ModCheck = Mod;
358b7bdb8cfSRichard Smith   for (unsigned I = 0, N = Path.size(); I != N; ++I) {
359b7bdb8cfSRichard Smith     // If we've run out of module parents, just drop the remaining identifiers.
360b7bdb8cfSRichard Smith     // We need the length to be consistent.
361b7bdb8cfSRichard Smith     if (!ModCheck)
362b7bdb8cfSRichard Smith       break;
363b7bdb8cfSRichard Smith     ModCheck = ModCheck->Parent;
364b7bdb8cfSRichard Smith 
365b7bdb8cfSRichard Smith     IdentifierLocs.push_back(Path[I].second);
366b7bdb8cfSRichard Smith   }
367b7bdb8cfSRichard Smith 
368b7bdb8cfSRichard Smith   // If this was a header import, pad out with dummy locations.
369b7bdb8cfSRichard Smith   // FIXME: Pass in and use the location of the header-name token in this case.
370b7bdb8cfSRichard Smith   if (Path.empty()) {
371b7bdb8cfSRichard Smith     for (; ModCheck; ModCheck = ModCheck->Parent) {
372b7bdb8cfSRichard Smith       IdentifierLocs.push_back(SourceLocation());
373b7bdb8cfSRichard Smith     }
374b7bdb8cfSRichard Smith   }
375b7bdb8cfSRichard Smith 
376b7bdb8cfSRichard Smith   ImportDecl *Import = ImportDecl::Create(Context, CurContext, StartLoc,
377b7bdb8cfSRichard Smith                                           Mod, IdentifierLocs);
378b7bdb8cfSRichard Smith   CurContext->addDecl(Import);
379b7bdb8cfSRichard Smith 
380b7bdb8cfSRichard Smith   // Sequence initialization of the imported module before that of the current
381b7bdb8cfSRichard Smith   // module, if any.
382b7bdb8cfSRichard Smith   if (!ModuleScopes.empty())
383b7bdb8cfSRichard Smith     Context.addModuleInitializer(ModuleScopes.back().Module, Import);
384b7bdb8cfSRichard Smith 
385b7bdb8cfSRichard Smith   // Re-export the module if needed.
386b7bdb8cfSRichard Smith   if (!ModuleScopes.empty() && ModuleScopes.back().ModuleInterface) {
387b7bdb8cfSRichard Smith     if (ExportLoc.isValid() || Import->isExported())
388b7bdb8cfSRichard Smith       getCurrentModule()->Exports.emplace_back(Mod, false);
389b7bdb8cfSRichard Smith   } else if (ExportLoc.isValid()) {
390b7bdb8cfSRichard Smith     Diag(ExportLoc, diag::err_export_not_in_module_interface);
391b7bdb8cfSRichard Smith   }
392b7bdb8cfSRichard Smith 
393b7bdb8cfSRichard Smith   return Import;
394b7bdb8cfSRichard Smith }
395b7bdb8cfSRichard Smith 
396b7bdb8cfSRichard Smith void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
397b7bdb8cfSRichard Smith   checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
398b7bdb8cfSRichard Smith   BuildModuleInclude(DirectiveLoc, Mod);
399b7bdb8cfSRichard Smith }
400b7bdb8cfSRichard Smith 
401b7bdb8cfSRichard Smith void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) {
402b7bdb8cfSRichard Smith   // Determine whether we're in the #include buffer for a module. The #includes
403b7bdb8cfSRichard Smith   // in that buffer do not qualify as module imports; they're just an
404b7bdb8cfSRichard Smith   // implementation detail of us building the module.
405b7bdb8cfSRichard Smith   //
406b7bdb8cfSRichard Smith   // FIXME: Should we even get ActOnModuleInclude calls for those?
407b7bdb8cfSRichard Smith   bool IsInModuleIncludes =
408b7bdb8cfSRichard Smith       TUKind == TU_Module &&
409b7bdb8cfSRichard Smith       getSourceManager().isWrittenInMainFile(DirectiveLoc);
410b7bdb8cfSRichard Smith 
411b7bdb8cfSRichard Smith   bool ShouldAddImport = !IsInModuleIncludes;
412b7bdb8cfSRichard Smith 
413b7bdb8cfSRichard Smith   // If this module import was due to an inclusion directive, create an
414b7bdb8cfSRichard Smith   // implicit import declaration to capture it in the AST.
415b7bdb8cfSRichard Smith   if (ShouldAddImport) {
416b7bdb8cfSRichard Smith     TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
417b7bdb8cfSRichard Smith     ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
418b7bdb8cfSRichard Smith                                                      DirectiveLoc, Mod,
419b7bdb8cfSRichard Smith                                                      DirectiveLoc);
420b7bdb8cfSRichard Smith     if (!ModuleScopes.empty())
421b7bdb8cfSRichard Smith       Context.addModuleInitializer(ModuleScopes.back().Module, ImportD);
422b7bdb8cfSRichard Smith     TU->addDecl(ImportD);
423b7bdb8cfSRichard Smith     Consumer.HandleImplicitImportDecl(ImportD);
424b7bdb8cfSRichard Smith   }
425b7bdb8cfSRichard Smith 
426b7bdb8cfSRichard Smith   getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc);
427b7bdb8cfSRichard Smith   VisibleModules.setVisible(Mod, DirectiveLoc);
428b7bdb8cfSRichard Smith }
429b7bdb8cfSRichard Smith 
430b7bdb8cfSRichard Smith void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) {
431b7bdb8cfSRichard Smith   checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true);
432b7bdb8cfSRichard Smith 
433b7bdb8cfSRichard Smith   ModuleScopes.push_back({});
434b7bdb8cfSRichard Smith   ModuleScopes.back().Module = Mod;
435b7bdb8cfSRichard Smith   if (getLangOpts().ModulesLocalVisibility)
436b7bdb8cfSRichard Smith     ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules);
437b7bdb8cfSRichard Smith 
438b7bdb8cfSRichard Smith   VisibleModules.setVisible(Mod, DirectiveLoc);
439b7bdb8cfSRichard Smith 
440b7bdb8cfSRichard Smith   // The enclosing context is now part of this module.
441b7bdb8cfSRichard Smith   // FIXME: Consider creating a child DeclContext to hold the entities
442b7bdb8cfSRichard Smith   // lexically within the module.
443b7bdb8cfSRichard Smith   if (getLangOpts().trackLocalOwningModule()) {
444b7bdb8cfSRichard Smith     for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
445b7bdb8cfSRichard Smith       cast<Decl>(DC)->setModuleOwnershipKind(
446b7bdb8cfSRichard Smith           getLangOpts().ModulesLocalVisibility
447b7bdb8cfSRichard Smith               ? Decl::ModuleOwnershipKind::VisibleWhenImported
448b7bdb8cfSRichard Smith               : Decl::ModuleOwnershipKind::Visible);
449b7bdb8cfSRichard Smith       cast<Decl>(DC)->setLocalOwningModule(Mod);
450b7bdb8cfSRichard Smith     }
451b7bdb8cfSRichard Smith   }
452b7bdb8cfSRichard Smith }
453b7bdb8cfSRichard Smith 
454b7bdb8cfSRichard Smith void Sema::ActOnModuleEnd(SourceLocation EomLoc, Module *Mod) {
455b7bdb8cfSRichard Smith   if (getLangOpts().ModulesLocalVisibility) {
456b7bdb8cfSRichard Smith     VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules);
457b7bdb8cfSRichard Smith     // Leaving a module hides namespace names, so our visible namespace cache
458b7bdb8cfSRichard Smith     // is now out of date.
459b7bdb8cfSRichard Smith     VisibleNamespaceCache.clear();
460b7bdb8cfSRichard Smith   }
461b7bdb8cfSRichard Smith 
462b7bdb8cfSRichard Smith   assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod &&
463b7bdb8cfSRichard Smith          "left the wrong module scope");
464b7bdb8cfSRichard Smith   ModuleScopes.pop_back();
465b7bdb8cfSRichard Smith 
466b7bdb8cfSRichard Smith   // We got to the end of processing a local module. Create an
467b7bdb8cfSRichard Smith   // ImportDecl as we would for an imported module.
468b7bdb8cfSRichard Smith   FileID File = getSourceManager().getFileID(EomLoc);
469b7bdb8cfSRichard Smith   SourceLocation DirectiveLoc;
470b7bdb8cfSRichard Smith   if (EomLoc == getSourceManager().getLocForEndOfFile(File)) {
471b7bdb8cfSRichard Smith     // We reached the end of a #included module header. Use the #include loc.
472b7bdb8cfSRichard Smith     assert(File != getSourceManager().getMainFileID() &&
473b7bdb8cfSRichard Smith            "end of submodule in main source file");
474b7bdb8cfSRichard Smith     DirectiveLoc = getSourceManager().getIncludeLoc(File);
475b7bdb8cfSRichard Smith   } else {
476b7bdb8cfSRichard Smith     // We reached an EOM pragma. Use the pragma location.
477b7bdb8cfSRichard Smith     DirectiveLoc = EomLoc;
478b7bdb8cfSRichard Smith   }
479b7bdb8cfSRichard Smith   BuildModuleInclude(DirectiveLoc, Mod);
480b7bdb8cfSRichard Smith 
481b7bdb8cfSRichard Smith   // Any further declarations are in whatever module we returned to.
482b7bdb8cfSRichard Smith   if (getLangOpts().trackLocalOwningModule()) {
483b7bdb8cfSRichard Smith     // The parser guarantees that this is the same context that we entered
484b7bdb8cfSRichard Smith     // the module within.
485b7bdb8cfSRichard Smith     for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) {
486b7bdb8cfSRichard Smith       cast<Decl>(DC)->setLocalOwningModule(getCurrentModule());
487b7bdb8cfSRichard Smith       if (!getCurrentModule())
488b7bdb8cfSRichard Smith         cast<Decl>(DC)->setModuleOwnershipKind(
489b7bdb8cfSRichard Smith             Decl::ModuleOwnershipKind::Unowned);
490b7bdb8cfSRichard Smith     }
491b7bdb8cfSRichard Smith   }
492b7bdb8cfSRichard Smith }
493b7bdb8cfSRichard Smith 
494b7bdb8cfSRichard Smith void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
495b7bdb8cfSRichard Smith                                                       Module *Mod) {
496b7bdb8cfSRichard Smith   // Bail if we're not allowed to implicitly import a module here.
497b7bdb8cfSRichard Smith   if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery ||
498b7bdb8cfSRichard Smith       VisibleModules.isVisible(Mod))
499b7bdb8cfSRichard Smith     return;
500b7bdb8cfSRichard Smith 
501b7bdb8cfSRichard Smith   // Create the implicit import declaration.
502b7bdb8cfSRichard Smith   TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl();
503b7bdb8cfSRichard Smith   ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU,
504b7bdb8cfSRichard Smith                                                    Loc, Mod, Loc);
505b7bdb8cfSRichard Smith   TU->addDecl(ImportD);
506b7bdb8cfSRichard Smith   Consumer.HandleImplicitImportDecl(ImportD);
507b7bdb8cfSRichard Smith 
508b7bdb8cfSRichard Smith   // Make the module visible.
509b7bdb8cfSRichard Smith   getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc);
510b7bdb8cfSRichard Smith   VisibleModules.setVisible(Mod, Loc);
511b7bdb8cfSRichard Smith }
512b7bdb8cfSRichard Smith 
513b7bdb8cfSRichard Smith /// We have parsed the start of an export declaration, including the '{'
514b7bdb8cfSRichard Smith /// (if present).
515b7bdb8cfSRichard Smith Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
516b7bdb8cfSRichard Smith                                  SourceLocation LBraceLoc) {
517b7bdb8cfSRichard Smith   ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc);
518b7bdb8cfSRichard Smith 
519*a5bbbfefSRichard Smith   // C++20 [module.interface]p1:
520*a5bbbfefSRichard Smith   //   An export-declaration shall appear only [...] in the purview of a module
521*a5bbbfefSRichard Smith   //   interface unit. An export-declaration shall not appear directly or
522*a5bbbfefSRichard Smith   //   indirectly within an unnamed namespace or a private-module-fragment.
523*a5bbbfefSRichard Smith   // FIXME: Check for the unnamed namespace case.
524*a5bbbfefSRichard Smith   if (ModuleScopes.empty() || !ModuleScopes.back().Module->isModulePurview()) {
525*a5bbbfefSRichard Smith     Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0;
526*a5bbbfefSRichard Smith   } else if (!ModuleScopes.back().ModuleInterface) {
527*a5bbbfefSRichard Smith     Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1;
528*a5bbbfefSRichard Smith     Diag(ModuleScopes.back().BeginLoc,
529*a5bbbfefSRichard Smith          diag::note_not_module_interface_add_export)
530*a5bbbfefSRichard Smith         << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export ");
531*a5bbbfefSRichard Smith   } else if (ModuleScopes.back().Module->Kind ==
532*a5bbbfefSRichard Smith              Module::PrivateModuleFragment) {
533*a5bbbfefSRichard Smith     Diag(ExportLoc, diag::err_export_in_private_module_fragment);
534*a5bbbfefSRichard Smith     Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment);
535*a5bbbfefSRichard Smith   }
536b7bdb8cfSRichard Smith 
537*a5bbbfefSRichard Smith   //   [...] its declaration or declaration-seq shall not contain an
538b7bdb8cfSRichard Smith   //   export-declaration.
539b7bdb8cfSRichard Smith   if (D->isExported())
540b7bdb8cfSRichard Smith     Diag(ExportLoc, diag::err_export_within_export);
541b7bdb8cfSRichard Smith 
542b7bdb8cfSRichard Smith   CurContext->addDecl(D);
543b7bdb8cfSRichard Smith   PushDeclContext(S, D);
544b7bdb8cfSRichard Smith   D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported);
545b7bdb8cfSRichard Smith   return D;
546b7bdb8cfSRichard Smith }
547b7bdb8cfSRichard Smith 
548b7bdb8cfSRichard Smith /// Complete the definition of an export declaration.
549b7bdb8cfSRichard Smith Decl *Sema::ActOnFinishExportDecl(Scope *S, Decl *D, SourceLocation RBraceLoc) {
550b7bdb8cfSRichard Smith   auto *ED = cast<ExportDecl>(D);
551b7bdb8cfSRichard Smith   if (RBraceLoc.isValid())
552b7bdb8cfSRichard Smith     ED->setRBraceLoc(RBraceLoc);
553b7bdb8cfSRichard Smith 
554b7bdb8cfSRichard Smith   // FIXME: Diagnose export of internal-linkage declaration (including
555b7bdb8cfSRichard Smith   // anonymous namespace).
556b7bdb8cfSRichard Smith 
557b7bdb8cfSRichard Smith   PopDeclContext();
558b7bdb8cfSRichard Smith   return D;
559b7bdb8cfSRichard Smith }
560