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