blob: 588721189d88014b28589a6bdbd2602eee3540e9 [file] [log] [blame]
Argyrios Kyrtzidisd7711ec2011-12-21 16:56:29 +00001//===- unittests/Basic/SourceManagerTest.cpp ------ SourceManager tests ---===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "clang/Basic/SourceManager.h"
11#include "clang/Basic/FileManager.h"
12#include "clang/Basic/Diagnostic.h"
13#include "clang/Basic/LangOptions.h"
14#include "clang/Basic/TargetOptions.h"
15#include "clang/Basic/TargetInfo.h"
16#include "clang/Lex/ModuleLoader.h"
17#include "clang/Lex/HeaderSearch.h"
18#include "clang/Lex/Preprocessor.h"
Benjamin Kramer8fe83e12012-02-04 13:45:25 +000019#include "llvm/ADT/SmallString.h"
Argyrios Kyrtzidiscee5ec92011-12-21 16:56:35 +000020#include "llvm/Config/config.h"
Argyrios Kyrtzidisd7711ec2011-12-21 16:56:29 +000021
22#include "gtest/gtest.h"
23
24using namespace llvm;
25using namespace clang;
26
27namespace {
28
29// The test fixture.
30class SourceManagerTest : public ::testing::Test {
31protected:
32 SourceManagerTest()
33 : FileMgr(FileMgrOpts),
34 DiagID(new DiagnosticIDs()),
35 Diags(DiagID, new IgnoringDiagConsumer()),
36 SourceMgr(Diags, FileMgr) {
37 TargetOpts.Triple = "x86_64-apple-darwin11.1.0";
38 Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
39 }
40
41 FileSystemOptions FileMgrOpts;
42 FileManager FileMgr;
43 llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
44 DiagnosticsEngine Diags;
45 SourceManager SourceMgr;
46 LangOptions LangOpts;
47 TargetOptions TargetOpts;
48 llvm::IntrusiveRefCntPtr<TargetInfo> Target;
49};
50
51class VoidModuleLoader : public ModuleLoader {
52 virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
53 Module::NameVisibilityKind Visibility,
54 bool IsInclusionDirective) {
55 return 0;
56 }
57};
58
59TEST_F(SourceManagerTest, isBeforeInTranslationUnit) {
60 const char *source =
61 "#define M(x) [x]\n"
62 "M(foo)";
63 MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
64 FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(buf);
65
66 VoidModuleLoader ModLoader;
Douglas Gregordc58aa72012-01-30 06:01:29 +000067 HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target);
Argyrios Kyrtzidisd7711ec2011-12-21 16:56:29 +000068 Preprocessor PP(Diags, LangOpts,
69 Target.getPtr(),
70 SourceMgr, HeaderInfo, ModLoader,
71 /*IILookup =*/ 0,
72 /*OwnsHeaderSearch =*/false,
73 /*DelayInitialization =*/ false);
74 PP.EnterMainSourceFile();
75
76 std::vector<Token> toks;
77 while (1) {
78 Token tok;
79 PP.Lex(tok);
80 if (tok.is(tok::eof))
81 break;
82 toks.push_back(tok);
83 }
84
85 // Make sure we got the tokens that we expected.
86 ASSERT_EQ(3U, toks.size());
87 ASSERT_EQ(tok::l_square, toks[0].getKind());
88 ASSERT_EQ(tok::identifier, toks[1].getKind());
89 ASSERT_EQ(tok::r_square, toks[2].getKind());
90
91 SourceLocation lsqrLoc = toks[0].getLocation();
92 SourceLocation idLoc = toks[1].getLocation();
93 SourceLocation rsqrLoc = toks[2].getLocation();
94
95 SourceLocation macroExpStartLoc = SourceMgr.translateLineCol(mainFileID, 2, 1);
96 SourceLocation macroExpEndLoc = SourceMgr.translateLineCol(mainFileID, 2, 6);
97 ASSERT_TRUE(macroExpStartLoc.isFileID());
98 ASSERT_TRUE(macroExpEndLoc.isFileID());
99
100 llvm::SmallString<32> str;
101 ASSERT_EQ("M", PP.getSpelling(macroExpStartLoc, str));
102 ASSERT_EQ(")", PP.getSpelling(macroExpEndLoc, str));
103
104 EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(lsqrLoc, idLoc));
105 EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, rsqrLoc));
106 EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(macroExpStartLoc, idLoc));
107 EXPECT_TRUE(SourceMgr.isBeforeInTranslationUnit(idLoc, macroExpEndLoc));
108}
109
Argyrios Kyrtzidiscee5ec92011-12-21 16:56:35 +0000110#if defined(LLVM_ON_UNIX)
111
112TEST_F(SourceManagerTest, getMacroArgExpandedLocation) {
113 const char *header =
114 "#define FM(x,y) x\n";
115
116 const char *main =
117 "#include \"/test-header.h\"\n"
118 "#define VAL 0\n"
119 "FM(VAL,0)\n"
120 "FM(0,VAL)\n"
121 "FM(FM(0,VAL),0)\n"
122 "#define CONCAT(X, Y) X##Y\n"
123 "CONCAT(1,1)\n";
124
125 MemoryBuffer *headerBuf = MemoryBuffer::getMemBuffer(header);
126 MemoryBuffer *mainBuf = MemoryBuffer::getMemBuffer(main);
127 FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(mainBuf);
128
129 const FileEntry *headerFile = FileMgr.getVirtualFile("/test-header.h",
130 headerBuf->getBufferSize(), 0);
131 SourceMgr.overrideFileContents(headerFile, headerBuf);
132
133 VoidModuleLoader ModLoader;
Douglas Gregordc58aa72012-01-30 06:01:29 +0000134 HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts, &*Target);
Argyrios Kyrtzidiscee5ec92011-12-21 16:56:35 +0000135 Preprocessor PP(Diags, LangOpts,
136 Target.getPtr(),
137 SourceMgr, HeaderInfo, ModLoader,
138 /*IILookup =*/ 0,
139 /*OwnsHeaderSearch =*/false,
140 /*DelayInitialization =*/ false);
141 PP.EnterMainSourceFile();
142
143 std::vector<Token> toks;
144 while (1) {
145 Token tok;
146 PP.Lex(tok);
147 if (tok.is(tok::eof))
148 break;
149 toks.push_back(tok);
150 }
151
152 // Make sure we got the tokens that we expected.
153 ASSERT_EQ(4U, toks.size());
154 ASSERT_EQ(tok::numeric_constant, toks[0].getKind());
155 ASSERT_EQ(tok::numeric_constant, toks[1].getKind());
156 ASSERT_EQ(tok::numeric_constant, toks[2].getKind());
157 ASSERT_EQ(tok::numeric_constant, toks[3].getKind());
158
159 SourceLocation defLoc = SourceMgr.translateLineCol(mainFileID, 2, 13);
160 SourceLocation loc1 = SourceMgr.translateLineCol(mainFileID, 3, 8);
161 SourceLocation loc2 = SourceMgr.translateLineCol(mainFileID, 4, 4);
162 SourceLocation loc3 = SourceMgr.translateLineCol(mainFileID, 5, 7);
163 SourceLocation defLoc2 = SourceMgr.translateLineCol(mainFileID, 6, 22);
164 defLoc = SourceMgr.getMacroArgExpandedLocation(defLoc);
165 loc1 = SourceMgr.getMacroArgExpandedLocation(loc1);
166 loc2 = SourceMgr.getMacroArgExpandedLocation(loc2);
167 loc3 = SourceMgr.getMacroArgExpandedLocation(loc3);
168 defLoc2 = SourceMgr.getMacroArgExpandedLocation(defLoc2);
169
170 EXPECT_TRUE(defLoc.isFileID());
171 EXPECT_TRUE(loc1.isFileID());
172 EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc2));
173 EXPECT_TRUE(SourceMgr.isMacroArgExpansion(loc3));
174 EXPECT_EQ(loc2, toks[1].getLocation());
175 EXPECT_EQ(loc3, toks[2].getLocation());
176 EXPECT_TRUE(defLoc2.isFileID());
177}
178
179#endif
180
Argyrios Kyrtzidisd7711ec2011-12-21 16:56:29 +0000181} // anonymous namespace