================
@@ -1119,41 +1121,233 @@ bool Preprocessor::LexHeaderName(Token &FilenameTok, 
bool AllowMacroExpansion) {
   return false;
 }
 
+std::optional<Token> Preprocessor::peekNextPPToken() const {
+  // Do some quick tests for rejection cases.
+  std::optional<Token> Val;
+  if (CurLexer)
+    Val = CurLexer->peekNextPPToken();
+  else
+    Val = CurTokenLexer->peekNextPPToken();
+
+  if (!Val) {
+    // We have run off the end.  If it's a source file we don't
+    // examine enclosing ones (C99 5.1.1.2p4).  Otherwise walk up the
+    // macro stack.
+    if (CurPPLexer)
+      return std::nullopt;
+    for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
+      if (Entry.TheLexer)
+        Val = Entry.TheLexer->peekNextPPToken();
+      else
+        Val = Entry.TheTokenLexer->peekNextPPToken();
+
+      if (Val)
+        break;
+
+      // Ran off the end of a source file?
+      if (Entry.ThePPLexer)
+        return std::nullopt;
+    }
+  }
+
+  // Okay, we found the token and return.  Otherwise we found the end of the
+  // translation unit.
+  return Val;
+}
+
+// We represent the primary and partition names as 'Paths' which are sections
+// of the hierarchical access path for a clang module.  However for C++20
+// the periods in a name are just another character, and we will need to
+// flatten them into a string.
+std::string ModuleLoader::getFlatNameFromPath(ModuleIdPath Path) {
+  std::string Name;
+  if (Path.empty())
+    return Name;
+
+  for (auto &Piece : Path) {
+    assert(Piece.getIdentifierInfo() && Piece.getLoc().isValid());
+    if (!Name.empty())
+      Name += ".";
+    Name += Piece.getIdentifierInfo()->getName();
+  }
+  return Name;
+}
+
+ModuleNameLoc *ModuleNameLoc::Create(Preprocessor &PP, ModuleIdPath Path) {
+  assert(!Path.empty() && "expect at least one identifier in a module name");
+  void *Mem = PP.getPreprocessorAllocator().Allocate(
+      totalSizeToAlloc<IdentifierLoc>(Path.size()), alignof(ModuleNameLoc));
+  return new (Mem) ModuleNameLoc(Path);
+}
+
+bool Preprocessor::LexModuleNameContinue(Token &Tok, SourceLocation UseLoc,
+                                         SmallVectorImpl<Token> &Suffix,
+                                         SmallVectorImpl<IdentifierLoc> &Path,
+                                         bool AllowMacroExpansion,
+                                         bool IsPartition) {
+  auto ConsumeToken = [&]() {
+    if (AllowMacroExpansion)
+      Lex(Tok);
+    else
+      LexUnexpandedToken(Tok);
+    Suffix.push_back(Tok);
+  };
+
+  while (true) {
+    if (Tok.isNot(tok::identifier)) {
+      if (Tok.is(tok::code_completion)) {
+        CurLexer->cutOffLexing();
+        CodeComplete->CodeCompleteModuleImport(UseLoc, Path);
+        return true;
+      }
+
+      Diag(Tok, diag::err_pp_module_expected_ident) << Path.empty();
+      return true;
+    }
+
+    // [cpp.pre]/p2:
+    // No identifier in the pp-module-name or pp-module-partition shall
+    // currently be defined as an object-like macro.
+    if (MacroInfo *MI = getMacroInfo(Tok.getIdentifierInfo());
+        MI && MI->isObjectLike() && getLangOpts().CPlusPlus20 &&
+        !AllowMacroExpansion) {
+      Diag(Tok, diag::err_pp_module_name_is_macro)
+          << IsPartition << Tok.getIdentifierInfo();
+      Diag(MI->getDefinitionLoc(), diag::note_macro_here)
+          << Tok.getIdentifierInfo();
+    }
+
+    // Record this part of the module path.
+    Path.emplace_back(Tok.getLocation(), Tok.getIdentifierInfo());
+    ConsumeToken();
+
+    if (Tok.isNot(tok::period))
+      return false;
+
+    ConsumeToken();
+  }
+}
+
+/// P1857R3: Modules Dependency Discovery
+///
----------------
yronglin wrote:

Done.

https://github.com/llvm/llvm-project/pull/107168
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to