[clang] 6738792 - Revert "[C++20][Modules][1/8] Track valid import state."

Iain Sandoe via cfe-commits cfe-commits at lists.llvm.org
Sun Feb 20 02:22:19 PST 2022


Author: Iain Sandoe
Date: 2022-02-20T10:22:07Z
New Revision: 673879249d4d1c4e6d763a6db4a4812d721b41b6

URL: https://github.com/llvm/llvm-project/commit/673879249d4d1c4e6d763a6db4a4812d721b41b6
DIFF: https://github.com/llvm/llvm-project/commit/673879249d4d1c4e6d763a6db4a4812d721b41b6.diff

LOG: Revert "[C++20][Modules][1/8] Track valid import state."

This reverts commit 8a3f9a584ad43369cf6a034dc875ebfca76d9033.

need to investigate build failures that do not show on CI or local
testing.

Added: 
    

Modified: 
    clang/include/clang/Basic/DiagnosticParseKinds.td
    clang/include/clang/Parse/Parser.h
    clang/include/clang/Sema/Sema.h
    clang/lib/Interpreter/IncrementalParser.cpp
    clang/lib/Parse/ParseAST.cpp
    clang/lib/Parse/ParseObjc.cpp
    clang/lib/Parse/Parser.cpp
    clang/lib/Sema/SemaModule.cpp

Removed: 
    clang/test/Modules/cxx20-import-diagnostics-a.cpp


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td
index f21e841bcdd38..e23810f402365 100644
--- a/clang/include/clang/Basic/DiagnosticParseKinds.td
+++ b/clang/include/clang/Basic/DiagnosticParseKinds.td
@@ -1539,10 +1539,6 @@ def err_private_module_fragment_expected_semi : Error<
 def err_missing_before_module_end : Error<"expected %0 at end of module">;
 def err_unsupported_module_partition : Error<
   "sorry, module partitions are not yet supported">;
-def err_import_not_allowed_here : Error<
-  "imports must immediately follow the module declaration">;
-def err_import_in_wrong_fragment : Error<
-  "module%select{| partition}0 imports cannot be in the %select{global|private}1 module fragment">;
 
 def err_export_empty : Error<"export declaration cannot be empty">;
 }

diff  --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 08d492a7ec721..981800a7e2356 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -464,17 +464,14 @@ class Parser : public CodeCompletionHandler {
   void Initialize();
 
   /// Parse the first top-level declaration in a translation unit.
-  bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
-                              Sema::ModuleImportState &ImportState);
+  bool ParseFirstTopLevelDecl(DeclGroupPtrTy &Result);
 
   /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if
   /// the EOF was encountered.
-  bool ParseTopLevelDecl(DeclGroupPtrTy &Result,
-                         Sema::ModuleImportState &ImportState);
+  bool ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl = false);
   bool ParseTopLevelDecl() {
     DeclGroupPtrTy Result;
-    Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
-    return ParseTopLevelDecl(Result, IS);
+    return ParseTopLevelDecl(Result);
   }
 
   /// ConsumeToken - Consume the current 'peek token' and lex the next one.
