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