1e30903d99ca2d530f95f22430a9a01fe2e1921d4Samuel Benzaquen//===--- Registry.cpp - Matcher registry -------------------------===//
2f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
3f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//                     The LLVM Compiler Infrastructure
4f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
5f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// This file is distributed under the University of Illinois Open Source
6f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// License. See LICENSE.TXT for details.
7f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek//
8e30903d99ca2d530f95f22430a9a01fe2e1921d4Samuel Benzaquen//===------------------------------------------------------------===//
9f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
10f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \file
11f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Registry map populated at static initialization time.
12f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek///
13e30903d99ca2d530f95f22430a9a01fe2e1921d4Samuel Benzaquen//===------------------------------------------------------------===//
14f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
15f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/Dynamic/Registry.h"
16f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "Marshallers.h"
17f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "clang/ASTMatchers/ASTMatchers.h"
18f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "llvm/ADT/StringMap.h"
19f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "llvm/ADT/StringRef.h"
20f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#include "llvm/Support/ManagedStatic.h"
21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <set>
22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include <utility>
23651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesusing namespace clang::ast_type_traits;
25f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
26f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace clang {
27f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace ast_matchers {
28f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace dynamic {
29f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimeknamespace {
30f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesusing internal::MatcherDescriptor;
32f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef llvm::StringMap<const MatcherDescriptor *> ConstructorMap;
34f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekclass RegistryMaps {
35f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekpublic:
36f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  RegistryMaps();
37f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ~RegistryMaps();
38f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
39f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  const ConstructorMap &constructors() const { return Constructors; }
40f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
41f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekprivate:
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void registerMatcher(StringRef MatcherName, MatcherDescriptor *Callback);
43f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ConstructorMap Constructors;
44f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek};
45f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
46f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekvoid RegistryMaps::registerMatcher(StringRef MatcherName,
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                   MatcherDescriptor *Callback) {
487a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  assert(Constructors.find(MatcherName) == Constructors.end());
49f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  Constructors[MatcherName] = Callback;
50f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
51f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
52f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek#define REGISTER_MATCHER(name)                                                 \
53f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  registerMatcher(#name, internal::makeMatcherAutoMarshall(                    \
54f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek                             ::clang::ast_matchers::name, #name));
55f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
560e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen#define SPECIFIC_MATCHER_OVERLOAD(name, Id)                                    \
570e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  static_cast< ::clang::ast_matchers::name##_Type##Id>(                        \
580e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      ::clang::ast_matchers::name)
590e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen
600e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen#define REGISTER_OVERLOADED_2(name)                                            \
610e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  do {                                                                         \
62651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    MatcherDescriptor *Callbacks[] = {                                         \
630e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 0),    \
640e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen                                        #name),                                \
650e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 1),    \
660e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen                                        #name)                                 \
670e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen    };                                                                         \
68ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen    registerMatcher(#name,                                                     \
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                    new internal::OverloadedMatcherDescriptor(Callbacks));     \
706de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen  } while (0)
716de440e1989ee7932c942dcba85e862c31bf4604Samuel Benzaquen
72f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek/// \brief Generate a registry map with all the known matchers.
73f7f295f321fd434e1e542844a71f538a56f2f8fbManuel KlimekRegistryMaps::RegistryMaps() {
747a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  // TODO: Here is the list of the missing matchers, grouped by reason.
757a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  //
767a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  // Need Variant/Parser fixes:
777a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  // ofKind
787a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  //
797a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  // Polymorphic + argument overload:
807a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  // findAll
817a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  //
827a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  // Other:
837a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  // equals
847a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  // equalsNode
85f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
860e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  REGISTER_OVERLOADED_2(callee);
870e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  REGISTER_OVERLOADED_2(hasPrefix);
880e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  REGISTER_OVERLOADED_2(hasType);
890e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  REGISTER_OVERLOADED_2(isDerivedFrom);
900e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  REGISTER_OVERLOADED_2(isSameOrDerivedFrom);
91651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_OVERLOADED_2(loc);
920e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  REGISTER_OVERLOADED_2(pointsTo);
930e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  REGISTER_OVERLOADED_2(references);
940e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  REGISTER_OVERLOADED_2(thisPointerType);
950e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen
967a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(accessSpecDecl);
977a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(alignOfExpr);
98a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen  REGISTER_MATCHER(allOf);
99a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen  REGISTER_MATCHER(anyOf);
100ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(anything);
101ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(argumentCountIs);
1027a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(arraySubscriptExpr);
1037a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(arrayType);
1047a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(asString);
1057a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(asmStmt);
1067a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(atomicType);
1077a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(autoType);
108f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(binaryOperator);
109f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(bindTemporaryExpr);
1107a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(blockPointerType);
111f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(boolLiteral);
1127a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(breakStmt);
1137a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(builtinType);
1147a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(cStyleCastExpr);
115f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(callExpr);
116651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(caseStmt);
1177a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(castExpr);
1187a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(catchStmt);
119f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(characterLiteral);
1207a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(classTemplateDecl);
1217a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(classTemplateSpecializationDecl);
1227a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(complexType);
1237a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(compoundLiteralExpr);
124f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(compoundStmt);
125f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(conditionalOperator);
126f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(constCastExpr);
1277a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(constantArrayType);
128f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(constructExpr);
129f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(constructorDecl);
1307a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(containsDeclaration);
1317a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(continueStmt);
13230d405bf736e1f5280e49cc0a7f93c28cfc690d8Stefanus Du Toit  REGISTER_MATCHER(ctorInitializer);
1337a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(decl);
1347a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(declCountIs);
135f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(declRefExpr);
136f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(declStmt);
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(declaratorDecl);
138f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(defaultArgExpr);
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(defaultStmt);
1407a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(deleteExpr);
1417a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(dependentSizedArrayType);
1427a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(destructorDecl);
143f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(doStmt);
144f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(dynamicCastExpr);
145a735090449197f1edcdc85a6080eebc0304a31ddSamuel Benzaquen  REGISTER_MATCHER(eachOf);
1467a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(elaboratedType);
1477a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(enumConstantDecl);
1487a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(enumDecl);
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(equalsBoundNode);
150f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(explicitCastExpr);
151f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(expr);
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(exprWithCleanups);
153f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(fieldDecl);
154c5ae717c2b774bfce6bce4bb51072f664b2d54aaDaniel Jasper  REGISTER_MATCHER(floatLiteral);
155ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen  REGISTER_MATCHER(forEach);
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(forEachConstructorInitializer);
157ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen  REGISTER_MATCHER(forEachDescendant);
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(forEachSwitchCase);
15986e4d744eaa44f7e674e41074913d8ed61f1d433Samuel Benzaquen  REGISTER_MATCHER(forField);
1607a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(forRangeStmt);
161f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(forStmt);
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(friendDecl);
163f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(functionDecl);
1647a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(functionTemplateDecl);
1657a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(functionType);
1667a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(functionalCastExpr);
1677a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(gotoStmt);
168ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen  REGISTER_MATCHER(has);
169ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen  REGISTER_MATCHER(hasAncestor);
170ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(hasAnyArgument);
17186e4d744eaa44f7e674e41074913d8ed61f1d433Samuel Benzaquen  REGISTER_MATCHER(hasAnyConstructorInitializer);
172f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasAnyParameter);
173f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasAnySubstatement);
174671840a66f63f55705175e51fb44f77a55e0e3b6Samuel Benzaquen  REGISTER_MATCHER(hasAnyTemplateArgument);
1757a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasAnyUsingShadowDecl);
176ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(hasArgument);
1777a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasArgumentOfType);
1787a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasBase);
179ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(hasBody);
1807a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasCanonicalType);
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(hasCaseConstant);
182ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(hasCondition);
183f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasConditionVariableStatement);
1847a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasDeclContext);
1856c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen  REGISTER_MATCHER(hasDeclaration);
1863f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  REGISTER_MATCHER(hasDeducedType);
187ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen  REGISTER_MATCHER(hasDescendant);
188f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasDestinationType);
189f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasEitherOperand);
1903f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  REGISTER_MATCHER(hasElementType);
191f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasFalseExpression);
192ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  REGISTER_MATCHER(hasGlobalStorage);
193f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasImplicitDestinationType);
1947a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasIncrement);
1957a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasIndex);
196f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasInitializer);
197f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasLHS);
1987a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasLocalQualifiers);
199ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  REGISTER_MATCHER(hasLocalStorage);
2007a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasLoopInit);
2017a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasMethod);
202f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasName);
203f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasObjectExpression);
204ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(hasOperatorName);
205ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(hasOverloadedOperatorName);
2067a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasParameter);
207ee0da9520fe94f701240e9e1c97773ee412be102Samuel Benzaquen  REGISTER_MATCHER(hasParent);
2087a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasQualifier);
209f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasRHS);
2107a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasSingleDecl);
2117a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasSize);
2127a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasSizeExpr);
213f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasSourceExpression);
2147a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(hasTargetDecl);
215671840a66f63f55705175e51fb44f77a55e0e3b6Samuel Benzaquen  REGISTER_MATCHER(hasTemplateArgument);
216f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasTrueExpression);
217651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(hasTypeLoc);
218f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(hasUnaryOperand);
2193f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  REGISTER_MATCHER(hasValueType);
220f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(ifStmt);
2217a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(ignoringImpCasts);
2227a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(ignoringParenCasts);
2237a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(ignoringParenImpCasts);
224f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(implicitCastExpr);
2257a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(incompleteArrayType);
2267a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(initListExpr);
2273f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  REGISTER_MATCHER(innerType);
228f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(integerLiteral);
229f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(isArrow);
230651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(isConst);
231f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(isConstQualified);
232ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(isDefinition);
233ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(isExplicitTemplateSpecialization);
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(isExpr);
2357a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(isExternC);
236f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(isImplicit);
2377a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(isInteger);
238651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(isListInitialization);
2397a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(isOverride);
2407a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(isPrivate);
2417a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(isProtected);
2427a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(isPublic);
243ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  REGISTER_MATCHER(isTemplateInstantiation);
2447a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(isVirtual);
24586e4d744eaa44f7e674e41074913d8ed61f1d433Samuel Benzaquen  REGISTER_MATCHER(isWritten);
2467a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(lValueReferenceType);
2477a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(labelStmt);
2487a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(lambdaExpr);
2497a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(matchesName);
2507a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(materializeTemporaryExpr);
251f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(member);
2527a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(memberCallExpr);
253f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(memberExpr);
2547a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(memberPointerType);
255f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(methodDecl);
256f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(namedDecl);
2577a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(namesType);
2587a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(namespaceDecl);
2597a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(nestedNameSpecifier);
2607a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(nestedNameSpecifierLoc);
261f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(newExpr);
2627a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(nullPtrLiteralExpr);
2637a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(nullStmt);
264f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(ofClass);
265f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(on);
266f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(onImplicitObjectArgument);
267f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(operatorCallExpr);
2687a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(parameterCountIs);
2697a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(parenType);
270651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(parmVarDecl);
2713f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  REGISTER_MATCHER(pointee);
2727a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(pointerType);
2737a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(qualType);
2747a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(rValueReferenceType);
275f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(recordDecl);
2767a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(recordType);
2777a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(referenceType);
2787a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(refersToDeclaration);
2797a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(refersToType);
280f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(reinterpretCastExpr);
2817a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(returnStmt);
2827a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(returns);
2837a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(sizeOfExpr);
2847a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(specifiesNamespace);
2857a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(specifiesType);
2867a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(specifiesTypeLoc);
2877a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(statementCountIs);
288f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(staticCastExpr);
289f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(stmt);
290f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(stringLiteral);
291f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(switchCase);
2927a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(switchStmt);
2937a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(templateSpecializationType);
294651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(temporaryObjectExpr);
2957a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(thisExpr);
2967a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(throughUsingDecl);
2977a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(throwExpr);
298f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(to);
2997a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(tryStmt);
3007a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(type);
3017a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(typeLoc);
3027a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(typedefType);
3037a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
304f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(unaryOperator);
305651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(unaryTransformType);
306651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(unless);
307651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(unresolvedConstructExpr);
308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  REGISTER_MATCHER(unresolvedUsingValueDecl);
3097a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(userDefinedLiteral);
3107a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(usingDecl);
311f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(varDecl);
3127a337af9e8bc752a2d3b227e4058ed2baf7a19d1Samuel Benzaquen  REGISTER_MATCHER(variableArrayType);
313f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  REGISTER_MATCHER(whileStmt);
31486e4d744eaa44f7e674e41074913d8ed61f1d433Samuel Benzaquen  REGISTER_MATCHER(withInitializer);
315f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
316f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
317f7f295f321fd434e1e542844a71f538a56f2f8fbManuel KlimekRegistryMaps::~RegistryMaps() {
318f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  for (ConstructorMap::iterator it = Constructors.begin(),
319f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek                                end = Constructors.end();
320f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek       it != end; ++it) {
321f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek    delete it->second;
322f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  }
323f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
324f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
325f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimekstatic llvm::ManagedStatic<RegistryMaps> RegistryData;
326f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
327f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek} // anonymous namespace
328f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
329f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek// static
3306bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesllvm::Optional<MatcherCtor> Registry::lookupMatcherCtor(StringRef MatcherName) {
331f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek  ConstructorMap::const_iterator it =
332f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek      RegistryData->constructors().find(MatcherName);
3336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return it == RegistryData->constructors().end()
3346bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines             ? llvm::Optional<MatcherCtor>()
3356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines             : it->second;
336651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
337651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesnamespace {
339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
340651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesllvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
341651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                              const std::set<ASTNodeKind> &KS) {
342651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  unsigned Count = 0;
343651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (std::set<ASTNodeKind>::const_iterator I = KS.begin(), E = KS.end();
344651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       I != E; ++I) {
345651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (I != KS.begin())
346651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "|";
347651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (Count++ == 3) {
348651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << "...";
349651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      break;
350651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
351651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    OS << *I;
352651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
353651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return OS;
354651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
355651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
356651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct ReverseSpecificityThenName {
357651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  bool operator()(const std::pair<unsigned, std::string> &A,
358651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                  const std::pair<unsigned, std::string> &B) const {
359651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return A.first > B.first || (A.first == B.first && A.second < B.second);
360651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
361651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines};
362651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
365651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstd::vector<MatcherCompletion> Registry::getCompletions(
366ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    ArrayRef<std::pair<MatcherCtor, unsigned> > Context) {
367651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASTNodeKind InitialTypes[] = {
368651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ASTNodeKind::getFromNodeKind<Decl>(),
369651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ASTNodeKind::getFromNodeKind<QualType>(),
370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ASTNodeKind::getFromNodeKind<Type>(),
371651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ASTNodeKind::getFromNodeKind<Stmt>(),
372651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ASTNodeKind::getFromNodeKind<NestedNameSpecifier>(),
373651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>(),
374651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    ASTNodeKind::getFromNodeKind<TypeLoc>()
375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  };
376ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  ArrayRef<ASTNodeKind> InitialTypesRef(InitialTypes);
377651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
378651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // Starting with the above seed of acceptable top-level matcher types, compute
379651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // the acceptable type set for the argument indicated by each context element.
380651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::set<ASTNodeKind> TypeSet(InitialTypesRef.begin(), InitialTypesRef.end());
381ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  for (ArrayRef<std::pair<MatcherCtor, unsigned> >::iterator
382651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           CtxI = Context.begin(),
383651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           CtxE = Context.end();
384651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       CtxI != CtxE; ++CtxI) {
385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    std::vector<internal::ArgKind> NextTypeSet;
386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (std::set<ASTNodeKind>::iterator I = TypeSet.begin(), E = TypeSet.end();
387651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         I != E; ++I) {
388651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (CtxI->first->isConvertibleTo(*I) &&
389651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          (CtxI->first->isVariadic() ||
390651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines           CtxI->second < CtxI->first->getNumArgs()))
391651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        CtxI->first->getArgKinds(*I, CtxI->second, NextTypeSet);
392651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
393651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    TypeSet.clear();
394651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (std::vector<internal::ArgKind>::iterator I = NextTypeSet.begin(),
395651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                                  E = NextTypeSet.end();
396651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         I != E; ++I) {
397651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (I->getArgKind() == internal::ArgKind::AK_Matcher)
398651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        TypeSet.insert(I->getMatcherKind());
399651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
400651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
401651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
402651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  typedef std::map<std::pair<unsigned, std::string>, MatcherCompletion,
403651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   ReverseSpecificityThenName> CompletionsTy;
404651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  CompletionsTy Completions;
405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // TypeSet now contains the list of acceptable types for the argument we are
407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  // completing.  Search the registry for acceptable matchers.
408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (ConstructorMap::const_iterator I = RegistryData->constructors().begin(),
409651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                      E = RegistryData->constructors().end();
410651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       I != E; ++I) {
411651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    std::set<ASTNodeKind> RetKinds;
412651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned NumArgs = I->second->isVariadic() ? 1 : I->second->getNumArgs();
413651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    bool IsPolymorphic = I->second->isPolymorphic();
414651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    std::vector<std::vector<internal::ArgKind> > ArgsKinds(NumArgs);
415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    unsigned MaxSpecificity = 0;
416651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    for (std::set<ASTNodeKind>::iterator TI = TypeSet.begin(),
417651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                         TE = TypeSet.end();
418651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         TI != TE; ++TI) {
419651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      unsigned Specificity;
420651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      ASTNodeKind LeastDerivedKind;
421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (I->second->isConvertibleTo(*TI, &Specificity, &LeastDerivedKind)) {
422651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (MaxSpecificity < Specificity)
423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          MaxSpecificity = Specificity;
424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        RetKinds.insert(LeastDerivedKind);
425651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        for (unsigned Arg = 0; Arg != NumArgs; ++Arg)
426651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          I->second->getArgKinds(*TI, Arg, ArgsKinds[Arg]);
427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        if (IsPolymorphic)
428651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          break;
429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
430651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
431651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
432651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    if (!RetKinds.empty() && MaxSpecificity > 0) {
433651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      std::string Decl;
434651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      llvm::raw_string_ostream OS(Decl);
435651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
436651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (IsPolymorphic) {
437651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        OS << "Matcher<T> " << I->first() << "(Matcher<T>";
438651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      } else {
439651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        OS << "Matcher<" << RetKinds << "> " << I->first() << "(";
440651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        for (std::vector<std::vector<internal::ArgKind> >::iterator
441651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 KI = ArgsKinds.begin(),
442651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                 KE = ArgsKinds.end();
443651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines             KI != KE; ++KI) {
444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if (KI != ArgsKinds.begin())
445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            OS << ", ";
446651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          // This currently assumes that a matcher may not overload a
447651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          // non-matcher, and all non-matcher overloads have identical
448651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          // arguments.
449651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          if ((*KI)[0].getArgKind() == internal::ArgKind::AK_Matcher) {
450651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            std::set<ASTNodeKind> MatcherKinds;
451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            std::transform(
452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                KI->begin(), KI->end(),
453651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                std::inserter(MatcherKinds, MatcherKinds.end()),
454651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                std::mem_fun_ref(&internal::ArgKind::getMatcherKind));
455651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            OS << "Matcher<" << MatcherKinds << ">";
456651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          } else {
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            OS << (*KI)[0].asString();
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          }
459651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        }
460651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
461651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (I->second->isVariadic())
462651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        OS << "...";
463651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      OS << ")";
464651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
465651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      std::string TypedText = I->first();
466651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      TypedText += "(";
467651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      if (ArgsKinds.empty())
468651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        TypedText += ")";
469651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      else if (ArgsKinds[0][0].getArgKind() == internal::ArgKind::AK_String)
470651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines        TypedText += "\"";
471651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
472651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      Completions[std::make_pair(MaxSpecificity, I->first())] =
473651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines          MatcherCompletion(TypedText, OS.str());
474651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    }
475651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  }
476651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
477651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::vector<MatcherCompletion> RetVal;
478651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (CompletionsTy::iterator I = Completions.begin(), E = Completions.end();
479651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines       I != E; ++I)
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    RetVal.push_back(I->second);
481651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return RetVal;
482651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
483651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
484651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// static
485651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesVariantMatcher Registry::constructMatcher(MatcherCtor Ctor,
486651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          const SourceRange &NameRange,
487651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          ArrayRef<ParserValue> Args,
488651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                                          Diagnostics *Error) {
489651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return Ctor->create(NameRange, Args, Error);
490f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}
491f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek
4924f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen// static
493651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesVariantMatcher Registry::constructBoundMatcher(MatcherCtor Ctor,
4949d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                               const SourceRange &NameRange,
4959d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                               StringRef BindID,
4969d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                               ArrayRef<ParserValue> Args,
4979d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen                                               Diagnostics *Error) {
498651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  VariantMatcher Out = constructMatcher(Ctor, NameRange, Args, Error);
4999d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen  if (Out.isNull()) return Out;
5009d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen
501b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen  llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher();
502b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen  if (Result.hasValue()) {
503b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen    llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID);
504b7488d77414b000ce2506b520a6b29f845fb3950Samuel Benzaquen    if (Bound.hasValue()) {
5059d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen      return VariantMatcher::SingleMatcher(*Bound);
506ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen    }
5074f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen  }
5088a77c20375874c0759a5cd5b4a34e83465d821b2Samuel Benzaquen  Error->addError(NameRange, Error->ET_RegistryNotBindable);
5099d02807c3ea9782442b98201df68294cd7cd7313Samuel Benzaquen  return VariantMatcher();
5104f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen}
5114f37d925927dfdd0c770702ffb22de38fc2007dcSamuel Benzaquen
512f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace dynamic
513f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace ast_matchers
514f7f295f321fd434e1e542844a71f538a56f2f8fbManuel Klimek}  // namespace clang
515