clang API Documentation
00001 //===--- ASTMatchersInternal.cpp - Structural query framework -------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Implements the base layer of the matcher framework. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/ASTMatchers/ASTMatchers.h" 00015 #include "clang/ASTMatchers/ASTMatchersInternal.h" 00016 #include "llvm/ADT/SmallString.h" 00017 #include "llvm/Support/ManagedStatic.h" 00018 00019 namespace clang { 00020 namespace ast_matchers { 00021 namespace internal { 00022 00023 void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) { 00024 if (Bindings.empty()) 00025 Bindings.push_back(BoundNodesMap()); 00026 for (BoundNodesMap &Binding : Bindings) { 00027 ResultVisitor->visitMatch(BoundNodes(Binding)); 00028 } 00029 } 00030 00031 namespace { 00032 00033 class VariadicMatcher : public DynMatcherInterface { 00034 public: 00035 VariadicMatcher(DynTypedMatcher::VariadicOperatorFunction Func, 00036 std::vector<DynTypedMatcher> InnerMatchers) 00037 : Func(Func), InnerMatchers(std::move(InnerMatchers)) {} 00038 00039 bool dynMatches(const ast_type_traits::DynTypedNode &DynNode, 00040 ASTMatchFinder *Finder, 00041 BoundNodesTreeBuilder *Builder) const override { 00042 return Func(DynNode, Finder, Builder, InnerMatchers); 00043 } 00044 00045 private: 00046 DynTypedMatcher::VariadicOperatorFunction Func; 00047 std::vector<DynTypedMatcher> InnerMatchers; 00048 }; 00049 00050 class IdDynMatcher : public DynMatcherInterface { 00051 public: 00052 IdDynMatcher(StringRef ID, 00053 const IntrusiveRefCntPtr<DynMatcherInterface> &InnerMatcher) 00054 : ID(ID), InnerMatcher(InnerMatcher) {} 00055 00056 bool dynMatches(const ast_type_traits::DynTypedNode &DynNode, 00057 ASTMatchFinder *Finder, 00058 BoundNodesTreeBuilder *Builder) const override { 00059 bool Result = InnerMatcher->dynMatches(DynNode, Finder, Builder); 00060 if (Result) Builder->setBinding(ID, DynNode); 00061 return Result; 00062 } 00063 00064 private: 00065 const std::string ID; 00066 const IntrusiveRefCntPtr<DynMatcherInterface> InnerMatcher; 00067 }; 00068 00069 /// \brief A matcher that always returns true. 00070 /// 00071 /// We only ever need one instance of this matcher, so we create a global one 00072 /// and reuse it to reduce the overhead of the matcher and increase the chance 00073 /// of cache hits. 00074 class TrueMatcherImpl : public DynMatcherInterface { 00075 public: 00076 TrueMatcherImpl() { 00077 Retain(); // Reference count will never become zero. 00078 } 00079 bool dynMatches(const ast_type_traits::DynTypedNode &, ASTMatchFinder *, 00080 BoundNodesTreeBuilder *) const override { 00081 return true; 00082 } 00083 }; 00084 static llvm::ManagedStatic<TrueMatcherImpl> TrueMatcherInstance; 00085 00086 } // namespace 00087 00088 DynTypedMatcher DynTypedMatcher::constructVariadic( 00089 DynTypedMatcher::VariadicOperatorFunction Func, 00090 std::vector<DynTypedMatcher> InnerMatchers) { 00091 assert(InnerMatchers.size() > 0 && "Array must not be empty."); 00092 assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(), 00093 [&InnerMatchers](const DynTypedMatcher &M) { 00094 return InnerMatchers[0].SupportedKind.isSame(M.SupportedKind); 00095 }) && 00096 "SupportedKind must match!"); 00097 00098 // We must relax the restrict kind here. 00099 // The different operators might deal differently with a mismatch. 00100 // Make it the same as SupportedKind, since that is the broadest type we are 00101 // allowed to accept. 00102 auto SupportedKind = InnerMatchers[0].SupportedKind; 00103 return DynTypedMatcher(SupportedKind, SupportedKind, 00104 new VariadicMatcher(Func, std::move(InnerMatchers))); 00105 } 00106 00107 DynTypedMatcher DynTypedMatcher::trueMatcher( 00108 ast_type_traits::ASTNodeKind NodeKind) { 00109 return DynTypedMatcher(NodeKind, NodeKind, &*TrueMatcherInstance); 00110 } 00111 00112 DynTypedMatcher DynTypedMatcher::dynCastTo( 00113 const ast_type_traits::ASTNodeKind Kind) const { 00114 auto Copy = *this; 00115 Copy.SupportedKind = Kind; 00116 Copy.RestrictKind = 00117 ast_type_traits::ASTNodeKind::getMostDerivedType(Kind, RestrictKind); 00118 return Copy; 00119 } 00120 00121 bool DynTypedMatcher::matches(const ast_type_traits::DynTypedNode &DynNode, 00122 ASTMatchFinder *Finder, 00123 BoundNodesTreeBuilder *Builder) const { 00124 if (RestrictKind.isBaseOf(DynNode.getNodeKind()) && 00125 Implementation->dynMatches(DynNode, Finder, Builder)) { 00126 return true; 00127 } 00128 // Delete all bindings when a matcher does not match. 00129 // This prevents unexpected exposure of bound nodes in unmatches 00130 // branches of the match tree. 00131 Builder->removeBindings([](const BoundNodesMap &) { return true; }); 00132 return false; 00133 } 00134 00135 llvm::Optional<DynTypedMatcher> DynTypedMatcher::tryBind(StringRef ID) const { 00136 if (!AllowBind) return llvm::None; 00137 auto Result = *this; 00138 Result.Implementation = new IdDynMatcher(ID, Result.Implementation); 00139 return Result; 00140 } 00141 00142 bool DynTypedMatcher::canConvertTo(ast_type_traits::ASTNodeKind To) const { 00143 const auto From = getSupportedKind(); 00144 auto QualKind = ast_type_traits::ASTNodeKind::getFromNodeKind<QualType>(); 00145 auto TypeKind = ast_type_traits::ASTNodeKind::getFromNodeKind<Type>(); 00146 /// Mimic the implicit conversions of Matcher<>. 00147 /// - From Matcher<Type> to Matcher<QualType> 00148 if (From.isSame(TypeKind) && To.isSame(QualKind)) return true; 00149 /// - From Matcher<Base> to Matcher<Derived> 00150 return From.isBaseOf(To); 00151 } 00152 00153 void BoundNodesTreeBuilder::addMatch(const BoundNodesTreeBuilder &Other) { 00154 Bindings.append(Other.Bindings.begin(), Other.Bindings.end()); 00155 } 00156 00157 bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode, 00158 ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, 00159 ArrayRef<DynTypedMatcher> InnerMatchers) { 00160 if (InnerMatchers.size() != 1) 00161 return false; 00162 00163 // The 'unless' matcher will always discard the result: 00164 // If the inner matcher doesn't match, unless returns true, 00165 // but the inner matcher cannot have bound anything. 00166 // If the inner matcher matches, the result is false, and 00167 // any possible binding will be discarded. 00168 // We still need to hand in all the bound nodes up to this 00169 // point so the inner matcher can depend on bound nodes, 00170 // and we need to actively discard the bound nodes, otherwise 00171 // the inner matcher will reset the bound nodes if it doesn't 00172 // match, but this would be inversed by 'unless'. 00173 BoundNodesTreeBuilder Discard(*Builder); 00174 return !InnerMatchers[0].matches(DynNode, Finder, &Discard); 00175 } 00176 00177 bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 00178 ASTMatchFinder *Finder, 00179 BoundNodesTreeBuilder *Builder, 00180 ArrayRef<DynTypedMatcher> InnerMatchers) { 00181 // allOf leads to one matcher for each alternative in the first 00182 // matcher combined with each alternative in the second matcher. 00183 // Thus, we can reuse the same Builder. 00184 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) { 00185 if (!InnerMatcher.matches(DynNode, Finder, Builder)) 00186 return false; 00187 } 00188 return true; 00189 } 00190 00191 bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 00192 ASTMatchFinder *Finder, 00193 BoundNodesTreeBuilder *Builder, 00194 ArrayRef<DynTypedMatcher> InnerMatchers) { 00195 BoundNodesTreeBuilder Result; 00196 bool Matched = false; 00197 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) { 00198 BoundNodesTreeBuilder BuilderInner(*Builder); 00199 if (InnerMatcher.matches(DynNode, Finder, &BuilderInner)) { 00200 Matched = true; 00201 Result.addMatch(BuilderInner); 00202 } 00203 } 00204 *Builder = std::move(Result); 00205 return Matched; 00206 } 00207 00208 bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, 00209 ASTMatchFinder *Finder, 00210 BoundNodesTreeBuilder *Builder, 00211 ArrayRef<DynTypedMatcher> InnerMatchers) { 00212 for (const DynTypedMatcher &InnerMatcher : InnerMatchers) { 00213 BoundNodesTreeBuilder Result = *Builder; 00214 if (InnerMatcher.matches(DynNode, Finder, &Result)) { 00215 *Builder = std::move(Result); 00216 return true; 00217 } 00218 } 00219 return false; 00220 } 00221 00222 HasNameMatcher::HasNameMatcher(StringRef NameRef) 00223 : UseUnqualifiedMatch(NameRef.find("::") == NameRef.npos), Name(NameRef) { 00224 assert(!Name.empty()); 00225 } 00226 00227 bool HasNameMatcher::matchesNodeUnqualified(const NamedDecl &Node) const { 00228 assert(UseUnqualifiedMatch); 00229 if (Node.getIdentifier()) { 00230 // Simple name. 00231 return Name == Node.getName(); 00232 } 00233 if (Node.getDeclName()) { 00234 // Name needs to be constructed. 00235 llvm::SmallString<128> NodeName; 00236 llvm::raw_svector_ostream OS(NodeName); 00237 Node.printName(OS); 00238 return Name == OS.str(); 00239 } 00240 return false; 00241 } 00242 00243 bool HasNameMatcher::matchesNodeFull(const NamedDecl &Node) const { 00244 llvm::SmallString<128> NodeName = StringRef("::"); 00245 llvm::raw_svector_ostream OS(NodeName); 00246 Node.printQualifiedName(OS); 00247 const StringRef FullName = OS.str(); 00248 const StringRef Pattern = Name; 00249 00250 if (Pattern.startswith("::")) 00251 return FullName == Pattern; 00252 00253 return FullName.endswith(Pattern) && 00254 FullName.drop_back(Pattern.size()).endswith("::"); 00255 } 00256 00257 bool HasNameMatcher::matchesNode(const NamedDecl &Node) const { 00258 // FIXME: There is still room for improvement, but it would require copying a 00259 // lot of the logic from NamedDecl::printQualifiedName(). The benchmarks do 00260 // not show like that extra complexity is needed right now. 00261 if (UseUnqualifiedMatch) { 00262 assert(matchesNodeUnqualified(Node) == matchesNodeFull(Node)); 00263 return matchesNodeUnqualified(Node); 00264 } 00265 return matchesNodeFull(Node); 00266 } 00267 00268 } // end namespace internal 00269 } // end namespace ast_matchers 00270 } // end namespace clang