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