LexerTest.cpp revision 11b652d41d0d97380ab321a1dba48ecb044f9de8
119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis//===- unittests/Basic/LexerTest.cpp ------ Lexer tests -------------------===//
219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis//
319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis//
519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis//
819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
1019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Basic/SourceManager.h"
1119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Basic/FileManager.h"
1219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h"
1319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h"
1419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Basic/TargetOptions.h"
1519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h"
1619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Lex/ModuleLoader.h"
1719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h"
1819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h"
1919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "llvm/Config/config.h"
2019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
2119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis#include "gtest/gtest.h"
2219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
2319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidisusing namespace llvm;
2419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidisusing namespace clang;
2519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
2619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidisnamespace {
2719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
2819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis// The test fixture.
2919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidisclass LexerTest : public ::testing::Test {
3019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidisprotected:
3119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  LexerTest()
3219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    : FileMgr(FileMgrOpts),
3319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis      DiagID(new DiagnosticIDs()),
3419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis      Diags(DiagID, new IgnoringDiagConsumer()),
3519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis      SourceMgr(Diags, FileMgr) {
3619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    TargetOpts.Triple = "x86_64-apple-darwin11.1.0";
3719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
3819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  }
3919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
4019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  FileSystemOptions FileMgrOpts;
4119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  FileManager FileMgr;
4219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
4319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  DiagnosticsEngine Diags;
4419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  SourceManager SourceMgr;
4519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  LangOptions LangOpts;
4619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  TargetOptions TargetOpts;
4719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  llvm::IntrusiveRefCntPtr<TargetInfo> Target;
4819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis};
4919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
5019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidisclass VoidModuleLoader : public ModuleLoader {
5119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
5219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis                             Module::NameVisibilityKind Visibility,
5319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis                             bool IsInclusionDirective) {
5419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    return 0;
5519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  }
5619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis};
5719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
5819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios KyrtzidisTEST_F(LexerTest, LexAPI) {
5919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  const char *source =
6019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    "#define M(x) [x]\n"
6119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    "M(foo)";
6219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
6319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  FileID mainFileID = SourceMgr.createMainFileIDForMemBuffer(buf);
6419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
6519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  VoidModuleLoader ModLoader;
6619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  HeaderSearch HeaderInfo(FileMgr, Diags, LangOpts);
6719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  Preprocessor PP(Diags, LangOpts,
6819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis                  Target.getPtr(),
6919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis                  SourceMgr, HeaderInfo, ModLoader,
7019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis                  /*IILookup =*/ 0,
7119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis                  /*OwnsHeaderSearch =*/false,
7219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis                  /*DelayInitialization =*/ false);
7319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  PP.EnterMainSourceFile();
7419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
7519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  std::vector<Token> toks;
7619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  while (1) {
7719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    Token tok;
7819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    PP.Lex(tok);
7919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    if (tok.is(tok::eof))
8019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis      break;
8119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis    toks.push_back(tok);
8219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  }
8319d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
8419d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  // Make sure we got the tokens that we expected.
8519d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  ASSERT_EQ(3U, toks.size());
8619d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  ASSERT_EQ(tok::l_square, toks[0].getKind());
8719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  ASSERT_EQ(tok::identifier, toks[1].getKind());
8819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  ASSERT_EQ(tok::r_square, toks[2].getKind());
8919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
9019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  SourceLocation lsqrLoc = toks[0].getLocation();
9119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  SourceLocation idLoc = toks[1].getLocation();
9219d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  SourceLocation rsqrLoc = toks[2].getLocation();
9311b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  std::pair<SourceLocation,SourceLocation>
9411b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis    macroPair = SourceMgr.getExpansionRange(lsqrLoc);
9511b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  SourceRange macroRange = SourceRange(macroPair.first, macroPair.second);
9611b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis
9769bda4c027671df7163619f215209529eb236620Argyrios Kyrtzidis  SourceLocation Loc;
9869bda4c027671df7163619f215209529eb236620Argyrios Kyrtzidis  EXPECT_TRUE(Lexer::isAtStartOfMacroExpansion(lsqrLoc, SourceMgr, LangOpts, &Loc));
9911b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  EXPECT_EQ(Loc, macroRange.getBegin());
10019d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  EXPECT_FALSE(Lexer::isAtStartOfMacroExpansion(idLoc, SourceMgr, LangOpts));
10119d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis  EXPECT_FALSE(Lexer::isAtEndOfMacroExpansion(idLoc, SourceMgr, LangOpts));
10269bda4c027671df7163619f215209529eb236620Argyrios Kyrtzidis  EXPECT_TRUE(Lexer::isAtEndOfMacroExpansion(rsqrLoc, SourceMgr, LangOpts, &Loc));
10311b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  EXPECT_EQ(Loc, macroRange.getEnd());
10411b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis
10511b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  CharSourceRange range = Lexer::makeFileCharRange(SourceRange(lsqrLoc, idLoc),
10611b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis                                                   SourceMgr, LangOpts);
10711b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  EXPECT_TRUE(range.isInvalid());
10811b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  range = Lexer::makeFileCharRange(SourceRange(idLoc, rsqrLoc),
10911b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis                                   SourceMgr, LangOpts);
11011b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  EXPECT_TRUE(range.isInvalid());
11111b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  range = Lexer::makeFileCharRange(SourceRange(lsqrLoc, rsqrLoc),
11211b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis                                   SourceMgr, LangOpts);
11311b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  EXPECT_TRUE(!range.isTokenRange());
11411b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis  EXPECT_EQ(range.getAsRange(),
11511b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis            SourceRange(macroRange.getBegin(),
11611b652d41d0d97380ab321a1dba48ecb044f9de8Argyrios Kyrtzidis                        macroRange.getEnd().getLocWithOffset(1)));
11719d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis}
11819d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis
11919d5aea478b4f542e1ef7c36741e719c660bcc20Argyrios Kyrtzidis} // anonymous namespace
120