diff options
author | yronglin <yronglin777@gmail.com> | 2025-06-21 18:58:56 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-06-21 18:58:56 +0800 |
commit | ea321392ebc487c1000e43576f44af99edf28a5f (patch) | |
tree | e259fa69b0eec9757771f96085e12337c94b9b65 /clang/unittests/Lex/LexerTest.cpp | |
parent | 1b5d6ec6855369d109fcb740ecd3812231b7a279 (diff) | |
download | llvm-ea321392ebc487c1000e43576f44af99edf28a5f.zip llvm-ea321392ebc487c1000e43576f44af99edf28a5f.tar.gz llvm-ea321392ebc487c1000e43576f44af99edf28a5f.tar.bz2 |
[C++][Modules] A module directive may only appear as the first preprocessing tokens in a file (#144233)
This PR is 2nd part of
[P1857R3](https://github.com/llvm/llvm-project/pull/107168)
implementation, and mainly implement the restriction `A module directive
may only appear as the first preprocessing tokens in a file (excluding
the global module fragment.)`:
[cpp.pre](https://eel.is/c++draft/cpp.pre):
```
module-file:
pp-global-module-fragment[opt] pp-module group[opt] pp-private-module-fragment[opt]
```
We also refine tests use `split-file` instead of conditional macro.
Signed-off-by: yronglin <yronglin777@gmail.com>
Diffstat (limited to 'clang/unittests/Lex/LexerTest.cpp')
-rw-r--r-- | clang/unittests/Lex/LexerTest.cpp | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/clang/unittests/Lex/LexerTest.cpp b/clang/unittests/Lex/LexerTest.cpp index 381755d..33c8abb 100644 --- a/clang/unittests/Lex/LexerTest.cpp +++ b/clang/unittests/Lex/LexerTest.cpp @@ -49,7 +49,8 @@ protected: } std::unique_ptr<Preprocessor> CreatePP(StringRef Source, - TrivialModuleLoader &ModLoader) { + TrivialModuleLoader &ModLoader, + StringRef PreDefines = {}) { std::unique_ptr<llvm::MemoryBuffer> Buf = llvm::MemoryBuffer::getMemBuffer(Source); SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf))); @@ -61,6 +62,8 @@ protected: PPOpts, Diags, LangOpts, SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr, /*OwnsHeaderSearch =*/false); + if (!PreDefines.empty()) + PP->setPredefines(PreDefines.str()); PP->Initialize(*Target); PP->EnterMainSourceFile(); return PP; @@ -769,4 +772,46 @@ TEST(LexerPreambleTest, PreambleBounds) { } } +TEST_F(LexerTest, CheckFirstPPToken) { + { + TrivialModuleLoader ModLoader; + auto PP = CreatePP("// This is a comment\n" + "int a;", + ModLoader); + Token Tok; + PP->Lex(Tok); + EXPECT_TRUE(Tok.is(tok::kw_int)); + EXPECT_TRUE(PP->hasSeenMainFileFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().isFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().is(tok::kw_int)); + } + { + TrivialModuleLoader ModLoader; + auto PP = CreatePP("// This is a comment\n" + "#define FOO int\n" + "FOO a;", + ModLoader); + Token Tok; + PP->Lex(Tok); + EXPECT_TRUE(Tok.is(tok::kw_int)); + EXPECT_TRUE(PP->hasSeenMainFileFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().isFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().is(tok::hash)); + } + + { + TrivialModuleLoader ModLoader; + auto PP = CreatePP("// This is a comment\n" + "FOO a;", + ModLoader, "#define FOO int\n"); + Token Tok; + PP->Lex(Tok); + EXPECT_TRUE(Tok.is(tok::kw_int)); + EXPECT_TRUE(PP->hasSeenMainFileFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().isFirstPPToken()); + EXPECT_TRUE(PP->getMainFileFirstPPToken().is(tok::identifier)); + EXPECT_TRUE( + PP->getMainFileFirstPPToken().getIdentifierInfo()->isStr("FOO")); + } +} } // anonymous namespace |