================
@@ -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