Skip to content

Revert "[Clang] Implement P3034R1 Module Declarations Shouldn’t be Macros" #99838

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
5 changes: 0 additions & 5 deletions clang/include/clang/Basic/DiagnosticLexKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -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">;
Expand Down
24 changes: 3 additions & 21 deletions clang/include/clang/Basic/IdentifierTable.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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; }

Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 0 additions & 3 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
83 changes: 5 additions & 78 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
3 changes: 0 additions & 3 deletions clang/include/clang/Lex/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
3 changes: 1 addition & 2 deletions clang/lib/Basic/IdentifierTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 3 additions & 9 deletions clang/lib/Frontend/PrintPreprocessedOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
9 changes: 4 additions & 5 deletions clang/lib/Lex/PPLexerChange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}

Expand Down
Loading
Loading