xref: /llvm-project/clang/lib/ASTMatchers/Dynamic/Registry.cpp (revision a37bb8c01a980d06142e81b4b6d15e1c86a5d452)
1 //===--- Registry.cpp - Matcher registry -------------------------===//
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 /// \file
11 /// \brief Registry map populated at static initialization time.
12 ///
13 //===------------------------------------------------------------===//
14 
15 #include "clang/ASTMatchers/Dynamic/Registry.h"
16 
17 #include <utility>
18 
19 #include "Marshallers.h"
20 #include "clang/ASTMatchers/ASTMatchers.h"
21 #include "llvm/ADT/StringMap.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/Support/ManagedStatic.h"
24 
25 namespace clang {
26 namespace ast_matchers {
27 namespace dynamic {
28 namespace {
29 
30 using internal::MatcherCreateCallback;
31 
32 typedef llvm::StringMap<const MatcherCreateCallback *> ConstructorMap;
33 class RegistryMaps {
34 public:
35   RegistryMaps();
36   ~RegistryMaps();
37 
38   const ConstructorMap &constructors() const { return Constructors; }
39 
40 private:
41   void registerMatcher(StringRef MatcherName, MatcherCreateCallback *Callback);
42   ConstructorMap Constructors;
43 };
44 
45 void RegistryMaps::registerMatcher(StringRef MatcherName,
46                                    MatcherCreateCallback *Callback) {
47   assert(Constructors.find(MatcherName) == Constructors.end());
48   Constructors[MatcherName] = Callback;
49 }
50 
51 #define REGISTER_MATCHER(name)                                                 \
52   registerMatcher(#name, internal::makeMatcherAutoMarshall(                    \
53                              ::clang::ast_matchers::name, #name));
54 
55 /// \brief Generate a registry map with all the known matchers.
56 RegistryMaps::RegistryMaps() {
57   // TODO: Here is the list of the missing matchers, grouped by reason.
58   //
59   // Need Variant/Parser fixes:
60   // ofKind
61   //
62   // Function overloaded by args:
63   // hasType
64   // callee
65   // hasPrefix
66   // isDerivedFrom
67   // isSameOrDerivedFrom
68   // pointsTo
69   // references
70   // thisPointerType
71   //
72   // Polymorphic + argument overload:
73   // unless
74   // eachOf
75   // anyOf
76   // allOf
77   // findAll
78   //
79   // Adaptative matcher (similar to polymorphic matcher):
80   // has
81   // forEach
82   // forEachDescendant
83   // hasDescendant
84   // hasParent
85   // hasAncestor
86   //
87   // Other:
88   // loc
89   // equals
90   // equalsNode
91   // hasDeclaration
92 
93   REGISTER_MATCHER(accessSpecDecl);
94   REGISTER_MATCHER(alignOfExpr);
95   REGISTER_MATCHER(anything);
96   REGISTER_MATCHER(argumentCountIs);
97   REGISTER_MATCHER(arraySubscriptExpr);
98   REGISTER_MATCHER(arrayType);
99   REGISTER_MATCHER(asString);
100   REGISTER_MATCHER(asmStmt);
101   REGISTER_MATCHER(atomicType);
102   REGISTER_MATCHER(autoType);
103   REGISTER_MATCHER(binaryOperator);
104   REGISTER_MATCHER(bindTemporaryExpr);
105   REGISTER_MATCHER(blockPointerType);
106   REGISTER_MATCHER(boolLiteral);
107   REGISTER_MATCHER(breakStmt);
108   REGISTER_MATCHER(builtinType);
109   REGISTER_MATCHER(cStyleCastExpr);
110   REGISTER_MATCHER(callExpr);
111   REGISTER_MATCHER(castExpr);
112   REGISTER_MATCHER(catchStmt);
113   REGISTER_MATCHER(characterLiteral);
114   REGISTER_MATCHER(classTemplateDecl);
115   REGISTER_MATCHER(classTemplateSpecializationDecl);
116   REGISTER_MATCHER(complexType);
117   REGISTER_MATCHER(compoundLiteralExpr);
118   REGISTER_MATCHER(compoundStmt);
119   REGISTER_MATCHER(conditionalOperator);
120   REGISTER_MATCHER(constCastExpr);
121   REGISTER_MATCHER(constantArrayType);
122   REGISTER_MATCHER(constructExpr);
123   REGISTER_MATCHER(constructorDecl);
124   REGISTER_MATCHER(containsDeclaration);
125   REGISTER_MATCHER(continueStmt);
126   REGISTER_MATCHER(decl);
127   REGISTER_MATCHER(declCountIs);
128   REGISTER_MATCHER(declRefExpr);
129   REGISTER_MATCHER(declStmt);
130   REGISTER_MATCHER(defaultArgExpr);
131   REGISTER_MATCHER(deleteExpr);
132   REGISTER_MATCHER(dependentSizedArrayType);
133   REGISTER_MATCHER(destructorDecl);
134   REGISTER_MATCHER(doStmt);
135   REGISTER_MATCHER(dynamicCastExpr);
136   REGISTER_MATCHER(elaboratedType);
137   REGISTER_MATCHER(enumConstantDecl);
138   REGISTER_MATCHER(enumDecl);
139   REGISTER_MATCHER(explicitCastExpr);
140   REGISTER_MATCHER(expr);
141   REGISTER_MATCHER(fieldDecl);
142   REGISTER_MATCHER(forField);
143   REGISTER_MATCHER(forRangeStmt);
144   REGISTER_MATCHER(forStmt);
145   REGISTER_MATCHER(functionDecl);
146   REGISTER_MATCHER(functionTemplateDecl);
147   REGISTER_MATCHER(functionType);
148   REGISTER_MATCHER(functionalCastExpr);
149   REGISTER_MATCHER(gotoStmt);
150   REGISTER_MATCHER(hasAnyArgument);
151   REGISTER_MATCHER(hasAnyConstructorInitializer);
152   REGISTER_MATCHER(hasAnyParameter);
153   REGISTER_MATCHER(hasAnySubstatement);
154   REGISTER_MATCHER(hasAnyTemplateArgument);
155   REGISTER_MATCHER(hasAnyUsingShadowDecl);
156   REGISTER_MATCHER(hasArgument);
157   REGISTER_MATCHER(hasArgumentOfType);
158   REGISTER_MATCHER(hasBase);
159   REGISTER_MATCHER(hasBody);
160   REGISTER_MATCHER(hasCanonicalType);
161   REGISTER_MATCHER(hasCondition);
162   REGISTER_MATCHER(hasConditionVariableStatement);
163   REGISTER_MATCHER(hasDeclContext);
164   REGISTER_MATCHER(hasDeducedType);
165   REGISTER_MATCHER(hasDestinationType);
166   REGISTER_MATCHER(hasEitherOperand);
167   REGISTER_MATCHER(hasElementType);
168   REGISTER_MATCHER(hasFalseExpression);
169   REGISTER_MATCHER(hasImplicitDestinationType);
170   REGISTER_MATCHER(hasIncrement);
171   REGISTER_MATCHER(hasIndex);
172   REGISTER_MATCHER(hasInitializer);
173   REGISTER_MATCHER(hasLHS);
174   REGISTER_MATCHER(hasLocalQualifiers);
175   REGISTER_MATCHER(hasLoopInit);
176   REGISTER_MATCHER(hasMethod);
177   REGISTER_MATCHER(hasName);
178   REGISTER_MATCHER(hasObjectExpression);
179   REGISTER_MATCHER(hasOperatorName);
180   REGISTER_MATCHER(hasOverloadedOperatorName);
181   REGISTER_MATCHER(hasParameter);
182   REGISTER_MATCHER(hasQualifier);
183   REGISTER_MATCHER(hasRHS);
184   REGISTER_MATCHER(hasSingleDecl);
185   REGISTER_MATCHER(hasSize);
186   REGISTER_MATCHER(hasSizeExpr);
187   REGISTER_MATCHER(hasSourceExpression);
188   REGISTER_MATCHER(hasTargetDecl);
189   REGISTER_MATCHER(hasTemplateArgument);
190   REGISTER_MATCHER(hasTrueExpression);
191   REGISTER_MATCHER(hasUnaryOperand);
192   REGISTER_MATCHER(hasValueType);
193   REGISTER_MATCHER(ifStmt);
194   REGISTER_MATCHER(ignoringImpCasts);
195   REGISTER_MATCHER(ignoringParenCasts);
196   REGISTER_MATCHER(ignoringParenImpCasts);
197   REGISTER_MATCHER(implicitCastExpr);
198   REGISTER_MATCHER(incompleteArrayType);
199   REGISTER_MATCHER(initListExpr);
200   REGISTER_MATCHER(innerType);
201   REGISTER_MATCHER(integerLiteral);
202   REGISTER_MATCHER(isArrow);
203   REGISTER_MATCHER(isConstQualified);
204   REGISTER_MATCHER(isDefinition);
205   REGISTER_MATCHER(isExplicitTemplateSpecialization);
206   REGISTER_MATCHER(isExternC);
207   REGISTER_MATCHER(isImplicit);
208   REGISTER_MATCHER(isInteger);
209   REGISTER_MATCHER(isOverride);
210   REGISTER_MATCHER(isPrivate);
211   REGISTER_MATCHER(isProtected);
212   REGISTER_MATCHER(isPublic);
213   REGISTER_MATCHER(isTemplateInstantiation);
214   REGISTER_MATCHER(isVirtual);
215   REGISTER_MATCHER(isWritten);
216   REGISTER_MATCHER(lValueReferenceType);
217   REGISTER_MATCHER(labelStmt);
218   REGISTER_MATCHER(lambdaExpr);
219   REGISTER_MATCHER(matchesName);
220   REGISTER_MATCHER(materializeTemporaryExpr);
221   REGISTER_MATCHER(member);
222   REGISTER_MATCHER(memberCallExpr);
223   REGISTER_MATCHER(memberExpr);
224   REGISTER_MATCHER(memberPointerType);
225   REGISTER_MATCHER(methodDecl);
226   REGISTER_MATCHER(namedDecl);
227   REGISTER_MATCHER(namesType);
228   REGISTER_MATCHER(namespaceDecl);
229   REGISTER_MATCHER(nestedNameSpecifier);
230   REGISTER_MATCHER(nestedNameSpecifierLoc);
231   REGISTER_MATCHER(newExpr);
232   REGISTER_MATCHER(nullPtrLiteralExpr);
233   REGISTER_MATCHER(nullStmt);
234   REGISTER_MATCHER(ofClass);
235   REGISTER_MATCHER(on);
236   REGISTER_MATCHER(onImplicitObjectArgument);
237   REGISTER_MATCHER(operatorCallExpr);
238   REGISTER_MATCHER(parameterCountIs);
239   REGISTER_MATCHER(parenType);
240   REGISTER_MATCHER(pointee);
241   REGISTER_MATCHER(pointerType);
242   REGISTER_MATCHER(qualType);
243   REGISTER_MATCHER(rValueReferenceType);
244   REGISTER_MATCHER(recordDecl);
245   REGISTER_MATCHER(recordType);
246   REGISTER_MATCHER(referenceType);
247   REGISTER_MATCHER(refersToDeclaration);
248   REGISTER_MATCHER(refersToType);
249   REGISTER_MATCHER(reinterpretCastExpr);
250   REGISTER_MATCHER(returnStmt);
251   REGISTER_MATCHER(returns);
252   REGISTER_MATCHER(sizeOfExpr);
253   REGISTER_MATCHER(specifiesNamespace);
254   REGISTER_MATCHER(specifiesType);
255   REGISTER_MATCHER(specifiesTypeLoc);
256   REGISTER_MATCHER(statementCountIs);
257   REGISTER_MATCHER(staticCastExpr);
258   REGISTER_MATCHER(stmt);
259   REGISTER_MATCHER(stringLiteral);
260   REGISTER_MATCHER(switchCase);
261   REGISTER_MATCHER(switchStmt);
262   REGISTER_MATCHER(templateSpecializationType);
263   REGISTER_MATCHER(thisExpr);
264   REGISTER_MATCHER(throughUsingDecl);
265   REGISTER_MATCHER(throwExpr);
266   REGISTER_MATCHER(to);
267   REGISTER_MATCHER(tryStmt);
268   REGISTER_MATCHER(type);
269   REGISTER_MATCHER(typeLoc);
270   REGISTER_MATCHER(typedefType);
271   REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
272   REGISTER_MATCHER(unaryOperator);
273   REGISTER_MATCHER(userDefinedLiteral);
274   REGISTER_MATCHER(usingDecl);
275   REGISTER_MATCHER(varDecl);
276   REGISTER_MATCHER(variableArrayType);
277   REGISTER_MATCHER(whileStmt);
278   REGISTER_MATCHER(withInitializer);
279 }
280 
281 RegistryMaps::~RegistryMaps() {
282   for (ConstructorMap::iterator it = Constructors.begin(),
283                                 end = Constructors.end();
284        it != end; ++it) {
285     delete it->second;
286   }
287 }
288 
289 static llvm::ManagedStatic<RegistryMaps> RegistryData;
290 
291 } // anonymous namespace
292 
293 // static
294 MatcherList Registry::constructMatcher(StringRef MatcherName,
295                                        const SourceRange &NameRange,
296                                        ArrayRef<ParserValue> Args,
297                                        Diagnostics *Error) {
298   ConstructorMap::const_iterator it =
299       RegistryData->constructors().find(MatcherName);
300   if (it == RegistryData->constructors().end()) {
301     Error->addError(NameRange, Error->ET_RegistryNotFound) << MatcherName;
302     return MatcherList();
303   }
304 
305   return it->second->run(NameRange, Args, Error);
306 }
307 
308 // static
309 MatcherList Registry::constructBoundMatcher(StringRef MatcherName,
310                                             const SourceRange &NameRange,
311                                             StringRef BindID,
312                                             ArrayRef<ParserValue> Args,
313                                             Diagnostics *Error) {
314   MatcherList Out = constructMatcher(MatcherName, NameRange, Args, Error);
315   if (Out.empty()) return Out;
316 
317   ArrayRef<const DynTypedMatcher*> Matchers = Out.matchers();
318   if (Matchers.size() == 1) {
319     OwningPtr<DynTypedMatcher> Bound(Matchers[0]->tryBind(BindID));
320     if (Bound) {
321       return *Bound;
322     }
323   }
324   Error->addError(NameRange, Error->ET_RegistryNotBindable);
325   return MatcherList();
326 }
327 
328 }  // namespace dynamic
329 }  // namespace ast_matchers
330 }  // namespace clang
331