@@ -3494,9 +3491,8 @@ class Parser : public CodeCompletionHandler {
 
   //===--------------------------------------------------------------------===//
   // Modules
-  DeclGroupPtrTy ParseModuleDecl(Sema::ModuleImportState &ImportState);
-  Decl *ParseModuleImport(SourceLocation AtLoc,
-                          Sema::ModuleImportState &ImportState);
+  DeclGroupPtrTy ParseModuleDecl(bool IsFirstDecl);
+  Decl *ParseModuleImport(SourceLocation AtLoc);
   bool parseMisplacedModuleImport();
   bool tryParseMisplacedModuleImport() {
     tok::TokenKind Kind = Tok.getKind();

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index dfa12ad40b72a..c1e846c55dee7 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -2949,24 +2949,11 @@ class Sema final {
     Implementation, ///< 'module X;'
   };
 
-  /// An enumeration to represent the transition of states in parsing module
-  /// fragments and imports.  If we are not parsing a C++20 TU, or we find
-  /// an error in state transition, the state is set to NotACXX20Module.
-  enum class ModuleImportState {
-    FirstDecl,       ///< Parsing the first decl in a TU.
-    GlobalFragment,  ///< after 'module;' but before 'module X;'
-    ImportAllowed,   ///< after 'module X;' but before any non-import decl.
-    ImportFinished,  ///< after any non-import decl.
-    PrivateFragment, ///< after 'module :private;'.
-    NotACXX20Module  ///< Not a C++20 TU, or an invalid state was found.
-  };
-
   /// The parser has processed a module-declaration that begins the definition
   /// of a module interface or implementation.
   DeclGroupPtrTy ActOnModuleDecl(SourceLocation StartLoc,
                                  SourceLocation ModuleLoc, ModuleDeclKind MDK,
-                                 ModuleIdPath Path,
-                                 ModuleImportState &ImportState);
+                                 ModuleIdPath Path, bool IsFirstDecl);
 
   /// The parser has processed a global-module-fragment declaration that begins
   /// the definition of the global module fragment of the current module unit.

diff  --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp
index 0f1ef3233a2a1..4ade8b8bb0741 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -164,9 +164,8 @@ IncrementalParser::ParseOrWrapTopLevelDecl() {
   }
 
   Parser::DeclGroupPtrTy ADecl;
-  Sema::ModuleImportState ImportState;
-  for (bool AtEOF = P->ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
-       AtEOF = P->ParseTopLevelDecl(ADecl, ImportState)) {
+  for (bool AtEOF = P->ParseFirstTopLevelDecl(ADecl); !AtEOF;
+       AtEOF = P->ParseTopLevelDecl(ADecl)) {
     // If we got a null return and something *was* parsed, ignore it.  This
     // is due to a top-level semicolon, an action override, or a parse error
     // skipping something.

diff  --git a/clang/lib/Parse/ParseAST.cpp b/clang/lib/Parse/ParseAST.cpp
index fd79ed3ca158b..01510e8caf3b7 100644
--- a/clang/lib/Parse/ParseAST.cpp
+++ b/clang/lib/Parse/ParseAST.cpp
@@ -154,9 +154,8 @@ void clang::ParseAST(Sema &S, bool PrintStats, bool SkipFunctionBodies) {
     llvm::TimeTraceScope TimeScope("Frontend");
     P.Initialize();
     Parser::DeclGroupPtrTy ADecl;
-    Sema::ModuleImportState ImportState;
-    for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl, ImportState); !AtEOF;
-         AtEOF = P.ParseTopLevelDecl(ADecl, ImportState)) {
+    for (bool AtEOF = P.ParseFirstTopLevelDecl(ADecl); !AtEOF;
+         AtEOF = P.ParseTopLevelDecl(ADecl)) {
       // If we got a null return and something *was* parsed, ignore it.  This
       // is due to a top-level semicolon, an action override, or a parse error
       // skipping something.

diff  --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
index 08f131ed0d874..f493ac9b92caf 100644
--- a/clang/lib/Parse/ParseObjc.cpp
+++ b/clang/lib/Parse/ParseObjc.cpp
@@ -79,8 +79,7 @@ Parser::ParseObjCAtDirectives(ParsedAttributesWithRange &Attrs) {
     break;
   case tok::objc_import:
     if (getLangOpts().Modules || getLangOpts().DebuggerSupport) {
-      Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
-      SingleDecl = ParseModuleImport(AtLoc, IS);
+      SingleDecl = ParseModuleImport(AtLoc);
       break;
     }
     Diag(AtLoc, diag::err_atimport);

diff  --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 87500a0405531..ffa1e0f027f1d 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -581,20 +581,15 @@ void Parser::DestroyTemplateIds() {
 ///                 top-level-declaration-seq[opt] private-module-fragment[opt]
 ///
 /// Note that in C, it is an error if there is no first declaration.
-bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
-                                    Sema::ModuleImportState &ImportState) {
+bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result) {
   Actions.ActOnStartOfTranslationUnit();
 
-  // For C++20 modules, a module decl must be the first in the TU.  We also
-  // need to track module imports.
-  ImportState = Sema::ModuleImportState::FirstDecl;
-  bool NoTopLevelDecls = ParseTopLevelDecl(Result, ImportState);
-
   // C11 6.9p1 says translation units must have at least one top-level
   // declaration. C++ doesn't have this restriction. We also don't want to
   // complain if we have a precompiled header, although technically if the PCH
   // is empty we should still emit the (pedantic) diagnostic.
   // If the main file is a header, we're only pretending it's a TU; don't warn.
+  bool NoTopLevelDecls = ParseTopLevelDecl(Result, true);
   if (NoTopLevelDecls && !Actions.getASTContext().getExternalSource() &&
       !getLangOpts().CPlusPlus && !getLangOpts().IsHeaderFile)
     Diag(diag::ext_empty_translation_unit);
@@ -608,8 +603,7 @@ bool Parser::ParseFirstTopLevelDecl(DeclGroupPtrTy &Result,
 ///   top-level-declaration:
 ///           declaration
 /// [C++20]   module-import-declaration
-bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
-                               Sema::ModuleImportState &ImportState) {
+bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result, bool IsFirstDecl) {
   DestroyTemplateIdAnnotationsRAIIObj CleanupRAII(*this);
 
   // Skip over the EOF token, flagging end of previous input for incremental
@@ -653,12 +647,13 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
 
   case tok::kw_module:
   module_decl:
-    Result = ParseModuleDecl(ImportState);
+    Result = ParseModuleDecl(IsFirstDecl);
     return false;
 
-  case tok::kw_import:
+  // tok::kw_import is handled by ParseExternalDeclaration. (Under the Modules
+  // TS, an import can occur within an export block.)
   import_decl: {
-    Decl *ImportDecl = ParseModuleImport(SourceLocation(), ImportState);
+    Decl *ImportDecl = ParseModuleImport(SourceLocation());
     Result = Actions.ConvertDeclToDeclGroup(ImportDecl);
     return false;
   }
@@ -674,14 +669,12 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
     Actions.ActOnModuleBegin(Tok.getLocation(), reinterpret_cast<Module *>(
                                                     Tok.getAnnotationValue()));
     ConsumeAnnotationToken();
-    ImportState = Sema::ModuleImportState::NotACXX20Module;
     return false;
 
   case tok::annot_module_end:
     Actions.ActOnModuleEnd(Tok.getLocation(), reinterpret_cast<Module *>(
                                                   Tok.getAnnotationValue()));
     ConsumeAnnotationToken();
-    ImportState = Sema::ModuleImportState::NotACXX20Module;
     return false;
 
   case tok::eof:
@@ -725,16 +718,6 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result,
   MaybeParseCXX11Attributes(attrs);
 
   Result = ParseExternalDeclaration(attrs);
-  // An empty Result might mean a line with ';' or some parsing error, ignore
-  // it.
-  if (Result) {
-    if (ImportState == Sema::ModuleImportState::FirstDecl)
-      // First decl was not modular.
-      ImportState = Sema::ModuleImportState::NotACXX20Module;
-    else if (ImportState == Sema::ModuleImportState::ImportAllowed)
-      // Non-imports disallow further imports.
-      ImportState = Sema::ModuleImportState::ImportFinished;
-  }
   return false;
 }
 
@@ -904,17 +887,11 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
         getCurScope(),
         CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
     return nullptr;
-  case tok::kw_import: {
-    Sema::ModuleImportState IS = Sema::ModuleImportState::NotACXX20Module;
-    if (getLangOpts().CPlusPlusModules) {
-      llvm_unreachable("not expecting a c++20 import here");
-      ProhibitAttributes(attrs);
-    }
-    SingleDecl = ParseModuleImport(SourceLocation(), IS);
-  } break;
+  case tok::kw_import:
+    SingleDecl = ParseModuleImport(SourceLocation());
+    break;
   case tok::kw_export:
     if (getLangOpts().CPlusPlusModules || getLangOpts().ModulesTS) {
-      ProhibitAttributes(attrs);
       SingleDecl = ParseExportDeclaration();
       break;
     }
@@ -2314,8 +2291,7 @@ void Parser::ParseMicrosoftIfExistsExternalDeclaration() {
 ///            attribute-specifier-seq[opt] ';'
 ///   private-module-fragment: [C++2a]
 ///     'module' ':' 'private' ';' top-level-declaration-seq[opt]
-Parser::DeclGroupPtrTy
-Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
+Parser::DeclGroupPtrTy Parser::ParseModuleDecl(bool IsFirstDecl) {
   SourceLocation StartLoc = Tok.getLocation();
 
   Sema::ModuleDeclKind MDK = TryConsumeToken(tok::kw_export)
@@ -2335,7 +2311,7 @@ Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
   // Parse a global-module-fragment, if present.
   if (getLangOpts().CPlusPlusModules && Tok.is(tok::semi)) {
     SourceLocation SemiLoc = ConsumeToken();
-    if (ImportState != Sema::ModuleImportState::FirstDecl) {
+    if (!IsFirstDecl) {
       Diag(StartLoc, diag::err_global_module_introducer_not_at_start)
         << SourceRange(StartLoc, SemiLoc);
       return nullptr;
@@ -2344,7 +2320,6 @@ Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
       Diag(StartLoc, diag::err_module_fragment_exported)
         << /*global*/0 << FixItHint::CreateRemoval(StartLoc);
     }
-    ImportState = Sema::ModuleImportState::GlobalFragment;
     return Actions.ActOnGlobalModuleFragmentDecl(ModuleLoc);
   }
 
@@ -2359,7 +2334,6 @@ Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
     SourceLocation PrivateLoc = ConsumeToken();
     DiagnoseAndSkipCXX11Attributes();
     ExpectAndConsumeSemi(diag::err_private_module_fragment_expected_semi);
-    ImportState = Sema::ModuleImportState::PrivateFragment;
     return Actions.ActOnPrivateModuleFragmentDecl(ModuleLoc, PrivateLoc);
   }
 
@@ -2387,7 +2361,7 @@ Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
 
   ExpectAndConsumeSemi(diag::err_module_expected_semi);
 
-  return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, ImportState);
+  return Actions.ActOnModuleDecl(StartLoc, ModuleLoc, MDK, Path, IsFirstDecl);
 }
 
 /// Parse a module import declaration. This is essentially the same for
@@ -2405,8 +2379,7 @@ Parser::ParseModuleDecl(Sema::ModuleImportState &ImportState) {
 ///                   attribute-specifier-seq[opt] ';'
 ///           'export'[opt] 'import' header-name
 ///                   attribute-specifier-seq[opt] ';'
-Decl *Parser::ParseModuleImport(SourceLocation AtLoc,
-                                Sema::ModuleImportState &ImportState) {
+Decl *Parser::ParseModuleImport(SourceLocation AtLoc) {
   SourceLocation StartLoc = AtLoc.isInvalid() ? Tok.getLocation() : AtLoc;
 
   SourceLocation ExportLoc;
@@ -2455,42 +2428,6 @@ Decl *Parser::ParseModuleImport(SourceLocation AtLoc,
     return nullptr;
   }
 
-  // Diagnose mis-imports.
-  bool SeenError = true;
-  switch (ImportState) {
-  case Sema::ModuleImportState::ImportAllowed:
-    SeenError = false;
-    break;
-  case Sema::ModuleImportState::FirstDecl:
-  case Sema::ModuleImportState::NotACXX20Module:
-    // TODO: These cases will be an error when partitions are implemented.
-    SeenError = false;
-    break;
-  case Sema::ModuleImportState::GlobalFragment:
-    // We can only have pre-processor directives in the global module
-    // fragment.  We can, however have a header unit import here.
-    if (!HeaderUnit)
-      // We do not have partition support yet, so first arg is 0.
-      Diag(ImportLoc, diag::err_import_in_wrong_fragment) << 0 << 0;
-    else
-      SeenError = false;
-    break;
-  case Sema::ModuleImportState::ImportFinished:
-    if (getLangOpts().CPlusPlusModules)
-      Diag(ImportLoc, diag::err_import_not_allowed_here);
-    else
-      SeenError = false;
-    break;
-  case Sema::ModuleImportState::PrivateFragment:
-    // We do not have partition support yet, so first arg is 0.
-    Diag(ImportLoc, diag::err_import_in_wrong_fragment) << 0 << 1;
-    break;
-  }
-  if (SeenError) {
-    ExpectAndConsumeSemi(diag::err_module_expected_semi);
-    return nullptr;
-  }
-
   DeclResult Import;
   if (HeaderUnit)
     Import =

diff  --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp
index 9bed3cb769f70..85e58640044dc 100644
--- a/clang/lib/Sema/SemaModule.cpp
+++ b/clang/lib/Sema/SemaModule.cpp
@@ -80,20 +80,12 @@ Sema::ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc) {
   return nullptr;
 }
 
-Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
-                                           SourceLocation ModuleLoc,
-                                           ModuleDeclKind MDK,
-                                           ModuleIdPath Path,
-                                           ModuleImportState &ImportState) {
+Sema::DeclGroupPtrTy
+Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc,
+                      ModuleDeclKind MDK, ModuleIdPath Path, bool IsFirstDecl) {
   assert((getLangOpts().ModulesTS || getLangOpts().CPlusPlusModules) &&
          "should only have module decl in Modules TS or C++20");
 
-  bool IsFirstDecl = ImportState == ModuleImportState::FirstDecl;
-  bool SeenGMF = ImportState == ModuleImportState::GlobalFragment;
-  // If any of the steps here fail, we count that as invalidating C++20
-  // module state;
-  ImportState = ModuleImportState::NotACXX20Module;
-
   // A module implementation unit requires that we are not compiling a module
   // of any kind. A module interface unit requires that we are not compiling a
   // module map.
@@ -142,13 +134,9 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
       ModuleScopes.back().Module->Kind == Module::GlobalModuleFragment)
     GlobalModuleFragment = ModuleScopes.back().Module;
 
-  assert((!getLangOpts().CPlusPlusModules ||
-          SeenGMF == (bool)GlobalModuleFragment) &&
-         "mismatched global module state");
-
   // In C++20, the module-declaration must be the first declaration if there
   // is no global module fragment.
-  if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !SeenGMF) {
+  if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !GlobalModuleFragment) {
     Diag(ModuleLoc, diag::err_module_decl_not_at_start);
     SourceLocation BeginLoc =
         ModuleScopes.empty()
@@ -243,10 +231,6 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc,
   TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate);
   TU->setLocalOwningModule(Mod);
 
-  // We are in the module purview, but before any other (non import)
-  // statements, so imports are allowed.
-  ImportState = ModuleImportState::ImportAllowed;
-
   // FIXME: Create a ModuleDecl.
   return nullptr;
 }
@@ -317,10 +301,10 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
                                    SourceLocation ExportLoc,
                                    SourceLocation ImportLoc,
                                    ModuleIdPath Path) {
-  // Flatten the module path for a C++20 or Modules TS module name.
+  // Flatten the module path for a Modules TS module name.
   std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc;
-  std::string ModuleName;
-  if (getLangOpts().CPlusPlusModules || getLangOpts().ModulesTS) {
+  if (getLangOpts().ModulesTS) {
+    std::string ModuleName;
     for (auto &Piece : Path) {
       if (!ModuleName.empty())
         ModuleName += ".";
@@ -330,14 +314,6 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
     Path = ModuleIdPath(ModuleNameLoc);
   }
 
-  // Diagnose self-import before attempting a load.
-  if (getLangOpts().CPlusPlusModules && isCurrentModulePurview() &&
-      getCurrentModule()->Name == ModuleName) {
-    Diag(ImportLoc, diag::err_module_self_import)
-        << ModuleName << getLangOpts().CurrentModule;
-    return true;
-  }
-
   Module *Mod =
       getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible,
                                    /*IsInclusionDirective=*/false);
@@ -366,9 +342,11 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
   // FIXME: we should support importing a submodule within a 
diff erent submodule
   // of the same top-level module. Until we do, make it an error rather than
   // silently ignoring the import.
-  // FIXME: Should we warn on a redundant import of the current module?
-  if (!getLangOpts().CPlusPlusModules &&
-      Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
+  // Import-from-implementation is valid in the Modules TS. FIXME: Should we
+  // warn on a redundant import of the current module?
+  // FIXME: Import of a module from an implementation partition of the same
+  // module is permitted.
+  if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule &&
       (getLangOpts().isCompilingModule() || !getLangOpts().ModulesTS)) {
     Diag(ImportLoc, getLangOpts().isCompilingModule()
                         ? diag::err_module_self_import

diff  --git a/clang/test/Modules/cxx20-import-diagnostics-a.cpp b/clang/test/Modules/cxx20-import-diagnostics-a.cpp
deleted file mode 100644
index fd4085bcb4713..0000000000000
--- a/clang/test/Modules/cxx20-import-diagnostics-a.cpp
+++ /dev/null
@@ -1,140 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir -p %t
-
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=0 -x c++ %s \
-// RUN:  -o %t/B.pcm
-
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=1 -x c++ %s \
-// RUN:  -o %t/C.pcm
-
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=2 -x c++ %s \
-// RUN:  -fmodule-file=%t/B.pcm -fmodule-file=%t/C.pcm -o %t/AOK1.pcm
-
-// RUN: %clang_cc1 -std=c++20 -S -D TU=3 -x c++ %s \
-// RUN:  -fmodule-file=%t/AOK1.pcm -o %t/tu_3.s -verify
-
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=4 -x c++ %s \
-// RUN:  -fmodule-file=%t/B.pcm -fmodule-file=%t/C.pcm -o %t/BC.pcm -verify
-
-// RUN: %clang_cc1 -std=c++20 -S -D TU=5 -x c++ %s \
-// RUN:  -fmodule-file=%t/B.pcm -fmodule-file=%t/C.pcm -o %t/tu_5.s -verify
-
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=6 -x c++ %s \
-// RUN:  -fmodule-file=%t/B.pcm -o %t/D.pcm -verify
-
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=7 -x c++ %s \
-// RUN:  -fmodule-file=%t/B.pcm -o %t/D.pcm -verify
-
-// RUN: %clang_cc1 -std=c++20 -S -D TU=8 -x c++ %s \
-// RUN:  -fmodule-file=%t/B.pcm -o %t/tu_8.s -verify
-
-// RUN: %clang_cc1 -std=c++20 -emit-module-interface -D TU=9 -x c++ %s \
-// RUN:  -o %t/B.pcm -verify
-
-// RUN: %clang_cc1 -std=c++20 -emit-obj -D TU=10 -x c++ %s \
-// RUN:  -fmodule-file=%t/C.pcm  -o %t/impl.o
-
-// Test diagnostics for incorrect module import sequences.
-
-#if TU == 0
-
-export module B;
-
-int foo ();
-
-// expected-no-diagnostics
-
-#elif TU == 1
-
-export module C;
-
-int bar ();
-
-// expected-no-diagnostics
-
-#elif TU == 2
-
-export module AOK1;
-
-import B;
-export import C;
-
-export int theAnswer ();
-
-// expected-no-diagnostics
-
-#elif TU == 3
-
-module;
-
-module AOK1;
-
-export import C; // expected-error {{export declaration can only be used within a module interface unit}}
-
-int theAnswer () { return 42; }
-
-#elif TU == 4
-
-export module BC;
-
-export import B;
-
-int foo () { return 10; }
-
-import C; // expected-error {{imports must immediately follow the module declaration}}
-
-#elif TU == 5
-
-module B; // implicitly imports B.
-
-int foo () { return 10; }
-
-import C; // expected-error {{imports must immediately follow the module declaration}}
-
-#elif TU == 6
-
-module;
-// We can only have preprocessor commands here, which could include an include
-// translated header unit.  However those are identified specifically by the
-// preprocessor; non-preprocessed user code should not contain an import here.
-import B; // expected-error {{module imports cannot be in the global module fragment}}
-
-export module D;
-
-int delta ();
-
-#elif TU == 7
-
-export module D;
-
-int delta ();
-
-module :private;
-
-import B; // expected-error {{module imports cannot be in the private module fragment}}
-
-#elif TU == 8
-
-module B;
-
-import B; // expected-error {{import of module 'B' appears within same top-level module 'B'}}
-
-#elif TU == 9
-
-export module B;
-
-import B; // expected-error {{import of module 'B' appears within same top-level module 'B'}}
-
-#elif TU == 10
-
-int x;
-
-import C;
-
-int baz() { return 6174; }
-
-// expected-no-diagnostics
-
-#else
-#error "no MODE set"
-#endif


        


More information about the cfe-commits mailing list