ASTMatchersInternal.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  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. #include "clang/ASTMatchers/ASTMatchers.h"
  14. #include "clang/ASTMatchers/ASTMatchersInternal.h"
  15. #include "llvm/ADT/SmallString.h"
  16. #include "llvm/Support/ManagedStatic.h"
  17. namespace clang {
  18. namespace ast_matchers {
  19. namespace internal {
  20. bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
  21. ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
  22. ArrayRef<DynTypedMatcher> InnerMatchers);
  23. bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
  24. ASTMatchFinder *Finder,
  25. BoundNodesTreeBuilder *Builder,
  26. ArrayRef<DynTypedMatcher> InnerMatchers);
  27. bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
  28. ASTMatchFinder *Finder,
  29. BoundNodesTreeBuilder *Builder,
  30. ArrayRef<DynTypedMatcher> InnerMatchers);
  31. bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
  32. ASTMatchFinder *Finder,
  33. BoundNodesTreeBuilder *Builder,
  34. ArrayRef<DynTypedMatcher> InnerMatchers);
  35. void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) {
  36. if (Bindings.empty())
  37. Bindings.push_back(BoundNodesMap());
  38. for (BoundNodesMap &Binding : Bindings) {
  39. ResultVisitor->visitMatch(BoundNodes(Binding));
  40. }
  41. }
  42. namespace {
  43. typedef bool (*VariadicOperatorFunction)(
  44. const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
  45. BoundNodesTreeBuilder *Builder, ArrayRef<DynTypedMatcher> InnerMatchers);
  46. template <VariadicOperatorFunction Func>
  47. class VariadicMatcher : public DynMatcherInterface {
  48. public:
  49. VariadicMatcher(std::vector<DynTypedMatcher> InnerMatchers)
  50. : InnerMatchers(std::move(InnerMatchers)) {}
  51. bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
  52. ASTMatchFinder *Finder,
  53. BoundNodesTreeBuilder *Builder) const override {
  54. return Func(DynNode, Finder, Builder, InnerMatchers);
  55. }
  56. private:
  57. std::vector<DynTypedMatcher> InnerMatchers;
  58. };
  59. class IdDynMatcher : public DynMatcherInterface {
  60. public:
  61. IdDynMatcher(StringRef ID,
  62. const IntrusiveRefCntPtr<DynMatcherInterface> &InnerMatcher)
  63. : ID(ID), InnerMatcher(InnerMatcher) {}
  64. bool dynMatches(const ast_type_traits::DynTypedNode &DynNode,
  65. ASTMatchFinder *Finder,
  66. BoundNodesTreeBuilder *Builder) const override {
  67. bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder);
  68. if (Result) Builder->setBinding(ID, DynNode);
  69. return Result;
  70. }
  71. private:
  72. const std::string ID;
  73. const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher;
  74. };
  75. /// \brief A matcher that always returns true.
  76. ///
  77. /// We only ever need one instance of this matcher, so we create a global one
  78. /// and reuse it to reduce the overhead of the matcher and increase the chance
  79. /// of cache hits.
  80. class TrueMatcherImpl : public DynMatcherInterface {
  81. public:
  82. TrueMatcherImpl() {
  83. Retain(); // Reference count will never become zero.
  84. }
  85. bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *,
  86. BoundNodesTreeBuilder *) const override {
  87. return true;
  88. }
  89. };
  90. static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance;
  91. } // namespace
  92. DynTypedMatcher DynTypedMatcher::constructVariadic(
  93. DynTypedMatcher::VariadicOperator Op,
  94. std::vector<DynTypedMatcher> InnerMatchers) {
  95. assert(InnerMatchers.size() > 0 && "Array must not be empty.");
  96. assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(),
  97. [&InnerMatchers](const DynTypedMatcher &M) {
  98. return InnerMatchers[0].canConvertTo(M.SupportedKind);
  99. }) &&
  100. "SupportedKind must be convertible to a common type!");
  101. auto SupportedKind = InnerMatchers[0].SupportedKind;
  102. // We must relax the restrict kind here.
  103. // The different operators might deal differently with a mismatch.
  104. // Make it the same as SupportedKind, since that is the broadest type we are
  105. // allowed to accept.
  106. auto RestrictKind = SupportedKind;
  107. switch (Op) {
  108. case VO_AllOf:
  109. // In the case of allOf() we must pass all the checks, so making
  110. // RestrictKind the most restrictive can save us time. This way we reject
  111. // invalid types earlier and we can elide the kind checks inside the
  112. // matcher.
  113. for (auto &IM : InnerMatchers) {
  114. RestrictKind = ast_type_traits::ASTNodeKind::getMostDerivedType(
  115. RestrictKind, IM.RestrictKind);
  116. }
  117. return DynTypedMatcher(
  118. SupportedKind, RestrictKind,
  119. new VariadicMatcher<AllOfVariadicOperator>(std::move(InnerMatchers)));
  120. case VO_AnyOf:
  121. return DynTypedMatcher(
  122. SupportedKind, RestrictKind,
  123. new VariadicMatcher<AnyOfVariadicOperator>(std::move(InnerMatchers)));
  124. case VO_EachOf:
  125. return DynTypedMatcher(
  126. SupportedKind, RestrictKind,
  127. new VariadicMatcher<EachOfVariadicOperator>(std::move(InnerMatchers)));
  128. case VO_UnaryNot:
  129. // FIXME: Implement the Not operator to take a single matcher instead of a
  130. // vector.
  131. return DynTypedMatcher(
  132. SupportedKind, RestrictKind,
  133. new VariadicMatcher<NotUnaryOperator>(std::move(InnerMatchers)));
  134. }
  135. llvm_unreachable("Invalid Op value.");
  136. }
  137. DynTypedMatcher DynTypedMatcher::trueMatcher(
  138. ast_type_traits::ASTNodeKind NodeKind) {
  139. return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance);
  140. }
  141. bool DynTypedMatcher::canMatchNodesOfKind(
  142. ast_type_traits::ASTNodeKind Kind) const {
  143. return RestrictKind.isBaseOf(Kind);
  144. }
  145. DynTypedMatcher DynTypedMatcher::dynCastTo(
  146. const ast_type_traits::ASTNodeKind Kind) const {
  147. auto Copy = *this;
  148. Copy.SupportedKind = Kind;
  149. Copy.RestrictKind =
  150. ast_type_traits::ASTNodeKind::getMostDerivedType(Kind, RestrictKind);
  151. return Copy;
  152. }
  153. bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode,
  154. ASTMatchFinder *Finder,
  155. BoundNodesTreeBuilder *Builder) const {
  156. if (RestrictKind.isBaseOf(DynNode.getNodeKind()) &&
  157. Implementation->dynMatches(DynNode, Finder, Builder)) {
  158. return true;
  159. }
  160. // Delete all bindings when a matcher does not match.
  161. // This prevents unexpected exposure of bound nodes in unmatches
  162. // branches of the match tree.
  163. Builder->removeBindings([](const BoundNodesMap &) { return true; });
  164. return false;
  165. }
  166. bool DynTypedMatcher::matchesNoKindCheck(
  167. const ast_type_traits::DynTypedNode &DynNode, ASTMatchFinder *Finder,
  168. BoundNodesTreeBuilder *Builder) const {
  169. assert(RestrictKind.isBaseOf(DynNode.getNodeKind()));
  170. if (Implementation->dynMatches(DynNode, Finder, Builder)) {
  171. return true;
  172. }
  173. // Delete all bindings when a matcher does not match.
  174. // This prevents unexpected exposure of bound nodes in unmatches
  175. // branches of the match tree.
  176. Builder->removeBindings([](const BoundNodesMap &) { return true; });
  177. return false;
  178. }
  179. llvm::Optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const {
  180. if (!AllowBind) return llvm::None;
  181. auto Result = *this;
  182. Result.Implementation = new IdDynMatcher(ID, Result.Implementation);
  183. return Result;
  184. }
  185. bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const {
  186. const auto From = getSupportedKind();
  187. auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>();
  188. auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>();
  189. /// Mimic the implicit conversions of Matcher<>.
  190. /// - From Matcher<Type> to Matcher<QualType>
  191. if (From.isSame(TypeKind) && To.isSame(QualKind)) return true;
  192. /// - From Matcher<Base> to Matcher<Derived>
  193. return From.isBaseOf(To);
  194. }
  195. void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) {
  196. Bindings.append(Other.Bindings.begin(), Other.Bindings.end());
  197. }
  198. bool NotUnaryOperator(const ast_type_traits::DynTypedNode &DynNode,
  199. ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
  200. ArrayRef<DynTypedMatcher> InnerMatchers) {
  201. if (InnerMatchers.size() != 1)
  202. return false;
  203. // The 'unless' matcher will always discard the result:
  204. // If the inner matcher doesn't match, unless returns true,
  205. // but the inner matcher cannot have bound anything.
  206. // If the inner matcher matches, the result is false, and
  207. // any possible binding will be discarded.
  208. // We still need to hand in all the bound nodes up to this
  209. // point so the inner matcher can depend on bound nodes,
  210. // and we need to actively discard the bound nodes, otherwise
  211. // the inner matcher will reset the bound nodes if it doesn't
  212. // match, but this would be inversed by 'unless'.
  213. BoundNodesTreeBuilder Discard(*Builder);
  214. return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
  215. }
  216. bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
  217. ASTMatchFinder *Finder,
  218. BoundNodesTreeBuilder *Builder,
  219. ArrayRef<DynTypedMatcher> InnerMatchers) {
  220. // allOf leads to one matcher for each alternative in the first
  221. // matcher combined with each alternative in the second matcher.
  222. // Thus, we can reuse the same Builder.
  223. for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
  224. if (!InnerMatcher.matchesNoKindCheck(DynNode, Finder, Builder))
  225. return false;
  226. }
  227. return true;
  228. }
  229. bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
  230. ASTMatchFinder *Finder,
  231. BoundNodesTreeBuilder *Builder,
  232. ArrayRef<DynTypedMatcher> InnerMatchers) {
  233. BoundNodesTreeBuilder Result;
  234. bool Matched = false;
  235. for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
  236. BoundNodesTreeBuilder BuilderInner(*Builder);
  237. if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) {
  238. Matched = true;
  239. Result.addMatch(BuilderInner);
  240. }
  241. }
  242. *Builder = std::move(Result);
  243. return Matched;
  244. }
  245. bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode &DynNode,
  246. ASTMatchFinder *Finder,
  247. BoundNodesTreeBuilder *Builder,
  248. ArrayRef<DynTypedMatcher> InnerMatchers) {
  249. for (const DynTypedMatcher &InnerMatcher : InnerMatchers) {
  250. BoundNodesTreeBuilder Result = *Builder;
  251. if (InnerMatcher.matches(DynNode, Finder, &Result)) {
  252. *Builder = std::move(Result);
  253. return true;
  254. }
  255. }
  256. return false;
  257. }
  258. HasNameMatcher::HasNameMatcher(StringRef NameRef)
  259. : UseUnqualifiedMatch(NameRef.find("::") == NameRef.npos), Name(NameRef) {
  260. assert(!Name.empty());
  261. }
  262. bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const {
  263. assert(UseUnqualifiedMatch);
  264. if (Node.getIdentifier()) {
  265. // Simple name.
  266. return Name == Node.getName();
  267. }
  268. if (Node.getDeclName()) {
  269. // Name needs to be constructed.
  270. llvm::SmallString<128> NodeName;
  271. llvm::raw_svector_ostream OS(NodeName);
  272. Node.printName(OS);
  273. return Name == OS.str();
  274. }
  275. return false;
  276. }
  277. bool HasNameMatcher::matchesNodeFull(const NamedDecl &Node) const {
  278. llvm::SmallString<128> NodeName = StringRef("::");
  279. llvm::raw_svector_ostream OS(NodeName);
  280. Node.printQualifiedName(OS);
  281. const StringRef FullName = OS.str();
  282. const StringRef Pattern = Name;
  283. if (Pattern.startswith("::"))
  284. return FullName == Pattern;
  285. return FullName.endswith(Pattern) &&
  286. FullName.drop_back(Pattern.size()).endswith("::");
  287. }
  288. bool HasNameMatcher::matchesNode(const NamedDecl &Node) const {
  289. // FIXME: There is still room for improvement, but it would require copying a
  290. // lot of the logic from NamedDecl::printQualifiedName(). The benchmarks do
  291. // not show like that extra complexity is needed right now.
  292. if (UseUnqualifiedMatch) {
  293. assert(matchesNodeUnqualified(Node) == matchesNodeFull(Node));
  294. return matchesNodeUnqualified(Node);
  295. }
  296. return matchesNodeFull(Node);
  297. }
  298. } // end namespace internal
  299. } // end namespace ast_matchers
  300. } // end namespace clang