annotate clang/unittests/CrossTU/CrossTranslationUnitTest.cpp @ 207:2e18cbf3894f

LLVM12
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Jun 2021 06:07:14 +0900
parents 1d019706d866
children c4bab56944e8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
150
anatofuz
parents:
diff changeset
1 //===- unittest/Tooling/CrossTranslationUnitTest.cpp - Tooling unit tests -===//
anatofuz
parents:
diff changeset
2 //
anatofuz
parents:
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
anatofuz
parents:
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
anatofuz
parents:
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
anatofuz
parents:
diff changeset
6 //
anatofuz
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
anatofuz
parents:
diff changeset
8
anatofuz
parents:
diff changeset
9 #include "clang/CrossTU/CrossTranslationUnit.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
10 #include "clang/AST/ASTConsumer.h"
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
11 #include "clang/AST/ParentMapContext.h"
150
anatofuz
parents:
diff changeset
12 #include "clang/Frontend/CompilerInstance.h"
anatofuz
parents:
diff changeset
13 #include "clang/Frontend/FrontendAction.h"
anatofuz
parents:
diff changeset
14 #include "clang/Tooling/Tooling.h"
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
15 #include "llvm/ADT/Optional.h"
150
anatofuz
parents:
diff changeset
16 #include "llvm/Support/FileSystem.h"
anatofuz
parents:
diff changeset
17 #include "llvm/Support/Path.h"
anatofuz
parents:
diff changeset
18 #include "llvm/Support/ToolOutputFile.h"
anatofuz
parents:
diff changeset
19 #include "gtest/gtest.h"
anatofuz
parents:
diff changeset
20 #include <cassert>
anatofuz
parents:
diff changeset
21
anatofuz
parents:
diff changeset
22 namespace clang {
anatofuz
parents:
diff changeset
23 namespace cross_tu {
anatofuz
parents:
diff changeset
24
anatofuz
parents:
diff changeset
25 namespace {
anatofuz
parents:
diff changeset
26
anatofuz
parents:
diff changeset
27 class CTUASTConsumer : public clang::ASTConsumer {
anatofuz
parents:
diff changeset
28 public:
anatofuz
parents:
diff changeset
29 explicit CTUASTConsumer(clang::CompilerInstance &CI, bool *Success)
anatofuz
parents:
diff changeset
30 : CTU(CI), Success(Success) {}
anatofuz
parents:
diff changeset
31
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
32 void HandleTranslationUnit(ASTContext &Ctx) override {
150
anatofuz
parents:
diff changeset
33 auto FindFInTU = [](const TranslationUnitDecl *TU) {
anatofuz
parents:
diff changeset
34 const FunctionDecl *FD = nullptr;
anatofuz
parents:
diff changeset
35 for (const Decl *D : TU->decls()) {
anatofuz
parents:
diff changeset
36 FD = dyn_cast<FunctionDecl>(D);
anatofuz
parents:
diff changeset
37 if (FD && FD->getName() == "f")
anatofuz
parents:
diff changeset
38 break;
anatofuz
parents:
diff changeset
39 }
anatofuz
parents:
diff changeset
40 return FD;
anatofuz
parents:
diff changeset
41 };
anatofuz
parents:
diff changeset
42
anatofuz
parents:
diff changeset
43 const TranslationUnitDecl *TU = Ctx.getTranslationUnitDecl();
anatofuz
parents:
diff changeset
44 const FunctionDecl *FD = FindFInTU(TU);
anatofuz
parents:
diff changeset
45 assert(FD && FD->getName() == "f");
anatofuz
parents:
diff changeset
46 bool OrigFDHasBody = FD->hasBody();
anatofuz
parents:
diff changeset
47
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
48 const DynTypedNodeList ParentsBeforeImport =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
49 Ctx.getParentMapContext().getParents<Decl>(*FD);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
50 ASSERT_FALSE(ParentsBeforeImport.empty());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
51
150
anatofuz
parents:
diff changeset
52 // Prepare the index file and the AST file.
anatofuz
parents:
diff changeset
53 int ASTFD;
anatofuz
parents:
diff changeset
54 llvm::SmallString<256> ASTFileName;
anatofuz
parents:
diff changeset
55 ASSERT_FALSE(
anatofuz
parents:
diff changeset
56 llvm::sys::fs::createTemporaryFile("f_ast", "ast", ASTFD, ASTFileName));
anatofuz
parents:
diff changeset
57 llvm::ToolOutputFile ASTFile(ASTFileName, ASTFD);
anatofuz
parents:
diff changeset
58
anatofuz
parents:
diff changeset
59 int IndexFD;
anatofuz
parents:
diff changeset
60 llvm::SmallString<256> IndexFileName;
anatofuz
parents:
diff changeset
61 ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("index", "txt", IndexFD,
anatofuz
parents:
diff changeset
62 IndexFileName));
anatofuz
parents:
diff changeset
63 llvm::ToolOutputFile IndexFile(IndexFileName, IndexFD);
anatofuz
parents:
diff changeset
64 IndexFile.os() << "c:@F@f#I# " << ASTFileName << "\n";
anatofuz
parents:
diff changeset
65 IndexFile.os().flush();
anatofuz
parents:
diff changeset
66 EXPECT_TRUE(llvm::sys::fs::exists(IndexFileName));
anatofuz
parents:
diff changeset
67
anatofuz
parents:
diff changeset
68 StringRef SourceText = "int f(int) { return 0; }\n";
anatofuz
parents:
diff changeset
69 // This file must exist since the saved ASTFile will reference it.
anatofuz
parents:
diff changeset
70 int SourceFD;
anatofuz
parents:
diff changeset
71 llvm::SmallString<256> SourceFileName;
anatofuz
parents:
diff changeset
72 ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("input", "cpp", SourceFD,
anatofuz
parents:
diff changeset
73 SourceFileName));
anatofuz
parents:
diff changeset
74 llvm::ToolOutputFile SourceFile(SourceFileName, SourceFD);
anatofuz
parents:
diff changeset
75 SourceFile.os() << SourceText;
anatofuz
parents:
diff changeset
76 SourceFile.os().flush();
anatofuz
parents:
diff changeset
77 EXPECT_TRUE(llvm::sys::fs::exists(SourceFileName));
anatofuz
parents:
diff changeset
78
anatofuz
parents:
diff changeset
79 std::unique_ptr<ASTUnit> ASTWithDefinition =
anatofuz
parents:
diff changeset
80 tooling::buildASTFromCode(SourceText, SourceFileName);
anatofuz
parents:
diff changeset
81 ASTWithDefinition->Save(ASTFileName.str());
anatofuz
parents:
diff changeset
82 EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName));
anatofuz
parents:
diff changeset
83
anatofuz
parents:
diff changeset
84 // Load the definition from the AST file.
anatofuz
parents:
diff changeset
85 llvm::Expected<const FunctionDecl *> NewFDorError = handleExpected(
anatofuz
parents:
diff changeset
86 CTU.getCrossTUDefinition(FD, "", IndexFileName, false),
anatofuz
parents:
diff changeset
87 []() { return nullptr; }, [](IndexError &) {});
anatofuz
parents:
diff changeset
88
anatofuz
parents:
diff changeset
89 if (NewFDorError) {
anatofuz
parents:
diff changeset
90 const FunctionDecl *NewFD = *NewFDorError;
anatofuz
parents:
diff changeset
91 *Success = NewFD && NewFD->hasBody() && !OrigFDHasBody;
anatofuz
parents:
diff changeset
92
anatofuz
parents:
diff changeset
93 if (NewFD) {
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
94 // Check parent map.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
95 const DynTypedNodeList ParentsAfterImport =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
96 Ctx.getParentMapContext().getParents<Decl>(*FD);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
97 const DynTypedNodeList ParentsOfImported =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
98 Ctx.getParentMapContext().getParents<Decl>(*NewFD);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
99 EXPECT_TRUE(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
100 checkParentListsEq(ParentsBeforeImport, ParentsAfterImport));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
101 EXPECT_FALSE(ParentsOfImported.empty());
150
anatofuz
parents:
diff changeset
102 }
anatofuz
parents:
diff changeset
103 }
anatofuz
parents:
diff changeset
104 }
anatofuz
parents:
diff changeset
105
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
106 static bool checkParentListsEq(const DynTypedNodeList &L1,
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
107 const DynTypedNodeList &L2) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
108 if (L1.size() != L2.size())
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
109 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
110 for (unsigned int I = 0; I < L1.size(); ++I)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
111 if (L1[I] != L2[I])
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
112 return false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
113 return true;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
114 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
115
150
anatofuz
parents:
diff changeset
116 private:
anatofuz
parents:
diff changeset
117 CrossTranslationUnitContext CTU;
anatofuz
parents:
diff changeset
118 bool *Success;
anatofuz
parents:
diff changeset
119 };
anatofuz
parents:
diff changeset
120
anatofuz
parents:
diff changeset
121 class CTUAction : public clang::ASTFrontendAction {
anatofuz
parents:
diff changeset
122 public:
anatofuz
parents:
diff changeset
123 CTUAction(bool *Success, unsigned OverrideLimit)
anatofuz
parents:
diff changeset
124 : Success(Success), OverrideLimit(OverrideLimit) {}
anatofuz
parents:
diff changeset
125
anatofuz
parents:
diff changeset
126 protected:
anatofuz
parents:
diff changeset
127 std::unique_ptr<clang::ASTConsumer>
anatofuz
parents:
diff changeset
128 CreateASTConsumer(clang::CompilerInstance &CI, StringRef) override {
anatofuz
parents:
diff changeset
129 CI.getAnalyzerOpts()->CTUImportThreshold = OverrideLimit;
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
130 CI.getAnalyzerOpts()->CTUImportCppThreshold = OverrideLimit;
150
anatofuz
parents:
diff changeset
131 return std::make_unique<CTUASTConsumer>(CI, Success);
anatofuz
parents:
diff changeset
132 }
anatofuz
parents:
diff changeset
133
anatofuz
parents:
diff changeset
134 private:
anatofuz
parents:
diff changeset
135 bool *Success;
anatofuz
parents:
diff changeset
136 const unsigned OverrideLimit;
anatofuz
parents:
diff changeset
137 };
anatofuz
parents:
diff changeset
138
anatofuz
parents:
diff changeset
139 } // end namespace
anatofuz
parents:
diff changeset
140
anatofuz
parents:
diff changeset
141 TEST(CrossTranslationUnit, CanLoadFunctionDefinition) {
anatofuz
parents:
diff changeset
142 bool Success = false;
anatofuz
parents:
diff changeset
143 EXPECT_TRUE(tooling::runToolOnCode(std::make_unique<CTUAction>(&Success, 1u),
anatofuz
parents:
diff changeset
144 "int f(int);"));
anatofuz
parents:
diff changeset
145 EXPECT_TRUE(Success);
anatofuz
parents:
diff changeset
146 }
anatofuz
parents:
diff changeset
147
anatofuz
parents:
diff changeset
148 TEST(CrossTranslationUnit, RespectsLoadThreshold) {
anatofuz
parents:
diff changeset
149 bool Success = false;
anatofuz
parents:
diff changeset
150 EXPECT_TRUE(tooling::runToolOnCode(std::make_unique<CTUAction>(&Success, 0u),
anatofuz
parents:
diff changeset
151 "int f(int);"));
anatofuz
parents:
diff changeset
152 EXPECT_FALSE(Success);
anatofuz
parents:
diff changeset
153 }
anatofuz
parents:
diff changeset
154
anatofuz
parents:
diff changeset
155 TEST(CrossTranslationUnit, IndexFormatCanBeParsed) {
anatofuz
parents:
diff changeset
156 llvm::StringMap<std::string> Index;
anatofuz
parents:
diff changeset
157 Index["a"] = "/b/f1";
anatofuz
parents:
diff changeset
158 Index["c"] = "/d/f2";
anatofuz
parents:
diff changeset
159 Index["e"] = "/f/f3";
anatofuz
parents:
diff changeset
160 std::string IndexText = createCrossTUIndexString(Index);
anatofuz
parents:
diff changeset
161
anatofuz
parents:
diff changeset
162 int IndexFD;
anatofuz
parents:
diff changeset
163 llvm::SmallString<256> IndexFileName;
anatofuz
parents:
diff changeset
164 ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("index", "txt", IndexFD,
anatofuz
parents:
diff changeset
165 IndexFileName));
anatofuz
parents:
diff changeset
166 llvm::ToolOutputFile IndexFile(IndexFileName, IndexFD);
anatofuz
parents:
diff changeset
167 IndexFile.os() << IndexText;
anatofuz
parents:
diff changeset
168 IndexFile.os().flush();
anatofuz
parents:
diff changeset
169 EXPECT_TRUE(llvm::sys::fs::exists(IndexFileName));
anatofuz
parents:
diff changeset
170 llvm::Expected<llvm::StringMap<std::string>> IndexOrErr =
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
171 parseCrossTUIndex(IndexFileName);
150
anatofuz
parents:
diff changeset
172 EXPECT_TRUE((bool)IndexOrErr);
anatofuz
parents:
diff changeset
173 llvm::StringMap<std::string> ParsedIndex = IndexOrErr.get();
anatofuz
parents:
diff changeset
174 for (const auto &E : Index) {
anatofuz
parents:
diff changeset
175 EXPECT_TRUE(ParsedIndex.count(E.getKey()));
anatofuz
parents:
diff changeset
176 EXPECT_EQ(ParsedIndex[E.getKey()], E.getValue());
anatofuz
parents:
diff changeset
177 }
anatofuz
parents:
diff changeset
178 for (const auto &E : ParsedIndex)
anatofuz
parents:
diff changeset
179 EXPECT_TRUE(Index.count(E.getKey()));
anatofuz
parents:
diff changeset
180 }
anatofuz
parents:
diff changeset
181
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
182 TEST(CrossTranslationUnit, EmptyInvocationListIsNotValid) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
183 auto Input = "";
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
184
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
185 llvm::Expected<InvocationListTy> Result = parseInvocationList(Input);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
186 EXPECT_FALSE(static_cast<bool>(Result));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
187 bool IsWrongFromatError = false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
188 llvm::handleAllErrors(Result.takeError(), [&](IndexError &Err) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
189 IsWrongFromatError =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
190 Err.getCode() == index_error_code::invocation_list_wrong_format;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
191 });
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
192 EXPECT_TRUE(IsWrongFromatError);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
193 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
194
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
195 TEST(CrossTranslationUnit, AmbiguousInvocationListIsDetected) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
196 // The same source file occurs twice (for two different architecture) in
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
197 // this test case. The disambiguation is the responsibility of the user.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
198 auto Input = R"(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
199 /tmp/main.cpp:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
200 - clang++
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
201 - -c
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
202 - -m32
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
203 - -o
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
204 - main32.o
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
205 - /tmp/main.cpp
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
206 /tmp/main.cpp:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
207 - clang++
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
208 - -c
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
209 - -m64
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
210 - -o
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
211 - main64.o
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
212 - /tmp/main.cpp
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
213 )";
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
214
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
215 llvm::Expected<InvocationListTy> Result = parseInvocationList(Input);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
216 EXPECT_FALSE(static_cast<bool>(Result));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
217 bool IsAmbiguousError = false;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
218 llvm::handleAllErrors(Result.takeError(), [&](IndexError &Err) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
219 IsAmbiguousError =
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
220 Err.getCode() == index_error_code::invocation_list_ambiguous;
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
221 });
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
222 EXPECT_TRUE(IsAmbiguousError);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
223 }
150
anatofuz
parents:
diff changeset
224
207
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
225 TEST(CrossTranslationUnit, SingleInvocationCanBeParsed) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
226 auto Input = R"(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
227 /tmp/main.cpp:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
228 - clang++
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
229 - /tmp/main.cpp
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
230 )";
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
231 llvm::Expected<InvocationListTy> Result = parseInvocationList(Input);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
232 EXPECT_TRUE(static_cast<bool>(Result));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
233
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
234 EXPECT_EQ(Result->size(), 1u);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
235
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
236 auto It = Result->find("/tmp/main.cpp");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
237 EXPECT_TRUE(It != Result->end());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
238 EXPECT_EQ(It->getValue()[0], "clang++");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
239 EXPECT_EQ(It->getValue()[1], "/tmp/main.cpp");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
240 }
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
241
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
242 TEST(CrossTranslationUnit, MultipleInvocationsCanBeParsed) {
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
243 auto Input = R"(
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
244 /tmp/main.cpp:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
245 - clang++
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
246 - /tmp/other.o
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
247 - /tmp/main.cpp
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
248 /tmp/other.cpp:
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
249 - g++
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
250 - -c
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
251 - -o
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
252 - /tmp/other.o
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
253 - /tmp/other.cpp
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
254 )";
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
255 llvm::Expected<InvocationListTy> Result = parseInvocationList(Input);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
256 EXPECT_TRUE(static_cast<bool>(Result));
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
257
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
258 EXPECT_EQ(Result->size(), 2u);
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
259
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
260 auto It = Result->find("/tmp/main.cpp");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
261 EXPECT_TRUE(It != Result->end());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
262 EXPECT_EQ(It->getKey(), "/tmp/main.cpp");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
263 EXPECT_EQ(It->getValue()[0], "clang++");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
264 EXPECT_EQ(It->getValue()[1], "/tmp/other.o");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
265 EXPECT_EQ(It->getValue()[2], "/tmp/main.cpp");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
266
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
267 It = Result->find("/tmp/other.cpp");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
268 EXPECT_TRUE(It != Result->end());
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
269 EXPECT_EQ(It->getValue()[0], "g++");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
270 EXPECT_EQ(It->getValue()[1], "-c");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
271 EXPECT_EQ(It->getValue()[2], "-o");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
272 EXPECT_EQ(It->getValue()[3], "/tmp/other.o");
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 150
diff changeset
273 EXPECT_EQ(It->getValue()[4], "/tmp/other.cpp");
150
anatofuz
parents:
diff changeset
274 }
anatofuz
parents:
diff changeset
275
anatofuz
parents:
diff changeset
276 } // end namespace cross_tu
anatofuz
parents:
diff changeset
277 } // end namespace clang