137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis//===- unittests/Lex/PPConditionalDirectiveRecordTest.cpp-PP directive tests =//
2c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis//
3c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
4c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis//
5c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
6c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
7c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis//
8c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
9c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
101050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Lex/PPConditionalDirectiveRecord.h"
11c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis#include "clang/Basic/Diagnostic.h"
1216a4abf5d98e62ef5cc1af4685dbffa593042709Douglas Gregor#include "clang/Basic/DiagnosticOptions.h"
131050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Basic/FileManager.h"
14c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis#include "clang/Basic/LangOptions.h"
157cc315ccf80382fab7674735fbfda95990d28f8eChandler Carruth#include "clang/Basic/SourceManager.h"
16c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis#include "clang/Basic/TargetInfo.h"
171050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Basic/TargetOptions.h"
18c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis#include "clang/Lex/HeaderSearch.h"
19b0985c86f7f75e780bfeb366afdbee7676c28948Douglas Gregor#include "clang/Lex/HeaderSearchOptions.h"
201050e8b2252d89a0004a6fd25a58dab88b5ee625Chandler Carruth#include "clang/Lex/ModuleLoader.h"
21c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis#include "clang/Lex/Preprocessor.h"
2236a16498ff911a218f26c7955376bbe99ddb16dfDouglas Gregor#include "clang/Lex/PreprocessorOptions.h"
23c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis#include "gtest/gtest.h"
24c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
25c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidisusing namespace llvm;
26c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidisusing namespace clang;
27c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
28c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidisnamespace {
29c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
30c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis// The test fixture.
3137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidisclass PPConditionalDirectiveRecordTest : public ::testing::Test {
32c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidisprotected:
3337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  PPConditionalDirectiveRecordTest()
34c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis    : FileMgr(FileMgrOpts),
35c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      DiagID(new DiagnosticIDs()),
3616a4abf5d98e62ef5cc1af4685dbffa593042709Douglas Gregor      Diags(DiagID, new DiagnosticOptions, new IgnoringDiagConsumer()),
3707f8cf4ec3ffb6668b35e7b864354faa76167209Douglas Gregor      SourceMgr(Diags, FileMgr),
3807f8cf4ec3ffb6668b35e7b864354faa76167209Douglas Gregor      TargetOpts(new TargetOptions)
3907f8cf4ec3ffb6668b35e7b864354faa76167209Douglas Gregor  {
4007f8cf4ec3ffb6668b35e7b864354faa76167209Douglas Gregor    TargetOpts->Triple = "x86_64-apple-darwin11.1.0";
41ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
42c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  }
43c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
44c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  FileSystemOptions FileMgrOpts;
45c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  FileManager FileMgr;
46c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  IntrusiveRefCntPtr<DiagnosticIDs> DiagID;
47c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  DiagnosticsEngine Diags;
48c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  SourceManager SourceMgr;
49c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  LangOptions LangOpts;
50ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  std::shared_ptr<TargetOptions> TargetOpts;
51c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  IntrusiveRefCntPtr<TargetInfo> Target;
52c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis};
53c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
54c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidisclass VoidModuleLoader : public ModuleLoader {
556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ModuleLoadResult loadModule(SourceLocation ImportLoc,
566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                              ModuleIdPath Path,
576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                              Module::NameVisibilityKind Visibility,
586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                              bool IsInclusionDirective) override {
597dff05bf3019995798def5d1066e4282b8578df6Douglas Gregor    return ModuleLoadResult();
60c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  }
611a4191d0697098c424646654784399b839f87bc4NAKAMURA Takumi
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  void makeModuleVisible(Module *Mod,
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                         Module::NameVisibilityKind Visibility,
646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                         SourceLocation ImportLoc,
656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                         bool Complain) override { }
666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override
68ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    { return nullptr; }
696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    { return 0; };
71c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis};
72c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
7337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios KyrtzidisTEST_F(PPConditionalDirectiveRecordTest, PPRecAPI) {
74c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  const char *source =
75c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "0 1\n"
76c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#if 1\n"
77c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "2\n"
78c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#ifndef BB\n"
79c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "3 4\n"
80c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#else\n"
81c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#endif\n"
82c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "5\n"
83c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#endif\n"
84c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "6\n"
85c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#if 1\n"
86c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "7\n"
87c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#if 1\n"
88c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#endif\n"
89c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "8\n"
90c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "#endif\n"
91c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      "9\n";
92c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
93c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  MemoryBuffer *buf = MemoryBuffer::getMemBuffer(source);
946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  SourceMgr.setMainFileID(SourceMgr.createFileID(buf));
95c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
96c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  VoidModuleLoader ModLoader;
97ee0cd37fe4a9f4e2ee73ae34cf93c410cb299a82Manuel Klimek  HeaderSearch HeaderInfo(new HeaderSearchOptions, SourceMgr, Diags, LangOpts,
98ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                          Target.get());
996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Preprocessor PP(new PreprocessorOptions(), Diags, LangOpts, SourceMgr,
1006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                  HeaderInfo, ModLoader,
101ef8225444452a1486bd721f3285301fe84643b00Stephen Hines                  /*IILookup =*/nullptr,
1026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                  /*OwnsHeaderSearch =*/false);
1036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  PP.Initialize(*Target);
10437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  PPConditionalDirectiveRecord *
10537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis    PPRec = new PPConditionalDirectiveRecord(SourceMgr);
10637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  PP.addPPCallbacks(PPRec);
107c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  PP.EnterMainSourceFile();
108c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
109c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  std::vector<Token> toks;
110c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  while (1) {
111c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis    Token tok;
112c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis    PP.Lex(tok);
113c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis    if (tok.is(tok::eof))
114c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis      break;
115c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis    toks.push_back(tok);
116c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  }
117c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
118c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  // Make sure we got the tokens that we expected.
119c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis  ASSERT_EQ(10U, toks.size());
120c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
12137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective(
122c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[0].getLocation(), toks[1].getLocation())));
12337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective(
124c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[0].getLocation(), toks[2].getLocation())));
12537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective(
126c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[3].getLocation(), toks[4].getLocation())));
12737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective(
128c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[1].getLocation(), toks[5].getLocation())));
12937ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective(
130c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[2].getLocation(), toks[6].getLocation())));
13137ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective(
132c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[2].getLocation(), toks[5].getLocation())));
13337ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective(
134c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[0].getLocation(), toks[6].getLocation())));
13537ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_TRUE(PPRec->rangeIntersectsConditionalDirective(
136c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[2].getLocation(), toks[8].getLocation())));
13737ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_FALSE(PPRec->rangeIntersectsConditionalDirective(
138c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    SourceRange(toks[0].getLocation(), toks[9].getLocation())));
139c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
14037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion(
141c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    toks[0].getLocation(), toks[2].getLocation()));
14237ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_FALSE(PPRec->areInDifferentConditionalDirectiveRegion(
143c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    toks[3].getLocation(), toks[4].getLocation()));
14437ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion(
145c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    toks[1].getLocation(), toks[5].getLocation()));
14637ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion(
147c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    toks[2].getLocation(), toks[0].getLocation()));
14837ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_FALSE(PPRec->areInDifferentConditionalDirectiveRegion(
149c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    toks[4].getLocation(), toks[3].getLocation()));
15037ed12720a35b7bfa1c4de73ad6f1c6c1c88ee17Argyrios Kyrtzidis  EXPECT_TRUE(PPRec->areInDifferentConditionalDirectiveRegion(
151c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis                    toks[5].getLocation(), toks[1].getLocation()));
152c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis}
153c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis
154c6c54521f95760a5eaf29b668d4bf41fe2af49d7Argyrios Kyrtzidis} // anonymous namespace
155