clang API Documentation
00001 //===--- Registry.cpp - Matcher registry -------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief Registry map populated at static initialization time. 00012 /// 00013 //===------------------------------------------------------------===// 00014 00015 #include "clang/ASTMatchers/Dynamic/Registry.h" 00016 #include "Marshallers.h" 00017 #include "clang/ASTMatchers/ASTMatchers.h" 00018 #include "llvm/ADT/StringMap.h" 00019 #include "llvm/ADT/StringRef.h" 00020 #include "llvm/Support/ManagedStatic.h" 00021 #include <set> 00022 #include <utility> 00023 00024 using namespace clang::ast_type_traits; 00025 00026 namespace clang { 00027 namespace ast_matchers { 00028 namespace dynamic { 00029 namespace { 00030 00031 using internal::MatcherDescriptor; 00032 00033 typedef llvm::StringMap<const MatcherDescriptor *> ConstructorMap; 00034 class RegistryMaps { 00035 public: 00036 RegistryMaps(); 00037 ~RegistryMaps(); 00038 00039 const ConstructorMap &constructors() const { return Constructors; } 00040 00041 private: 00042 void registerMatcher(StringRef MatcherName, MatcherDescriptor *Callback); 00043 ConstructorMap Constructors; 00044 }; 00045 00046 void RegistryMaps::registerMatcher(StringRef MatcherName, 00047 MatcherDescriptor *Callback) { 00048 assert(Constructors.find(MatcherName) == Constructors.end()); 00049 Constructors[MatcherName] = Callback; 00050 } 00051 00052 #define REGISTER_MATCHER(name) \ 00053 registerMatcher(#name, internal::makeMatcherAutoMarshall( \ 00054 ::clang::ast_matchers::name, #name)); 00055 00056 #define SPECIFIC_MATCHER_OVERLOAD(name, Id) \ 00057 static_cast< ::clang::ast_matchers::name##_Type##Id>( \ 00058 ::clang::ast_matchers::name) 00059 00060 #define REGISTER_OVERLOADED_2(name) \ 00061 do { \ 00062 MatcherDescriptor *Callbacks[] = { \ 00063 internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 0), \ 00064 #name), \ 00065 internal::makeMatcherAutoMarshall(SPECIFIC_MATCHER_OVERLOAD(name, 1), \ 00066 #name) \ 00067 }; \ 00068 registerMatcher(#name, \ 00069 new internal::OverloadedMatcherDescriptor(Callbacks)); \ 00070 } while (0) 00071 00072 /// \brief Generate a registry map with all the known matchers. 00073 RegistryMaps::RegistryMaps() { 00074 // TODO: Here is the list of the missing matchers, grouped by reason. 00075 // 00076 // Need Variant/Parser fixes: 00077 // ofKind 00078 // 00079 // Polymorphic + argument overload: 00080 // findAll 00081 // 00082 // Other: 00083 // equals 00084 // equalsNode 00085 00086 REGISTER_OVERLOADED_2(callee); 00087 REGISTER_OVERLOADED_2(hasPrefix); 00088 REGISTER_OVERLOADED_2(hasType); 00089 REGISTER_OVERLOADED_2(isDerivedFrom); 00090 REGISTER_OVERLOADED_2(isSameOrDerivedFrom); 00091 REGISTER_OVERLOADED_2(loc); 00092 REGISTER_OVERLOADED_2(pointsTo); 00093 REGISTER_OVERLOADED_2(references); 00094 REGISTER_OVERLOADED_2(thisPointerType); 00095 00096 REGISTER_MATCHER(accessSpecDecl); 00097 REGISTER_MATCHER(alignOfExpr); 00098 REGISTER_MATCHER(allOf); 00099 REGISTER_MATCHER(anyOf); 00100 REGISTER_MATCHER(anything); 00101 REGISTER_MATCHER(argumentCountIs); 00102 REGISTER_MATCHER(arraySubscriptExpr); 00103 REGISTER_MATCHER(arrayType); 00104 REGISTER_MATCHER(asmStmt); 00105 REGISTER_MATCHER(asString); 00106 REGISTER_MATCHER(atomicType); 00107 REGISTER_MATCHER(autoType); 00108 REGISTER_MATCHER(binaryOperator); 00109 REGISTER_MATCHER(bindTemporaryExpr); 00110 REGISTER_MATCHER(blockPointerType); 00111 REGISTER_MATCHER(boolLiteral); 00112 REGISTER_MATCHER(breakStmt); 00113 REGISTER_MATCHER(builtinType); 00114 REGISTER_MATCHER(callExpr); 00115 REGISTER_MATCHER(caseStmt); 00116 REGISTER_MATCHER(castExpr); 00117 REGISTER_MATCHER(catchStmt); 00118 REGISTER_MATCHER(characterLiteral); 00119 REGISTER_MATCHER(classTemplateDecl); 00120 REGISTER_MATCHER(classTemplateSpecializationDecl); 00121 REGISTER_MATCHER(complexType); 00122 REGISTER_MATCHER(compoundLiteralExpr); 00123 REGISTER_MATCHER(compoundStmt); 00124 REGISTER_MATCHER(conditionalOperator); 00125 REGISTER_MATCHER(constantArrayType); 00126 REGISTER_MATCHER(constCastExpr); 00127 REGISTER_MATCHER(constructExpr); 00128 REGISTER_MATCHER(constructorDecl); 00129 REGISTER_MATCHER(containsDeclaration); 00130 REGISTER_MATCHER(continueStmt); 00131 REGISTER_MATCHER(cStyleCastExpr); 00132 REGISTER_MATCHER(ctorInitializer); 00133 REGISTER_MATCHER(CUDAKernelCallExpr); 00134 REGISTER_MATCHER(decl); 00135 REGISTER_MATCHER(declaratorDecl); 00136 REGISTER_MATCHER(declCountIs); 00137 REGISTER_MATCHER(declRefExpr); 00138 REGISTER_MATCHER(declStmt); 00139 REGISTER_MATCHER(defaultArgExpr); 00140 REGISTER_MATCHER(defaultStmt); 00141 REGISTER_MATCHER(deleteExpr); 00142 REGISTER_MATCHER(dependentSizedArrayType); 00143 REGISTER_MATCHER(destructorDecl); 00144 REGISTER_MATCHER(doStmt); 00145 REGISTER_MATCHER(dynamicCastExpr); 00146 REGISTER_MATCHER(eachOf); 00147 REGISTER_MATCHER(elaboratedType); 00148 REGISTER_MATCHER(enumConstantDecl); 00149 REGISTER_MATCHER(enumDecl); 00150 REGISTER_MATCHER(equalsBoundNode); 00151 REGISTER_MATCHER(equalsIntegralValue); 00152 REGISTER_MATCHER(explicitCastExpr); 00153 REGISTER_MATCHER(expr); 00154 REGISTER_MATCHER(exprWithCleanups); 00155 REGISTER_MATCHER(fieldDecl); 00156 REGISTER_MATCHER(floatLiteral); 00157 REGISTER_MATCHER(forEach); 00158 REGISTER_MATCHER(forEachConstructorInitializer); 00159 REGISTER_MATCHER(forEachDescendant); 00160 REGISTER_MATCHER(forEachSwitchCase); 00161 REGISTER_MATCHER(forField); 00162 REGISTER_MATCHER(forRangeStmt); 00163 REGISTER_MATCHER(forStmt); 00164 REGISTER_MATCHER(friendDecl); 00165 REGISTER_MATCHER(functionalCastExpr); 00166 REGISTER_MATCHER(functionDecl); 00167 REGISTER_MATCHER(functionTemplateDecl); 00168 REGISTER_MATCHER(functionType); 00169 REGISTER_MATCHER(gotoStmt); 00170 REGISTER_MATCHER(has); 00171 REGISTER_MATCHER(hasAncestor); 00172 REGISTER_MATCHER(hasAnyArgument); 00173 REGISTER_MATCHER(hasAnyConstructorInitializer); 00174 REGISTER_MATCHER(hasAnyParameter); 00175 REGISTER_MATCHER(hasAnySubstatement); 00176 REGISTER_MATCHER(hasAnyTemplateArgument); 00177 REGISTER_MATCHER(hasAnyUsingShadowDecl); 00178 REGISTER_MATCHER(hasArgument); 00179 REGISTER_MATCHER(hasArgumentOfType); 00180 REGISTER_MATCHER(hasAttr); 00181 REGISTER_MATCHER(hasBase); 00182 REGISTER_MATCHER(hasBody); 00183 REGISTER_MATCHER(hasCanonicalType); 00184 REGISTER_MATCHER(hasCaseConstant); 00185 REGISTER_MATCHER(hasCondition); 00186 REGISTER_MATCHER(hasConditionVariableStatement); 00187 REGISTER_MATCHER(hasDeclaration); 00188 REGISTER_MATCHER(hasDeclContext); 00189 REGISTER_MATCHER(hasDeducedType); 00190 REGISTER_MATCHER(hasDescendant); 00191 REGISTER_MATCHER(hasDestinationType); 00192 REGISTER_MATCHER(hasEitherOperand); 00193 REGISTER_MATCHER(hasElementType); 00194 REGISTER_MATCHER(hasElse); 00195 REGISTER_MATCHER(hasFalseExpression); 00196 REGISTER_MATCHER(hasGlobalStorage); 00197 REGISTER_MATCHER(hasImplicitDestinationType); 00198 REGISTER_MATCHER(hasIncrement); 00199 REGISTER_MATCHER(hasIndex); 00200 REGISTER_MATCHER(hasInitializer); 00201 REGISTER_MATCHER(hasLHS); 00202 REGISTER_MATCHER(hasLocalQualifiers); 00203 REGISTER_MATCHER(hasLocalStorage); 00204 REGISTER_MATCHER(hasLoopInit); 00205 REGISTER_MATCHER(hasLoopVariable); 00206 REGISTER_MATCHER(hasMethod); 00207 REGISTER_MATCHER(hasName); 00208 REGISTER_MATCHER(hasObjectExpression); 00209 REGISTER_MATCHER(hasOperatorName); 00210 REGISTER_MATCHER(hasOverloadedOperatorName); 00211 REGISTER_MATCHER(hasParameter); 00212 REGISTER_MATCHER(hasParent); 00213 REGISTER_MATCHER(hasQualifier); 00214 REGISTER_MATCHER(hasRangeInit); 00215 REGISTER_MATCHER(hasRHS); 00216 REGISTER_MATCHER(hasSingleDecl); 00217 REGISTER_MATCHER(hasSize); 00218 REGISTER_MATCHER(hasSizeExpr); 00219 REGISTER_MATCHER(hasSourceExpression); 00220 REGISTER_MATCHER(hasTargetDecl); 00221 REGISTER_MATCHER(hasTemplateArgument); 00222 REGISTER_MATCHER(hasThen); 00223 REGISTER_MATCHER(hasTrueExpression); 00224 REGISTER_MATCHER(hasTypeLoc); 00225 REGISTER_MATCHER(hasUnaryOperand); 00226 REGISTER_MATCHER(hasValueType); 00227 REGISTER_MATCHER(ifStmt); 00228 REGISTER_MATCHER(ignoringImpCasts); 00229 REGISTER_MATCHER(ignoringParenCasts); 00230 REGISTER_MATCHER(ignoringParenImpCasts); 00231 REGISTER_MATCHER(implicitCastExpr); 00232 REGISTER_MATCHER(incompleteArrayType); 00233 REGISTER_MATCHER(initListExpr); 00234 REGISTER_MATCHER(innerType); 00235 REGISTER_MATCHER(integerLiteral); 00236 REGISTER_MATCHER(isArrow); 00237 REGISTER_MATCHER(isConst); 00238 REGISTER_MATCHER(isConstQualified); 00239 REGISTER_MATCHER(isDefinition); 00240 REGISTER_MATCHER(isDeleted); 00241 REGISTER_MATCHER(isExplicitTemplateSpecialization); 00242 REGISTER_MATCHER(isExpr); 00243 REGISTER_MATCHER(isExternC); 00244 REGISTER_MATCHER(isImplicit); 00245 REGISTER_MATCHER(isInstantiated); 00246 REGISTER_MATCHER(isInteger); 00247 REGISTER_MATCHER(isIntegral); 00248 REGISTER_MATCHER(isInTemplateInstantiation); 00249 REGISTER_MATCHER(isListInitialization); 00250 REGISTER_MATCHER(isOverride); 00251 REGISTER_MATCHER(isPrivate); 00252 REGISTER_MATCHER(isProtected); 00253 REGISTER_MATCHER(isPublic); 00254 REGISTER_MATCHER(isPure); 00255 REGISTER_MATCHER(isTemplateInstantiation); 00256 REGISTER_MATCHER(isVirtual); 00257 REGISTER_MATCHER(isWritten); 00258 REGISTER_MATCHER(labelStmt); 00259 REGISTER_MATCHER(lambdaExpr); 00260 REGISTER_MATCHER(lValueReferenceType); 00261 REGISTER_MATCHER(matchesName); 00262 REGISTER_MATCHER(materializeTemporaryExpr); 00263 REGISTER_MATCHER(member); 00264 REGISTER_MATCHER(memberCallExpr); 00265 REGISTER_MATCHER(memberExpr); 00266 REGISTER_MATCHER(memberPointerType); 00267 REGISTER_MATCHER(methodDecl); 00268 REGISTER_MATCHER(namedDecl); 00269 REGISTER_MATCHER(namespaceDecl); 00270 REGISTER_MATCHER(namesType); 00271 REGISTER_MATCHER(nestedNameSpecifier); 00272 REGISTER_MATCHER(nestedNameSpecifierLoc); 00273 REGISTER_MATCHER(newExpr); 00274 REGISTER_MATCHER(nullPtrLiteralExpr); 00275 REGISTER_MATCHER(nullStmt); 00276 REGISTER_MATCHER(ofClass); 00277 REGISTER_MATCHER(on); 00278 REGISTER_MATCHER(onImplicitObjectArgument); 00279 REGISTER_MATCHER(operatorCallExpr); 00280 REGISTER_MATCHER(parameterCountIs); 00281 REGISTER_MATCHER(parenType); 00282 REGISTER_MATCHER(parmVarDecl); 00283 REGISTER_MATCHER(pointee); 00284 REGISTER_MATCHER(pointerType); 00285 REGISTER_MATCHER(qualType); 00286 REGISTER_MATCHER(recordDecl); 00287 REGISTER_MATCHER(recordType); 00288 REGISTER_MATCHER(referenceType); 00289 REGISTER_MATCHER(refersToDeclaration); 00290 REGISTER_MATCHER(refersToIntegralType); 00291 REGISTER_MATCHER(refersToType); 00292 REGISTER_MATCHER(reinterpretCastExpr); 00293 REGISTER_MATCHER(returns); 00294 REGISTER_MATCHER(returnStmt); 00295 REGISTER_MATCHER(rValueReferenceType); 00296 REGISTER_MATCHER(sizeOfExpr); 00297 REGISTER_MATCHER(specifiesNamespace); 00298 REGISTER_MATCHER(specifiesType); 00299 REGISTER_MATCHER(specifiesTypeLoc); 00300 REGISTER_MATCHER(statementCountIs); 00301 REGISTER_MATCHER(staticCastExpr); 00302 REGISTER_MATCHER(stmt); 00303 REGISTER_MATCHER(stringLiteral); 00304 REGISTER_MATCHER(substNonTypeTemplateParmExpr); 00305 REGISTER_MATCHER(switchCase); 00306 REGISTER_MATCHER(switchStmt); 00307 REGISTER_MATCHER(templateArgument); 00308 REGISTER_MATCHER(templateArgumentCountIs); 00309 REGISTER_MATCHER(templateSpecializationType); 00310 REGISTER_MATCHER(temporaryObjectExpr); 00311 REGISTER_MATCHER(thisExpr); 00312 REGISTER_MATCHER(throughUsingDecl); 00313 REGISTER_MATCHER(throwExpr); 00314 REGISTER_MATCHER(to); 00315 REGISTER_MATCHER(tryStmt); 00316 REGISTER_MATCHER(type); 00317 REGISTER_MATCHER(typedefType); 00318 REGISTER_MATCHER(typeLoc); 00319 REGISTER_MATCHER(unaryExprOrTypeTraitExpr); 00320 REGISTER_MATCHER(unaryOperator); 00321 REGISTER_MATCHER(unaryTransformType); 00322 REGISTER_MATCHER(unless); 00323 REGISTER_MATCHER(unresolvedConstructExpr); 00324 REGISTER_MATCHER(unresolvedUsingValueDecl); 00325 REGISTER_MATCHER(userDefinedLiteral); 00326 REGISTER_MATCHER(usingDecl); 00327 REGISTER_MATCHER(usingDirectiveDecl); 00328 REGISTER_MATCHER(valueDecl); 00329 REGISTER_MATCHER(varDecl); 00330 REGISTER_MATCHER(variableArrayType); 00331 REGISTER_MATCHER(whileStmt); 00332 REGISTER_MATCHER(withInitializer); 00333 } 00334 00335 RegistryMaps::~RegistryMaps() { 00336 for (ConstructorMap::iterator it = Constructors.begin(), 00337 end = Constructors.end(); 00338 it != end; ++it) { 00339 delete it->second; 00340 } 00341 } 00342 00343 static llvm::ManagedStatic<RegistryMaps> RegistryData; 00344 00345 } // anonymous namespace 00346 00347 // static 00348 llvm::Optional<MatcherCtor> Registry::lookupMatcherCtor(StringRef MatcherName) { 00349 ConstructorMap::const_iterator it = 00350 RegistryData->constructors().find(MatcherName); 00351 return it == RegistryData->constructors().end() 00352 ? llvm::Optional<MatcherCtor>() 00353 : it->second; 00354 } 00355 00356 namespace { 00357 00358 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, 00359 const std::set<ASTNodeKind> &KS) { 00360 unsigned Count = 0; 00361 for (std::set<ASTNodeKind>::const_iterator I = KS.begin(), E = KS.end(); 00362 I != E; ++I) { 00363 if (I != KS.begin()) 00364 OS << "|"; 00365 if (Count++ == 3) { 00366 OS << "..."; 00367 break; 00368 } 00369 OS << *I; 00370 } 00371 return OS; 00372 } 00373 00374 } // namespace 00375 00376 std::vector<ArgKind> Registry::getAcceptedCompletionTypes( 00377 ArrayRef<std::pair<MatcherCtor, unsigned>> Context) { 00378 ASTNodeKind InitialTypes[] = { 00379 ASTNodeKind::getFromNodeKind<Decl>(), 00380 ASTNodeKind::getFromNodeKind<QualType>(), 00381 ASTNodeKind::getFromNodeKind<Type>(), 00382 ASTNodeKind::getFromNodeKind<Stmt>(), 00383 ASTNodeKind::getFromNodeKind<NestedNameSpecifier>(), 00384 ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>(), 00385 ASTNodeKind::getFromNodeKind<TypeLoc>()}; 00386 00387 // Starting with the above seed of acceptable top-level matcher types, compute 00388 // the acceptable type set for the argument indicated by each context element. 00389 std::set<ArgKind> TypeSet(std::begin(InitialTypes), std::end(InitialTypes)); 00390 for (const auto &CtxEntry : Context) { 00391 MatcherCtor Ctor = CtxEntry.first; 00392 unsigned ArgNumber = CtxEntry.second; 00393 std::vector<ArgKind> NextTypeSet; 00394 for (const ArgKind &Kind : TypeSet) { 00395 if (Kind.getArgKind() == Kind.AK_Matcher && 00396 Ctor->isConvertibleTo(Kind.getMatcherKind()) && 00397 (Ctor->isVariadic() || ArgNumber < Ctor->getNumArgs())) 00398 Ctor->getArgKinds(Kind.getMatcherKind(), ArgNumber, NextTypeSet); 00399 } 00400 TypeSet.clear(); 00401 TypeSet.insert(NextTypeSet.begin(), NextTypeSet.end()); 00402 } 00403 return std::vector<ArgKind>(TypeSet.begin(), TypeSet.end()); 00404 } 00405 00406 std::vector<MatcherCompletion> 00407 Registry::getMatcherCompletions(ArrayRef<ArgKind> AcceptedTypes) { 00408 std::vector<MatcherCompletion> Completions; 00409 00410 // Search the registry for acceptable matchers. 00411 for (ConstructorMap::const_iterator I = RegistryData->constructors().begin(), 00412 E = RegistryData->constructors().end(); 00413 I != E; ++I) { 00414 std::set<ASTNodeKind> RetKinds; 00415 unsigned NumArgs = I->second->isVariadic() ? 1 : I->second->getNumArgs(); 00416 bool IsPolymorphic = I->second->isPolymorphic(); 00417 std::vector<std::vector<ArgKind>> ArgsKinds(NumArgs); 00418 unsigned MaxSpecificity = 0; 00419 for (const ArgKind& Kind : AcceptedTypes) { 00420 if (Kind.getArgKind() != Kind.AK_Matcher) 00421 continue; 00422 unsigned Specificity; 00423 ASTNodeKind LeastDerivedKind; 00424 if (I->second->isConvertibleTo(Kind.getMatcherKind(), &Specificity, 00425 &LeastDerivedKind)) { 00426 if (MaxSpecificity < Specificity) 00427 MaxSpecificity = Specificity; 00428 RetKinds.insert(LeastDerivedKind); 00429 for (unsigned Arg = 0; Arg != NumArgs; ++Arg) 00430 I->second->getArgKinds(Kind.getMatcherKind(), Arg, ArgsKinds[Arg]); 00431 if (IsPolymorphic) 00432 break; 00433 } 00434 } 00435 00436 if (!RetKinds.empty() && MaxSpecificity > 0) { 00437 std::string Decl; 00438 llvm::raw_string_ostream OS(Decl); 00439 00440 if (IsPolymorphic) { 00441 OS << "Matcher<T> " << I->first() << "(Matcher<T>"; 00442 } else { 00443 OS << "Matcher<" << RetKinds << "> " << I->first() << "("; 00444 for (const std::vector<ArgKind> &Arg : ArgsKinds) { 00445 if (&Arg != &ArgsKinds[0]) 00446 OS << ", "; 00447 00448 bool FirstArgKind = true; 00449 std::set<ASTNodeKind> MatcherKinds; 00450 // Two steps. First all non-matchers, then matchers only. 00451 for (const ArgKind &AK : Arg) { 00452 if (AK.getArgKind() == ArgKind::AK_Matcher) { 00453 MatcherKinds.insert(AK.getMatcherKind()); 00454 } else { 00455 if (!FirstArgKind) OS << "|"; 00456 FirstArgKind = false; 00457 OS << AK.asString(); 00458 } 00459 } 00460 if (!MatcherKinds.empty()) { 00461 if (!FirstArgKind) OS << "|"; 00462 OS << "Matcher<" << MatcherKinds << ">"; 00463 } 00464 } 00465 } 00466 if (I->second->isVariadic()) 00467 OS << "..."; 00468 OS << ")"; 00469 00470 std::string TypedText = I->first(); 00471 TypedText += "("; 00472 if (ArgsKinds.empty()) 00473 TypedText += ")"; 00474 else if (ArgsKinds[0][0].getArgKind() == ArgKind::AK_String) 00475 TypedText += "\""; 00476 00477 Completions.emplace_back(TypedText, OS.str(), MaxSpecificity); 00478 } 00479 } 00480 00481 return Completions; 00482 } 00483 00484 // static 00485 VariantMatcher Registry::constructMatcher(MatcherCtor Ctor, 00486 const SourceRange &NameRange, 00487 ArrayRef<ParserValue> Args, 00488 Diagnostics *Error) { 00489 return Ctor->create(NameRange, Args, Error); 00490 } 00491 00492 // static 00493 VariantMatcher Registry::constructBoundMatcher(MatcherCtor Ctor, 00494 const SourceRange &NameRange, 00495 StringRef BindID, 00496 ArrayRef<ParserValue> Args, 00497 Diagnostics *Error) { 00498 VariantMatcher Out = constructMatcher(Ctor, NameRange, Args, Error); 00499 if (Out.isNull()) return Out; 00500 00501 llvm::Optional<DynTypedMatcher> Result = Out.getSingleMatcher(); 00502 if (Result.hasValue()) { 00503 llvm::Optional<DynTypedMatcher> Bound = Result->tryBind(BindID); 00504 if (Bound.hasValue()) { 00505 return VariantMatcher::SingleMatcher(*Bound); 00506 } 00507 } 00508 Error->addError(NameRange, Error->ET_RegistryNotBindable); 00509 return VariantMatcher(); 00510 } 00511 00512 } // namespace dynamic 00513 } // namespace ast_matchers 00514 } // namespace clang