llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (yronglin) <details> <summary>Changes</summary> Reverts llvm/llvm-project#<!-- -->90574 --- Patch is 55.48 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/99838.diff 19 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (-2) - (modified) clang/include/clang/Basic/DiagnosticLexKinds.td (-5) - (modified) clang/include/clang/Basic/IdentifierTable.h (+3-21) - (modified) clang/include/clang/Basic/TokenKinds.def (-3) - (modified) clang/include/clang/Lex/Preprocessor.h (+5-78) - (modified) clang/include/clang/Lex/Token.h (-3) - (modified) clang/include/clang/Parse/Parser.h (+1-1) - (modified) clang/lib/Basic/IdentifierTable.cpp (+1-2) - (modified) clang/lib/Frontend/PrintPreprocessedOutput.cpp (+3-9) - (modified) clang/lib/Lex/PPLexerChange.cpp (+4-5) - (modified) clang/lib/Lex/Preprocessor.cpp (+134-310) - (modified) clang/lib/Lex/TokenConcatenation.cpp (-10) - (modified) clang/lib/Parse/ParseDecl.cpp (+1-7) - (modified) clang/lib/Parse/Parser.cpp (+35-58) - (removed) clang/test/CXX/cpp/cpp.module/p2.cppm (-88) - (modified) clang/test/CXX/module/basic/basic.link/module-declaration.cpp (+30-31) - (modified) clang/test/CXX/module/dcl.dcl/dcl.module/dcl.module.import/p1.cppm (+9-30) - (modified) clang/test/SemaCXX/modules.cppm (+36-53) - (modified) clang/www/cxx_status.html (+1-1) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4ab6bd9de8ea9..7ac6ed934290d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -285,8 +285,6 @@ C++2c Feature Support - Implemented `P2963R3 Ordering of constraints involving fold expressions <https://wg21.link/P2963R3>`_. -- Implemented `P3034R1 Module Declarations Shouldn’t be Macros <https://wg21.link/P3034R1>`_. - Resolutions to C++ Defect Reports ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 08ece01009387..12d7b8c0205ee 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -952,11 +952,6 @@ def warn_module_conflict : Warning< InGroup<ModuleConflict>; // C++20 modules -def err_module_decl_cannot_be_macros : Error< - "the module name in a module%select{| partition}0 declaration cannot contain " - "an object-like macro %1">; -def err_unxepected_paren_in_module_decl : Error< - "unexpected '(' after the module name in a module%select{| partition}0 declaration">; def err_header_import_semi_in_macro : Error< "semicolon terminating header import declaration cannot be produced " "by a macro">; diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index f40f74d0355ad..ae9ebd9f59154 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -180,10 +180,6 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { LLVM_PREFERRED_TYPE(bool) unsigned IsModulesImport : 1; - // True if this is the 'module' contextual keyword. - LLVM_PREFERRED_TYPE(bool) - unsigned IsModulesDecl : 1; - // True if this is a mangled OpenMP variant name. LLVM_PREFERRED_TYPE(bool) unsigned IsMangledOpenMPVariantName : 1; @@ -200,7 +196,7 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { LLVM_PREFERRED_TYPE(bool) unsigned IsFinal : 1; - // 21 bits left in a 64-bit word. + // 22 bits left in a 64-bit word. // Managed by the language front-end. void *FETokenInfo = nullptr; @@ -216,8 +212,8 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { IsCPPOperatorKeyword(false), NeedsHandleIdentifier(false), IsFromAST(false), ChangedAfterLoad(false), FEChangedAfterLoad(false), RevertedTokenID(false), OutOfDate(false), IsModulesImport(false), - IsModulesDecl(false), IsMangledOpenMPVariantName(false), - IsDeprecatedMacro(false), IsRestrictExpansion(false), IsFinal(false) {} + IsMangledOpenMPVariantName(false), IsDeprecatedMacro(false), + IsRestrictExpansion(false), IsFinal(false) {} public: IdentifierInfo(const IdentifierInfo &) = delete; @@ -524,18 +520,6 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { RecomputeNeedsHandleIdentifier(); } - /// Determine whether this is the contextual keyword \c module. - bool isModulesDeclaration() const { return IsModulesDecl; } - - /// Set whether this identifier is the contextual keyword \c module. - void setModulesDeclaration(bool I) { - IsModulesDecl = I; - if (I) - NeedsHandleIdentifier = true; - else - RecomputeNeedsHandleIdentifier(); - } - /// Determine whether this is the mangled name of an OpenMP variant. bool isMangledOpenMPVariantName() const { return IsMangledOpenMPVariantName; } @@ -756,8 +740,6 @@ class IdentifierTable { // If this is the 'import' contextual keyword, mark it as such. if (Name == "import") II->setModulesImport(true); - else if (Name == "module") - II->setModulesDeclaration(true); return *II; } diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 8db18c049b6d0..7f4912b9bcd96 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -1003,9 +1003,6 @@ ANNOTATION(module_include) ANNOTATION(module_begin) ANNOTATION(module_end) -// Annotations for C++, Clang and Objective-C named modules. -ANNOTATION(module_name) - // Annotation for a header_name token that has been looked up and transformed // into the name of a header unit. ANNOTATION(header_unit) diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 56aef99a3f38a..fc7d0053f2323 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -615,6 +615,10 @@ class Preprocessor { ModuleDeclSeq ModuleDeclState; + /// Whether the module import expects an identifier next. Otherwise, + /// it expects a '.' or ';'. + bool ModuleImportExpectsIdentifier = false; + /// The identifier and source location of the currently-active /// \#pragma clang arc_cf_code_audited begin. std::pair<IdentifierInfo *, SourceLocation> PragmaARCCFCodeAuditedInfo; @@ -1740,14 +1744,11 @@ class Preprocessor { /// Lex a token, forming a header-name token if possible. bool LexHeaderName(Token &Result, bool AllowMacroExpansion = true); - /// Lex a module name or a partition name. - bool LexModuleName(Token &Result, bool IsImport); - /// Lex the parameters for an #embed directive, returns nullopt on error. std::optional<LexEmbedParametersResult> LexEmbedParameters(Token &Current, bool ForHasEmbed); + bool LexAfterModuleImport(Token &Result); - bool LexAfterModuleDecl(Token &Result); void CollectPpImportSuffix(SmallVectorImpl<Token> &Toks); void makeModuleVisible(Module *M, SourceLocation Loc); @@ -3038,9 +3039,6 @@ class Preprocessor { static bool CLK_LexAfterModuleImport(Preprocessor &P, Token &Result) { return P.LexAfterModuleImport(Result); } - static bool CLK_LexAfterModuleDecl(Preprocessor &P, Token &Result) { - return P.LexAfterModuleDecl(Result); - } }; /// Abstract base class that describes a handler that will receive @@ -3073,77 +3071,6 @@ struct EmbedAnnotationData { /// Registry of pragma handlers added by plugins using PragmaHandlerRegistry = llvm::Registry<PragmaHandler>; -/// Represents module or partition name token sequance. -/// -/// module-name: -/// module-name-qualifier[opt] identifier -/// -/// partition-name: [C++20] -/// : module-name-qualifier[opt] identifier -/// -/// module-name-qualifier -/// module-name-qualifier[opt] identifier . -/// -/// This class can only be created by the preprocessor and guarantees that the -/// two source array being contiguous in memory and only contains 3 kind of -/// tokens (identifier, '.' and ':'). And only available when the preprocessor -/// returns annot_module_name token. -/// -/// For exmaple: -/// -/// export module m.n:c.d -/// -/// The module name array has 3 tokens ['m', '.', 'n']. -/// The partition name array has 4 tokens [':', 'c', '.', 'd']. -/// -/// When import a partition in a named module fragment (Eg. import :part1;), -/// the module name array will be empty, and the partition name array has 2 -/// tokens. -/// -/// When we meet a private-module-fragment (Eg. module :private;), preprocessor -/// will not return a annot_module_name token, but will return 2 separate tokens -/// [':', 'kw_private']. - -class ModuleNameInfo { - friend class Preprocessor; - ArrayRef<Token> ModuleName; - ArrayRef<Token> PartitionName; - - ModuleNameInfo(ArrayRef<Token> AnnotToks, std::optional<unsigned> ColonIndex); - -public: - /// Return the contiguous token array. - ArrayRef<Token> getTokens() const { - if (ModuleName.empty()) - return PartitionName; - if (PartitionName.empty()) - return ModuleName; - return ArrayRef(ModuleName.begin(), PartitionName.end()); - } - bool hasModuleName() const { return !ModuleName.empty(); } - bool hasPartitionName() const { return !PartitionName.empty(); } - ArrayRef<Token> getModuleName() const { return ModuleName; } - ArrayRef<Token> getPartitionName() const { return PartitionName; } - Token getColonToken() const { - assert(hasPartitionName() && "Do not have a partition name"); - return getPartitionName().front(); - } - - /// Under the standard C++ Modules, the dot is just part of the module name, - /// and not a real hierarchy separator. Flatten such module names now. - std::string getFlatName() const; - - /// Build a module id path from the contiguous token array, both include - /// module name and partition name. - void getModuleIdPath( - SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path) const; - - /// Build a module id path from \param ModuleName. - static void getModuleIdPath( - ArrayRef<Token> ModuleName, - SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path); -}; - } // namespace clang #endif // LLVM_CLANG_LEX_PREPROCESSOR_H diff --git a/clang/include/clang/Lex/Token.h b/clang/include/clang/Lex/Token.h index 2be3ad39529f0..4f29fb7d11415 100644 --- a/clang/include/clang/Lex/Token.h +++ b/clang/include/clang/Lex/Token.h @@ -235,9 +235,6 @@ class Token { assert(isAnnotation() && "Used AnnotVal on non-annotation token"); return PtrData; } - template <class T> T getAnnotationValueAs() const { - return static_cast<T>(getAnnotationValue()); - } void setAnnotationValue(void *val) { assert(isAnnotation() && "Used AnnotVal on non-annotation token"); PtrData = val; diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index afcdacf02583a..93e60be512aae 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -3876,7 +3876,7 @@ class Parser : public CodeCompletionHandler { } bool ParseModuleName( - SourceLocation UseLoc, ArrayRef<Token> ModuleName, + SourceLocation UseLoc, SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path, bool IsImport); diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index 97d830214f890..4f7ccaf4021d6 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -322,9 +322,8 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { if (LangOpts.IEEE128) AddKeyword("__ieee128", tok::kw___float128, KEYALL, LangOpts, *this); - // Add the 'import' and 'module' contextual keyword. + // Add the 'import' contextual keyword. get("import").setModulesImport(true); - get("module").setModulesDeclaration(true); } /// Checks if the specified token kind represents a keyword in the diff --git a/clang/lib/Frontend/PrintPreprocessedOutput.cpp b/clang/lib/Frontend/PrintPreprocessedOutput.cpp index 1fff88ccf0405..0592423c12eca 100644 --- a/clang/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/clang/lib/Frontend/PrintPreprocessedOutput.cpp @@ -758,10 +758,9 @@ void PrintPPOutputPPCallbacks::HandleWhitespaceBeforeTok(const Token &Tok, // These tokens are not expanded to anything and don't need whitespace before // them. if (Tok.is(tok::eof) || - (Tok.isAnnotation() && Tok.isNot(tok::annot_header_unit) && - Tok.isNot(tok::annot_module_begin) && Tok.isNot(tok::annot_module_end) && - Tok.isNot(tok::annot_module_name) && - Tok.isNot(tok::annot_repl_input_end) && Tok.isNot(tok::annot_embed))) + (Tok.isAnnotation() && !Tok.is(tok::annot_header_unit) && + !Tok.is(tok::annot_module_begin) && !Tok.is(tok::annot_module_end) && + !Tok.is(tok::annot_repl_input_end) && !Tok.is(tok::annot_embed))) return; // EmittedDirectiveOnThisLine takes priority over RequireSameLine. @@ -952,11 +951,6 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok, PP.Lex(Tok); IsStartOfLine = true; continue; - } else if (Tok.is(tok::annot_module_name)) { - auto *Info = static_cast<ModuleNameInfo *>(Tok.getAnnotationValue()); - *Callbacks->OS << Info->getFlatName(); - PP.Lex(Tok); - continue; } else if (Tok.is(tok::annot_header_unit)) { // This is a header-name that has been (effectively) converted into a // module-name. diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index c3a903917e9ce..8221db46e06ac 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -122,8 +122,7 @@ void Preprocessor::EnterSourceFileWithLexer(Lexer *TheLexer, CurPPLexer = TheLexer; CurDirLookup = CurDir; CurLexerSubmodule = nullptr; - if (CurLexerCallback != CLK_LexAfterModuleImport && - CurLexerCallback != CLK_LexAfterModuleDecl) + if (CurLexerCallback != CLK_LexAfterModuleImport) CurLexerCallback = TheLexer->isDependencyDirectivesLexer() ? CLK_DependencyDirectivesLexer : CLK_Lexer; @@ -162,7 +161,8 @@ void Preprocessor::EnterMacro(Token &Tok, SourceLocation ILEnd, PushIncludeMacroStack(); CurDirLookup = nullptr; CurTokenLexer = std::move(TokLexer); - CurLexerCallback = CLK_TokenLexer; + if (CurLexerCallback != CLK_LexAfterModuleImport) + CurLexerCallback = CLK_TokenLexer; } /// EnterTokenStream - Add a "macro" context to the top of the include stack, @@ -216,8 +216,7 @@ void Preprocessor::EnterTokenStream(const Token *Toks, unsigned NumToks, PushIncludeMacroStack(); CurDirLookup = nullptr; CurTokenLexer = std::move(TokLexer); - if (CurLexerCallback != CLK_LexAfterModuleImport && - CurLexerCallback != CLK_LexAfterModuleDecl) + if (CurLexerCallback != CLK_LexAfterModuleImport) CurLexerCallback = CLK_TokenLexer; } diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 2726fae344337..63e27e62cffc8 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -860,15 +860,9 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) { ModuleImportLoc = Identifier.getLocation(); NamedModuleImportPath.clear(); IsAtImport = true; + ModuleImportExpectsIdentifier = true; CurLexerCallback = CLK_LexAfterModuleImport; } - - if ((II.isModulesDeclaration() || Identifier.is(tok::kw_module)) && - !InMacroArgs && !DisableMacroExpansion && - (getLangOpts().CPlusPlusModules || getLangOpts().DebuggerSupport) && - CurLexerCallback != CLK_CachingLexer) { - CurLexerCallback = CLK_LexAfterModuleDecl; - } return true; } @@ -911,7 +905,6 @@ void Preprocessor::Lex(Token &Result) { // This token is injected to represent the translation of '#include "a.h"' // into "import a.h;". Mimic the notional ';'. case tok::annot_module_include: - case tok::annot_repl_input_end: case tok::semi: TrackGMFState.handleSemi(); StdCXXImportSeqState.handleSemi(); @@ -926,30 +919,12 @@ void Preprocessor::Lex(Token &Result) { StdCXXImportSeqState.handleExport(); ModuleDeclState.handleExport(); break; - case tok::annot_module_name: { - auto *Info = static_cast<ModuleNameInfo *>(Result.getAnnotationValue()); - for (const auto &Tok : Info->getTokens()) { - switch (Tok.getKind()) { - case tok::identifier: - ModuleDeclState.handleIdentifier(Tok.getIdentifierInfo()); - break; - case tok::period: - ModuleDeclState.handlePeriod(); - break; - case tok::colon: - ModuleDeclState.handleColon(); - break; - default: - llvm_unreachable("Unexpected token in module name"); - } - } - if (ModuleDeclState.isModuleCandidate()) - break; - TrackGMFState.handleMisc(); - StdCXXImportSeqState.handleMisc(); - ModuleDeclState.handleMisc(); + case tok::colon: + ModuleDeclState.handleColon(); + break; + case tok::period: + ModuleDeclState.handlePeriod(); break; - } case tok::identifier: // Check "import" and "module" when there is no open bracket. The two // identifiers are not meaningful with open brackets. @@ -961,17 +936,17 @@ void Preprocessor::Lex(Token &Result) { ModuleImportLoc = Result.getLocation(); NamedModuleImportPath.clear(); IsAtImport = false; + ModuleImportExpectsIdentifier = true; CurLexerCallback = CLK_LexAfterModuleImport; } break; - } - if (Result.getIdentifierInfo()->isModulesDeclaration()) { + } else if (Result.getIdentifierInfo() == getIdentifierInfo("module")) { TrackGMFState.handleModule(StdCXXImportSeqState.afterTopLevelSeq()); ModuleDeclState.handleModule(); - CurLexerCallback = CLK_LexAfterModuleDecl; break; } } + ModuleDeclState.handleIdentifier(Result.getIdentifierInfo()); if (ModuleDeclState.isModuleCandidate()) break; [[fallthrough]]; @@ -1146,151 +1121,6 @@ void Preprocessor::CollectPpImportSuffix(SmallVectorImpl<Token> &Toks) { } } -ModuleNameInfo::ModuleNameInfo(ArrayRef<Token> AnnotToks, - std::optional<unsigned> ColonIndex) { - assert(!AnnotToks.empty() && "Named module token cannot be empty."); - if (!ColonIndex.has_value()) - ColonIndex = AnnotToks.size(); - ModuleName = ArrayRef(AnnotToks.begin(), AnnotToks.begin() + *ColonIndex); - PartitionName = ArrayRef(AnnotToks.begin() + *ColonIndex, AnnotToks.end()); - assert(ModuleName.end() == PartitionName.begin()); -} - -std::string ModuleNameInfo::getFlatName() const { - std::string FlatModuleName; - for (auto &Tok : getTokens()) { - switch (Tok.getKind()) { - case tok::identifier: - FlatModuleName += Tok.getIdentifierInfo()->getName(); - break; - case tok::period: - FlatModuleName += '.'; - break; - case tok::colon: - FlatModuleName += ':'; - break; - default: - llvm_unreachable("Unexpected token in module name"); - } - } - return FlatModuleName; -} - -void ModuleNameInfo::getModuleIdPath( - SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path) const { - return getModuleIdPath(getTokens(), Path); -} - -void ModuleNameInfo::getModuleIdPath( - ArrayRef<Token> ModuleName, - SmallVectorImpl<std::pair<IdentifierInfo *, SourceLocation>> &Path) { - for (const auto &Tok : ModuleName) { - if (Tok.is(tok::identifier)) - Path.push_back( - std::make_pair(Tok.getIdentifierInfo(), Tok.getLocation())); - } -} - -/// Lex a module name or a partition name. -/// -/// module-name: -/// module-name-qualifier[opt] identifier -/// -/// partition-name: [C++20] -/// : module-name-qualifier[opt] identifier -/// -/// module-name-qualifier -/// module-name-qualifier[opt] identifier . -bool Preprocessor::LexModuleName(Token &Result, bool IsImport) { - bool ExpectsIdentifier = true, IsLexingPartition = false; - SmallVector<Token, 8> ModuleName; - std::optional<unsigned> ColonTokIndex; - auto LexNextToken = [&](Token &Tok) { - if (IsImport) - Lex(Tok); - else - LexUnexpandedToken(Tok); - }; - - while (true) { - LexNextToken(Result); - if (ExpectsIdentifier && Result.is(tok::identifier)) { - auto *MI = getMacroInfo(Result.getIdentifierInfo()); - if (getLangOpts().CPlusPlusModules && !IsImport && MI && - MI->isObjectLike()) { - Diag(Result, diag::err_module_decl_cannot_be_macros) - << Result.getLocation() << IsLexingPartition - << Result.getIdentifierInfo(); - } - ModuleName.push_back(Result); - ExpectsIdentifier = false; - continue; - } - - if (!ExpectsIdentifier && Result.is(tok::period)) { - ModuleName.push_back(Result); - ExpectsIdentifier = true; - continue; - } - - // Module partition only allowed in C++20 Modules. - if (getLangOpts().CPlusPlusModules && Result.is(tok::colon)) { - // Handle the form like: import :P; - // If the token after ':' is not an identifier, this is a invalid module - // name. - if (ModuleName.empty()) { - Token Tmp; - LexNextToken(Tmp); - EnterToken(Tmp, /*IsReiject=*/false); - // A private-module-fragment: - // export module :private; - if (!IsImport && Tmp.is(tok::kw_private)) - return true; - // import :N; -... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/99838 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits