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 Constructors[MatcherName] = Callback; 48 } 49 50 #define REGISTER_MATCHER(name) \ 51 registerMatcher(#name, internal::makeMatcherAutoMarshall( \ 52 ::clang::ast_matchers::name, #name)); 53 54 /// \brief Generate a registry map with all the known matchers. 55 RegistryMaps::RegistryMaps() { 56 // TODO: This list is not complete. It only has non-overloaded matchers, 57 // which are the simplest to add to the system. Overloaded matchers require 58 // more supporting code that was omitted from the first revision for 59 // simplicitly of code review. 60 61 REGISTER_MATCHER(binaryOperator); 62 REGISTER_MATCHER(bindTemporaryExpr); 63 REGISTER_MATCHER(boolLiteral); 64 REGISTER_MATCHER(callExpr); 65 REGISTER_MATCHER(characterLiteral); 66 REGISTER_MATCHER(compoundStmt); 67 REGISTER_MATCHER(conditionalOperator); 68 REGISTER_MATCHER(constCastExpr); 69 REGISTER_MATCHER(constructExpr); 70 REGISTER_MATCHER(constructorDecl); 71 REGISTER_MATCHER(declRefExpr); 72 REGISTER_MATCHER(declStmt); 73 REGISTER_MATCHER(defaultArgExpr); 74 REGISTER_MATCHER(doStmt); 75 REGISTER_MATCHER(dynamicCastExpr); 76 REGISTER_MATCHER(explicitCastExpr); 77 REGISTER_MATCHER(expr); 78 REGISTER_MATCHER(fieldDecl); 79 REGISTER_MATCHER(forStmt); 80 REGISTER_MATCHER(functionDecl); 81 REGISTER_MATCHER(hasAnyParameter); 82 REGISTER_MATCHER(hasAnySubstatement); 83 REGISTER_MATCHER(hasConditionVariableStatement); 84 REGISTER_MATCHER(hasDestinationType); 85 REGISTER_MATCHER(hasEitherOperand); 86 REGISTER_MATCHER(hasFalseExpression); 87 REGISTER_MATCHER(hasImplicitDestinationType); 88 REGISTER_MATCHER(hasInitializer); 89 REGISTER_MATCHER(hasLHS); 90 REGISTER_MATCHER(hasName); 91 REGISTER_MATCHER(hasObjectExpression); 92 REGISTER_MATCHER(hasRHS); 93 REGISTER_MATCHER(hasSourceExpression); 94 REGISTER_MATCHER(hasTrueExpression); 95 REGISTER_MATCHER(hasUnaryOperand); 96 REGISTER_MATCHER(ifStmt); 97 REGISTER_MATCHER(implicitCastExpr); 98 REGISTER_MATCHER(integerLiteral); 99 REGISTER_MATCHER(isArrow); 100 REGISTER_MATCHER(isConstQualified); 101 REGISTER_MATCHER(isImplicit); 102 REGISTER_MATCHER(member); 103 REGISTER_MATCHER(memberExpr); 104 REGISTER_MATCHER(methodDecl); 105 REGISTER_MATCHER(namedDecl); 106 REGISTER_MATCHER(newExpr); 107 REGISTER_MATCHER(ofClass); 108 REGISTER_MATCHER(on); 109 REGISTER_MATCHER(onImplicitObjectArgument); 110 REGISTER_MATCHER(operatorCallExpr); 111 REGISTER_MATCHER(recordDecl); 112 REGISTER_MATCHER(reinterpretCastExpr); 113 REGISTER_MATCHER(staticCastExpr); 114 REGISTER_MATCHER(stmt); 115 REGISTER_MATCHER(stringLiteral); 116 REGISTER_MATCHER(switchCase); 117 REGISTER_MATCHER(to); 118 REGISTER_MATCHER(unaryOperator); 119 REGISTER_MATCHER(varDecl); 120 REGISTER_MATCHER(whileStmt); 121 } 122 123 RegistryMaps::~RegistryMaps() { 124 for (ConstructorMap::iterator it = Constructors.begin(), 125 end = Constructors.end(); 126 it != end; ++it) { 127 delete it->second; 128 } 129 } 130 131 static llvm::ManagedStatic<RegistryMaps> RegistryData; 132 133 } // anonymous namespace 134 135 // static 136 DynTypedMatcher *Registry::constructMatcher(StringRef MatcherName, 137 const SourceRange &NameRange, 138 ArrayRef<ParserValue> Args, 139 Diagnostics *Error) { 140 ConstructorMap::const_iterator it = 141 RegistryData->constructors().find(MatcherName); 142 if (it == RegistryData->constructors().end()) { 143 Error->pushErrorFrame(NameRange, Error->ET_RegistryNotFound) 144 << MatcherName; 145 return NULL; 146 } 147 148 return it->second->run(NameRange, Args, Error); 149 } 150 151 // static 152 DynTypedMatcher *Registry::constructBoundMatcher(StringRef MatcherName, 153 const SourceRange &NameRange, 154 StringRef BindID, 155 ArrayRef<ParserValue> Args, 156 Diagnostics *Error) { 157 OwningPtr<DynTypedMatcher> Out( 158 constructMatcher(MatcherName, NameRange, Args, Error)); 159 if (!Out) return NULL; 160 DynTypedMatcher *Bound = Out->tryBind(BindID); 161 if (!Bound) { 162 Error->pushErrorFrame(NameRange, Error->ET_RegistryNotBindable); 163 return NULL; 164 } 165 return Bound; 166 } 167 168 } // namespace dynamic 169 } // namespace ast_matchers 170 } // namespace clang 171