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(*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(*On, OS); 60 return; 61 } 62 if (const LocationCall *On = Call.on()) { 63 print(*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(std::make_pair( 82 SourceLocation(), 83 llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "getSourceRange"))); 84 EXPECT_EQ(slm.size(), 1u); 85 86 auto callTypeLoc = 87 llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "getTypeLoc"); 88 slm.insert(std::make_pair( 89 SourceLocation(), 90 llvm::makeIntrusiveRefCnt<LocationCall>(callTypeLoc, "getSourceRange"))); 91 EXPECT_EQ(slm.size(), 2u); 92 } 93 94 TEST(Introspection, SourceLocations_CallContainer2) { 95 SourceRangeMap slm; 96 SharedLocationCall Prefix; 97 slm.insert( 98 std::make_pair(SourceRange(), llvm::makeIntrusiveRefCnt<LocationCall>( 99 Prefix, "getCXXOperatorNameRange"))); 100 EXPECT_EQ(slm.size(), 1u); 101 102 slm.insert(std::make_pair( 103 SourceRange(), 104 llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "getSourceRange"))); 105 EXPECT_EQ(slm.size(), 2u); 106 } 107 108 TEST(Introspection, SourceLocations_CallChainFormatting) { 109 SharedLocationCall Prefix; 110 auto chainedCall = llvm::makeIntrusiveRefCnt<LocationCall>( 111 llvm::makeIntrusiveRefCnt<LocationCall>(Prefix, "getTypeLoc"), 112 "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 llvm::makeIntrusiveRefCnt<LocationCall>( 121 llvm::makeIntrusiveRefCnt<LocationCall>( 122 llvm::makeIntrusiveRefCnt<LocationCall>( 123 Prefix, "getTypeSourceInfo", LocationCall::ReturnsPointer), 124 "getTypeLoc"), 125 "getAs<clang::TypeSpecTypeLoc>", LocationCall::IsCast), 126 "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 return; 138 auto AST = buildASTFromCode("void foo() {} void bar() { foo(); }", "foo.cpp", 139 std::make_shared<PCHContainerOperations>()); 140 auto &Ctx = AST->getASTContext(); 141 auto &TU = *Ctx.getTranslationUnitDecl(); 142 143 auto BoundNodes = ast_matchers::match( 144 decl(hasDescendant( 145 callExpr(callee(functionDecl(hasName("foo")))).bind("fooCall"))), 146 TU, Ctx); 147 148 EXPECT_EQ(BoundNodes.size(), 1u); 149 150 auto *FooCall = BoundNodes[0].getNodeAs<CallExpr>("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 return; 173 auto AST = 174 buildASTFromCode(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 "foo.cpp", std::make_shared<PCHContainerOperations>()); 193 auto &Ctx = AST->getASTContext(); 194 auto &TU = *Ctx.getTranslationUnitDecl(); 195 196 auto BoundNodes = ast_matchers::match( 197 decl(hasDescendant( 198 cxxMethodDecl(hasName("method"), isDefinition()).bind("method"))), 199 TU, Ctx); 200 201 EXPECT_EQ(BoundNodes.size(), 1u); 202 203 const auto *MethodDecl = BoundNodes[0].getNodeAs<CXXMethodDecl>("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::makeArrayRef(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 return; 358 auto AST = 359 buildASTFromCode(R"cpp( 360 namespace ns 361 { 362 struct A { 363 void foo(); 364 }; 365 } 366 void ns::A::foo() {} 367 )cpp", 368 "foo.cpp", std::make_shared<PCHContainerOperations>()); 369 auto &Ctx = AST->getASTContext(); 370 auto &TU = *Ctx.getTranslationUnitDecl(); 371 372 auto BoundNodes = ast_matchers::match( 373 decl(hasDescendant(nestedNameSpecifierLoc().bind("nns"))), TU, Ctx); 374 375 EXPECT_EQ(BoundNodes.size(), 1u); 376 377 const auto *NNS = BoundNodes[0].getNodeAs<NestedNameSpecifierLoc>("nns"); 378 379 auto Result = NodeIntrospection::GetLocations(*NNS); 380 381 auto ExpectedLocations = 382 FormatExpected<SourceLocation>(Result.LocationAccessors); 383 384 llvm::sort(ExpectedLocations); 385 386 EXPECT_EQ( 387 llvm::makeArrayRef(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>(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 return; 418 auto AST = 419 buildASTFromCode(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 "foo.cpp", std::make_shared<PCHContainerOperations>()); 431 auto &Ctx = AST->getASTContext(); 432 auto &TU = *Ctx.getTranslationUnitDecl(); 433 434 auto BoundNodes = ast_matchers::match( 435 decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); 436 437 EXPECT_EQ(BoundNodes.size(), 1u); 438 439 const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); 440 441 auto Result = NodeIntrospection::GetLocations(*TA); 442 443 auto ExpectedLocations = 444 FormatExpected<SourceLocation>(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>(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 return; 476 auto AST = 477 buildASTFromCode(R"cpp( 478 template<void(*Ty)()> 479 void test2() {} 480 void doNothing() {} 481 void test() { 482 test2<doNothing>(); 483 } 484 )cpp", 485 "foo.cpp", std::make_shared<PCHContainerOperations>()); 486 auto &Ctx = AST->getASTContext(); 487 auto &TU = *Ctx.getTranslationUnitDecl(); 488 489 auto BoundNodes = ast_matchers::match( 490 decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); 491 492 EXPECT_EQ(BoundNodes.size(), 1u); 493 494 const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); 495 496 auto Result = NodeIntrospection::GetLocations(*TA); 497 498 auto ExpectedLocations = 499 FormatExpected<SourceLocation>(Result.LocationAccessors); 500 501 EXPECT_THAT(ExpectedLocations, 502 UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); 503 504 auto ExpectedRanges = FormatExpected<SourceRange>(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 return; 513 auto AST = 514 buildASTFromCode(R"cpp( 515 template<void(*Ty)()> 516 void test2() {} 517 void doNothing() {} 518 void test() { 519 test2<nullptr>(); 520 } 521 )cpp", 522 "foo.cpp", std::make_shared<PCHContainerOperations>()); 523 auto &Ctx = AST->getASTContext(); 524 auto &TU = *Ctx.getTranslationUnitDecl(); 525 526 auto BoundNodes = ast_matchers::match( 527 decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); 528 529 EXPECT_EQ(BoundNodes.size(), 1u); 530 531 const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); 532 533 auto Result = NodeIntrospection::GetLocations(*TA); 534 535 auto ExpectedLocations = 536 FormatExpected<SourceLocation>(Result.LocationAccessors); 537 538 EXPECT_THAT(ExpectedLocations, 539 UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); 540 541 auto ExpectedRanges = FormatExpected<SourceRange>(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 return; 550 auto AST = 551 buildASTFromCode(R"cpp( 552 template<int> 553 void test2() {} 554 void test() { 555 test2<42>(); 556 } 557 )cpp", 558 "foo.cpp", std::make_shared<PCHContainerOperations>()); 559 auto &Ctx = AST->getASTContext(); 560 auto &TU = *Ctx.getTranslationUnitDecl(); 561 562 auto BoundNodes = ast_matchers::match( 563 decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); 564 565 EXPECT_EQ(BoundNodes.size(), 1u); 566 567 const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); 568 569 auto Result = NodeIntrospection::GetLocations(*TA); 570 571 auto ExpectedLocations = 572 FormatExpected<SourceLocation>(Result.LocationAccessors); 573 574 EXPECT_THAT(ExpectedLocations, 575 UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); 576 577 auto ExpectedRanges = FormatExpected<SourceRange>(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 return; 586 auto AST = 587 buildASTFromCode(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 "foo.cpp", std::make_shared<PCHContainerOperations>()); 596 auto &Ctx = AST->getASTContext(); 597 auto &TU = *Ctx.getTranslationUnitDecl(); 598 599 auto BoundNodes = ast_matchers::match( 600 decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); 601 602 EXPECT_EQ(BoundNodes.size(), 1u); 603 604 const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); 605 606 auto Result = NodeIntrospection::GetLocations(*TA); 607 608 auto ExpectedLocations = 609 FormatExpected<SourceLocation>(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>(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 return; 625 auto AST = buildASTFromCodeWithArgs( 626 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 {"-fno-delayed-template-parsing"}, "foo.cpp", "clang-tool", 633 std::make_shared<PCHContainerOperations>()); 634 auto &Ctx = AST->getASTContext(); 635 auto &TU = *Ctx.getTranslationUnitDecl(); 636 637 auto BoundNodes = ast_matchers::match( 638 decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); 639 640 EXPECT_EQ(BoundNodes.size(), 1u); 641 642 const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); 643 644 auto Result = NodeIntrospection::GetLocations(*TA); 645 646 auto ExpectedLocations = 647 FormatExpected<SourceLocation>(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>(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 return; 664 auto AST = 665 buildASTFromCode(R"cpp( 666 template<int, int = 0> class testExpr; 667 template<int I> class testExpr<I> { }; 668 )cpp", 669 "foo.cpp", std::make_shared<PCHContainerOperations>()); 670 auto &Ctx = AST->getASTContext(); 671 auto &TU = *Ctx.getTranslationUnitDecl(); 672 673 auto BoundNodes = ast_matchers::match( 674 decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); 675 676 EXPECT_EQ(BoundNodes.size(), 1u); 677 678 const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); 679 680 auto Result = NodeIntrospection::GetLocations(*TA); 681 682 auto ExpectedLocations = 683 FormatExpected<SourceLocation>(Result.LocationAccessors); 684 685 EXPECT_THAT(ExpectedLocations, 686 UnorderedElementsAre(STRING_LOCATION_PAIR(TA, getLocation()))); 687 688 auto ExpectedRanges = FormatExpected<SourceRange>(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 return; 697 auto AST = buildASTFromCodeWithArgs( 698 R"cpp( 699 template<typename... T> class A {}; 700 void foo() 701 { 702 A<int> ai; 703 } 704 )cpp", 705 {"-fno-delayed-template-parsing"}, "foo.cpp", "clang-tool", 706 std::make_shared<PCHContainerOperations>()); 707 auto &Ctx = AST->getASTContext(); 708 auto &TU = *Ctx.getTranslationUnitDecl(); 709 710 auto BoundNodes = ast_matchers::match( 711 decl(hasDescendant(templateArgumentLoc().bind("ta"))), TU, Ctx); 712 713 EXPECT_EQ(BoundNodes.size(), 1u); 714 715 const auto *TA = BoundNodes[0].getNodeAs<TemplateArgumentLoc>("ta"); 716 717 auto Result = NodeIntrospection::GetLocations(*TA); 718 719 auto ExpectedLocations = 720 FormatExpected<SourceLocation>(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>(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 return; 752 auto AST = 753 buildASTFromCode(R"cpp( 754 struct A { 755 }; 756 757 struct B : A { 758 B() : A() {} 759 }; 760 )cpp", 761 "foo.cpp", std::make_shared<PCHContainerOperations>()); 762 auto &Ctx = AST->getASTContext(); 763 auto &TU = *Ctx.getTranslationUnitDecl(); 764 765 auto BoundNodes = ast_matchers::match( 766 decl(hasDescendant(cxxConstructorDecl( 767 hasAnyConstructorInitializer(cxxCtorInitializer().bind("init"))))), 768 TU, Ctx); 769 770 EXPECT_EQ(BoundNodes.size(), 1u); 771 772 const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>("init"); 773 774 auto Result = NodeIntrospection::GetLocations(CtorInit); 775 776 auto ExpectedLocations = 777 FormatExpected<SourceLocation>(Result.LocationAccessors); 778 779 // clang-format off 780 EXPECT_THAT( 781 ExpectedLocations, 782 UnorderedElementsAre( 783 STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), 784 STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getBeginLoc()), 785 STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getEndLoc()), 786 STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), 787 STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), 788 STRING_LOCATION_PAIR(CtorInit, getSourceLocation()), 789 STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), 790 STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), 791 STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()) 792 )); 793 // clang-format on 794 795 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 796 797 // clang-format off 798 EXPECT_THAT( 799 ExpectedRanges, 800 UnorderedElementsAre( 801 STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getLocalSourceRange()), 802 STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getSourceRange()), 803 STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), 804 STRING_LOCATION_PAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()), 805 STRING_LOCATION_PAIR(CtorInit, getSourceRange()))); 806 // clang-format on 807 } 808 809 TEST(Introspection, SourceLocations_CXXCtorInitializer_member) { 810 if (!NodeIntrospection::hasIntrospectionSupport()) 811 return; 812 auto AST = 813 buildASTFromCode(R"cpp( 814 struct A { 815 int m_i; 816 A() : m_i(42) {} 817 }; 818 )cpp", 819 "foo.cpp", std::make_shared<PCHContainerOperations>()); 820 auto &Ctx = AST->getASTContext(); 821 auto &TU = *Ctx.getTranslationUnitDecl(); 822 823 auto BoundNodes = ast_matchers::match( 824 decl(hasDescendant(cxxConstructorDecl( 825 hasAnyConstructorInitializer(cxxCtorInitializer().bind("init"))))), 826 TU, Ctx); 827 828 EXPECT_EQ(BoundNodes.size(), 1u); 829 830 const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>("init"); 831 832 auto Result = NodeIntrospection::GetLocations(CtorInit); 833 834 auto ExpectedLocations = 835 FormatExpected<SourceLocation>(Result.LocationAccessors); 836 837 EXPECT_THAT(ExpectedLocations, 838 UnorderedElementsAre( 839 STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), 840 STRING_LOCATION_PAIR(CtorInit, getMemberLocation()), 841 STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), 842 STRING_LOCATION_PAIR(CtorInit, getSourceLocation()))); 843 844 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 845 846 EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( 847 CtorInit, getSourceRange()))); 848 } 849 850 TEST(Introspection, SourceLocations_CXXCtorInitializer_ctor) { 851 if (!NodeIntrospection::hasIntrospectionSupport()) 852 return; 853 auto AST = 854 buildASTFromCode(R"cpp( 855 struct C { 856 C() : C(42) {} 857 C(int) {} 858 }; 859 )cpp", 860 "foo.cpp", std::make_shared<PCHContainerOperations>()); 861 auto &Ctx = AST->getASTContext(); 862 auto &TU = *Ctx.getTranslationUnitDecl(); 863 864 auto BoundNodes = ast_matchers::match( 865 decl(hasDescendant(cxxConstructorDecl( 866 hasAnyConstructorInitializer(cxxCtorInitializer().bind("init"))))), 867 TU, Ctx); 868 869 EXPECT_EQ(BoundNodes.size(), 1u); 870 871 const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>("init"); 872 873 auto Result = NodeIntrospection::GetLocations(CtorInit); 874 875 auto ExpectedLocations = 876 FormatExpected<SourceLocation>(Result.LocationAccessors); 877 878 // clang-format off 879 EXPECT_THAT( 880 ExpectedLocations, 881 UnorderedElementsAre( 882 STRING_LOCATION_PAIR(CtorInit, getLParenLoc()), 883 STRING_LOCATION_PAIR(CtorInit, getRParenLoc()), 884 STRING_LOCATION_PAIR(CtorInit, getSourceLocation()), 885 STRING_LOCATION_PAIR(CtorInit, 886 getTypeSourceInfo()->getTypeLoc().getBeginLoc()), 887 STRING_LOCATION_PAIR(CtorInit, 888 getTypeSourceInfo()->getTypeLoc().getEndLoc()), 889 STRING_LOCATION_PAIR(CtorInit, 890 getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()) 891 )); 892 // clang-format on 893 894 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 895 896 EXPECT_THAT( 897 ExpectedRanges, 898 UnorderedElementsAre( 899 STRING_LOCATION_PAIR(CtorInit, getSourceRange()), 900 STRING_LOCATION_PAIR( 901 CtorInit, 902 getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), 903 STRING_LOCATION_PAIR( 904 CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()))); 905 } 906 907 TEST(Introspection, SourceLocations_CXXCtorInitializer_pack) { 908 if (!NodeIntrospection::hasIntrospectionSupport()) 909 return; 910 auto AST = buildASTFromCodeWithArgs( 911 R"cpp( 912 template<typename... T> 913 struct Templ { 914 }; 915 916 template<typename... T> 917 struct D : Templ<T...> { 918 D(T... t) : Templ<T>(t)... {} 919 }; 920 )cpp", 921 {"-fno-delayed-template-parsing"}, "foo.cpp", "clang-tool", 922 std::make_shared<PCHContainerOperations>()); 923 auto &Ctx = AST->getASTContext(); 924 auto &TU = *Ctx.getTranslationUnitDecl(); 925 926 auto BoundNodes = ast_matchers::match( 927 decl(hasDescendant(cxxConstructorDecl( 928 hasAnyConstructorInitializer(cxxCtorInitializer().bind("init"))))), 929 TU, Ctx); 930 931 EXPECT_EQ(BoundNodes.size(), 1u); 932 933 const auto *CtorInit = BoundNodes[0].getNodeAs<CXXCtorInitializer>("init"); 934 935 auto Result = NodeIntrospection::GetLocations(CtorInit); 936 937 auto ExpectedLocations = 938 FormatExpected<SourceLocation>(Result.LocationAccessors); 939 940 llvm::sort(ExpectedLocations); 941 942 // clang-format off 943 EXPECT_EQ( 944 llvm::makeArrayRef(ExpectedLocations), 945 (ArrayRef<std::pair<std::string, SourceLocation>>{ 946 STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), 947 STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), 948 STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), 949 STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getBeginLoc()), 950 STRING_LOCATION_STDPAIR(CtorInit, getBaseClassLoc().getEndLoc()), 951 STRING_LOCATION_STDPAIR(CtorInit, getEllipsisLoc()), 952 STRING_LOCATION_STDPAIR(CtorInit, getLParenLoc()), 953 STRING_LOCATION_STDPAIR(CtorInit, getMemberLocation()), 954 STRING_LOCATION_STDPAIR(CtorInit, getRParenLoc()), 955 STRING_LOCATION_STDPAIR(CtorInit, getSourceLocation()), 956 STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), 957 STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()), 958 STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), 959 STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), 960 STRING_LOCATION_STDPAIR(CtorInit, getTypeSourceInfo()->getTypeLoc().getEndLoc()) 961 })); 962 // clang-format on 963 964 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 965 966 EXPECT_THAT( 967 ExpectedRanges, 968 UnorderedElementsAre( 969 STRING_LOCATION_PAIR(CtorInit, 970 getBaseClassLoc().getLocalSourceRange()), 971 STRING_LOCATION_PAIR(CtorInit, getBaseClassLoc().getSourceRange()), 972 STRING_LOCATION_PAIR(CtorInit, getSourceRange()), 973 STRING_LOCATION_PAIR( 974 CtorInit, 975 getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), 976 STRING_LOCATION_PAIR( 977 CtorInit, getTypeSourceInfo()->getTypeLoc().getSourceRange()))); 978 } 979 980 TEST(Introspection, SourceLocations_CXXBaseSpecifier_plain) { 981 if (!NodeIntrospection::hasIntrospectionSupport()) 982 return; 983 auto AST = 984 buildASTFromCode(R"cpp( 985 class A {}; 986 class B : A {}; 987 )cpp", 988 "foo.cpp", std::make_shared<PCHContainerOperations>()); 989 auto &Ctx = AST->getASTContext(); 990 auto &TU = *Ctx.getTranslationUnitDecl(); 991 992 auto BoundNodes = ast_matchers::match( 993 decl(hasDescendant(cxxRecordDecl(hasDirectBase( 994 cxxBaseSpecifier(hasType(asString("class A"))).bind("base"))))), 995 TU, Ctx); 996 997 EXPECT_EQ(BoundNodes.size(), 1u); 998 999 const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>("base"); 1000 1001 auto Result = NodeIntrospection::GetLocations(Base); 1002 1003 auto ExpectedLocations = 1004 FormatExpected<SourceLocation>(Result.LocationAccessors); 1005 1006 // clang-format off 1007 EXPECT_THAT(ExpectedLocations, 1008 UnorderedElementsAre( 1009 STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), 1010 STRING_LOCATION_PAIR(Base, getBeginLoc()), 1011 STRING_LOCATION_PAIR(Base, getEndLoc()), 1012 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), 1013 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), 1014 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) 1015 )); 1016 // clang-format on 1017 1018 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1019 1020 // clang-format off 1021 EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( 1022 STRING_LOCATION_PAIR(Base, getSourceRange()), 1023 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), 1024 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) 1025 )); 1026 // clang-format on 1027 } 1028 1029 TEST(Introspection, SourceLocations_CXXBaseSpecifier_accessspec) { 1030 if (!NodeIntrospection::hasIntrospectionSupport()) 1031 return; 1032 auto AST = 1033 buildASTFromCode(R"cpp( 1034 class A {}; 1035 class B : public A {}; 1036 )cpp", 1037 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1038 auto &Ctx = AST->getASTContext(); 1039 auto &TU = *Ctx.getTranslationUnitDecl(); 1040 1041 auto BoundNodes = ast_matchers::match( 1042 decl(hasDescendant(cxxRecordDecl(hasDirectBase( 1043 cxxBaseSpecifier(hasType(asString("class A"))).bind("base"))))), 1044 TU, Ctx); 1045 1046 EXPECT_EQ(BoundNodes.size(), 1u); 1047 1048 const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>("base"); 1049 1050 auto Result = NodeIntrospection::GetLocations(Base); 1051 1052 auto ExpectedLocations = 1053 FormatExpected<SourceLocation>(Result.LocationAccessors); 1054 1055 // clang-format off 1056 EXPECT_THAT(ExpectedLocations, 1057 UnorderedElementsAre( 1058 STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), 1059 STRING_LOCATION_PAIR(Base, getBeginLoc()), 1060 STRING_LOCATION_PAIR(Base, getEndLoc()), 1061 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), 1062 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), 1063 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) 1064 )); 1065 // clang-format on 1066 1067 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1068 1069 // clang-format off 1070 EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( 1071 STRING_LOCATION_PAIR(Base, getSourceRange()), 1072 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()), 1073 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()) 1074 )); 1075 // clang-format on 1076 } 1077 1078 TEST(Introspection, SourceLocations_CXXBaseSpecifier_virtual) { 1079 if (!NodeIntrospection::hasIntrospectionSupport()) 1080 return; 1081 auto AST = 1082 buildASTFromCode(R"cpp( 1083 class A {}; 1084 class B {}; 1085 class C : virtual B, A {}; 1086 )cpp", 1087 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1088 auto &Ctx = AST->getASTContext(); 1089 auto &TU = *Ctx.getTranslationUnitDecl(); 1090 1091 auto BoundNodes = ast_matchers::match( 1092 decl(hasDescendant(cxxRecordDecl(hasDirectBase( 1093 cxxBaseSpecifier(hasType(asString("class A"))).bind("base"))))), 1094 TU, Ctx); 1095 1096 EXPECT_EQ(BoundNodes.size(), 1u); 1097 1098 const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>("base"); 1099 1100 auto Result = NodeIntrospection::GetLocations(Base); 1101 1102 auto ExpectedLocations = 1103 FormatExpected<SourceLocation>(Result.LocationAccessors); 1104 1105 // clang-format off 1106 EXPECT_THAT(ExpectedLocations, 1107 UnorderedElementsAre( 1108 STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), 1109 STRING_LOCATION_PAIR(Base, getBeginLoc()), 1110 STRING_LOCATION_PAIR(Base, getEndLoc()), 1111 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), 1112 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), 1113 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()) 1114 )); 1115 // clang-format on 1116 1117 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1118 1119 // clang-format off 1120 EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( 1121 STRING_LOCATION_PAIR(Base, getSourceRange()), 1122 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), 1123 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) 1124 )); 1125 // clang-format on 1126 } 1127 1128 TEST(Introspection, SourceLocations_CXXBaseSpecifier_template_base) { 1129 if (!NodeIntrospection::hasIntrospectionSupport()) 1130 return; 1131 auto AST = 1132 buildASTFromCode(R"cpp( 1133 template<typename T, typename U> 1134 class A {}; 1135 class B : A<int, bool> {}; 1136 )cpp", 1137 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1138 auto &Ctx = AST->getASTContext(); 1139 auto &TU = *Ctx.getTranslationUnitDecl(); 1140 1141 auto BoundNodes = 1142 ast_matchers::match(decl(hasDescendant(cxxRecordDecl( 1143 hasDirectBase(cxxBaseSpecifier().bind("base"))))), 1144 TU, Ctx); 1145 1146 EXPECT_EQ(BoundNodes.size(), 1u); 1147 1148 const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>("base"); 1149 1150 auto Result = NodeIntrospection::GetLocations(Base); 1151 1152 auto ExpectedLocations = 1153 FormatExpected<SourceLocation>(Result.LocationAccessors); 1154 1155 // clang-format off 1156 EXPECT_THAT(ExpectedLocations, 1157 UnorderedElementsAre( 1158 STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), 1159 STRING_LOCATION_PAIR(Base, getBeginLoc()), 1160 STRING_LOCATION_PAIR(Base, getEndLoc()), 1161 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()), 1162 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getTemplateNameLoc()), 1163 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getLAngleLoc()), 1164 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), 1165 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TemplateSpecializationTypeLoc>().getRAngleLoc()) 1166 )); 1167 // clang-format on 1168 1169 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1170 1171 // clang-format off 1172 EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( 1173 STRING_LOCATION_PAIR(Base, getSourceRange()), 1174 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), 1175 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) 1176 )); 1177 // clang-format on 1178 } 1179 1180 TEST(Introspection, SourceLocations_CXXBaseSpecifier_pack) { 1181 if (!NodeIntrospection::hasIntrospectionSupport()) 1182 return; 1183 auto AST = buildASTFromCodeWithArgs( 1184 R"cpp( 1185 template<typename... T> 1186 struct Templ : T... { 1187 }; 1188 )cpp", 1189 {"-fno-delayed-template-parsing"}, "foo.cpp", "clang-tool", 1190 std::make_shared<PCHContainerOperations>()); 1191 auto &Ctx = AST->getASTContext(); 1192 auto &TU = *Ctx.getTranslationUnitDecl(); 1193 1194 auto BoundNodes = 1195 ast_matchers::match(decl(hasDescendant(cxxRecordDecl( 1196 hasDirectBase(cxxBaseSpecifier().bind("base"))))), 1197 TU, Ctx); 1198 1199 EXPECT_EQ(BoundNodes.size(), 1u); 1200 1201 const auto *Base = BoundNodes[0].getNodeAs<CXXBaseSpecifier>("base"); 1202 1203 auto Result = NodeIntrospection::GetLocations(Base); 1204 1205 auto ExpectedLocations = 1206 FormatExpected<SourceLocation>(Result.LocationAccessors); 1207 1208 // clang-format off 1209 EXPECT_THAT(ExpectedLocations, 1210 UnorderedElementsAre( 1211 STRING_LOCATION_PAIR(Base, getBaseTypeLoc()), 1212 STRING_LOCATION_PAIR(Base, getEllipsisLoc()), 1213 STRING_LOCATION_PAIR(Base, getBeginLoc()), 1214 STRING_LOCATION_PAIR(Base, getEndLoc()), 1215 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getEndLoc()), 1216 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), 1217 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getBeginLoc()) 1218 )); 1219 // clang-format on 1220 1221 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1222 1223 // clang-format off 1224 EXPECT_THAT(ExpectedRanges, UnorderedElementsAre( 1225 STRING_LOCATION_PAIR(Base, getSourceRange()), 1226 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getSourceRange()), 1227 STRING_LOCATION_PAIR(Base, getTypeSourceInfo()->getTypeLoc().getLocalSourceRange()) 1228 )); 1229 // clang-format on 1230 } 1231 1232 TEST(Introspection, SourceLocations_FunctionProtoTypeLoc) { 1233 if (!NodeIntrospection::hasIntrospectionSupport()) 1234 return; 1235 auto AST = 1236 buildASTFromCode(R"cpp( 1237 int foo(); 1238 )cpp", 1239 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1240 auto &Ctx = AST->getASTContext(); 1241 auto &TU = *Ctx.getTranslationUnitDecl(); 1242 1243 auto BoundNodes = ast_matchers::match( 1244 decl(hasDescendant(loc(functionProtoType()).bind("tl"))), TU, Ctx); 1245 1246 EXPECT_EQ(BoundNodes.size(), 1u); 1247 1248 const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>("tl"); 1249 auto Result = NodeIntrospection::GetLocations(*TL); 1250 1251 auto ExpectedLocations = 1252 FormatExpected<SourceLocation>(Result.LocationAccessors); 1253 1254 llvm::sort(ExpectedLocations); 1255 1256 // clang-format off 1257 EXPECT_EQ( 1258 llvm::makeArrayRef(ExpectedLocations), 1259 (ArrayRef<std::pair<std::string, SourceLocation>>{ 1260 STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLParenLoc()), 1261 STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLocalRangeBegin()), 1262 STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getLocalRangeEnd()), 1263 STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getRParenLoc()), 1264 STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), 1265 STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), 1266 STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getBeginLoc()), 1267 STRING_LOCATION_STDPAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getEndLoc()), 1268 STRING_LOCATION_STDPAIR(TL, getBeginLoc()), 1269 STRING_LOCATION_STDPAIR(TL, getEndLoc()), 1270 STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), 1271 STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), 1272 STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getBeginLoc()), 1273 STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getEndLoc()) 1274 })); 1275 // clang-format on 1276 1277 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1278 1279 // clang-format off 1280 EXPECT_THAT( 1281 ExpectedRanges, 1282 UnorderedElementsAre( 1283 STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getParensRange()), 1284 STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getLocalSourceRange()), 1285 STRING_LOCATION_PAIR(TL, getAs<clang::FunctionTypeLoc>().getReturnLoc().getSourceRange()), 1286 STRING_LOCATION_PAIR(TL, getLocalSourceRange()), 1287 STRING_LOCATION_PAIR(TL, getNextTypeLoc().getLocalSourceRange()), 1288 STRING_LOCATION_PAIR(TL, getNextTypeLoc().getSourceRange()), 1289 STRING_LOCATION_PAIR(TL, getSourceRange()) 1290 )); 1291 // clang-format on 1292 } 1293 1294 TEST(Introspection, SourceLocations_PointerTypeLoc) { 1295 if (!NodeIntrospection::hasIntrospectionSupport()) 1296 return; 1297 auto AST = 1298 buildASTFromCode(R"cpp( 1299 int* i; 1300 )cpp", 1301 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1302 auto &Ctx = AST->getASTContext(); 1303 auto &TU = *Ctx.getTranslationUnitDecl(); 1304 1305 auto BoundNodes = ast_matchers::match( 1306 decl(hasDescendant( 1307 varDecl(hasName("i"), hasDescendant(loc(pointerType()).bind("tl"))))), 1308 TU, Ctx); 1309 1310 EXPECT_EQ(BoundNodes.size(), 1u); 1311 1312 const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>("tl"); 1313 auto Result = NodeIntrospection::GetLocations(*TL); 1314 1315 auto ExpectedLocations = 1316 FormatExpected<SourceLocation>(Result.LocationAccessors); 1317 1318 llvm::sort(ExpectedLocations); 1319 1320 // clang-format off 1321 EXPECT_EQ( 1322 llvm::makeArrayRef(ExpectedLocations), 1323 (ArrayRef<std::pair<std::string, SourceLocation>>{ 1324 STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), 1325 STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), 1326 STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getBeginLoc()), 1327 STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getEndLoc()), 1328 STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getSigilLoc()), 1329 STRING_LOCATION_STDPAIR(TL, getAs<clang::PointerTypeLoc>().getStarLoc()), 1330 STRING_LOCATION_STDPAIR(TL, getBeginLoc()), 1331 STRING_LOCATION_STDPAIR(TL, getEndLoc()), 1332 STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getBuiltinLoc()), 1333 STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getAs<clang::BuiltinTypeLoc>().getNameLoc()), 1334 STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getBeginLoc()), 1335 STRING_LOCATION_STDPAIR(TL, getNextTypeLoc().getEndLoc()) 1336 })); 1337 // clang-format on 1338 1339 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1340 1341 // clang-format off 1342 EXPECT_THAT( 1343 ExpectedRanges, 1344 UnorderedElementsAre( 1345 STRING_LOCATION_PAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getLocalSourceRange()), 1346 STRING_LOCATION_PAIR(TL, getAs<clang::PointerTypeLoc>().getPointeeLoc().getSourceRange()), 1347 STRING_LOCATION_PAIR(TL, getLocalSourceRange()), 1348 STRING_LOCATION_PAIR(TL, getNextTypeLoc().getLocalSourceRange()), 1349 STRING_LOCATION_PAIR(TL, getNextTypeLoc().getSourceRange()), 1350 STRING_LOCATION_PAIR(TL, getSourceRange()) 1351 )); 1352 // clang-format on 1353 } 1354 1355 #ifndef _WIN32 1356 // This test doesn't work on windows due to use of the typeof extension. 1357 TEST(Introspection, SourceLocations_TypeOfTypeLoc) { 1358 if (!NodeIntrospection::hasIntrospectionSupport()) 1359 return; 1360 auto AST = 1361 buildASTFromCode(R"cpp( 1362 typeof (static_cast<void *>(0)) i; 1363 )cpp", 1364 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1365 auto &Ctx = AST->getASTContext(); 1366 auto &TU = *Ctx.getTranslationUnitDecl(); 1367 1368 auto BoundNodes = ast_matchers::match( 1369 decl(hasDescendant( 1370 varDecl(hasName("i"), hasDescendant(loc(type()).bind("tl"))))), 1371 TU, Ctx); 1372 1373 EXPECT_EQ(BoundNodes.size(), 1u); 1374 1375 const auto *TL = BoundNodes[0].getNodeAs<TypeLoc>("tl"); 1376 auto Result = NodeIntrospection::GetLocations(*TL); 1377 1378 auto ExpectedLocations = 1379 FormatExpected<SourceLocation>(Result.LocationAccessors); 1380 1381 EXPECT_THAT(ExpectedLocations, 1382 UnorderedElementsAre( 1383 STRING_LOCATION_PAIR(TL, getBeginLoc()), 1384 STRING_LOCATION_PAIR(TL, getEndLoc()), 1385 STRING_LOCATION_PAIR( 1386 TL, getAs<clang::TypeOfExprTypeLoc>().getTypeofLoc()), 1387 STRING_LOCATION_PAIR( 1388 TL, getAs<clang::TypeOfExprTypeLoc>().getLParenLoc()), 1389 STRING_LOCATION_PAIR( 1390 TL, getAs<clang::TypeOfExprTypeLoc>().getRParenLoc()))); 1391 1392 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1393 1394 EXPECT_THAT(ExpectedRanges, 1395 UnorderedElementsAre( 1396 STRING_LOCATION_PAIR(TL, getLocalSourceRange()), 1397 STRING_LOCATION_PAIR(TL, getSourceRange()), 1398 STRING_LOCATION_PAIR( 1399 TL, getAs<clang::TypeOfExprTypeLoc>().getParensRange()))); 1400 } 1401 #endif 1402 1403 TEST(Introspection, SourceLocations_DeclarationNameInfo_Dtor) { 1404 if (!NodeIntrospection::hasIntrospectionSupport()) 1405 return; 1406 auto AST = 1407 buildASTFromCode(R"cpp( 1408 class Foo 1409 { 1410 ~Foo() {} 1411 }; 1412 )cpp", 1413 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1414 auto &Ctx = AST->getASTContext(); 1415 auto &TU = *Ctx.getTranslationUnitDecl(); 1416 1417 auto BoundNodes = ast_matchers::match( 1418 decl(hasDescendant(cxxDestructorDecl(hasName("~Foo")).bind("dtor"))), TU, 1419 Ctx); 1420 1421 EXPECT_EQ(BoundNodes.size(), 1u); 1422 1423 const auto *Dtor = BoundNodes[0].getNodeAs<CXXDestructorDecl>("dtor"); 1424 auto NI = Dtor->getNameInfo(); 1425 auto Result = NodeIntrospection::GetLocations(NI); 1426 1427 auto ExpectedLocations = 1428 FormatExpected<SourceLocation>(Result.LocationAccessors); 1429 1430 llvm::sort(ExpectedLocations); 1431 1432 // clang-format off 1433 EXPECT_EQ( 1434 llvm::makeArrayRef(ExpectedLocations), 1435 (ArrayRef<std::pair<std::string, SourceLocation>>{ 1436 STRING_LOCATION_STDPAIR((&NI), getBeginLoc()), 1437 STRING_LOCATION_STDPAIR((&NI), getEndLoc()), 1438 STRING_LOCATION_STDPAIR((&NI), getLoc()), 1439 STRING_LOCATION_STDPAIR((&NI), 1440 getNamedTypeInfo()->getTypeLoc().getAs<clang::TypeSpecTypeLoc>().getNameLoc()), 1441 STRING_LOCATION_STDPAIR( 1442 (&NI), getNamedTypeInfo()->getTypeLoc().getBeginLoc()), 1443 STRING_LOCATION_STDPAIR( 1444 (&NI), getNamedTypeInfo()->getTypeLoc().getEndLoc())})); 1445 // clang-format on 1446 1447 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1448 1449 EXPECT_THAT( 1450 ExpectedRanges, 1451 UnorderedElementsAre( 1452 STRING_LOCATION_PAIR( 1453 (&NI), getNamedTypeInfo()->getTypeLoc().getLocalSourceRange()), 1454 STRING_LOCATION_PAIR( 1455 (&NI), getNamedTypeInfo()->getTypeLoc().getSourceRange()), 1456 STRING_LOCATION_PAIR((&NI), getSourceRange()))); 1457 } 1458 1459 TEST(Introspection, SourceLocations_DeclarationNameInfo_CRef) { 1460 if (!NodeIntrospection::hasIntrospectionSupport()) 1461 return; 1462 1463 auto AST = buildASTFromCodeWithArgs( 1464 R"cpp( 1465 template<typename T> 1466 struct MyContainer 1467 { 1468 template <typename U> 1469 void pushBack(); 1470 }; 1471 1472 template<typename T> 1473 void foo() 1474 { 1475 MyContainer<T> mc; 1476 mc.template pushBack<int>(); 1477 } 1478 )cpp", 1479 {"-fno-delayed-template-parsing"}, "foo.cpp", "clang-tool", 1480 std::make_shared<PCHContainerOperations>()); 1481 1482 auto &Ctx = AST->getASTContext(); 1483 auto &TU = *Ctx.getTranslationUnitDecl(); 1484 1485 auto BoundNodes = ast_matchers::match( 1486 decl(hasDescendant(cxxDependentScopeMemberExpr(hasMemberName("pushBack")).bind("member"))), TU, 1487 Ctx); 1488 1489 EXPECT_EQ(BoundNodes.size(), 1u); 1490 1491 const auto *Member = BoundNodes[0].getNodeAs<CXXDependentScopeMemberExpr>("member"); 1492 auto Result = NodeIntrospection::GetLocations(Member); 1493 1494 auto ExpectedLocations = 1495 FormatExpected<SourceLocation>(Result.LocationAccessors); 1496 1497 llvm::sort(ExpectedLocations); 1498 1499 EXPECT_EQ( 1500 llvm::makeArrayRef(ExpectedLocations), 1501 (ArrayRef<std::pair<std::string, SourceLocation>>{ 1502 STRING_LOCATION_STDPAIR(Member, getBeginLoc()), 1503 STRING_LOCATION_STDPAIR(Member, getEndLoc()), 1504 STRING_LOCATION_STDPAIR(Member, getExprLoc()), 1505 STRING_LOCATION_STDPAIR(Member, getLAngleLoc()), 1506 STRING_LOCATION_STDPAIR(Member, getMemberLoc()), 1507 STRING_LOCATION_STDPAIR(Member, getMemberNameInfo().getBeginLoc()), 1508 STRING_LOCATION_STDPAIR(Member, getMemberNameInfo().getEndLoc()), 1509 STRING_LOCATION_STDPAIR(Member, getMemberNameInfo().getLoc()), 1510 STRING_LOCATION_STDPAIR(Member, getOperatorLoc()), 1511 STRING_LOCATION_STDPAIR(Member, getRAngleLoc()), 1512 STRING_LOCATION_STDPAIR(Member, getTemplateKeywordLoc()) 1513 })); 1514 1515 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1516 1517 EXPECT_THAT( 1518 ExpectedRanges, 1519 UnorderedElementsAre( 1520 STRING_LOCATION_PAIR(Member, getMemberNameInfo().getSourceRange()), 1521 STRING_LOCATION_PAIR(Member, getSourceRange()) 1522 )); 1523 } 1524 1525 TEST(Introspection, SourceLocations_DeclarationNameInfo_ConvOp) { 1526 if (!NodeIntrospection::hasIntrospectionSupport()) 1527 return; 1528 auto AST = 1529 buildASTFromCode(R"cpp( 1530 class Foo 1531 { 1532 bool operator==(const Foo&) const { return false; } 1533 }; 1534 )cpp", 1535 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1536 auto &Ctx = AST->getASTContext(); 1537 auto &TU = *Ctx.getTranslationUnitDecl(); 1538 1539 auto BoundNodes = ast_matchers::match( 1540 decl(hasDescendant(cxxMethodDecl().bind("opeq"))), TU, Ctx); 1541 1542 EXPECT_EQ(BoundNodes.size(), 1u); 1543 1544 const auto *Opeq = BoundNodes[0].getNodeAs<CXXMethodDecl>("opeq"); 1545 auto NI = Opeq->getNameInfo(); 1546 auto Result = NodeIntrospection::GetLocations(NI); 1547 1548 auto ExpectedLocations = 1549 FormatExpected<SourceLocation>(Result.LocationAccessors); 1550 1551 llvm::sort(ExpectedLocations); 1552 1553 EXPECT_EQ(llvm::makeArrayRef(ExpectedLocations), 1554 (ArrayRef<std::pair<std::string, SourceLocation>>{ 1555 STRING_LOCATION_STDPAIR((&NI), getBeginLoc()), 1556 STRING_LOCATION_STDPAIR((&NI), getEndLoc()), 1557 STRING_LOCATION_STDPAIR((&NI), getLoc())})); 1558 1559 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1560 1561 EXPECT_THAT(ExpectedRanges, 1562 UnorderedElementsAre( 1563 STRING_LOCATION_PAIR((&NI), getSourceRange()), 1564 STRING_LOCATION_PAIR((&NI), getCXXOperatorNameRange()))); 1565 } 1566 1567 TEST(Introspection, SourceLocations_DeclarationNameInfo_LitOp) { 1568 if (!NodeIntrospection::hasIntrospectionSupport()) 1569 return; 1570 auto AST = 1571 buildASTFromCode(R"cpp( 1572 long double operator"" _identity ( long double val ) 1573 { 1574 return val; 1575 } 1576 )cpp", 1577 "foo.cpp", std::make_shared<PCHContainerOperations>()); 1578 auto &Ctx = AST->getASTContext(); 1579 auto &TU = *Ctx.getTranslationUnitDecl(); 1580 1581 auto BoundNodes = ast_matchers::match( 1582 decl(hasDescendant(functionDecl().bind("litop"))), TU, Ctx); 1583 1584 EXPECT_EQ(BoundNodes.size(), 1u); 1585 1586 const auto *LitOp = BoundNodes[0].getNodeAs<FunctionDecl>("litop"); 1587 auto NI = LitOp->getNameInfo(); 1588 auto Result = NodeIntrospection::GetLocations(NI); 1589 1590 auto ExpectedLocations = 1591 FormatExpected<SourceLocation>(Result.LocationAccessors); 1592 1593 llvm::sort(ExpectedLocations); 1594 1595 EXPECT_EQ(llvm::makeArrayRef(ExpectedLocations), 1596 (ArrayRef<std::pair<std::string, SourceLocation>>{ 1597 STRING_LOCATION_STDPAIR((&NI), getBeginLoc()), 1598 STRING_LOCATION_STDPAIR((&NI), getCXXLiteralOperatorNameLoc()), 1599 STRING_LOCATION_STDPAIR((&NI), getEndLoc()), 1600 STRING_LOCATION_STDPAIR((&NI), getLoc())})); 1601 1602 auto ExpectedRanges = FormatExpected<SourceRange>(Result.RangeAccessors); 1603 1604 EXPECT_THAT(ExpectedRanges, UnorderedElementsAre(STRING_LOCATION_PAIR( 1605 (&NI), getSourceRange()))); 1606 } 1607