1 //===- ASTMatchersInternal.cpp - Structural query framework ---------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Implements the base layer of the matcher framework. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/ASTMatchers/ASTMatchersInternal.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTTypeTraits.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/AST/DeclTemplate.h" 19 #include "clang/AST/PrettyPrinter.h" 20 #include "clang/ASTMatchers/ASTMatchers.h" 21 #include "clang/Basic/LLVM.h" 22 #include "llvm/ADT/ArrayRef.h" 23 #include "llvm/ADT/IntrusiveRefCntPtr.h" 24 #include "llvm/ADT/None.h" 25 #include "llvm/ADT/SmallString.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/ADT/StringRef.h" 28 #include "llvm/Support/Casting.h" 29 #include "llvm/Support/ErrorHandling.h" 30 #include "llvm/Support/ManagedStatic.h" 31 #include "llvm/Support/raw_ostream.h" 32 #include <algorithm> 33 #include <cassert> 34 #include <cstddef> 35 #include <string> 36 #include <utility> 37 #include <vector> 38 39 namespace clang { 40 namespace ast_matchers { 41 namespace internal { 42 43 bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode, 44 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, 45 ArrayRef<DynTypedMatcher> InnerMatchers); 46 47 bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, 48 ASTMatchFinder *Finder, 49 BoundNodesTreeBuilder *Builder, 50 ArrayRef<DynTypedMatcher> InnerMatchers); 51 52 bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, 53 ASTMatchFinder *Finder, 54 BoundNodesTreeBuilder *Builder, 55 ArrayRef<DynTypedMatcher> InnerMatchers); 56 57 bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, 58 ASTMatchFinder *Finder, 59 BoundNodesTreeBuilder *Builder, 60 ArrayRef<DynTypedMatcher> InnerMatchers); 61 62 void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) { 63 if (Bindings.empty()) 64 Bindings.push_back(BoundNodesMap()); 65 for (BoundNodesMap &Binding : Bindings) { 66 ResultVisitor->visitMatch(BoundNodes(Binding)); 67 } 68 } 69 70 namespace { 71 72 using VariadicOperatorFunction = bool (*)( 73 const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder, 74 BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers); 75 76 template <VariadicOperatorFunction Func> 77 class VariadicMatcher : public DynMatcherInterface { 78 public: 79 VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers) 80 : InnerMatchers(std::move(InnerMatchers)) {} 81 82 bool dynMatches(const ast_type_traits::DynTypedNode &DynNode, 83 ASTMatchFinder *Finder, 84 BoundNodesTreeBuilder *Builder) const override { 85 return Func(DynNode, Finder, Builder, InnerMatchers); 86 } 87 88 private: 89 std::vector<DynTypedMatcher> InnerMatchers; 90 }; 91 92 class IdDynMatcher : public DynMatcherInterface { 93 public: 94 IdDynMatcher(StringRef ID, 95 IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher) 96 : ID(ID), InnerMatcher(std::move(InnerMatcher)) {} 97 98 bool dynMatches(const ast_type_traits::DynTypedNode &DynNode, 99 ASTMatchFinder *Finder, 100 BoundNodesTreeBuilder *Builder) const override { 101 bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder); 102 if (Result) Builder->setBinding(ID, DynNode); 103 return Result; 104 } 105 106 private: 107 const std::string ID; 108 const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher; 109 }; 110 111 /// \brief A matcher that always returns true. 112 /// 113 /// We only ever need one instance of this matcher, so we create a global one 114 /// and reuse it to reduce the overhead of the matcher and increase the chance 115 /// of cache hits. 116 class TrueMatcherImpl : public DynMatcherInterface { 117 public: 118 TrueMatcherImpl() { 119 Retain(); // Reference count will never become zero. 120 } 121 122 bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *, 123 BoundNodesTreeBuilder *) const override { 124 return true; 125 } 126 }; 127 128 } // namespace 129 130 static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance; 131 132 DynTypedMatcher DynTypedMatcher::constructVariadic( 133 DynTypedMatcher::VariadicOperator Op, 134 ast_type_traits::ASTNodeKind SupportedKind, 135 std::vector<DynTypedMatcher> InnerMatchers) { 136 assert(!InnerMatchers.empty() && "Array must not be empty."); 137 assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(), 138 [SupportedKind](const DynTypedMatcher &M) { 139 return M.canConvertTo(SupportedKind); 140 }) && 141 "InnerMatchers must be convertible to SupportedKind!"); 142 143 // We must relax the restrict kind here. 144 // The different operators might deal differently with a mismatch. 145 // Make it the same as SupportedKind, since that is the broadest type we are 146 // allowed to accept. 147 auto RestrictKind = SupportedKind; 148 149 switch (Op) { 150 case VO_AllOf: 151 // In the case of allOf() we must pass all the checks, so making 152 // RestrictKind the most restrictive can save us time. This way we reject 153 // invalid types earlier and we can elide the kind checks inside the 154 // matcher. 155 for (auto &IM : InnerMatchers) { 156 RestrictKind = ast_type_traits::ASTNodeKind::getMostDerivedType( 157 RestrictKind, IM.RestrictKind); 158 } 159 return DynTypedMatcher( 160 SupportedKind, RestrictKind, 161 new VariadicMatcher<AllOfVariadicOperator>(std::move(InnerMatchers))); 162 163 case VO_AnyOf: 164 return DynTypedMatcher( 165 SupportedKind, RestrictKind, 166 new VariadicMatcher<AnyOfVariadicOperator>(std::move(InnerMatchers))); 167 168 case VO_EachOf: 169 return DynTypedMatcher( 170 SupportedKind, RestrictKind, 171 new VariadicMatcher<EachOfVariadicOperator>(std::move(InnerMatchers))); 172 173 case VO_UnaryNot: 174 // FIXME: Implement the Not operator to take a single matcher instead of a 175 // vector. 176 return DynTypedMatcher( 177 SupportedKind, RestrictKind, 178 new VariadicMatcher<NotUnaryOperator>(std::move(InnerMatchers))); 179 } 180 llvm_unreachable("Invalid Op value."); 181 } 182 183 DynTypedMatcher DynTypedMatcher::trueMatcher( 184 ast_type_traits::ASTNodeKind NodeKind) { 185 return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance); 186 } 187 188 bool DynTypedMatcher::canMatchNodesOfKind( 189 ast_type_traits::ASTNodeKind Kind) const { 190 return RestrictKind.isBaseOf(Kind); 191 } 192 193 DynTypedMatcher DynTypedMatcher::dynCastTo( 194 const ast_type_traits::ASTNodeKind Kind) const { 195 auto Copy = *this; 196 Copy.SupportedKind = Kind; 197 Copy.RestrictKind = 198 ast_type_traits::ASTNodeKind::getMostDerivedType(Kind, RestrictKind); 199 return Copy; 200 } 201 202 bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode, 203 ASTMatchFinder *Finder, 204 BoundNodesTreeBuilder *Builder) const { 205 if (RestrictKind.isBaseOf(DynNode.getNodeKind()) && 206 Implementation->dynMatches(DynNode, Finder, Builder)) { 207 return true; 208 } 209 // Delete all bindings when a matcher does not match. 210 // This prevents unexpected exposure of bound nodes in unmatches 211 // branches of the match tree. 212 Builder->removeBindings([](const BoundNodesMap &) { return true; }); 213 return false; 214 } 215 216 bool DynTypedMatcher::matchesNoKindCheck( 217 const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder, 218 BoundNodesTreeBuilder *Builder) const { 219 assert(RestrictKind.isBaseOf(DynNode.getNodeKind())); 220 if (Implementation->dynMatches(DynNode, Finder, Builder)) { 221 return true; 222 } 223 // Delete all bindings when a matcher does not match. 224 // This prevents unexpected exposure of bound nodes in unmatches 225 // branches of the match tree. 226 Builder->removeBindings([](const BoundNodesMap &) { return true; }); 227 return false; 228 } 229 230 llvm::Optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const { 231 if (!AllowBind) return llvm::None; 232 auto Result = *this; 233 Result.Implementation = 234 new IdDynMatcher(ID, std::move(Result.Implementation)); 235 return std::move(Result); 236 } 237 238 bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const { 239 const auto From = getSupportedKind(); 240 auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>(); 241 auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>(); 242 /// Mimic the implicit conversions of Matcher<>. 243 /// - From Matcher<Type> to Matcher<QualType> 244 if (From.isSame(TypeKind) && To.isSame(QualKind)) return true; 245 /// - From Matcher<Base> to Matcher<Derived> 246 return From.isBaseOf(To); 247 } 248 249 void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) { 250 Bindings.append(Other.Bindings.begin(), Other.Bindings.end()); 251 } 252 253 bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode, 254 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, 255 ArrayRef<DynTypedMatcher> InnerMatchers) { 256 if (InnerMatchers.size() != 1) 257 return false; 258 259 // The 'unless' matcher will always discard the result: 260 // If the inner matcher doesn't match, unless returns true, 261 // but the inner matcher cannot have bound anything. 262 // If the inner matcher matches, the result is false, and 263 // any possible binding will be discarded. 264 // We still need to hand in all the bound nodes up to this 265 // point so the inner matcher can depend on bound nodes, 266 // and we need to actively discard the bound nodes, otherwise 267 // the inner matcher will reset the bound nodes if it doesn't 268 // match, but this would be inversed by 'unless'. 269 BoundNodesTreeBuilder Discard(*Builder); 270 return !InnerMatchers[0].matches(DynNode, Finder, &Discard); 271 } 272 273 bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, 274 ASTMatchFinder *Finder, 275 BoundNodesTreeBuilder *Builder, 276 ArrayRef<DynTypedMatcher> InnerMatchers) { 277 // allOf leads to one matcher for each alternative in the first 278 // matcher combined with each alternative in the second matcher. 279 // Thus, we can reuse the same Builder. 280 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) { 281 if (!InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder)) 282 return false; 283 } 284 return true; 285 } 286 287 bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, 288 ASTMatchFinder *Finder, 289 BoundNodesTreeBuilder *Builder, 290 ArrayRef<DynTypedMatcher> InnerMatchers) { 291 BoundNodesTreeBuilder Result; 292 bool Matched = false; 293 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) { 294 BoundNodesTreeBuilder BuilderInner(*Builder); 295 if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) { 296 Matched = true; 297 Result.addMatch(BuilderInner); 298 } 299 } 300 *Builder = std::move(Result); 301 return Matched; 302 } 303 304 bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode, 305 ASTMatchFinder *Finder, 306 BoundNodesTreeBuilder *Builder, 307 ArrayRef<DynTypedMatcher> InnerMatchers) { 308 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) { 309 BoundNodesTreeBuilder Result = *Builder; 310 if (InnerMatcher.matches(DynNode, Finder, &Result)) { 311 *Builder = std::move(Result); 312 return true; 313 } 314 } 315 return false; 316 } 317 318 Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs) { 319 std::vector<std::string> Names; 320 for (auto *Name : NameRefs) 321 Names.emplace_back(*Name); 322 return internal::Matcher<NamedDecl>( 323 new internal::HasNameMatcher(std::move(Names))); 324 } 325 326 HasNameMatcher::HasNameMatcher(std::vector<std::string> N) 327 : UseUnqualifiedMatch(std::all_of( 328 N.begin(), N.end(), 329 [](StringRef Name) { return Name.find("::") == Name.npos; })), 330 Names(std::move(N)) { 331 #ifndef NDEBUG 332 for (StringRef Name : Names) 333 assert(!Name.empty()); 334 #endif 335 } 336 337 static bool consumeNameSuffix(StringRef &FullName, StringRef Suffix) { 338 StringRef Name = FullName; 339 if (!Name.endswith(Suffix)) 340 return false; 341 Name = Name.drop_back(Suffix.size()); 342 if (!Name.empty()) { 343 if (!Name.endswith("::")) 344 return false; 345 Name = Name.drop_back(2); 346 } 347 FullName = Name; 348 return true; 349 } 350 351 static StringRef getNodeName(const NamedDecl &Node, 352 llvm::SmallString<128> &Scratch) { 353 // Simple name. 354 if (Node.getIdentifier()) 355 return Node.getName(); 356 357 if (Node.getDeclName()) { 358 // Name needs to be constructed. 359 Scratch.clear(); 360 llvm::raw_svector_ostream OS(Scratch); 361 Node.printName(OS); 362 return OS.str(); 363 } 364 365 return "(anonymous)"; 366 } 367 368 static StringRef getNodeName(const RecordDecl &Node, 369 llvm::SmallString<128> &Scratch) { 370 if (Node.getIdentifier()) { 371 return Node.getName(); 372 } 373 Scratch.clear(); 374 return ("(anonymous " + Node.getKindName() + ")").toStringRef(Scratch); 375 } 376 377 static StringRef getNodeName(const NamespaceDecl &Node, 378 llvm::SmallString<128> &Scratch) { 379 return Node.isAnonymousNamespace() ? "(anonymous namespace)" : Node.getName(); 380 } 381 382 namespace { 383 384 class PatternSet { 385 public: 386 PatternSet(ArrayRef<std::string> Names) { 387 for (StringRef Name : Names) 388 Patterns.push_back({Name, Name.startswith("::")}); 389 } 390 391 /// Consumes the name suffix from each pattern in the set and removes the ones 392 /// that didn't match. 393 /// Return true if there are still any patterns left. 394 bool consumeNameSuffix(StringRef NodeName, bool CanSkip) { 395 for (size_t I = 0; I < Patterns.size();) { 396 if (internal::consumeNameSuffix(Patterns[I].P, NodeName) || 397 CanSkip) { 398 ++I; 399 } else { 400 Patterns.erase(Patterns.begin() + I); 401 } 402 } 403 return !Patterns.empty(); 404 } 405 406 /// Check if any of the patterns are a match. 407 /// A match will be a pattern that was fully consumed, that also matches the 408 /// 'fully qualified' requirement. 409 bool foundMatch(bool AllowFullyQualified) const { 410 for (auto& P: Patterns) 411 if (P.P.empty() && (AllowFullyQualified || !P.IsFullyQualified)) 412 return true; 413 return false; 414 } 415 416 private: 417 struct Pattern { 418 StringRef P; 419 bool IsFullyQualified; 420 }; 421 422 llvm::SmallVector<Pattern, 8> Patterns; 423 }; 424 425 } // namespace 426 427 bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const { 428 assert(UseUnqualifiedMatch); 429 llvm::SmallString<128> Scratch; 430 StringRef NodeName = getNodeName(Node, Scratch); 431 return std::any_of(Names.begin(), Names.end(), [&](StringRef Name) { 432 return consumeNameSuffix(Name, NodeName) && Name.empty(); 433 }); 434 } 435 436 bool HasNameMatcher::matchesNodeFullFast(const NamedDecl &Node) const { 437 PatternSet Patterns(Names); 438 llvm::SmallString<128> Scratch; 439 440 // This function is copied and adapted from NamedDecl::printQualifiedName() 441 // By matching each part individually we optimize in a couple of ways: 442 // - We can exit early on the first failure. 443 // - We can skip inline/anonymous namespaces without another pass. 444 // - We print one name at a time, reducing the chance of overflowing the 445 // inlined space of the SmallString. 446 447 // First, match the name. 448 if (!Patterns.consumeNameSuffix(getNodeName(Node, Scratch), 449 /*CanSkip=*/false)) 450 return false; 451 452 // Try to match each declaration context. 453 // We are allowed to skip anonymous and inline namespaces if they don't match. 454 const DeclContext *Ctx = Node.getDeclContext(); 455 456 if (Ctx->isFunctionOrMethod()) 457 return Patterns.foundMatch(/*AllowFullyQualified=*/false); 458 459 for (; Ctx && isa<NamedDecl>(Ctx); Ctx = Ctx->getParent()) { 460 if (Patterns.foundMatch(/*AllowFullyQualified=*/false)) 461 return true; 462 463 if (const auto *ND = dyn_cast<NamespaceDecl>(Ctx)) { 464 // If it matches (or we can skip it), continue. 465 if (Patterns.consumeNameSuffix(getNodeName(*ND, Scratch), 466 /*CanSkip=*/ND->isAnonymousNamespace() || 467 ND->isInline())) 468 continue; 469 return false; 470 } 471 if (const auto *RD = dyn_cast<RecordDecl>(Ctx)) { 472 if (!isa<ClassTemplateSpecializationDecl>(Ctx)) { 473 if (Patterns.consumeNameSuffix(getNodeName(*RD, Scratch), 474 /*CanSkip=*/false)) 475 continue; 476 477 return false; 478 } 479 } 480 481 // We don't know how to deal with this DeclContext. 482 // Fallback to the slow version of the code. 483 return matchesNodeFullSlow(Node); 484 } 485 486 return Patterns.foundMatch(/*AllowFullyQualified=*/true); 487 } 488 489 bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const { 490 const bool SkipUnwrittenCases[] = {false, true}; 491 for (bool SkipUnwritten : SkipUnwrittenCases) { 492 llvm::SmallString<128> NodeName = StringRef("::"); 493 llvm::raw_svector_ostream OS(NodeName); 494 495 if (SkipUnwritten) { 496 PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy(); 497 Policy.SuppressUnwrittenScope = true; 498 Node.printQualifiedName(OS, Policy); 499 } else { 500 Node.printQualifiedName(OS); 501 } 502 503 const StringRef FullName = OS.str(); 504 505 for (const StringRef Pattern : Names) { 506 if (Pattern.startswith("::")) { 507 if (FullName == Pattern) 508 return true; 509 } else if (FullName.endswith(Pattern) && 510 FullName.drop_back(Pattern.size()).endswith("::")) { 511 return true; 512 } 513 } 514 } 515 516 return false; 517 } 518 519 bool HasNameMatcher::matchesNode(const NamedDecl &Node) const { 520 assert(matchesNodeFullFast(Node) == matchesNodeFullSlow(Node)); 521 if (UseUnqualifiedMatch) { 522 assert(matchesNodeUnqualified(Node) == matchesNodeFullFast(Node)); 523 return matchesNodeUnqualified(Node); 524 } 525 return matchesNodeFullFast(Node); 526 } 527 528 } // end namespace internal 529 } // end namespace ast_matchers 530 } // end namespace clang 531