Samuel Benzaquen | e30903d | 2013-05-15 19:49:05 +0000 | [diff] [blame] | 1 | //===--- Registry.cpp - Matcher registry -------------------------===// |
Manuel Klimek | f7f295f | 2013-05-14 09:13:00 +0000 | [diff] [blame] | 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 | // |
Samuel Benzaquen | e30903d | 2013-05-15 19:49:05 +0000 | [diff] [blame] | 8 | //===------------------------------------------------------------===// |
Manuel Klimek | f7f295f | 2013-05-14 09:13:00 +0000 | [diff] [blame] | 9 | /// |
| 10 | /// \file |
| 11 | /// \brief Registry map populated at static initialization time. |
| 12 | /// |
Samuel Benzaquen | e30903d | 2013-05-15 19:49:05 +0000 | [diff] [blame] | 13 | //===------------------------------------------------------------===// |
Manuel Klimek | f7f295f | 2013-05-14 09:13:00 +0000 | [diff] [blame] | 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 | } // namespace dynamic |
| 152 | } // namespace ast_matchers |
| 153 | } // namespace clang |