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