xref: /aosp_15_r20/external/clang/unittests/Lex/LexerTest.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===- unittests/Lex/LexerTest.cpp ------ Lexer tests ---------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li 
10*67e74705SXin Li #include "clang/Lex/Lexer.h"
11*67e74705SXin Li #include "clang/Basic/Diagnostic.h"
12*67e74705SXin Li #include "clang/Basic/DiagnosticOptions.h"
13*67e74705SXin Li #include "clang/Basic/FileManager.h"
14*67e74705SXin Li #include "clang/Basic/LangOptions.h"
15*67e74705SXin Li #include "clang/Basic/SourceManager.h"
16*67e74705SXin Li #include "clang/Basic/TargetInfo.h"
17*67e74705SXin Li #include "clang/Basic/TargetOptions.h"
18*67e74705SXin Li #include "clang/Lex/HeaderSearch.h"
19*67e74705SXin Li #include "clang/Lex/HeaderSearchOptions.h"
20*67e74705SXin Li #include "clang/Lex/ModuleLoader.h"
21*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
22*67e74705SXin Li #include "clang/Lex/PreprocessorOptions.h"
23*67e74705SXin Li #include "gtest/gtest.h"
24*67e74705SXin Li 
25*67e74705SXin Li using namespace clang;
26*67e74705SXin Li 
27*67e74705SXin Li namespace {
28*67e74705SXin Li 
29*67e74705SXin Li class VoidModuleLoader : public ModuleLoader {
loadModule(SourceLocation ImportLoc,ModuleIdPath Path,Module::NameVisibilityKind Visibility,bool IsInclusionDirective)30*67e74705SXin Li   ModuleLoadResult loadModule(SourceLocation ImportLoc,
31*67e74705SXin Li                               ModuleIdPath Path,
32*67e74705SXin Li                               Module::NameVisibilityKind Visibility,
33*67e74705SXin Li                               bool IsInclusionDirective) override {
34*67e74705SXin Li     return ModuleLoadResult();
35*67e74705SXin Li   }
36*67e74705SXin Li 
makeModuleVisible(Module * Mod,Module::NameVisibilityKind Visibility,SourceLocation ImportLoc)37*67e74705SXin Li   void makeModuleVisible(Module *Mod,
38*67e74705SXin Li                          Module::NameVisibilityKind Visibility,
39*67e74705SXin Li                          SourceLocation ImportLoc) override { }
40*67e74705SXin Li 
loadGlobalModuleIndex(SourceLocation TriggerLoc)41*67e74705SXin Li   GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
42*67e74705SXin Li     { return nullptr; }
lookupMissingImports(StringRef Name,SourceLocation TriggerLoc)43*67e74705SXin Li   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
44*67e74705SXin Li     { return 0; }
45*67e74705SXin Li };
46*67e74705SXin Li 
47*67e74705SXin Li // The test fixture.
48*67e74705SXin Li class LexerTest : public ::testing::Test {
49*67e74705SXin Li protected:
LexerTest()50*67e74705SXin Li   LexerTest()
51*67e74705SXin Li     : FileMgr(FileMgrOpts),
52*67e74705SXin Li       DiagID(new DiagnosticIDs()),
53*67e74705SXin Li       Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
54*67e74705SXin Li       SourceMgr(Diags, FileMgr),
55*67e74705SXin Li       TargetOpts(new TargetOptions)
56*67e74705SXin Li   {
57*67e74705SXin Li     TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
58*67e74705SXin Li     Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
59*67e74705SXin Li   }
60*67e74705SXin Li 
Lex(StringRef Source)61*67e74705SXin Li   std::vector<Token> Lex(StringRef Source) {
62*67e74705SXin Li     std::unique_ptr<llvm::MemoryBuffer> Buf =
63*67e74705SXin Li         llvm::MemoryBuffer::getMemBuffer(Source);
64*67e74705SXin Li     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
65*67e74705SXin Li 
66*67e74705SXin Li     VoidModuleLoader ModLoader;
67*67e74705SXin Li     HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
68*67e74705SXin Li                             Target.get());
69*67e74705SXin Li     Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
70*67e74705SXin Li                     HeaderInfo, ModLoader, /*IILookup =*/nullptr,
71*67e74705SXin Li                     /*OwnsHeaderSearch =*/false);
72*67e74705SXin Li     PP.Initialize(*Target);
73*67e74705SXin Li     PP.EnterMainSourceFile();
74*67e74705SXin Li 
75*67e74705SXin Li     std::vector<Token> toks;
76*67e74705SXin Li     while (1) {
77*67e74705SXin Li       Token tok;
78*67e74705SXin Li       PP.Lex(tok);
79*67e74705SXin Li       if (tok.is(tok::eof))
80*67e74705SXin Li         break;
81*67e74705SXin Li       toks.push_back(tok);
82*67e74705SXin Li     }
83*67e74705SXin Li 
84*67e74705SXin Li     return toks;
85*67e74705SXin Li   }
86*67e74705SXin Li 
CheckLex(StringRef Source,ArrayRef<tok::TokenKind> ExpectedTokens)87*67e74705SXin Li   std::vector<Token> CheckLex(StringRef Source,
88*67e74705SXin Li                               ArrayRef<tok::TokenKind> ExpectedTokens) {
89*67e74705SXin Li     auto toks = Lex(Source);
90*67e74705SXin Li     EXPECT_EQ(ExpectedTokens.size(), toks.size());
91*67e74705SXin Li     for (unsigned i = 0, e = ExpectedTokens.size(); i != e; ++i) {
92*67e74705SXin Li       EXPECT_EQ(ExpectedTokens[i], toks[i].getKind());
93*67e74705SXin Li     }
94*67e74705SXin Li 
95*67e74705SXin Li     return toks;
96*67e74705SXin Li   }
97*67e74705SXin Li 
getSourceText(Token Begin,Token End)98*67e74705SXin Li   std::string getSourceText(Token Begin, Token End) {
99*67e74705SXin Li     bool Invalid;
100*67e74705SXin Li     StringRef Str =
101*67e74705SXin Li         Lexer::getSourceText(CharSourceRange::getTokenRange(SourceRange(
102*67e74705SXin Li                                     Begin.getLocation(), End.getLocation())),
103*67e74705SXin Li                              SourceMgr, LangOpts, &Invalid);
104*67e74705SXin Li     if (Invalid)
105*67e74705SXin Li       return "<INVALID>";
106*67e74705SXin Li     return Str;
107*67e74705SXin Li   }
108*67e74705SXin Li 
109*67e74705SXin Li   FileSystemOptions FileMgrOpts;
110*67e74705SXin Li   FileManager FileMgr;
111*67e74705SXin Li   IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
112*67e74705SXin Li   DiagnosticsEngine Diags;
113*67e74705SXin Li   SourceManager SourceMgr;
114*67e74705SXin Li   LangOptions LangOpts;
115*67e74705SXin Li   std::shared_ptr<TargetOptions> TargetOpts;
116*67e74705SXin Li   IntrusiveRefCntPtr<TargetInfo> Target;
117*67e74705SXin Li };
118*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextExpandsToMaximumInMacroArgument)119*67e74705SXin Li TEST_F(LexerTest, GetSourceTextExpandsToMaximumInMacroArgument) {
120*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
121*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
122*67e74705SXin Li   ExpectedTokens.push_back(tok::l_paren);
123*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
124*67e74705SXin Li   ExpectedTokens.push_back(tok::r_paren);
125*67e74705SXin Li 
126*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
127*67e74705SXin Li                                      "M(f(M(i)))",
128*67e74705SXin Li                                      ExpectedTokens);
129*67e74705SXin Li 
130*67e74705SXin Li   EXPECT_EQ("M(i)", getSourceText(toks[2], toks[2]));
131*67e74705SXin Li }
132*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextExpandsToMaximumInMacroArgumentForEndOfMacro)133*67e74705SXin Li TEST_F(LexerTest, GetSourceTextExpandsToMaximumInMacroArgumentForEndOfMacro) {
134*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
135*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
136*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
137*67e74705SXin Li 
138*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
139*67e74705SXin Li                                      "M(M(i) c)",
140*67e74705SXin Li                                      ExpectedTokens);
141*67e74705SXin Li 
142*67e74705SXin Li   EXPECT_EQ("M(i)", getSourceText(toks[0], toks[0]));
143*67e74705SXin Li }
144*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextExpandsInMacroArgumentForBeginOfMacro)145*67e74705SXin Li TEST_F(LexerTest, GetSourceTextExpandsInMacroArgumentForBeginOfMacro) {
146*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
147*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
148*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
149*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
150*67e74705SXin Li 
151*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
152*67e74705SXin Li                                      "M(c c M(i))",
153*67e74705SXin Li                                      ExpectedTokens);
154*67e74705SXin Li 
155*67e74705SXin Li   EXPECT_EQ("c M(i)", getSourceText(toks[1], toks[2]));
156*67e74705SXin Li }
157*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextExpandsInMacroArgumentForEndOfMacro)158*67e74705SXin Li TEST_F(LexerTest, GetSourceTextExpandsInMacroArgumentForEndOfMacro) {
159*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
160*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
161*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
162*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
163*67e74705SXin Li 
164*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
165*67e74705SXin Li                                      "M(M(i) c c)",
166*67e74705SXin Li                                      ExpectedTokens);
167*67e74705SXin Li 
168*67e74705SXin Li   EXPECT_EQ("M(i) c", getSourceText(toks[0], toks[1]));
169*67e74705SXin Li }
170*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextInSeparateFnMacros)171*67e74705SXin Li TEST_F(LexerTest, GetSourceTextInSeparateFnMacros) {
172*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
173*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
174*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
175*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
176*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
177*67e74705SXin Li 
178*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
179*67e74705SXin Li                                      "M(c M(i)) M(M(i) c)",
180*67e74705SXin Li                                      ExpectedTokens);
181*67e74705SXin Li 
182*67e74705SXin Li   EXPECT_EQ("<INVALID>", getSourceText(toks[1], toks[2]));
183*67e74705SXin Li }
184*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextWorksAcrossTokenPastes)185*67e74705SXin Li TEST_F(LexerTest, GetSourceTextWorksAcrossTokenPastes) {
186*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
187*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
188*67e74705SXin Li   ExpectedTokens.push_back(tok::l_paren);
189*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
190*67e74705SXin Li   ExpectedTokens.push_back(tok::r_paren);
191*67e74705SXin Li 
192*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
193*67e74705SXin Li                                      "#define C(x) M(x##c)\n"
194*67e74705SXin Li                                      "M(f(C(i)))",
195*67e74705SXin Li                                      ExpectedTokens);
196*67e74705SXin Li 
197*67e74705SXin Li   EXPECT_EQ("C(i)", getSourceText(toks[2], toks[2]));
198*67e74705SXin Li }
199*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextExpandsAcrossMultipleMacroCalls)200*67e74705SXin Li TEST_F(LexerTest, GetSourceTextExpandsAcrossMultipleMacroCalls) {
201*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
202*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
203*67e74705SXin Li   ExpectedTokens.push_back(tok::l_paren);
204*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
205*67e74705SXin Li   ExpectedTokens.push_back(tok::r_paren);
206*67e74705SXin Li 
207*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
208*67e74705SXin Li                                      "f(M(M(i)))",
209*67e74705SXin Li                                      ExpectedTokens);
210*67e74705SXin Li   EXPECT_EQ("M(M(i))", getSourceText(toks[2], toks[2]));
211*67e74705SXin Li }
212*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextInMiddleOfMacroArgument)213*67e74705SXin Li TEST_F(LexerTest, GetSourceTextInMiddleOfMacroArgument) {
214*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
215*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
216*67e74705SXin Li   ExpectedTokens.push_back(tok::l_paren);
217*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
218*67e74705SXin Li   ExpectedTokens.push_back(tok::r_paren);
219*67e74705SXin Li 
220*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
221*67e74705SXin Li                                      "M(f(i))",
222*67e74705SXin Li                                      ExpectedTokens);
223*67e74705SXin Li   EXPECT_EQ("i", getSourceText(toks[2], toks[2]));
224*67e74705SXin Li }
225*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextExpandsAroundDifferentMacroCalls)226*67e74705SXin Li TEST_F(LexerTest, GetSourceTextExpandsAroundDifferentMacroCalls) {
227*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
228*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
229*67e74705SXin Li   ExpectedTokens.push_back(tok::l_paren);
230*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
231*67e74705SXin Li   ExpectedTokens.push_back(tok::r_paren);
232*67e74705SXin Li 
233*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
234*67e74705SXin Li                                      "#define C(x) x\n"
235*67e74705SXin Li                                      "f(C(M(i)))",
236*67e74705SXin Li                                      ExpectedTokens);
237*67e74705SXin Li   EXPECT_EQ("C(M(i))", getSourceText(toks[2], toks[2]));
238*67e74705SXin Li }
239*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextOnlyExpandsIfFirstTokenInMacro)240*67e74705SXin Li TEST_F(LexerTest, GetSourceTextOnlyExpandsIfFirstTokenInMacro) {
241*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
242*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
243*67e74705SXin Li   ExpectedTokens.push_back(tok::l_paren);
244*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
245*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
246*67e74705SXin Li   ExpectedTokens.push_back(tok::r_paren);
247*67e74705SXin Li 
248*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
249*67e74705SXin Li                                      "#define C(x) c x\n"
250*67e74705SXin Li                                      "f(C(M(i)))",
251*67e74705SXin Li                                      ExpectedTokens);
252*67e74705SXin Li   EXPECT_EQ("M(i)", getSourceText(toks[3], toks[3]));
253*67e74705SXin Li }
254*67e74705SXin Li 
TEST_F(LexerTest,GetSourceTextExpandsRecursively)255*67e74705SXin Li TEST_F(LexerTest, GetSourceTextExpandsRecursively) {
256*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
257*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
258*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
259*67e74705SXin Li   ExpectedTokens.push_back(tok::l_paren);
260*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
261*67e74705SXin Li   ExpectedTokens.push_back(tok::r_paren);
262*67e74705SXin Li 
263*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) x\n"
264*67e74705SXin Li                                      "#define C(x) c M(x)\n"
265*67e74705SXin Li                                      "C(f(M(i)))",
266*67e74705SXin Li                                      ExpectedTokens);
267*67e74705SXin Li   EXPECT_EQ("M(i)", getSourceText(toks[3], toks[3]));
268*67e74705SXin Li }
269*67e74705SXin Li 
TEST_F(LexerTest,LexAPI)270*67e74705SXin Li TEST_F(LexerTest, LexAPI) {
271*67e74705SXin Li   std::vector<tok::TokenKind> ExpectedTokens;
272*67e74705SXin Li   ExpectedTokens.push_back(tok::l_square);
273*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
274*67e74705SXin Li   ExpectedTokens.push_back(tok::r_square);
275*67e74705SXin Li   ExpectedTokens.push_back(tok::l_square);
276*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
277*67e74705SXin Li   ExpectedTokens.push_back(tok::r_square);
278*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
279*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
280*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
281*67e74705SXin Li   ExpectedTokens.push_back(tok::identifier);
282*67e74705SXin Li 
283*67e74705SXin Li   std::vector<Token> toks = CheckLex("#define M(x) [x]\n"
284*67e74705SXin Li                                      "#define N(x) x\n"
285*67e74705SXin Li                                      "#define INN(x) x\n"
286*67e74705SXin Li                                      "#define NOF1 INN(val)\n"
287*67e74705SXin Li                                      "#define NOF2 val\n"
288*67e74705SXin Li                                      "M(foo) N([bar])\n"
289*67e74705SXin Li                                      "N(INN(val)) N(NOF1) N(NOF2) N(val)",
290*67e74705SXin Li                                      ExpectedTokens);
291*67e74705SXin Li 
292*67e74705SXin Li   SourceLocation lsqrLoc = toks[0].getLocation();
293*67e74705SXin Li   SourceLocation idLoc = toks[1].getLocation();
294*67e74705SXin Li   SourceLocation rsqrLoc = toks[2].getLocation();
295*67e74705SXin Li   std::pair<SourceLocation,SourceLocation>
296*67e74705SXin Li     macroPair = SourceMgr.getExpansionRange(lsqrLoc);
297*67e74705SXin Li   SourceRange macroRange = SourceRange(macroPair.first, macroPair.second);
298*67e74705SXin Li 
299*67e74705SXin Li   SourceLocation Loc;
300*67e74705SXin Li   EXPECT_TRUE(Lexer::isAtStartOfMacroExpansion(lsqrLoc, SourceMgr, LangOpts, &Loc));
301*67e74705SXin Li   EXPECT_EQ(Loc, macroRange.getBegin());
302*67e74705SXin Li   EXPECT_FALSE(Lexer::isAtStartOfMacroExpansion(idLoc, SourceMgr, LangOpts));
303*67e74705SXin Li   EXPECT_FALSE(Lexer::isAtEndOfMacroExpansion(idLoc, SourceMgr, LangOpts));
304*67e74705SXin Li   EXPECT_TRUE(Lexer::isAtEndOfMacroExpansion(rsqrLoc, SourceMgr, LangOpts, &Loc));
305*67e74705SXin Li   EXPECT_EQ(Loc, macroRange.getEnd());
306*67e74705SXin Li 
307*67e74705SXin Li   CharSourceRange range = Lexer::makeFileCharRange(
308*67e74705SXin Li            CharSourceRange::getTokenRange(lsqrLoc, idLoc), SourceMgr, LangOpts);
309*67e74705SXin Li   EXPECT_TRUE(range.isInvalid());
310*67e74705SXin Li   range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(idLoc, rsqrLoc),
311*67e74705SXin Li                                    SourceMgr, LangOpts);
312*67e74705SXin Li   EXPECT_TRUE(range.isInvalid());
313*67e74705SXin Li   range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(lsqrLoc, rsqrLoc),
314*67e74705SXin Li                                    SourceMgr, LangOpts);
315*67e74705SXin Li   EXPECT_TRUE(!range.isTokenRange());
316*67e74705SXin Li   EXPECT_EQ(range.getAsRange(),
317*67e74705SXin Li             SourceRange(macroRange.getBegin(),
318*67e74705SXin Li                         macroRange.getEnd().getLocWithOffset(1)));
319*67e74705SXin Li 
320*67e74705SXin Li   StringRef text = Lexer::getSourceText(
321*67e74705SXin Li                                CharSourceRange::getTokenRange(lsqrLoc, rsqrLoc),
322*67e74705SXin Li                                SourceMgr, LangOpts);
323*67e74705SXin Li   EXPECT_EQ(text, "M(foo)");
324*67e74705SXin Li 
325*67e74705SXin Li   SourceLocation macroLsqrLoc = toks[3].getLocation();
326*67e74705SXin Li   SourceLocation macroIdLoc = toks[4].getLocation();
327*67e74705SXin Li   SourceLocation macroRsqrLoc = toks[5].getLocation();
328*67e74705SXin Li   SourceLocation fileLsqrLoc = SourceMgr.getSpellingLoc(macroLsqrLoc);
329*67e74705SXin Li   SourceLocation fileIdLoc = SourceMgr.getSpellingLoc(macroIdLoc);
330*67e74705SXin Li   SourceLocation fileRsqrLoc = SourceMgr.getSpellingLoc(macroRsqrLoc);
331*67e74705SXin Li 
332*67e74705SXin Li   range = Lexer::makeFileCharRange(
333*67e74705SXin Li       CharSourceRange::getTokenRange(macroLsqrLoc, macroIdLoc),
334*67e74705SXin Li       SourceMgr, LangOpts);
335*67e74705SXin Li   EXPECT_EQ(SourceRange(fileLsqrLoc, fileIdLoc.getLocWithOffset(3)),
336*67e74705SXin Li             range.getAsRange());
337*67e74705SXin Li 
338*67e74705SXin Li   range = Lexer::makeFileCharRange(CharSourceRange::getTokenRange(macroIdLoc, macroRsqrLoc),
339*67e74705SXin Li                                    SourceMgr, LangOpts);
340*67e74705SXin Li   EXPECT_EQ(SourceRange(fileIdLoc, fileRsqrLoc.getLocWithOffset(1)),
341*67e74705SXin Li             range.getAsRange());
342*67e74705SXin Li 
343*67e74705SXin Li   macroPair = SourceMgr.getExpansionRange(macroLsqrLoc);
344*67e74705SXin Li   range = Lexer::makeFileCharRange(
345*67e74705SXin Li                      CharSourceRange::getTokenRange(macroLsqrLoc, macroRsqrLoc),
346*67e74705SXin Li                      SourceMgr, LangOpts);
347*67e74705SXin Li   EXPECT_EQ(SourceRange(macroPair.first, macroPair.second.getLocWithOffset(1)),
348*67e74705SXin Li             range.getAsRange());
349*67e74705SXin Li 
350*67e74705SXin Li   text = Lexer::getSourceText(
351*67e74705SXin Li           CharSourceRange::getTokenRange(SourceRange(macroLsqrLoc, macroIdLoc)),
352*67e74705SXin Li           SourceMgr, LangOpts);
353*67e74705SXin Li   EXPECT_EQ(text, "[bar");
354*67e74705SXin Li 
355*67e74705SXin Li 
356*67e74705SXin Li   SourceLocation idLoc1 = toks[6].getLocation();
357*67e74705SXin Li   SourceLocation idLoc2 = toks[7].getLocation();
358*67e74705SXin Li   SourceLocation idLoc3 = toks[8].getLocation();
359*67e74705SXin Li   SourceLocation idLoc4 = toks[9].getLocation();
360*67e74705SXin Li   EXPECT_EQ("INN", Lexer::getImmediateMacroName(idLoc1, SourceMgr, LangOpts));
361*67e74705SXin Li   EXPECT_EQ("INN", Lexer::getImmediateMacroName(idLoc2, SourceMgr, LangOpts));
362*67e74705SXin Li   EXPECT_EQ("NOF2", Lexer::getImmediateMacroName(idLoc3, SourceMgr, LangOpts));
363*67e74705SXin Li   EXPECT_EQ("N", Lexer::getImmediateMacroName(idLoc4, SourceMgr, LangOpts));
364*67e74705SXin Li }
365*67e74705SXin Li 
TEST_F(LexerTest,DontMergeMacroArgsFromDifferentMacroFiles)366*67e74705SXin Li TEST_F(LexerTest, DontMergeMacroArgsFromDifferentMacroFiles) {
367*67e74705SXin Li   std::vector<Token> toks =
368*67e74705SXin Li       Lex("#define helper1 0\n"
369*67e74705SXin Li           "void helper2(const char *, ...);\n"
370*67e74705SXin Li           "#define M1(a, ...) helper2(a, ##__VA_ARGS__)\n"
371*67e74705SXin Li           "#define M2(a, ...) M1(a, helper1, ##__VA_ARGS__)\n"
372*67e74705SXin Li           "void f1() { M2(\"a\", \"b\"); }");
373*67e74705SXin Li 
374*67e74705SXin Li   // Check the file corresponding to the "helper1" macro arg in M2.
375*67e74705SXin Li   //
376*67e74705SXin Li   // The lexer used to report its size as 31, meaning that the end of the
377*67e74705SXin Li   // expansion would be on the *next line* (just past `M2("a", "b")`). Make
378*67e74705SXin Li   // sure that we get the correct end location (the comma after "helper1").
379*67e74705SXin Li   SourceLocation helper1ArgLoc = toks[20].getLocation();
380*67e74705SXin Li   EXPECT_EQ(SourceMgr.getFileIDSize(SourceMgr.getFileID(helper1ArgLoc)), 8U);
381*67e74705SXin Li }
382*67e74705SXin Li 
383*67e74705SXin Li } // anonymous namespace
384