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