================
@@ -4075,3 +4163,294 @@ void Preprocessor::HandleEmbedDirective(SourceLocation
HashLoc, Token &EmbedTok,
StringRef(static_cast<char *>(Mem), OriginalFilename.size());
HandleEmbedDirectiveImpl(HashLoc, *Params, BinaryContents, FilenameToGo);
}
+
+void Preprocessor::HandleCXXImportDirective(Token ImportTok) {
+ assert(getLangOpts().CPlusPlusModules && ImportTok.is(tok::kw_import));
+ llvm::SaveAndRestore<bool> SaveImportingCXXModules(
+ this->ImportingCXXNamedModules, true);
+
+ if (LastTokenWasExportKeyword.isValid())
+ LastTokenWasExportKeyword.reset();
+
+ Token Tok;
+ if (LexHeaderName(Tok)) {
+ if (Tok.isNot(tok::eod))
+ CheckEndOfDirective(ImportTok.getIdentifierInfo()->getName());
+ return;
+ }
+
+ SourceLocation UseLoc = ImportTok.getLocation();
+ SmallVector<Token, 4> DirToks{ImportTok};
+ SmallVector<IdentifierLoc, 2> Path;
+ bool ImportingHeader = false;
+ bool IsPartition = false;
+ std::string FlatName;
+ switch (Tok.getKind()) {
+ case tok::header_name:
+ ImportingHeader = true;
+ DirToks.push_back(Tok);
+ Lex(DirToks.emplace_back());
+ break;
+ case tok::colon:
+ IsPartition = true;
+ DirToks.push_back(Tok);
+ UseLoc = Tok.getLocation();
+ Lex(Tok);
+ [[fallthrough]];
+ case tok::identifier: {
+ bool LeadingSpace = Tok.hasLeadingSpace();
+ unsigned NumToksInDirective = DirToks.size();
+ if (LexModuleNameContinue(Tok, UseLoc, DirToks, Path)) {
+ if (Tok.isNot(tok::eod))
+ CheckEndOfDirective(ImportTok.getIdentifierInfo()->getName(),
+ /*EnableMacros=*/false, &DirToks);
+ EnterModuleSuffixTokenStream(DirToks);
+ return;
+ }
+
+ // Clean the module-name tokens and replace these tokens with
+ // annot_module_name.
+ DirToks.resize(NumToksInDirective);
+ ModuleNameLoc *NameLoc = ModuleNameLoc::Create(*this, Path);
+ DirToks.emplace_back();
+ DirToks.back().setKind(tok::annot_module_name);
+ DirToks.back().setAnnotationRange(NameLoc->getRange());
+ DirToks.back().setAnnotationValue(static_cast<void *>(NameLoc));
+ DirToks.back().setFlagValue(Token::LeadingSpace, LeadingSpace);
+ DirToks.push_back(Tok);
+
+ bool IsValid =
+ (IsPartition && ModuleDeclState.isNamedModule()) || !IsPartition;
+ if (Callbacks && IsValid) {
+ if (IsPartition && ModuleDeclState.isNamedModule()) {
+ FlatName += ModuleDeclState.getPrimaryName();
+ FlatName += ":";
+ }
+
+ FlatName += ModuleLoader::getFlatNameFromPath(Path);
+ SourceLocation StartLoc = IsPartition ? UseLoc : Path[0].getLoc();
+ IdentifierLoc FlatNameLoc(StartLoc, getIdentifierInfo(FlatName));
+
+ // We don't/shouldn't load the standard c++20 modules when preprocessing.
+ // so the imported module is nullptr.
+ Callbacks->moduleImport(ImportTok.getLocation(),
+ ModuleIdPath(FlatNameLoc),
+ /*Imported=*/nullptr);
+ }
+ break;
+ }
+ default:
+ DirToks.push_back(Tok);
+ break;
+ }
+
+ // Consume the pp-import-suffix and expand any macros in it now, if we're not
+ // at the semicolon already.
+ if (!DirToks.back().isOneOf(tok::semi, tok::eod))
+ CollectPPImportSuffix(DirToks);
+
+ if (DirToks.back().isNot(tok::eod))
+ CheckEndOfDirective(ImportTok.getIdentifierInfo()->getName());
+ else
+ DirToks.pop_back();
+
+ // This is not a pp-import after all.
+ if (DirToks.back().isNot(tok::semi)) {
+ EnterModuleSuffixTokenStream(DirToks);
+ return;
+ }
+
+ if (ImportingHeader) {
+ // C++2a [cpp.module]p1:
+ // The ';' preprocessing-token terminating a pp-import shall not have
+ // been produced by macro replacement.
+ SourceLocation SemiLoc = DirToks.back().getLocation();
+ if (SemiLoc.isMacroID())
+ Diag(SemiLoc, diag::err_header_import_semi_in_macro);
+
+ auto Action = HandleHeaderIncludeOrImport(
+ /*HashLoc*/ SourceLocation(), ImportTok, Tok, SemiLoc);
+ switch (Action.Kind) {
+ case ImportAction::None:
+ break;
+
+ case ImportAction::ModuleBegin:
+ // Let the parser know we're textually entering the module.
+ DirToks.emplace_back();
+ DirToks.back().startToken();
+ DirToks.back().setKind(tok::annot_module_begin);
+ DirToks.back().setLocation(SemiLoc);
+ DirToks.back().setAnnotationEndLoc(SemiLoc);
+ DirToks.back().setAnnotationValue(Action.ModuleForHeader);
+ [[fallthrough]];
+
+ case ImportAction::ModuleImport:
+ case ImportAction::HeaderUnitImport:
+ case ImportAction::SkippedModuleImport:
+ // We chose to import (or textually enter) the file. Convert the
+ // header-name token into a header unit annotation token.
+ DirToks[1].setKind(tok::annot_header_unit);
+ DirToks[1].setAnnotationEndLoc(DirToks[0].getLocation());
+ DirToks[1].setAnnotationValue(Action.ModuleForHeader);
+ // FIXME: Call the moduleImport callback?
+ break;
+ case ImportAction::Failure:
+ assert(TheModuleLoader.HadFatalFailure &&
+ "This should be an early exit only to a fatal error");
+ CurLexer->cutOffLexing();
+ return;
+ }
+ }
+
+ EnterModuleSuffixTokenStream(DirToks);
+}
+
+void Preprocessor::HandleCXXModuleDirective(Token ModuleTok) {
----------------
cor3ntin wrote:
This function could use more explanatory comments!
https://github.com/llvm/llvm-project/pull/107168
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits