File tree Expand file tree Collapse file tree 4 files changed +80
-0
lines changed Expand file tree Collapse file tree 4 files changed +80
-0
lines changed Original file line number Diff line number Diff line change 8
8
9
9
#include " TestFS.h"
10
10
#include " TestTU.h"
11
+ #include " llvm/ADT/StringRef.h"
11
12
#include " gmock/gmock.h"
12
13
#include " gtest/gtest.h"
13
14
@@ -109,6 +110,34 @@ TEST(Modules, UnknownFormat) {
109
110
// Test that we do not crash.
110
111
TU.build ();
111
112
}
113
+
114
+ // Test that we can build and use a preamble for a module unit.
115
+ TEST (Modules, ModulePreamble) {
116
+ TestTU TU = TestTU::withCode (R"cpp(
117
+ module;
118
+ #define PREAMBLE_MACRO 1
119
+ export module foo;
120
+ #define MODULE_MACRO 2
121
+ module :private;
122
+ #define PRIVATE_MACRO 3
123
+ )cpp" );
124
+ TU.ExtraArgs .push_back (" -std=c++20" );
125
+ TU.ExtraArgs .push_back (" --precompile" );
126
+
127
+ auto AST = TU.build ();
128
+ auto &SM = AST.getSourceManager ();
129
+ auto GetMacroFile = [&](llvm::StringRef Name) -> FileID {
130
+ if (auto *MI = AST.getPreprocessor ().getMacroInfo (
131
+ &AST.getASTContext ().Idents .get (Name)))
132
+ return SM.getFileID (MI->getDefinitionLoc ());
133
+ return {};
134
+ };
135
+
136
+ EXPECT_EQ (GetMacroFile (" PREAMBLE_MACRO" ), SM.getPreambleFileID ());
137
+ EXPECT_EQ (GetMacroFile (" MODULE_MACRO" ), SM.getMainFileID ());
138
+ EXPECT_EQ (GetMacroFile (" PRIVATE_MACRO" ), SM.getMainFileID ());
139
+ }
140
+
112
141
} // namespace
113
142
} // namespace clangd
114
143
} // namespace clang
Original file line number Diff line number Diff line change @@ -705,6 +705,22 @@ PreambleBounds Lexer::ComputePreamble(StringRef Buffer,
705
705
// directive or it was one that can't occur in the preamble at this
706
706
// point. Roll back the current token to the location of the '#'.
707
707
TheTok = HashTok;
708
+ } else if (TheTok.isAtStartOfLine () &&
709
+ TheTok.getKind () == tok::raw_identifier &&
710
+ TheTok.getRawIdentifier () == " module" &&
711
+ LangOpts.CPlusPlusModules ) {
712
+ // The initial global module fragment introducer "module;" is part of
713
+ // the preamble, which runs up to the module declaration "module foo;".
714
+ Token ModuleTok = TheTok;
715
+ do {
716
+ TheLexer.LexFromRawLexer (TheTok);
717
+ } while (TheTok.getKind () == tok::comment);
718
+ if (TheTok.getKind () != tok::semi) {
719
+ // Not global module fragment, roll back.
720
+ TheTok = ModuleTok;
721
+ break ;
722
+ }
723
+ continue ;
708
724
}
709
725
710
726
// We hit a token that we don't recognize as being in the
Original file line number Diff line number Diff line change @@ -25,5 +25,6 @@ clang_target_link_libraries(LexTests
25
25
26
26
target_link_libraries (LexTests
27
27
PRIVATE
28
+ LLVMTestingAnnotations
28
29
LLVMTestingSupport
29
30
)
Original file line number Diff line number Diff line change 26
26
#include " clang/Lex/PreprocessorOptions.h"
27
27
#include " llvm/ADT/ArrayRef.h"
28
28
#include " llvm/ADT/StringRef.h"
29
+ #include " llvm/Testing/Annotations/Annotations.h"
29
30
#include " gmock/gmock.h"
30
31
#include " gtest/gtest.h"
31
32
#include < memory>
33
+ #include < string>
32
34
#include < vector>
33
35
34
36
namespace {
@@ -660,4 +662,36 @@ TEST_F(LexerTest, RawAndNormalLexSameForLineComments) {
660
662
}
661
663
EXPECT_TRUE (ToksView.empty ());
662
664
}
665
+
666
+ TEST (LexerPreambleTest, PreambleBounds) {
667
+ std::vector<std::string> Cases = {
668
+ R"cc( [[
669
+ #include <foo>
670
+ ]]int bar;
671
+ )cc" ,
672
+ R"cc( [[
673
+ #include <foo>
674
+ ]])cc" ,
675
+ R"cc( [[
676
+ // leading comment
677
+ #include <foo>
678
+ ]]// trailing comment
679
+ int bar;
680
+ )cc" ,
681
+ R"cc( [[
682
+ module;
683
+ #include <foo>
684
+ ]]module bar;
685
+ int x;
686
+ )cc" ,
687
+ };
688
+ for (const auto & Case : Cases) {
689
+ llvm::Annotations A (Case);
690
+ clang::LangOptions LangOpts;
691
+ LangOpts.CPlusPlusModules = true ;
692
+ auto Bounds = Lexer::ComputePreamble (A.code (), LangOpts);
693
+ EXPECT_EQ (Bounds.Size , A.range ().End ) << Case;
694
+ }
695
+ }
696
+
663
697
} // anonymous namespace
You can’t perform that action at this time.
0 commit comments