Parser/Registry argument enhancements.

Summary:
 Parser/Registry argument enhancements.
  - 2 argument support.
  - unsigned values support.

Reviewers: klimek

CC: cfe-commits, revane

Differential Revision: http://llvm-reviews.chandlerc.com/D915

llvm-svn: 183231
diff --git a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
index 4b01b99..79c9389 100644
--- a/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Diagnostics.cpp
@@ -62,6 +62,8 @@
     return "Malformed bind() expression.";
   case Diagnostics::ET_ParserTrailingCode:
     return "Expected end of code.";
+  case Diagnostics::ET_ParserUnsignedError:
+    return "Error parsing unsigned token: <$0>";
 
   case Diagnostics::ET_None:
     return "<N/A>";
diff --git a/clang/lib/ASTMatchers/Dynamic/Marshallers.h b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
index a41ed24..2cc5f7c 100644
--- a/clang/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/clang/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -55,7 +55,13 @@
   static ast_matchers::internal::Matcher<T> get(const VariantValue &Value) {
     return Value.getTypedMatcher<T>();
   }
+};
 
+template <> struct ArgTypeTraits<unsigned> {
+  static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
+  static unsigned get(const VariantValue &Value) {
+    return Value.getUnsigned();
+  }
 };
 
 /// \brief Generic MatcherCreate interface.
@@ -116,15 +122,6 @@
     return NULL;                                                               \
   }
 
-/// \brief Metafunction to normalize argument types.
-///
-/// We need to remove the const& out of the function parameters to be able to
-/// find values on VariantValue.
-template <typename T>
-struct remove_const_ref :
-    public llvm::remove_const<typename llvm::remove_reference<T>::type> {
-};
-
 /// \brief 0-arg marshaller function.
 template <typename ReturnType>
 DynTypedMatcher *matcherMarshall0(ReturnType (*Func)(), StringRef MatcherName,
@@ -136,18 +133,31 @@
 }
 
 /// \brief 1-arg marshaller function.
-template <typename ReturnType, typename InArgType1>
-DynTypedMatcher *matcherMarshall1(ReturnType (*Func)(InArgType1),
+template <typename ReturnType, typename ArgType1>
+DynTypedMatcher *matcherMarshall1(ReturnType (*Func)(ArgType1),
                                   StringRef MatcherName,
                                   const SourceRange &NameRange,
                                   ArrayRef<ParserValue> Args,
                                   Diagnostics *Error) {
-  typedef typename remove_const_ref<InArgType1>::type ArgType1;
   CHECK_ARG_COUNT(1);
   CHECK_ARG_TYPE(0, ArgType1);
   return Func(ArgTypeTraits<ArgType1>::get(Args[0].Value)).clone();
 }
 
+/// \brief 2-arg marshaller function.
+template <typename ReturnType, typename ArgType1, typename ArgType2>
+DynTypedMatcher *matcherMarshall2(ReturnType (*Func)(ArgType1, ArgType2),
+                                  StringRef MatcherName,
+                                  const SourceRange &NameRange,
+                                  ArrayRef<ParserValue> Args,
+                                  Diagnostics *Error) {
+  CHECK_ARG_COUNT(2);
+  CHECK_ARG_TYPE(0, ArgType1);
+  CHECK_ARG_TYPE(1, ArgType2);
+  return Func(ArgTypeTraits<ArgType1>::get(Args[0].Value),
+              ArgTypeTraits<ArgType2>::get(Args[1].Value)).clone();
+}
+
 /// \brief Variadic marshaller function.
 template <typename BaseType, typename DerivedType>
 class VariadicMatcherCreateCallback : public MatcherCreateCallback {
@@ -197,6 +207,15 @@
                                   MatcherName);
 }
 
+/// \brief 2-arg overload
+template <typename ReturnType, typename ArgType1, typename ArgType2>
+MatcherCreateCallback *makeMatcherAutoMarshall(ReturnType (*Func)(ArgType1,
+                                                                  ArgType2),
+                                               StringRef MatcherName) {
+  return createMarshallerCallback(
+      matcherMarshall2<ReturnType, ArgType1, ArgType2>, Func, MatcherName);
+}
+
 /// \brief Variadic overload.
 template <typename MatcherType>
 MatcherCreateCallback *makeMatcherAutoMarshall(
diff --git a/clang/lib/ASTMatchers/Dynamic/Parser.cpp b/clang/lib/ASTMatchers/Dynamic/Parser.cpp
index 1ed40f3..eff50f4 100644
--- a/clang/lib/ASTMatchers/Dynamic/Parser.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -112,6 +112,12 @@
       consumeStringLiteral(&Result);
       break;
 
+    case '0': case '1': case '2': case '3': case '4':
+    case '5': case '6': case '7': case '8': case '9':
+      // Parse an unsigned literal.
+      consumeUnsignedLiteral(&Result);
+      break;
+
     default:
       if (isAlphanumeric(Code[0])) {
         // Parse an identifier
@@ -133,6 +139,35 @@
     return Result;
   }
 
+  /// \brief Consume an unsigned literal.
+  void consumeUnsignedLiteral(TokenInfo *Result) {
+    unsigned Length = 1;
+    if (Code.size() > 1) {
+      // Consume the 'x' or 'b' radix modifier, if present.
+      switch (toLowercase(Code[1])) {
+      case 'x': case 'b': Length = 2;
+      }
+    }
+    while (Length < Code.size() && isHexDigit(Code[Length]))
+      ++Length;
+
+    Result->Text = Code.substr(0, Length);
+    Code = Code.drop_front(Length);
+
+    unsigned Value;
+    if (!Result->Text.getAsInteger(0, Value)) {
+      Result->Kind = TokenInfo::TK_Literal;
+      Result->Value = Value;
+    } else {
+      SourceRange Range;
+      Range.Start = Result->Range.Start;
+      Range.End = currentLocation();
+      Error->pushErrorFrame(Range, Error->ET_ParserUnsignedError)
+          << Result->Text;
+      Result->Kind = TokenInfo::TK_Error;
+    }
+  }
+
   /// \brief Consume a string literal.
   ///
   /// \c Code must be positioned at the start of the literal (the opening
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 6e543fc..5f6b35d 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -44,6 +44,7 @@
 
 void RegistryMaps::registerMatcher(StringRef MatcherName,
                                    MatcherCreateCallback *Callback) {
+  assert(Constructors.find(MatcherName) == Constructors.end());
   Constructors[MatcherName] = Callback;
 }
 
@@ -53,70 +54,236 @@
 
 /// \brief Generate a registry map with all the known matchers.
 RegistryMaps::RegistryMaps() {
-  // TODO: This list is not complete. It only has non-overloaded matchers,
-  // which are the simplest to add to the system. Overloaded matchers require
-  // more supporting code that was omitted from the first revision for
-  // simplicitly of code review.
+  // TODO: Here is the list of the missing matchers, grouped by reason.
+  //
+  // Need DynTypedNode fixes:
+  // hasAnyTemplateArgument
+  // hasTemplateArgument
+  //
+  // Need Variant/Parser fixes:
+  // ofKind
+  //
+  // CXXCtorInitializer support:
+  // hasAnyConstructorInitializer
+  // forField
+  // withInitializer
+  // isWritten
+  // isImplicit
+  //
+  // Type traversal:
+  // hasElementType
+  // hasValueType
+  // hasDeducedType
+  // innerType
+  // pointee
+  //
+  // Function overloaded by args:
+  // hasType
+  // callee
+  // hasPrefix
+  // isDerivedFrom
+  // isSameOrDerivedFrom
+  // pointsTo
+  // references
+  // thisPointerType
+  //
+  // Polymorphic matchers:
+  // anything
+  // hasAnyArgument
+  // isTemplateInstantiation
+  // isExplicitTemplateSpecialization
+  // isDefinition
+  // hasOperatorName
+  // hasOverloadedOperatorName
+  // hasCondition
+  // hasBody
+  // argumentCountIs
+  // hasArgument
+  //
+  // Polymorphic + argument overload:
+  // unless
+  // eachOf
+  // anyOf
+  // allOf
+  // findAll
+  //
+  // Adaptative matcher (similar to polymorphic matcher):
+  // has
+  // forEach
+  // forEachDescendant
+  // hasDescendant
+  // hasParent
+  // hasAncestor
+  //
+  // Other:
+  // loc
+  // equals
+  // equalsNode
+  // hasDeclaration
 
+  REGISTER_MATCHER(accessSpecDecl);
+  REGISTER_MATCHER(alignOfExpr);
+  REGISTER_MATCHER(arraySubscriptExpr);
+  REGISTER_MATCHER(arrayType);
+  REGISTER_MATCHER(asString);
+  REGISTER_MATCHER(asmStmt);
+  REGISTER_MATCHER(atomicType);
+  REGISTER_MATCHER(autoType);
   REGISTER_MATCHER(binaryOperator);
   REGISTER_MATCHER(bindTemporaryExpr);
+  REGISTER_MATCHER(blockPointerType);
   REGISTER_MATCHER(boolLiteral);
+  REGISTER_MATCHER(breakStmt);
+  REGISTER_MATCHER(builtinType);
+  REGISTER_MATCHER(cStyleCastExpr);
   REGISTER_MATCHER(callExpr);
+  REGISTER_MATCHER(castExpr);
+  REGISTER_MATCHER(catchStmt);
   REGISTER_MATCHER(characterLiteral);
+  REGISTER_MATCHER(classTemplateDecl);
+  REGISTER_MATCHER(classTemplateSpecializationDecl);
+  REGISTER_MATCHER(complexType);
+  REGISTER_MATCHER(compoundLiteralExpr);
   REGISTER_MATCHER(compoundStmt);
   REGISTER_MATCHER(conditionalOperator);
   REGISTER_MATCHER(constCastExpr);
+  REGISTER_MATCHER(constantArrayType);
   REGISTER_MATCHER(constructExpr);
   REGISTER_MATCHER(constructorDecl);
+  REGISTER_MATCHER(containsDeclaration);
+  REGISTER_MATCHER(continueStmt);
+  REGISTER_MATCHER(decl);
+  REGISTER_MATCHER(declCountIs);
   REGISTER_MATCHER(declRefExpr);
   REGISTER_MATCHER(declStmt);
   REGISTER_MATCHER(defaultArgExpr);
+  REGISTER_MATCHER(deleteExpr);
+  REGISTER_MATCHER(dependentSizedArrayType);
+  REGISTER_MATCHER(destructorDecl);
   REGISTER_MATCHER(doStmt);
   REGISTER_MATCHER(dynamicCastExpr);
+  REGISTER_MATCHER(elaboratedType);
+  REGISTER_MATCHER(enumConstantDecl);
+  REGISTER_MATCHER(enumDecl);
   REGISTER_MATCHER(explicitCastExpr);
   REGISTER_MATCHER(expr);
   REGISTER_MATCHER(fieldDecl);
+  REGISTER_MATCHER(forRangeStmt);
   REGISTER_MATCHER(forStmt);
   REGISTER_MATCHER(functionDecl);
+  REGISTER_MATCHER(functionTemplateDecl);
+  REGISTER_MATCHER(functionType);
+  REGISTER_MATCHER(functionalCastExpr);
+  REGISTER_MATCHER(gotoStmt);
   REGISTER_MATCHER(hasAnyParameter);
   REGISTER_MATCHER(hasAnySubstatement);
+  REGISTER_MATCHER(hasAnyUsingShadowDecl);
+  REGISTER_MATCHER(hasArgumentOfType);
+  REGISTER_MATCHER(hasBase);
+  REGISTER_MATCHER(hasCanonicalType);
   REGISTER_MATCHER(hasConditionVariableStatement);
+  REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDestinationType);
   REGISTER_MATCHER(hasEitherOperand);
   REGISTER_MATCHER(hasFalseExpression);
   REGISTER_MATCHER(hasImplicitDestinationType);
+  REGISTER_MATCHER(hasIncrement);
+  REGISTER_MATCHER(hasIndex);
   REGISTER_MATCHER(hasInitializer);
   REGISTER_MATCHER(hasLHS);
+  REGISTER_MATCHER(hasLocalQualifiers);
+  REGISTER_MATCHER(hasLoopInit);
+  REGISTER_MATCHER(hasMethod);
   REGISTER_MATCHER(hasName);
   REGISTER_MATCHER(hasObjectExpression);
+  REGISTER_MATCHER(hasParameter);
+  REGISTER_MATCHER(hasQualifier);
   REGISTER_MATCHER(hasRHS);
+  REGISTER_MATCHER(hasSingleDecl);
+  REGISTER_MATCHER(hasSize);
+  REGISTER_MATCHER(hasSizeExpr);
   REGISTER_MATCHER(hasSourceExpression);
+  REGISTER_MATCHER(hasTargetDecl);
   REGISTER_MATCHER(hasTrueExpression);
   REGISTER_MATCHER(hasUnaryOperand);
   REGISTER_MATCHER(ifStmt);
+  REGISTER_MATCHER(ignoringImpCasts);
+  REGISTER_MATCHER(ignoringParenCasts);
+  REGISTER_MATCHER(ignoringParenImpCasts);
   REGISTER_MATCHER(implicitCastExpr);
+  REGISTER_MATCHER(incompleteArrayType);
+  REGISTER_MATCHER(initListExpr);
   REGISTER_MATCHER(integerLiteral);
   REGISTER_MATCHER(isArrow);
   REGISTER_MATCHER(isConstQualified);
+  REGISTER_MATCHER(isExternC);
   REGISTER_MATCHER(isImplicit);
+  REGISTER_MATCHER(isInteger);
+  REGISTER_MATCHER(isOverride);
+  REGISTER_MATCHER(isPrivate);
+  REGISTER_MATCHER(isProtected);
+  REGISTER_MATCHER(isPublic);
+  REGISTER_MATCHER(isVirtual);
+  REGISTER_MATCHER(lValueReferenceType);
+  REGISTER_MATCHER(labelStmt);
+  REGISTER_MATCHER(lambdaExpr);
+  REGISTER_MATCHER(matchesName);
+  REGISTER_MATCHER(materializeTemporaryExpr);
   REGISTER_MATCHER(member);
+  REGISTER_MATCHER(memberCallExpr);
   REGISTER_MATCHER(memberExpr);
+  REGISTER_MATCHER(memberPointerType);
   REGISTER_MATCHER(methodDecl);
   REGISTER_MATCHER(namedDecl);
+  REGISTER_MATCHER(namesType);
+  REGISTER_MATCHER(namespaceDecl);
+  REGISTER_MATCHER(nestedNameSpecifier);
+  REGISTER_MATCHER(nestedNameSpecifierLoc);
   REGISTER_MATCHER(newExpr);
+  REGISTER_MATCHER(nullPtrLiteralExpr);
+  REGISTER_MATCHER(nullStmt);
   REGISTER_MATCHER(ofClass);
   REGISTER_MATCHER(on);
   REGISTER_MATCHER(onImplicitObjectArgument);
   REGISTER_MATCHER(operatorCallExpr);
+  REGISTER_MATCHER(parameterCountIs);
+  REGISTER_MATCHER(parenType);
+  REGISTER_MATCHER(pointerType);
+  REGISTER_MATCHER(qualType);
+  REGISTER_MATCHER(rValueReferenceType);
   REGISTER_MATCHER(recordDecl);
+  REGISTER_MATCHER(recordType);
+  REGISTER_MATCHER(referenceType);
+  REGISTER_MATCHER(refersToDeclaration);
+  REGISTER_MATCHER(refersToType);
   REGISTER_MATCHER(reinterpretCastExpr);
+  REGISTER_MATCHER(returnStmt);
+  REGISTER_MATCHER(returns);
+  REGISTER_MATCHER(sizeOfExpr);
+  REGISTER_MATCHER(specifiesNamespace);
+  REGISTER_MATCHER(specifiesType);
+  REGISTER_MATCHER(specifiesTypeLoc);
+  REGISTER_MATCHER(statementCountIs);
   REGISTER_MATCHER(staticCastExpr);
   REGISTER_MATCHER(stmt);
   REGISTER_MATCHER(stringLiteral);
   REGISTER_MATCHER(switchCase);
+  REGISTER_MATCHER(switchStmt);
+  REGISTER_MATCHER(templateSpecializationType);
+  REGISTER_MATCHER(thisExpr);
+  REGISTER_MATCHER(throughUsingDecl);
+  REGISTER_MATCHER(throwExpr);
   REGISTER_MATCHER(to);
+  REGISTER_MATCHER(tryStmt);
+  REGISTER_MATCHER(type);
+  REGISTER_MATCHER(typeLoc);
+  REGISTER_MATCHER(typedefType);
+  REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
   REGISTER_MATCHER(unaryOperator);
+  REGISTER_MATCHER(userDefinedLiteral);
+  REGISTER_MATCHER(usingDecl);
   REGISTER_MATCHER(varDecl);
+  REGISTER_MATCHER(variableArrayType);
   REGISTER_MATCHER(whileStmt);
 }
 
diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
index e310fbf..6fcbe7f 100644
--- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -22,20 +22,27 @@
   *this = Other;
 }
 
-VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) {
-  setMatcher(Matcher);
+VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
+  setUnsigned(Unsigned);
 }
 
 VariantValue::VariantValue(const std::string &String) : Type(VT_Nothing) {
   setString(String);
 }
 
+VariantValue::VariantValue(const DynTypedMatcher &Matcher) : Type(VT_Nothing) {
+  setMatcher(Matcher);
+}
+
 VariantValue::~VariantValue() { reset(); }
 
 VariantValue &VariantValue::operator=(const VariantValue &Other) {
   if (this == &Other) return *this;
   reset();
   switch (Other.Type) {
+  case VT_Unsigned:
+    setUnsigned(Other.getUnsigned());
+    break;
   case VT_String:
     setString(Other.getString());
     break;
@@ -58,12 +65,28 @@
     delete Value.Matcher;
     break;
   // Cases that do nothing.
+  case VT_Unsigned:
   case VT_Nothing:
     break;
   }
   Type = VT_Nothing;
 }
 
+bool VariantValue::isUnsigned() const {
+  return Type == VT_Unsigned;
+}
+
+unsigned VariantValue::getUnsigned() const {
+  assert(isUnsigned());
+  return Value.Unsigned;
+}
+
+void VariantValue::setUnsigned(unsigned NewValue) {
+  reset();
+  Type = VT_Unsigned;
+  Value.Unsigned = NewValue;
+}
+
 bool VariantValue::isString() const {
   return Type == VT_String;
 }