1 | //===- unittest/Introspection/IntrospectionTest.cpp ----------*- C++ -*---===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // Tests for AST location API introspection. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "clang/AST/ASTContext.h" |
14 | #include "clang/ASTMatchers/ASTMatchFinder.h" |
15 | #include "clang/ASTMatchers/ASTMatchers.h" |
16 | #include "clang/Tooling/NodeIntrospection.h" |
17 | #include "clang/Tooling/Tooling.h" |
18 | #include "gmock/gmock-matchers.h" |
19 | #include "gmock/gmock.h" |
20 | #include "gtest/gtest.h" |
21 | |
22 | using namespace clang; |
23 | using namespace clang::ast_matchers; |
24 | using namespace clang::tooling; |
25 | |
26 | using ::testing::Pair; |
27 | using ::testing::UnorderedElementsAre; |
28 | |
29 | template <typename T, typename MapType> |
30 | std::vector<std::pair<std::string, T>> |
31 | FormatExpected(const MapType &Accessors) { |
32 | std::vector<std::pair<std::string, T>> Result; |
33 | llvm::transform(llvm::make_filter_range(Accessors, |
34 | [](const auto &Accessor) { |
35 | return Accessor.first.isValid(); |
36 | }), |
37 | std::back_inserter(Result), [](const auto &Accessor) { |
38 | return std::make_pair( |
39 | LocationCallFormatterCpp::format(Call: *Accessor.second), |
40 | Accessor.first); |
41 | }); |
42 | return Result; |
43 | } |
44 | |
45 | #define STRING_LOCATION_PAIR(INSTANCE, LOC) Pair(#LOC, INSTANCE->LOC) |
46 | |
47 | #define STRING_LOCATION_STDPAIR(INSTANCE, LOC) \ |
48 | std::make_pair(std::string(#LOC), INSTANCE->LOC) |
49 | |
50 | /** |
51 | A test formatter for a hypothetical language which needs |
52 | neither casts nor '->'. |
53 | */ |
54 | class LocationCallFormatterSimple { |
55 | public: |
56 | static void print(const LocationCall &Call, llvm::raw_ostream &OS) { |
57 | if (Call.isCast()) { |
58 | if (const LocationCall *On = Call.on()) |
59 | print(Call: *On, OS); |
60 | return; |
61 | } |
62 | if (const LocationCall *On = Call.on()) { |
63 | print(Call: *On, OS); |
64 | OS << '.'; |
65 | } |
66 | OS << Call.name() << "()" ; |
67 | } |
68 | |
69 | static std::string format(const LocationCall &Call) { |
70 | std::string Result; |
71 | llvm::raw_string_ostream OS(Result); |
72 | print(Call, OS); |
73 | OS.flush(); |
74 | return Result; |
75 | } |
76 | }; |
77 | |
78 | TEST(Introspection, SourceLocations_CallContainer) { |
79 | SourceLocationMap slm; |
80 | SharedLocationCall Prefix; |
81 | slm.insert(x: std::make_pair( |
82 | x: SourceLocation(), |
83 | y: llvm::makeIntrusiveRefCnt<LocationCall>(A&: Prefix, A: "getSourceRange" ))); |
84 | EXPECT_EQ(slm.size(), 1u); |
85 | |
86 | auto callTypeLoc = |
87 | llvm::makeIntrusiveRefCnt<LocationCall>(A&: Prefix, A: "getTypeLoc" ); |
88 | slm.insert(x: std::make_pair( |
89 | x: SourceLocation(), |
90 | y: llvm::makeIntrusiveRefCnt<LocationCall>(A&: callTypeLoc, A: "getSourceRange" ))); |
91 | EXPECT_EQ(slm.size(), 2u); |
92 | } |
93 | |
94 | TEST(Introspection, SourceLocations_CallContainer2) { |
95 | SourceRangeMap slm; |
96 | SharedLocationCall Prefix; |
97 | slm.insert( |
98 | x: std::make_pair(x: SourceRange(), y: llvm::makeIntrusiveRefCnt<LocationCall>( |
99 | A&: Prefix, A: "getCXXOperatorNameRange" ))); |
100 | EXPECT_EQ(slm.size(), 1u); |
101 | |
102 | slm.insert(x: std::make_pair( |
103 | x: SourceRange(), |
104 | y: llvm::makeIntrusiveRefCnt<LocationCall>(A&: Prefix, A: "getSourceRange" ))); |
105 | EXPECT_EQ(slm.size(), 2u); |
106 | } |
107 | |
108 | TEST(Introspection, SourceLocations_CallChainFormatting) { |
109 | SharedLocationCall Prefix; |
110 | auto chainedCall = llvm::makeIntrusiveRefCnt<LocationCall>( |
111 | A: llvm::makeIntrusiveRefCnt<LocationCall>(A&: Prefix, A: "getTypeLoc" ), |
112 | A: "getSourceRange" ); |
113 | EXPECT_EQ(LocationCallFormatterCpp::format(*chainedCall), |
114 | "getTypeLoc().getSourceRange()" ); |
115 | } |
116 | |
117 | TEST(Introspection, SourceLocations_Formatter) { |
118 | SharedLocationCall Prefix; |
119 | auto chainedCall = llvm::makeIntrusiveRefCnt<LocationCall>( |
120 | A: llvm::makeIntrusiveRefCnt<LocationCall>( |
121 | A: llvm::makeIntrusiveRefCnt<LocationCall>( |
122 | A: llvm::makeIntrusiveRefCnt<LocationCall>( |
123 | A&: Prefix, A: "getTypeSourceInfo" , A: LocationCall::ReturnsPointer), |
124 | A: "getTypeLoc" ), |
125 | A: "getAs<clang::TypeSpecTypeLoc>" , A: LocationCall::IsCast), |
126 | A: "getNameLoc" ); |
127 | |
128 | EXPECT_EQ("getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>()." |
129 | "getNameLoc()" , |
130 | LocationCallFormatterCpp::format(*chainedCall)); |
131 | EXPECT_EQ("getTypeSourceInfo().getTypeLoc().getNameLoc()" , |
132 | LocationCallFormatterSimple::format(*chainedCall)); |
133 | } |
134 | |
135 | TEST(Introspection, SourceLocations_Stmt) { |
136 | if (!NodeIntrospection::hasIntrospectionSupport()) |
137 | GTEST_SKIP(); |
138 | auto AST = buildASTFromCode(Code: "void foo() {} void bar() { foo(); }" , FileName: "foo.cpp" , |
139 | PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
140 | auto &Ctx = AST->getASTContext(); |
141 | auto &TU = *Ctx.getTranslationUnitDecl(); |
142 | |
143 | auto BoundNodes = ast_matchers::match( |
144 | Matcher: decl(hasDescendant( |
145 | callExpr(callee(InnerMatcher: functionDecl(hasName(Name: "foo" )))).bind(ID: "fooCall" ))), |
146 | Node: TU, Context&: Ctx); |
147 | |
148 | EXPECT_EQ(BoundNodes.size(), 1u); |
149 | |
150 | auto *FooCall = BoundNodes[0].getNodeAs<CallExpr>(ID: "fooCall" ); |
151 | |
152 | auto Result = NodeIntrospection::GetLocations(FooCall); |
153 | |
154 | auto ExpectedLocations = |
155 | FormatExpected<SourceLocation>(Result.LocationAccessors); |
156 | |
157 | EXPECT_THAT( |
158 | ExpectedLocations, |
159 | UnorderedElementsAre(STRING_LOCATION_PAIR(FooCall, getBeginLoc()), |
160 | STRING_LOCATION_PAIR(FooCall, getEndLoc()), |
161 | STRING_LOCATION_PAIR(FooCall, getExprLoc()), |
162 | STRING_LOCATION_PAIR(FooCall, getRParenLoc()))); |
163 | |
164 | auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); |
165 | |
166 | EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( |
167 | FooCall, getSourceRange()))); |
168 | } |
169 | |
170 | TEST(Introspection, SourceLocations_Decl) { |
171 | if (!NodeIntrospection::hasIntrospectionSupport()) |
172 | GTEST_SKIP(); |
173 | auto AST = |
174 | buildASTFromCode(Code: R"cpp( |
175 | namespace ns1 { |
176 | namespace ns2 { |
177 | template <typename T, typename U> struct Foo {}; |
178 | template <typename T, typename U> struct Bar { |
179 | struct Nested { |
180 | template <typename A, typename B> |
181 | Foo<A, B> method(int i, bool b) const noexcept(true); |
182 | }; |
183 | }; |
184 | } // namespace ns2 |
185 | } // namespace ns1 |
186 | |
187 | template <typename T, typename U> |
188 | template <typename A, typename B> |
189 | ns1::ns2::Foo<A, B> ns1::ns2::Bar<T, U>::Nested::method(int i, bool b) const |
190 | noexcept(true) {} |
191 | )cpp" , |
192 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
193 | auto &Ctx = AST->getASTContext(); |
194 | auto &TU = *Ctx.getTranslationUnitDecl(); |
195 | |
196 | auto BoundNodes = ast_matchers::match( |
197 | Matcher: decl(hasDescendant( |
198 | cxxMethodDecl(hasName(Name: "method" ), isDefinition()).bind(ID: "method" ))), |
199 | Node: TU, Context&: Ctx); |
200 | |
201 | EXPECT_EQ(BoundNodes.size(), 1u); |
202 | |
203 | const auto *MethodDecl = BoundNodes[0].getNodeAs<CXXMethodDecl>(ID: "method" ); |
204 | |
205 | auto Result = NodeIntrospection::GetLocations(MethodDecl); |
206 | |
207 | auto ExpectedLocations = |
208 | FormatExpected<SourceLocation>(Result.LocationAccessors); |
209 | |
210 | llvm::sort(ExpectedLocations); |
211 | |
212 | // clang-format off |
213 | std::vector<std::pair<std::string, SourceLocation>> ActualLocations{ |
214 | STRING_LOCATION_STDPAIR(MethodDecl, getBeginLoc()), |
215 | STRING_LOCATION_STDPAIR(MethodDecl, getBodyRBrace()), |
216 | STRING_LOCATION_STDPAIR(MethodDecl, getEndLoc()), |
217 | STRING_LOCATION_STDPAIR(MethodDecl, getInnerLocStart()), |
218 | STRING_LOCATION_STDPAIR(MethodDecl, getLocation()), |
219 | STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getBeginLoc()), |
220 | STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getEndLoc()), |
221 | STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getLoc()), |
222 | STRING_LOCATION_STDPAIR(MethodDecl, getOuterLocStart()), |
223 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getBeginLoc()), |
224 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getEndLoc()), |
225 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getLocalBeginLoc()), |
226 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getLocalEndLoc()), |
227 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getBeginLoc()), |
228 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getEndLoc()), |
229 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getLocalBeginLoc()), |
230 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getLocalEndLoc()), |
231 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getBeginLoc()), |
232 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getEndLoc()), |
233 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getLocalBeginLoc()), |
234 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getLocalEndLoc()), |
235 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getPrefix().getBeginLoc()), |
236 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getPrefix().getEndLoc()), |
237 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getPrefix().getLocalBeginLoc()), |
238 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getPrefix().getLocalEndLoc()), |
239 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
240 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
241 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
242 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getTypeLoc().getBeginLoc()), |
243 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getTypeLoc().getEndLoc()), |
244 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
245 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getTypeLoc().getBeginLoc()), |
246 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getTypeLoc().getEndLoc()), |
247 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getLParenLoc()), |
248 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getLocalRangeBegin()), |
249 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getLocalRangeEnd()), |
250 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getRParenLoc()), |
251 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
252 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
253 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
254 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
255 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
256 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getBeginLoc()), |
257 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getEndLoc()), |
258 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getLocalBeginLoc()), |
259 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getLocalEndLoc()), |
260 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getBeginLoc()), |
261 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getEndLoc()), |
262 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getLocalBeginLoc()), |
263 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getLocalEndLoc()), |
264 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getBeginLoc()), |
265 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getEndLoc()), |
266 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
267 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
268 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
269 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getBeginLoc()), |
270 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getEndLoc()), |
271 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
272 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getEndLoc()), |
273 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
274 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
275 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
276 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
277 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
278 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getBeginLoc()), |
279 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getEndLoc()), |
280 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getLocalBeginLoc()), |
281 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getLocalEndLoc()), |
282 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getBeginLoc()), |
283 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getEndLoc()), |
284 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getLocalBeginLoc()), |
285 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getLocalEndLoc()), |
286 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), |
287 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()), |
288 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
289 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
290 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
291 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getBeginLoc()), |
292 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getEndLoc()), |
293 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSpecEndLoc()), |
294 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSpecStartLoc()) |
295 | }; |
296 | // clang-format on |
297 | |
298 | EXPECT_EQ(ExpectedLocations, ActualLocations); |
299 | |
300 | auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); |
301 | |
302 | llvm::sort(ExpectedRanges, [](const auto &LHS, const auto &RHS) { |
303 | return LHS.first < RHS.first; |
304 | }); |
305 | |
306 | // clang-format off |
307 | EXPECT_EQ( |
308 | llvm::ArrayRef(ExpectedRanges), |
309 | (ArrayRef<std::pair<std::string, SourceRange>>{ |
310 | STRING_LOCATION_STDPAIR(MethodDecl, getExceptionSpecSourceRange()), |
311 | STRING_LOCATION_STDPAIR(MethodDecl, getNameInfo().getSourceRange()), |
312 | STRING_LOCATION_STDPAIR(MethodDecl, getParametersSourceRange()), |
313 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getLocalSourceRange()), |
314 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getLocalSourceRange()), |
315 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getLocalSourceRange()), |
316 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getPrefix().getLocalSourceRange()), |
317 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getPrefix().getSourceRange()), |
318 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getPrefix().getSourceRange()), |
319 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getSourceRange()), |
320 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getTypeLoc().getLocalSourceRange()), |
321 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getPrefix().getTypeLoc().getSourceRange()), |
322 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getSourceRange()), |
323 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getTypeLoc().getLocalSourceRange()), |
324 | STRING_LOCATION_STDPAIR(MethodDecl, getQualifierLoc().getTypeLoc().getSourceRange()), |
325 | STRING_LOCATION_STDPAIR(MethodDecl, getReturnTypeSourceRange()), |
326 | STRING_LOCATION_STDPAIR(MethodDecl, getSourceRange()), |
327 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getExceptionSpecRange()), |
328 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getParensRange()), |
329 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
330 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
331 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getLocalSourceRange()), |
332 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getLocalSourceRange()), |
333 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getSourceRange()), |
334 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getSourceRange()), |
335 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getLocalSourceRange()), |
336 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getLocalSourceRange()), |
337 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getNextTypeLoc().getSourceRange()), |
338 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getAs<clang::FunctionTypeLoc>().getReturnLoc().getSourceRange()), |
339 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), |
340 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
341 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
342 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getLocalSourceRange()), |
343 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getLocalSourceRange()), |
344 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getPrefix().getSourceRange()), |
345 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::ElaboratedTypeLoc>().getQualifierLoc().getSourceRange()), |
346 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
347 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
348 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getNextTypeLoc().getSourceRange()), |
349 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()), |
350 | STRING_LOCATION_STDPAIR(MethodDecl, getTypeSourceInfo()->getTypeLoc().getSourceRange()) |
351 | })); |
352 | // clang-format on |
353 | } |
354 | |
355 | TEST(Introspection, SourceLocations_NNS) { |
356 | if (!NodeIntrospection::hasIntrospectionSupport()) |
357 | GTEST_SKIP(); |
358 | auto AST = |
359 | buildASTFromCode(Code: R"cpp( |
360 | namespace ns |
361 | { |
362 | struct A { |
363 | void foo(); |
364 | }; |
365 | } |
366 | void ns::A::foo() {} |
367 | )cpp" , |
368 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
369 | auto &Ctx = AST->getASTContext(); |
370 | auto &TU = *Ctx.getTranslationUnitDecl(); |
371 | |
372 | auto BoundNodes = ast_matchers::match( |
373 | Matcher: decl(hasDescendant(nestedNameSpecifierLoc().bind(ID: "nns" ))), Node: TU, Context&: Ctx); |
374 | |
375 | EXPECT_EQ(BoundNodes.size(), 1u); |
376 | |
377 | const auto *NNS = BoundNodes[0].getNodeAs<NestedNameSpecifierLoc>(ID: "nns" ); |
378 | |
379 | auto Result = NodeIntrospection::GetLocations(*NNS); |
380 | |
381 | auto ExpectedLocations = |
382 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
383 | |
384 | llvm::sort(C&: ExpectedLocations); |
385 | |
386 | EXPECT_EQ( |
387 | llvm::ArrayRef(ExpectedLocations), |
388 | (ArrayRef<std::pair<std::string, SourceLocation>>{ |
389 | STRING_LOCATION_STDPAIR(NNS, getBeginLoc()), |
390 | STRING_LOCATION_STDPAIR(NNS, getEndLoc()), |
391 | STRING_LOCATION_STDPAIR(NNS, getLocalBeginLoc()), |
392 | STRING_LOCATION_STDPAIR(NNS, getLocalEndLoc()), |
393 | STRING_LOCATION_STDPAIR(NNS, getPrefix().getBeginLoc()), |
394 | STRING_LOCATION_STDPAIR(NNS, getPrefix().getEndLoc()), |
395 | STRING_LOCATION_STDPAIR(NNS, getPrefix().getLocalBeginLoc()), |
396 | STRING_LOCATION_STDPAIR(NNS, getPrefix().getLocalEndLoc()), |
397 | STRING_LOCATION_STDPAIR( |
398 | NNS, getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
399 | STRING_LOCATION_STDPAIR(NNS, getTypeLoc().getBeginLoc()), |
400 | STRING_LOCATION_STDPAIR(NNS, getTypeLoc().getEndLoc())})); |
401 | |
402 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
403 | |
404 | EXPECT_THAT( |
405 | ExpectedRanges, |
406 | UnorderedElementsAre( |
407 | STRING_LOCATION_PAIR(NNS, getPrefix().getLocalSourceRange()), |
408 | STRING_LOCATION_PAIR(NNS, getPrefix().getSourceRange()), |
409 | STRING_LOCATION_PAIR(NNS, getLocalSourceRange()), |
410 | STRING_LOCATION_PAIR(NNS, getSourceRange()), |
411 | STRING_LOCATION_PAIR(NNS, getTypeLoc().getSourceRange()), |
412 | STRING_LOCATION_PAIR(NNS, getTypeLoc().getLocalSourceRange()))); |
413 | } |
414 | |
415 | TEST(Introspection, SourceLocations_TA_Type) { |
416 | if (!NodeIntrospection::hasIntrospectionSupport()) |
417 | GTEST_SKIP(); |
418 | auto AST = |
419 | buildASTFromCode(Code: R"cpp( |
420 | template<typename T> |
421 | struct A { |
422 | void foo(); |
423 | }; |
424 | |
425 | void foo() |
426 | { |
427 | A<int> a; |
428 | } |
429 | )cpp" , |
430 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
431 | auto &Ctx = AST->getASTContext(); |
432 | auto &TU = *Ctx.getTranslationUnitDecl(); |
433 | |
434 | auto BoundNodes = ast_matchers::match( |
435 | Matcher: decl(hasDescendant(templateArgumentLoc().bind(ID: "ta" ))), Node: TU, Context&: Ctx); |
436 | |
437 | EXPECT_EQ(BoundNodes.size(), 1u); |
438 | |
439 | const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>(ID: "ta" ); |
440 | |
441 | auto Result = NodeIntrospection::GetLocations(*TA); |
442 | |
443 | auto ExpectedLocations = |
444 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
445 | |
446 | // clang-format off |
447 | EXPECT_THAT(ExpectedLocations, |
448 | UnorderedElementsAre( |
449 | STRING_LOCATION_PAIR(TA, getLocation()), |
450 | STRING_LOCATION_PAIR(TA, |
451 | getTypeSourceInfo()->getTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), |
452 | STRING_LOCATION_PAIR(TA, |
453 | getTypeSourceInfo()->getTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), |
454 | STRING_LOCATION_PAIR( |
455 | TA, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
456 | STRING_LOCATION_PAIR( |
457 | TA, getTypeSourceInfo()->getTypeLoc().getEndLoc()) |
458 | )); |
459 | // clang-format on |
460 | |
461 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
462 | |
463 | EXPECT_THAT( |
464 | ExpectedRanges, |
465 | UnorderedElementsAre( |
466 | STRING_LOCATION_PAIR(TA, getSourceRange()), |
467 | STRING_LOCATION_PAIR( |
468 | TA, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
469 | STRING_LOCATION_PAIR( |
470 | TA, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()))); |
471 | } |
472 | |
473 | TEST(Introspection, SourceLocations_TA_Decl) { |
474 | if (!NodeIntrospection::hasIntrospectionSupport()) |
475 | GTEST_SKIP(); |
476 | auto AST = |
477 | buildASTFromCode(Code: R"cpp( |
478 | template<void(*Ty)()> |
479 | void test2() {} |
480 | void doNothing() {} |
481 | void test() { |
482 | test2<doNothing>(); |
483 | } |
484 | )cpp" , |
485 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
486 | auto &Ctx = AST->getASTContext(); |
487 | auto &TU = *Ctx.getTranslationUnitDecl(); |
488 | |
489 | auto BoundNodes = ast_matchers::match( |
490 | Matcher: decl(hasDescendant(templateArgumentLoc().bind(ID: "ta" ))), Node: TU, Context&: Ctx); |
491 | |
492 | EXPECT_EQ(BoundNodes.size(), 1u); |
493 | |
494 | const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>(ID: "ta" ); |
495 | |
496 | auto Result = NodeIntrospection::GetLocations(*TA); |
497 | |
498 | auto ExpectedLocations = |
499 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
500 | |
501 | EXPECT_THAT(ExpectedLocations, |
502 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); |
503 | |
504 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
505 | |
506 | EXPECT_THAT(ExpectedRanges, |
507 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); |
508 | } |
509 | |
510 | TEST(Introspection, SourceLocations_TA_Nullptr) { |
511 | if (!NodeIntrospection::hasIntrospectionSupport()) |
512 | GTEST_SKIP(); |
513 | auto AST = |
514 | buildASTFromCode(Code: R"cpp( |
515 | template<void(*Ty)()> |
516 | void test2() {} |
517 | void doNothing() {} |
518 | void test() { |
519 | test2<nullptr>(); |
520 | } |
521 | )cpp" , |
522 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
523 | auto &Ctx = AST->getASTContext(); |
524 | auto &TU = *Ctx.getTranslationUnitDecl(); |
525 | |
526 | auto BoundNodes = ast_matchers::match( |
527 | Matcher: decl(hasDescendant(templateArgumentLoc().bind(ID: "ta" ))), Node: TU, Context&: Ctx); |
528 | |
529 | EXPECT_EQ(BoundNodes.size(), 1u); |
530 | |
531 | const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>(ID: "ta" ); |
532 | |
533 | auto Result = NodeIntrospection::GetLocations(*TA); |
534 | |
535 | auto ExpectedLocations = |
536 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
537 | |
538 | EXPECT_THAT(ExpectedLocations, |
539 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); |
540 | |
541 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
542 | |
543 | EXPECT_THAT(ExpectedRanges, |
544 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); |
545 | } |
546 | |
547 | TEST(Introspection, SourceLocations_TA_Integral) { |
548 | if (!NodeIntrospection::hasIntrospectionSupport()) |
549 | GTEST_SKIP(); |
550 | auto AST = |
551 | buildASTFromCode(Code: R"cpp( |
552 | template<int> |
553 | void test2() {} |
554 | void test() { |
555 | test2<42>(); |
556 | } |
557 | )cpp" , |
558 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
559 | auto &Ctx = AST->getASTContext(); |
560 | auto &TU = *Ctx.getTranslationUnitDecl(); |
561 | |
562 | auto BoundNodes = ast_matchers::match( |
563 | Matcher: decl(hasDescendant(templateArgumentLoc().bind(ID: "ta" ))), Node: TU, Context&: Ctx); |
564 | |
565 | EXPECT_EQ(BoundNodes.size(), 1u); |
566 | |
567 | const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>(ID: "ta" ); |
568 | |
569 | auto Result = NodeIntrospection::GetLocations(*TA); |
570 | |
571 | auto ExpectedLocations = |
572 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
573 | |
574 | EXPECT_THAT(ExpectedLocations, |
575 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); |
576 | |
577 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
578 | |
579 | EXPECT_THAT(ExpectedRanges, |
580 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); |
581 | } |
582 | |
583 | TEST(Introspection, SourceLocations_TA_Template) { |
584 | if (!NodeIntrospection::hasIntrospectionSupport()) |
585 | GTEST_SKIP(); |
586 | auto AST = |
587 | buildASTFromCode(Code: R"cpp( |
588 | template<typename T> class A; |
589 | template <template <typename> class T> void foo(); |
590 | void bar() |
591 | { |
592 | foo<A>(); |
593 | } |
594 | )cpp" , |
595 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
596 | auto &Ctx = AST->getASTContext(); |
597 | auto &TU = *Ctx.getTranslationUnitDecl(); |
598 | |
599 | auto BoundNodes = ast_matchers::match( |
600 | Matcher: decl(hasDescendant(templateArgumentLoc().bind(ID: "ta" ))), Node: TU, Context&: Ctx); |
601 | |
602 | EXPECT_EQ(BoundNodes.size(), 1u); |
603 | |
604 | const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>(ID: "ta" ); |
605 | |
606 | auto Result = NodeIntrospection::GetLocations(*TA); |
607 | |
608 | auto ExpectedLocations = |
609 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
610 | |
611 | EXPECT_THAT( |
612 | ExpectedLocations, |
613 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()), |
614 | STRING_LOCATION_PAIR(TA, getTemplateNameLoc()))); |
615 | |
616 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
617 | |
618 | EXPECT_THAT(ExpectedRanges, |
619 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); |
620 | } |
621 | |
622 | TEST(Introspection, SourceLocations_TA_TemplateExpansion) { |
623 | if (!NodeIntrospection::hasIntrospectionSupport()) |
624 | GTEST_SKIP(); |
625 | auto AST = buildASTFromCodeWithArgs( |
626 | Code: R"cpp( |
627 | template<template<typename> class ...> class B { }; |
628 | template<template<typename> class ...T> class C { |
629 | B<T...> testTemplateExpansion; |
630 | }; |
631 | )cpp" , |
632 | Args: {"-fno-delayed-template-parsing" }, FileName: "foo.cpp" , ToolName: "clang-tool" , |
633 | PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
634 | auto &Ctx = AST->getASTContext(); |
635 | auto &TU = *Ctx.getTranslationUnitDecl(); |
636 | |
637 | auto BoundNodes = ast_matchers::match( |
638 | Matcher: decl(hasDescendant(templateArgumentLoc().bind(ID: "ta" ))), Node: TU, Context&: Ctx); |
639 | |
640 | EXPECT_EQ(BoundNodes.size(), 1u); |
641 | |
642 | const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>(ID: "ta" ); |
643 | |
644 | auto Result = NodeIntrospection::GetLocations(*TA); |
645 | |
646 | auto ExpectedLocations = |
647 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
648 | |
649 | EXPECT_THAT( |
650 | ExpectedLocations, |
651 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()), |
652 | STRING_LOCATION_PAIR(TA, getTemplateNameLoc()), |
653 | STRING_LOCATION_PAIR(TA, getTemplateEllipsisLoc()))); |
654 | |
655 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
656 | |
657 | EXPECT_THAT(ExpectedRanges, |
658 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); |
659 | } |
660 | |
661 | TEST(Introspection, SourceLocations_TA_Expression) { |
662 | if (!NodeIntrospection::hasIntrospectionSupport()) |
663 | GTEST_SKIP(); |
664 | auto AST = |
665 | buildASTFromCode(Code: R"cpp( |
666 | template<int, int = 0> class testExpr; |
667 | template<int I> class testExpr<I> { }; |
668 | )cpp" , |
669 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
670 | auto &Ctx = AST->getASTContext(); |
671 | auto &TU = *Ctx.getTranslationUnitDecl(); |
672 | |
673 | auto BoundNodes = ast_matchers::match( |
674 | Matcher: decl(hasDescendant(templateArgumentLoc().bind(ID: "ta" ))), Node: TU, Context&: Ctx); |
675 | |
676 | EXPECT_EQ(BoundNodes.size(), 1u); |
677 | |
678 | const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>(ID: "ta" ); |
679 | |
680 | auto Result = NodeIntrospection::GetLocations(*TA); |
681 | |
682 | auto ExpectedLocations = |
683 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
684 | |
685 | EXPECT_THAT(ExpectedLocations, |
686 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); |
687 | |
688 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
689 | |
690 | EXPECT_THAT(ExpectedRanges, |
691 | UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getSourceRange()))); |
692 | } |
693 | |
694 | TEST(Introspection, SourceLocations_TA_Pack) { |
695 | if (!NodeIntrospection::hasIntrospectionSupport()) |
696 | GTEST_SKIP(); |
697 | auto AST = buildASTFromCodeWithArgs( |
698 | Code: R"cpp( |
699 | template<typename... T> class A {}; |
700 | void foo() |
701 | { |
702 | A<int> ai; |
703 | } |
704 | )cpp" , |
705 | Args: {"-fno-delayed-template-parsing" }, FileName: "foo.cpp" , ToolName: "clang-tool" , |
706 | PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
707 | auto &Ctx = AST->getASTContext(); |
708 | auto &TU = *Ctx.getTranslationUnitDecl(); |
709 | |
710 | auto BoundNodes = ast_matchers::match( |
711 | Matcher: decl(hasDescendant(templateArgumentLoc().bind(ID: "ta" ))), Node: TU, Context&: Ctx); |
712 | |
713 | EXPECT_EQ(BoundNodes.size(), 1u); |
714 | |
715 | const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>(ID: "ta" ); |
716 | |
717 | auto Result = NodeIntrospection::GetLocations(*TA); |
718 | |
719 | auto ExpectedLocations = |
720 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
721 | |
722 | // clang-format off |
723 | EXPECT_THAT(ExpectedLocations, |
724 | UnorderedElementsAre( |
725 | STRING_LOCATION_PAIR(TA, getLocation()), |
726 | STRING_LOCATION_PAIR(TA, |
727 | getTypeSourceInfo()->getTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), |
728 | STRING_LOCATION_PAIR(TA, |
729 | getTypeSourceInfo()->getTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), |
730 | STRING_LOCATION_PAIR( |
731 | TA, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
732 | STRING_LOCATION_PAIR( |
733 | TA, getTypeSourceInfo()->getTypeLoc().getEndLoc()) |
734 | )); |
735 | // clang-format on |
736 | |
737 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
738 | |
739 | EXPECT_THAT( |
740 | ExpectedRanges, |
741 | UnorderedElementsAre( |
742 | STRING_LOCATION_PAIR(TA, getSourceRange()), |
743 | STRING_LOCATION_PAIR( |
744 | TA, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
745 | STRING_LOCATION_PAIR( |
746 | TA, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()))); |
747 | } |
748 | |
749 | TEST(Introspection, SourceLocations_CXXCtorInitializer_base) { |
750 | if (!NodeIntrospection::hasIntrospectionSupport()) |
751 | GTEST_SKIP(); |
752 | auto AST = |
753 | buildASTFromCode(Code: R"cpp( |
754 | struct A { |
755 | }; |
756 | |
757 | struct B : A { |
758 | B() : A() {} |
759 | }; |
760 | )cpp" , |
761 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
762 | auto &Ctx = AST->getASTContext(); |
763 | auto &TU = *Ctx.getTranslationUnitDecl(); |
764 | |
765 | auto BoundNodes = ast_matchers::match( |
766 | Matcher: decl(hasDescendant(cxxConstructorDecl( |
767 | hasAnyConstructorInitializer(InnerMatcher: cxxCtorInitializer().bind(ID: "init" ))))), |
768 | Node: TU, Context&: Ctx); |
769 | |
770 | EXPECT_EQ(BoundNodes.size(), 1u); |
771 | |
772 | const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>(ID: "init" ); |
773 | |
774 | auto Result = NodeIntrospection::GetLocations(Object: CtorInit); |
775 | |
776 | auto ExpectedLocations = |
777 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
778 | |
779 | // clang-format off |
780 | EXPECT_THAT( |
781 | ExpectedLocations, |
782 | UnorderedElementsAre( |
783 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getBeginLoc()), |
784 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getEndLoc()), |
785 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
786 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
787 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getBeginLoc()), |
788 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getEndLoc()), |
789 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
790 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
791 | STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), |
792 | STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), |
793 | STRING_LOCATION_PAIR(CtorInit, getSourceLocation()), |
794 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
795 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
796 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), |
797 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()), |
798 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
799 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
800 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
801 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()) |
802 | )); |
803 | // clang-format on |
804 | |
805 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
806 | |
807 | // clang-format off |
808 | EXPECT_THAT( |
809 | ExpectedRanges, |
810 | UnorderedElementsAre( |
811 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getLocalSourceRange()), |
812 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getSourceRange()), |
813 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getSourceRange()), |
814 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
815 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
816 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
817 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()), |
818 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
819 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
820 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
821 | STRING_LOCATION_PAIR(CtorInit, getSourceRange()))); |
822 | // clang-format on |
823 | } |
824 | |
825 | TEST(Introspection, SourceLocations_CXXCtorInitializer_member) { |
826 | if (!NodeIntrospection::hasIntrospectionSupport()) |
827 | GTEST_SKIP(); |
828 | auto AST = |
829 | buildASTFromCode(Code: R"cpp( |
830 | struct A { |
831 | int m_i; |
832 | A() : m_i(42) {} |
833 | }; |
834 | )cpp" , |
835 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
836 | auto &Ctx = AST->getASTContext(); |
837 | auto &TU = *Ctx.getTranslationUnitDecl(); |
838 | |
839 | auto BoundNodes = ast_matchers::match( |
840 | Matcher: decl(hasDescendant(cxxConstructorDecl( |
841 | hasAnyConstructorInitializer(InnerMatcher: cxxCtorInitializer().bind(ID: "init" ))))), |
842 | Node: TU, Context&: Ctx); |
843 | |
844 | EXPECT_EQ(BoundNodes.size(), 1u); |
845 | |
846 | const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>(ID: "init" ); |
847 | |
848 | auto Result = NodeIntrospection::GetLocations(Object: CtorInit); |
849 | |
850 | auto ExpectedLocations = |
851 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
852 | |
853 | EXPECT_THAT(ExpectedLocations, |
854 | UnorderedElementsAre( |
855 | STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), |
856 | STRING_LOCATION_PAIR(CtorInit, getMemberLocation()), |
857 | STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), |
858 | STRING_LOCATION_PAIR(CtorInit, getSourceLocation()))); |
859 | |
860 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
861 | |
862 | EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( |
863 | CtorInit, getSourceRange()))); |
864 | } |
865 | |
866 | TEST(Introspection, SourceLocations_CXXCtorInitializer_ctor) { |
867 | if (!NodeIntrospection::hasIntrospectionSupport()) |
868 | GTEST_SKIP(); |
869 | auto AST = |
870 | buildASTFromCode(Code: R"cpp( |
871 | struct C { |
872 | C() : C(42) {} |
873 | C(int) {} |
874 | }; |
875 | )cpp" , |
876 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
877 | auto &Ctx = AST->getASTContext(); |
878 | auto &TU = *Ctx.getTranslationUnitDecl(); |
879 | |
880 | auto BoundNodes = ast_matchers::match( |
881 | Matcher: decl(hasDescendant(cxxConstructorDecl( |
882 | hasAnyConstructorInitializer(InnerMatcher: cxxCtorInitializer().bind(ID: "init" ))))), |
883 | Node: TU, Context&: Ctx); |
884 | |
885 | EXPECT_EQ(BoundNodes.size(), 1u); |
886 | |
887 | const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>(ID: "init" ); |
888 | |
889 | auto Result = NodeIntrospection::GetLocations(Object: CtorInit); |
890 | |
891 | auto ExpectedLocations = |
892 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
893 | |
894 | // clang-format off |
895 | EXPECT_THAT( |
896 | ExpectedLocations, |
897 | UnorderedElementsAre( |
898 | STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), |
899 | STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), |
900 | STRING_LOCATION_PAIR(CtorInit, getSourceLocation()), |
901 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
902 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()), |
903 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
904 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
905 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), |
906 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()), |
907 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
908 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()) |
909 | )); |
910 | // clang-format on |
911 | |
912 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
913 | |
914 | // clang-format off |
915 | EXPECT_THAT( |
916 | ExpectedRanges, |
917 | UnorderedElementsAre( |
918 | STRING_LOCATION_PAIR(CtorInit, getSourceRange()), |
919 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
920 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
921 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
922 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
923 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()) |
924 | )); |
925 | // clang-format on |
926 | } |
927 | |
928 | TEST(Introspection, SourceLocations_CXXCtorInitializer_pack) { |
929 | if (!NodeIntrospection::hasIntrospectionSupport()) |
930 | GTEST_SKIP(); |
931 | auto AST = buildASTFromCodeWithArgs( |
932 | Code: R"cpp( |
933 | template<typename... T> |
934 | struct Templ { |
935 | }; |
936 | |
937 | template<typename... T> |
938 | struct D : Templ<T...> { |
939 | D(T... t) : Templ<T>(t)... {} |
940 | }; |
941 | )cpp" , |
942 | Args: {"-fno-delayed-template-parsing" }, FileName: "foo.cpp" , ToolName: "clang-tool" , |
943 | PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
944 | auto &Ctx = AST->getASTContext(); |
945 | auto &TU = *Ctx.getTranslationUnitDecl(); |
946 | |
947 | auto BoundNodes = ast_matchers::match( |
948 | Matcher: decl(hasDescendant(cxxConstructorDecl( |
949 | hasAnyConstructorInitializer(InnerMatcher: cxxCtorInitializer().bind(ID: "init" ))))), |
950 | Node: TU, Context&: Ctx); |
951 | |
952 | EXPECT_EQ(BoundNodes.size(), 1u); |
953 | |
954 | const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>(ID: "init" ); |
955 | |
956 | auto Result = NodeIntrospection::GetLocations(Object: CtorInit); |
957 | |
958 | auto ExpectedLocations = |
959 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
960 | |
961 | llvm::sort(C&: ExpectedLocations); |
962 | |
963 | // clang-format off |
964 | EXPECT_EQ( |
965 | llvm::ArrayRef(ExpectedLocations), |
966 | (ArrayRef<std::pair<std::string, SourceLocation>>{ |
967 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
968 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
969 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
970 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
971 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
972 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getBeginLoc()), |
973 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getEndLoc()), |
974 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
975 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
976 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
977 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getBeginLoc()), |
978 | STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getEndLoc()), |
979 | STRING_LOCATION_STDPAIR(CtorInit, getEllipsisLoc()), |
980 | STRING_LOCATION_STDPAIR(CtorInit, getLParenLoc()), |
981 | STRING_LOCATION_STDPAIR(CtorInit, getMemberLocation()), |
982 | STRING_LOCATION_STDPAIR(CtorInit, getRParenLoc()), |
983 | STRING_LOCATION_STDPAIR(CtorInit, getSourceLocation()), |
984 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
985 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
986 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
987 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
988 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
989 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
990 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()), |
991 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
992 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
993 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
994 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), |
995 | STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()) |
996 | })); |
997 | // clang-format on |
998 | |
999 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1000 | |
1001 | // clang-format off |
1002 | EXPECT_THAT( |
1003 | ExpectedRanges, |
1004 | UnorderedElementsAre( |
1005 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
1006 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
1007 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getLocalSourceRange()), |
1008 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
1009 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getSourceRange()), |
1010 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
1011 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
1012 | STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getNextTypeLoc().getSourceRange()), |
1013 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()), |
1014 | STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
1015 | STRING_LOCATION_PAIR(CtorInit, getSourceRange()) |
1016 | )); |
1017 | // clang-format on |
1018 | } |
1019 | |
1020 | TEST(Introspection, SourceLocations_CXXBaseSpecifier_plain) { |
1021 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1022 | GTEST_SKIP(); |
1023 | auto AST = |
1024 | buildASTFromCode(Code: R"cpp( |
1025 | class A {}; |
1026 | class B : A {}; |
1027 | )cpp" , |
1028 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1029 | auto &Ctx = AST->getASTContext(); |
1030 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1031 | |
1032 | auto BoundNodes = ast_matchers::match( |
1033 | Matcher: decl(hasDescendant(cxxRecordDecl(hasDirectBase( |
1034 | BaseSpecMatcher: cxxBaseSpecifier(hasType(InnerMatcher: asString(Name: "A" ))).bind(ID: "base" ))))), |
1035 | Node: TU, Context&: Ctx); |
1036 | |
1037 | EXPECT_EQ(BoundNodes.size(), 1u); |
1038 | |
1039 | const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>(ID: "base" ); |
1040 | |
1041 | auto Result = NodeIntrospection::GetLocations(Base); |
1042 | |
1043 | auto ExpectedLocations = |
1044 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1045 | |
1046 | // clang-format off |
1047 | EXPECT_THAT(ExpectedLocations, |
1048 | UnorderedElementsAre( |
1049 | STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), |
1050 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
1051 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), |
1052 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
1053 | STRING_LOCATION_PAIR(Base, getBeginLoc()), |
1054 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
1055 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()), |
1056 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), |
1057 | STRING_LOCATION_PAIR(Base, getEndLoc()), |
1058 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
1059 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()) |
1060 | )); |
1061 | // clang-format on |
1062 | |
1063 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1064 | |
1065 | // clang-format off |
1066 | EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( |
1067 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
1068 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
1069 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
1070 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()), |
1071 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
1072 | STRING_LOCATION_PAIR(Base, getSourceRange()) |
1073 | )); |
1074 | // clang-format on |
1075 | } |
1076 | |
1077 | TEST(Introspection, SourceLocations_CXXBaseSpecifier_accessspec) { |
1078 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1079 | GTEST_SKIP(); |
1080 | auto AST = |
1081 | buildASTFromCode(Code: R"cpp( |
1082 | class A {}; |
1083 | class B : public A {}; |
1084 | )cpp" , |
1085 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1086 | auto &Ctx = AST->getASTContext(); |
1087 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1088 | |
1089 | auto BoundNodes = ast_matchers::match( |
1090 | Matcher: decl(hasDescendant(cxxRecordDecl(hasDirectBase( |
1091 | BaseSpecMatcher: cxxBaseSpecifier(hasType(InnerMatcher: asString(Name: "A" ))).bind(ID: "base" ))))), |
1092 | Node: TU, Context&: Ctx); |
1093 | |
1094 | EXPECT_EQ(BoundNodes.size(), 1u); |
1095 | |
1096 | const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>(ID: "base" ); |
1097 | |
1098 | auto Result = NodeIntrospection::GetLocations(Base); |
1099 | |
1100 | auto ExpectedLocations = |
1101 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1102 | |
1103 | // clang-format off |
1104 | EXPECT_THAT(ExpectedLocations, |
1105 | UnorderedElementsAre( |
1106 | STRING_LOCATION_PAIR(Base, getBeginLoc()), |
1107 | STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), |
1108 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
1109 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), |
1110 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
1111 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
1112 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()), |
1113 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), |
1114 | STRING_LOCATION_PAIR(Base, getEndLoc()), |
1115 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
1116 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()) |
1117 | )); |
1118 | // clang-format on |
1119 | |
1120 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1121 | |
1122 | // clang-format off |
1123 | EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( |
1124 | STRING_LOCATION_PAIR(Base, getSourceRange()), |
1125 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
1126 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
1127 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
1128 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()), |
1129 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()) |
1130 | )); |
1131 | // clang-format on |
1132 | } |
1133 | |
1134 | TEST(Introspection, SourceLocations_CXXBaseSpecifier_virtual) { |
1135 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1136 | GTEST_SKIP(); |
1137 | auto AST = |
1138 | buildASTFromCode(Code: R"cpp( |
1139 | class A {}; |
1140 | class B {}; |
1141 | class C : virtual B, A {}; |
1142 | )cpp" , |
1143 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1144 | auto &Ctx = AST->getASTContext(); |
1145 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1146 | |
1147 | auto BoundNodes = ast_matchers::match( |
1148 | Matcher: decl(hasDescendant(cxxRecordDecl(hasDirectBase( |
1149 | BaseSpecMatcher: cxxBaseSpecifier(hasType(InnerMatcher: asString(Name: "A" ))).bind(ID: "base" ))))), |
1150 | Node: TU, Context&: Ctx); |
1151 | |
1152 | EXPECT_EQ(BoundNodes.size(), 1u); |
1153 | |
1154 | const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>(ID: "base" ); |
1155 | |
1156 | auto Result = NodeIntrospection::GetLocations(Base); |
1157 | |
1158 | auto ExpectedLocations = |
1159 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1160 | |
1161 | // clang-format off |
1162 | EXPECT_THAT(ExpectedLocations, |
1163 | UnorderedElementsAre( |
1164 | STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), |
1165 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
1166 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), |
1167 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
1168 | STRING_LOCATION_PAIR(Base, getBeginLoc()), |
1169 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
1170 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()), |
1171 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), |
1172 | STRING_LOCATION_PAIR(Base, getEndLoc()), |
1173 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
1174 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()) |
1175 | )); |
1176 | // clang-format on |
1177 | |
1178 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1179 | |
1180 | // clang-format off |
1181 | EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( |
1182 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
1183 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
1184 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
1185 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()), |
1186 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
1187 | STRING_LOCATION_PAIR(Base, getSourceRange()) |
1188 | )); |
1189 | // clang-format on |
1190 | } |
1191 | |
1192 | TEST(Introspection, SourceLocations_CXXBaseSpecifier_template_base) { |
1193 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1194 | GTEST_SKIP(); |
1195 | auto AST = |
1196 | buildASTFromCode(Code: R"cpp( |
1197 | template<typename T, typename U> |
1198 | class A {}; |
1199 | class B : A<int, bool> {}; |
1200 | )cpp" , |
1201 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1202 | auto &Ctx = AST->getASTContext(); |
1203 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1204 | |
1205 | auto BoundNodes = |
1206 | ast_matchers::match(Matcher: decl(hasDescendant(cxxRecordDecl( |
1207 | hasDirectBase(BaseSpecMatcher: cxxBaseSpecifier().bind(ID: "base" ))))), |
1208 | Node: TU, Context&: Ctx); |
1209 | |
1210 | EXPECT_EQ(BoundNodes.size(), 1u); |
1211 | |
1212 | const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>(ID: "base" ); |
1213 | |
1214 | auto Result = NodeIntrospection::GetLocations(Base); |
1215 | |
1216 | auto ExpectedLocations = |
1217 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1218 | |
1219 | // clang-format off |
1220 | EXPECT_THAT(ExpectedLocations, |
1221 | UnorderedElementsAre( |
1222 | STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), |
1223 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getBeginLoc()), |
1224 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getBeginLoc()), |
1225 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), |
1226 | STRING_LOCATION_PAIR(Base, getBeginLoc()), |
1227 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
1228 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), |
1229 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
1230 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), |
1231 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getEndLoc()), |
1232 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getEndLoc()), |
1233 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), |
1234 | STRING_LOCATION_PAIR(Base, getEndLoc()), |
1235 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), |
1236 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()) |
1237 | )); |
1238 | // clang-format on |
1239 | |
1240 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1241 | |
1242 | // clang-format off |
1243 | EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( |
1244 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getLocalSourceRange()), |
1245 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getLocalSourceRange()), |
1246 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::ElaboratedTypeLoc>().getNamedTypeLoc().getSourceRange()), |
1247 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getNextTypeLoc().getSourceRange()), |
1248 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
1249 | STRING_LOCATION_PAIR(Base, getSourceRange()) |
1250 | )); |
1251 | // clang-format on |
1252 | } |
1253 | |
1254 | TEST(Introspection, SourceLocations_CXXBaseSpecifier_pack) { |
1255 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1256 | GTEST_SKIP(); |
1257 | auto AST = buildASTFromCodeWithArgs( |
1258 | Code: R"cpp( |
1259 | template<typename... T> |
1260 | struct Templ : T... { |
1261 | }; |
1262 | )cpp" , |
1263 | Args: {"-fno-delayed-template-parsing" }, FileName: "foo.cpp" , ToolName: "clang-tool" , |
1264 | PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1265 | auto &Ctx = AST->getASTContext(); |
1266 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1267 | |
1268 | auto BoundNodes = |
1269 | ast_matchers::match(Matcher: decl(hasDescendant(cxxRecordDecl( |
1270 | hasDirectBase(BaseSpecMatcher: cxxBaseSpecifier().bind(ID: "base" ))))), |
1271 | Node: TU, Context&: Ctx); |
1272 | |
1273 | EXPECT_EQ(BoundNodes.size(), 1u); |
1274 | |
1275 | const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>(ID: "base" ); |
1276 | |
1277 | auto Result = NodeIntrospection::GetLocations(Base); |
1278 | |
1279 | auto ExpectedLocations = |
1280 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1281 | |
1282 | // clang-format off |
1283 | EXPECT_THAT(ExpectedLocations, |
1284 | UnorderedElementsAre( |
1285 | STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), |
1286 | STRING_LOCATION_PAIR(Base, getEllipsisLoc()), |
1287 | STRING_LOCATION_PAIR(Base, getBeginLoc()), |
1288 | STRING_LOCATION_PAIR(Base, getEndLoc()), |
1289 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), |
1290 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
1291 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) |
1292 | )); |
1293 | // clang-format on |
1294 | |
1295 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1296 | |
1297 | // clang-format off |
1298 | EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( |
1299 | STRING_LOCATION_PAIR(Base, getSourceRange()), |
1300 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), |
1301 | STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) |
1302 | )); |
1303 | // clang-format on |
1304 | } |
1305 | |
1306 | TEST(Introspection, SourceLocations_FunctionProtoTypeLoc) { |
1307 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1308 | GTEST_SKIP(); |
1309 | auto AST = |
1310 | buildASTFromCode(Code: R"cpp( |
1311 | int foo(); |
1312 | )cpp" , |
1313 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1314 | auto &Ctx = AST->getASTContext(); |
1315 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1316 | |
1317 | auto BoundNodes = ast_matchers::match( |
1318 | Matcher: decl(hasDescendant(loc(InnerMatcher: functionProtoType()).bind(ID: "tl" ))), Node: TU, Context&: Ctx); |
1319 | |
1320 | EXPECT_EQ(BoundNodes.size(), 1u); |
1321 | |
1322 | const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>(ID: "tl" ); |
1323 | auto Result = NodeIntrospection::GetLocations(*TL); |
1324 | |
1325 | auto ExpectedLocations = |
1326 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1327 | |
1328 | llvm::sort(C&: ExpectedLocations); |
1329 | |
1330 | // clang-format off |
1331 | EXPECT_EQ( |
1332 | llvm::ArrayRef(ExpectedLocations), |
1333 | (ArrayRef<std::pair<std::string, SourceLocation>>{ |
1334 | STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLParenLoc()), |
1335 | STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLocalRangeBegin()), |
1336 | STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLocalRangeEnd()), |
1337 | STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getRParenLoc()), |
1338 | STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), |
1339 | STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), |
1340 | STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getBeginLoc()), |
1341 | STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getEndLoc()), |
1342 | STRING_LOCATION_STDPAIR(TL, getBeginLoc()), |
1343 | STRING_LOCATION_STDPAIR(TL, getEndLoc()), |
1344 | STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), |
1345 | STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), |
1346 | STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getBeginLoc()), |
1347 | STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getEndLoc()) |
1348 | })); |
1349 | // clang-format on |
1350 | |
1351 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1352 | |
1353 | // clang-format off |
1354 | EXPECT_THAT( |
1355 | ExpectedRanges, |
1356 | UnorderedElementsAre( |
1357 | STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getParensRange()), |
1358 | STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getLocalSourceRange()), |
1359 | STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getSourceRange()), |
1360 | STRING_LOCATION_PAIR(TL, getLocalSourceRange()), |
1361 | STRING_LOCATION_PAIR(TL, getNextTypeLoc().getLocalSourceRange()), |
1362 | STRING_LOCATION_PAIR(TL, getNextTypeLoc().getSourceRange()), |
1363 | STRING_LOCATION_PAIR(TL, getSourceRange()) |
1364 | )); |
1365 | // clang-format on |
1366 | } |
1367 | |
1368 | TEST(Introspection, SourceLocations_PointerTypeLoc) { |
1369 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1370 | GTEST_SKIP(); |
1371 | auto AST = |
1372 | buildASTFromCode(Code: R"cpp( |
1373 | int* i; |
1374 | )cpp" , |
1375 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1376 | auto &Ctx = AST->getASTContext(); |
1377 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1378 | |
1379 | auto BoundNodes = ast_matchers::match( |
1380 | Matcher: decl(hasDescendant( |
1381 | varDecl(hasName(Name: "i" ), hasDescendant(loc(InnerMatcher: pointerType()).bind(ID: "tl" ))))), |
1382 | Node: TU, Context&: Ctx); |
1383 | |
1384 | EXPECT_EQ(BoundNodes.size(), 1u); |
1385 | |
1386 | const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>(ID: "tl" ); |
1387 | auto Result = NodeIntrospection::GetLocations(*TL); |
1388 | |
1389 | auto ExpectedLocations = |
1390 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1391 | |
1392 | llvm::sort(C&: ExpectedLocations); |
1393 | |
1394 | // clang-format off |
1395 | EXPECT_EQ( |
1396 | llvm::ArrayRef(ExpectedLocations), |
1397 | (ArrayRef<std::pair<std::string, SourceLocation>>{ |
1398 | STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), |
1399 | STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), |
1400 | STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getBeginLoc()), |
1401 | STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getEndLoc()), |
1402 | STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getSigilLoc()), |
1403 | STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getStarLoc()), |
1404 | STRING_LOCATION_STDPAIR(TL, getBeginLoc()), |
1405 | STRING_LOCATION_STDPAIR(TL, getEndLoc()), |
1406 | STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), |
1407 | STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), |
1408 | STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getBeginLoc()), |
1409 | STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getEndLoc()) |
1410 | })); |
1411 | // clang-format on |
1412 | |
1413 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1414 | |
1415 | // clang-format off |
1416 | EXPECT_THAT( |
1417 | ExpectedRanges, |
1418 | UnorderedElementsAre( |
1419 | STRING_LOCATION_PAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getLocalSourceRange()), |
1420 | STRING_LOCATION_PAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getSourceRange()), |
1421 | STRING_LOCATION_PAIR(TL, getLocalSourceRange()), |
1422 | STRING_LOCATION_PAIR(TL, getNextTypeLoc().getLocalSourceRange()), |
1423 | STRING_LOCATION_PAIR(TL, getNextTypeLoc().getSourceRange()), |
1424 | STRING_LOCATION_PAIR(TL, getSourceRange()) |
1425 | )); |
1426 | // clang-format on |
1427 | } |
1428 | |
1429 | #ifndef _WIN32 |
1430 | // This test doesn't work on windows due to use of the typeof extension. |
1431 | TEST(Introspection, SourceLocations_TypeOfTypeLoc) { |
1432 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1433 | GTEST_SKIP(); |
1434 | auto AST = |
1435 | buildASTFromCode(Code: R"cpp( |
1436 | typeof (static_cast<void *>(0)) i; |
1437 | )cpp" , |
1438 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1439 | auto &Ctx = AST->getASTContext(); |
1440 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1441 | |
1442 | auto BoundNodes = ast_matchers::match( |
1443 | Matcher: decl(hasDescendant( |
1444 | varDecl(hasName(Name: "i" ), hasDescendant(loc(InnerMatcher: type()).bind(ID: "tl" ))))), |
1445 | Node: TU, Context&: Ctx); |
1446 | |
1447 | EXPECT_EQ(BoundNodes.size(), 1u); |
1448 | |
1449 | const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>(ID: "tl" ); |
1450 | auto Result = NodeIntrospection::GetLocations(*TL); |
1451 | |
1452 | auto ExpectedLocations = |
1453 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1454 | |
1455 | EXPECT_THAT(ExpectedLocations, |
1456 | UnorderedElementsAre( |
1457 | STRING_LOCATION_PAIR(TL, getBeginLoc()), |
1458 | STRING_LOCATION_PAIR(TL, getEndLoc()), |
1459 | STRING_LOCATION_PAIR( |
1460 | TL, getAs<clang::TypeOfExprTypeLoc>().getTypeofLoc()), |
1461 | STRING_LOCATION_PAIR( |
1462 | TL, getAs<clang::TypeOfExprTypeLoc>().getLParenLoc()), |
1463 | STRING_LOCATION_PAIR( |
1464 | TL, getAs<clang::TypeOfExprTypeLoc>().getRParenLoc()))); |
1465 | |
1466 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1467 | |
1468 | EXPECT_THAT(ExpectedRanges, |
1469 | UnorderedElementsAre( |
1470 | STRING_LOCATION_PAIR(TL, getLocalSourceRange()), |
1471 | STRING_LOCATION_PAIR(TL, getSourceRange()), |
1472 | STRING_LOCATION_PAIR( |
1473 | TL, getAs<clang::TypeOfExprTypeLoc>().getParensRange()))); |
1474 | } |
1475 | #endif |
1476 | |
1477 | TEST(Introspection, SourceLocations_DeclarationNameInfo_Dtor) { |
1478 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1479 | GTEST_SKIP(); |
1480 | auto AST = |
1481 | buildASTFromCode(Code: R"cpp( |
1482 | class Foo |
1483 | { |
1484 | ~Foo() {} |
1485 | }; |
1486 | )cpp" , |
1487 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1488 | auto &Ctx = AST->getASTContext(); |
1489 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1490 | |
1491 | auto BoundNodes = ast_matchers::match( |
1492 | Matcher: decl(hasDescendant(cxxDestructorDecl(hasName(Name: "~Foo" )).bind(ID: "dtor" ))), Node: TU, |
1493 | Context&: Ctx); |
1494 | |
1495 | EXPECT_EQ(BoundNodes.size(), 1u); |
1496 | |
1497 | const auto *Dtor = BoundNodes[0].getNodeAs<CXXDestructorDecl>(ID: "dtor" ); |
1498 | auto NI = Dtor->getNameInfo(); |
1499 | auto Result = NodeIntrospection::GetLocations(NI); |
1500 | |
1501 | auto ExpectedLocations = |
1502 | FormatExpected<SourceLocation>(Result.LocationAccessors); |
1503 | |
1504 | llvm::sort(ExpectedLocations); |
1505 | |
1506 | // clang-format off |
1507 | EXPECT_EQ( |
1508 | llvm::ArrayRef(ExpectedLocations), |
1509 | (ArrayRef<std::pair<std::string, SourceLocation>>{ |
1510 | STRING_LOCATION_STDPAIR((&NI), getBeginLoc()), |
1511 | STRING_LOCATION_STDPAIR((&NI), getEndLoc()), |
1512 | STRING_LOCATION_STDPAIR((&NI), getLoc()), |
1513 | STRING_LOCATION_STDPAIR((&NI), |
1514 | getNamedTypeInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), |
1515 | STRING_LOCATION_STDPAIR( |
1516 | (&NI), getNamedTypeInfo()->getTypeLoc().getBeginLoc()), |
1517 | STRING_LOCATION_STDPAIR( |
1518 | (&NI), getNamedTypeInfo()->getTypeLoc().getEndLoc())})); |
1519 | // clang-format on |
1520 | |
1521 | auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); |
1522 | |
1523 | EXPECT_THAT( |
1524 | ExpectedRanges, |
1525 | UnorderedElementsAre( |
1526 | STRING_LOCATION_PAIR( |
1527 | (&NI), getNamedTypeInfo()->getTypeLoc().getLocalSourceRange()), |
1528 | STRING_LOCATION_PAIR( |
1529 | (&NI), getNamedTypeInfo()->getTypeLoc().getSourceRange()), |
1530 | STRING_LOCATION_PAIR((&NI), getSourceRange()))); |
1531 | } |
1532 | |
1533 | TEST(Introspection, SourceLocations_DeclarationNameInfo_CRef) { |
1534 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1535 | GTEST_SKIP(); |
1536 | |
1537 | auto AST = buildASTFromCodeWithArgs( |
1538 | Code: R"cpp( |
1539 | template<typename T> |
1540 | struct MyContainer |
1541 | { |
1542 | template <typename U> |
1543 | void pushBack(); |
1544 | }; |
1545 | |
1546 | template<typename T> |
1547 | void foo() |
1548 | { |
1549 | MyContainer<T> mc; |
1550 | mc.template pushBack<int>(); |
1551 | } |
1552 | )cpp" , |
1553 | Args: {"-fno-delayed-template-parsing" }, FileName: "foo.cpp" , ToolName: "clang-tool" , |
1554 | PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1555 | |
1556 | auto &Ctx = AST->getASTContext(); |
1557 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1558 | |
1559 | auto BoundNodes = ast_matchers::match( |
1560 | Matcher: decl(hasDescendant(cxxDependentScopeMemberExpr(hasMemberName(N: "pushBack" )).bind(ID: "member" ))), Node: TU, |
1561 | Context&: Ctx); |
1562 | |
1563 | EXPECT_EQ(BoundNodes.size(), 1u); |
1564 | |
1565 | const auto *Member = BoundNodes[0].getNodeAs<CXXDependentScopeMemberExpr>(ID: "member" ); |
1566 | auto Result = NodeIntrospection::GetLocations(Member); |
1567 | |
1568 | auto ExpectedLocations = |
1569 | FormatExpected<SourceLocation>(Result.LocationAccessors); |
1570 | |
1571 | llvm::sort(ExpectedLocations); |
1572 | |
1573 | EXPECT_EQ( |
1574 | llvm::ArrayRef(ExpectedLocations), |
1575 | (ArrayRef<std::pair<std::string, SourceLocation>>{ |
1576 | STRING_LOCATION_STDPAIR(Member, getBeginLoc()), |
1577 | STRING_LOCATION_STDPAIR(Member, getEndLoc()), |
1578 | STRING_LOCATION_STDPAIR(Member, getExprLoc()), |
1579 | STRING_LOCATION_STDPAIR(Member, getLAngleLoc()), |
1580 | STRING_LOCATION_STDPAIR(Member, getMemberLoc()), |
1581 | STRING_LOCATION_STDPAIR(Member, getMemberNameInfo().getBeginLoc()), |
1582 | STRING_LOCATION_STDPAIR(Member, getMemberNameInfo().getEndLoc()), |
1583 | STRING_LOCATION_STDPAIR(Member, getMemberNameInfo().getLoc()), |
1584 | STRING_LOCATION_STDPAIR(Member, getOperatorLoc()), |
1585 | STRING_LOCATION_STDPAIR(Member, getRAngleLoc()), |
1586 | STRING_LOCATION_STDPAIR(Member, getTemplateKeywordLoc())})); |
1587 | |
1588 | auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); |
1589 | |
1590 | EXPECT_THAT( |
1591 | ExpectedRanges, |
1592 | UnorderedElementsAre( |
1593 | STRING_LOCATION_PAIR(Member, getMemberNameInfo().getSourceRange()), |
1594 | STRING_LOCATION_PAIR(Member, getSourceRange()) |
1595 | )); |
1596 | } |
1597 | |
1598 | TEST(Introspection, SourceLocations_DeclarationNameInfo_ConvOp) { |
1599 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1600 | GTEST_SKIP(); |
1601 | auto AST = |
1602 | buildASTFromCode(Code: R"cpp( |
1603 | class Foo |
1604 | { |
1605 | bool operator==(const Foo&) const { return false; } |
1606 | }; |
1607 | )cpp" , |
1608 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1609 | auto &Ctx = AST->getASTContext(); |
1610 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1611 | |
1612 | auto BoundNodes = ast_matchers::match( |
1613 | Matcher: decl(hasDescendant(cxxMethodDecl().bind(ID: "opeq" ))), Node: TU, Context&: Ctx); |
1614 | |
1615 | EXPECT_EQ(BoundNodes.size(), 1u); |
1616 | |
1617 | const auto *Opeq = BoundNodes[0].getNodeAs<CXXMethodDecl>(ID: "opeq" ); |
1618 | auto NI = Opeq->getNameInfo(); |
1619 | auto Result = NodeIntrospection::GetLocations(NI); |
1620 | |
1621 | auto ExpectedLocations = |
1622 | FormatExpected<SourceLocation>(Result.LocationAccessors); |
1623 | |
1624 | llvm::sort(ExpectedLocations); |
1625 | |
1626 | EXPECT_EQ(llvm::ArrayRef(ExpectedLocations), |
1627 | (ArrayRef<std::pair<std::string, SourceLocation>>{ |
1628 | STRING_LOCATION_STDPAIR((&NI), getBeginLoc()), |
1629 | STRING_LOCATION_STDPAIR((&NI), getEndLoc()), |
1630 | STRING_LOCATION_STDPAIR((&NI), getLoc())})); |
1631 | |
1632 | auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); |
1633 | |
1634 | EXPECT_THAT(ExpectedRanges, |
1635 | UnorderedElementsAre( |
1636 | STRING_LOCATION_PAIR((&NI), getSourceRange()), |
1637 | STRING_LOCATION_PAIR((&NI), getCXXOperatorNameRange()))); |
1638 | } |
1639 | |
1640 | TEST(Introspection, SourceLocations_DeclarationNameInfo_LitOp) { |
1641 | if (!NodeIntrospection::hasIntrospectionSupport()) |
1642 | GTEST_SKIP(); |
1643 | auto AST = |
1644 | buildASTFromCode(Code: R"cpp( |
1645 | long double operator"" _identity ( long double val ) |
1646 | { |
1647 | return val; |
1648 | } |
1649 | )cpp" , |
1650 | FileName: "foo.cpp" , PCHContainerOps: std::make_shared<PCHContainerOperations>()); |
1651 | auto &Ctx = AST->getASTContext(); |
1652 | auto &TU = *Ctx.getTranslationUnitDecl(); |
1653 | |
1654 | auto BoundNodes = ast_matchers::match( |
1655 | Matcher: decl(hasDescendant(functionDecl().bind(ID: "litop" ))), Node: TU, Context&: Ctx); |
1656 | |
1657 | EXPECT_EQ(BoundNodes.size(), 1u); |
1658 | |
1659 | const auto *LitOp = BoundNodes[0].getNodeAs<FunctionDecl>(ID: "litop" ); |
1660 | auto NI = LitOp->getNameInfo(); |
1661 | auto Result = NodeIntrospection::GetLocations(NI); |
1662 | |
1663 | auto ExpectedLocations = |
1664 | FormatExpected<SourceLocation>(Accessors: Result.LocationAccessors); |
1665 | |
1666 | llvm::sort(C&: ExpectedLocations); |
1667 | |
1668 | EXPECT_EQ(llvm::ArrayRef(ExpectedLocations), |
1669 | (ArrayRef<std::pair<std::string, SourceLocation>>{ |
1670 | STRING_LOCATION_STDPAIR((&NI), getBeginLoc()), |
1671 | STRING_LOCATION_STDPAIR((&NI), getCXXLiteralOperatorNameLoc()), |
1672 | STRING_LOCATION_STDPAIR((&NI), getEndLoc()), |
1673 | STRING_LOCATION_STDPAIR((&NI), getLoc())})); |
1674 | |
1675 | auto ExpectedRanges = FormatExpected<SourceRange>(Accessors: Result.RangeAccessors); |
1676 | |
1677 | EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( |
1678 | (&NI), getSourceRange()))); |
1679 | } |
1680 | |